Bug 787975 - Make JSTerm $0 helper work across content processes. r=msucan.

--HG--
extra : rebase_source : b7a3a698effb0b223160fabae5b6f9b0fe820888
This commit is contained in:
Mike Conley 2014-07-31 13:07:27 -04:00
parent 7c0f5a892a
commit e2ad979a38
5 changed files with 63 additions and 31 deletions

View File

@ -580,6 +580,30 @@ WebConsole.prototype = {
return null; return null;
}, },
/**
* Retrieves the current selection from the Inspector, if such a selection
* exists. This is used to pass the ID of the selected actor to the Web
* Console server for the $0 helper.
*
* @return object|null
* A Selection referring to the currently selected node in the
* Inspector.
* If the inspector was never opened, or no node was ever selected,
* then |null| is returned.
*/
getInspectorSelection: function WC_getInspectorSelection()
{
let toolbox = gDevTools.getToolbox(this.target);
if (!toolbox) {
return null;
}
let panel = toolbox.getPanel("inspector");
if (!panel || !panel.selection) {
return null;
}
return panel.selection;
},
/** /**
* Destroy the object. Call this method to avoid memory leaks when the Web * Destroy the object. Call this method to avoid memory leaks when the Web
* Console is closed. * Console is closed.

View File

@ -3264,6 +3264,12 @@ JSTerm.prototype = {
return; return;
} }
let selectedNodeActor = null;
let inspectorSelection = this.hud.owner.getInspectorSelection();
if (inspectorSelection) {
selectedNodeActor = inspectorSelection.nodeFront.actorID;
}
let message = new Messages.Simple(aExecuteString, { let message = new Messages.Simple(aExecuteString, {
category: "input", category: "input",
severity: "log", severity: "log",
@ -3271,7 +3277,11 @@ JSTerm.prototype = {
this.hud.output.addMessage(message); this.hud.output.addMessage(message);
let onResult = this._executeResultCallback.bind(this, message, aCallback); let onResult = this._executeResultCallback.bind(this, message, aCallback);
let options = { frame: this.SELECTED_FRAME }; let options = {
frame: this.SELECTED_FRAME,
selectedNodeActor: selectedNodeActor,
};
this.requestEvaluation(aExecuteString, options).then(onResult, onResult); this.requestEvaluation(aExecuteString, options).then(onResult, onResult);
// Append a new value in the history of executed code, or overwrite the most // Append a new value in the history of executed code, or overwrite the most
@ -3301,6 +3311,9 @@ JSTerm.prototype = {
* user-selected stackframe. * user-selected stackframe.
* If you do not provide a |frame| the string will be evaluated in the * If you do not provide a |frame| the string will be evaluated in the
* global content window. * global content window.
* - selectedNodeActor: tells the NodeActor ID of the current selection in
* the Inspector, if such a selection exists. This is used by helper
* functions that can evaluate on the current selection.
* @return object * @return object
* A promise object that is resolved when the server response is * A promise object that is resolved when the server response is
* received. * received.
@ -3326,6 +3339,7 @@ JSTerm.prototype = {
let evalOptions = { let evalOptions = {
bindObjectActor: aOptions.bindObjectActor, bindObjectActor: aOptions.bindObjectActor,
frameActor: frameActor, frameActor: frameActor,
selectedNodeActor: aOptions.selectedNodeActor,
}; };
this.webConsoleClient.evaluateJS(aString, onResult, evalOptions); this.webConsoleClient.evaluateJS(aString, onResult, evalOptions);

View File

@ -725,7 +725,9 @@ WebConsoleActor.prototype =
bindObjectActor: aRequest.bindObjectActor, bindObjectActor: aRequest.bindObjectActor,
frameActor: aRequest.frameActor, frameActor: aRequest.frameActor,
url: aRequest.url, url: aRequest.url,
selectedNodeActor: aRequest.selectedNodeActor,
}; };
let evalInfo = this.evalWithDebugger(input, evalOptions); let evalInfo = this.evalWithDebugger(input, evalOptions);
let evalResult = evalInfo.result; let evalResult = evalInfo.result;
let helperResult = evalInfo.helperResult; let helperResult = evalInfo.helperResult;
@ -967,6 +969,10 @@ WebConsoleActor.prototype =
* ObjectActor. * ObjectActor.
* - frameActor: the FrameActor ID to use for evaluation. The given * - frameActor: the FrameActor ID to use for evaluation. The given
* debugger frame is used for evaluation, instead of the global window. * debugger frame is used for evaluation, instead of the global window.
* - selectedNodeActor: the NodeActor ID of the currently selected node
* in the Inspector (or null, if there is no selection). This is used
* for helper functions that make reference to the currently selected
* node, like $0.
* @return object * @return object
* An object that holds the following properties: * An object that holds the following properties:
* - dbg: the debugger where the string was evaluated. * - dbg: the debugger where the string was evaluated.
@ -1031,6 +1037,13 @@ WebConsoleActor.prototype =
bindings._self = bindSelf; bindings._self = bindSelf;
} }
if (aOptions.selectedNodeActor) {
let actor = this.conn.getActor(aOptions.selectedNodeActor);
if (actor) {
helpers.selectedNode = actor.rawNode;
}
}
// Check if the Debugger.Frame or Debugger.Object for the global include // Check if the Debugger.Frame or Debugger.Object for the global include
// $ or $$. We will not overwrite these functions with the jsterm helpers. // $ or $$. We will not overwrite these functions with the jsterm helpers.
let found$ = false, found$$ = false; let found$ = false, found$$ = false;
@ -1075,6 +1088,7 @@ WebConsoleActor.prototype =
let helperResult = helpers.helperResult; let helperResult = helpers.helperResult;
delete helpers.evalInput; delete helpers.evalInput;
delete helpers.helperResult; delete helpers.helperResult;
delete helpers.selectedNode;
if ($) { if ($) {
bindings.$ = $; bindings.$ = $;

View File

@ -104,6 +104,11 @@ WebConsoleClient.prototype = {
* *
* - url: the url to evaluate the script as. Defaults to * - url: the url to evaluate the script as. Defaults to
* "debugger eval code". * "debugger eval code".
*
* - selectedNodeActor: the NodeActor ID of the current selection in the
* Inspector, if such a selection exists. This is used by helper functions
* that can reference the currently selected node in the Inspector, like
* $0.
*/ */
evaluateJS: function WCC_evaluateJS(aString, aOnResponse, aOptions = {}) evaluateJS: function WCC_evaluateJS(aString, aOnResponse, aOptions = {})
{ {
@ -114,6 +119,7 @@ WebConsoleClient.prototype = {
bindObjectActor: aOptions.bindObjectActor, bindObjectActor: aOptions.bindObjectActor,
frameActor: aOptions.frameActor, frameActor: aOptions.frameActor,
url: aOptions.url, url: aOptions.url,
selectedNodeActor: aOptions.selectedNodeActor,
}; };
this._client.request(packet, aOnResponse); this._client.request(packet, aOnResponse);
}, },

View File

@ -1563,38 +1563,12 @@ function JSTermHelpers(aOwner)
/** /**
* Returns the currently selected object in the highlighter. * Returns the currently selected object in the highlighter.
* *
* TODO: this implementation crosses the client/server boundaries! This is not * @return Object representing the current selection in the
* usable within a remote browser. To implement this feature correctly we need * Inspector, or null if no selection exists.
* support for remote inspection capabilities within the Inspector as well.
* See bug 787975.
*
* @return nsIDOMElement|null
* The DOM element currently selected in the highlighter.
*/ */
Object.defineProperty(aOwner.sandbox, "$0", { Object.defineProperty(aOwner.sandbox, "$0", {
get: function() { get: function() {
let window = aOwner.chromeWindow(); return aOwner.makeDebuggeeValue(aOwner.selectedNode)
if (!window) {
return null;
}
let target = null;
try {
target = devtools.TargetFactory.forTab(window.gBrowser.selectedTab);
}
catch (ex) {
// If we report this exception the user will get it in the Browser
// Console every time when she evaluates any string.
}
if (!target) {
return null;
}
let toolbox = gDevTools.getToolbox(target);
let node = toolbox && toolbox.selection ? toolbox.selection.node : null;
return node ? aOwner.makeDebuggeeValue(node) : null;
}, },
enumerable: true, enumerable: true,
configurable: false configurable: false