mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 886137 - Can't inspect objects in the webconsole, while debugging and inspecting; r=past
This commit is contained in:
parent
a8a59fd05f
commit
fff43b3fcf
@ -141,6 +141,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_console_filters.js \
|
||||
browser_console_dead_objects.js \
|
||||
browser_console_iframe_messages.js \
|
||||
browser_console_variables_view_while_debugging_and_inspecting.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Test that makes sure web console eval works while the js debugger paused the
|
||||
// page, and while the inspector is active. See bug 886137.
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-eval-in-stackframe.html";
|
||||
|
||||
let gWebConsole, gJSTerm, gDebuggerWin, gThread, gDebuggerController,
|
||||
gStackframes, gVariablesView;
|
||||
|
||||
function test()
|
||||
{
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
openConsole(null, consoleOpened);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function consoleOpened(hud)
|
||||
{
|
||||
gWebConsole = hud;
|
||||
gJSTerm = hud.jsterm;
|
||||
|
||||
info("openDebugger");
|
||||
openDebugger().then(debuggerOpened);
|
||||
}
|
||||
|
||||
function debuggerOpened(aResult)
|
||||
{
|
||||
gDebuggerWin = aResult.panelWin;
|
||||
gDebuggerController = gDebuggerWin.DebuggerController;
|
||||
gThread = gDebuggerController.activeThread;
|
||||
gStackframes = gDebuggerController.StackFrames;
|
||||
|
||||
openInspector(inspectorOpened);
|
||||
}
|
||||
|
||||
function inspectorOpened(aPanel)
|
||||
{
|
||||
gThread.addOneTimeListener("framesadded", onFramesAdded);
|
||||
|
||||
info("firstCall()");
|
||||
content.wrappedJSObject.firstCall();
|
||||
}
|
||||
|
||||
function onFramesAdded()
|
||||
{
|
||||
info("onFramesAdded");
|
||||
|
||||
openConsole(null, () => gJSTerm.execute("fooObj", onExecuteFooObj));
|
||||
}
|
||||
|
||||
function onExecuteFooObj()
|
||||
{
|
||||
let msg = gWebConsole.outputNode.querySelector(".webconsole-msg-output");
|
||||
ok(msg, "output message found");
|
||||
isnot(msg.textContent.indexOf("[object Object]"), -1, "message text check");
|
||||
|
||||
gJSTerm.once("variablesview-fetched", onFooObjFetch);
|
||||
|
||||
EventUtils.synthesizeMouse(msg, 2, 2, {}, gWebConsole.iframeWindow);
|
||||
}
|
||||
|
||||
function onFooObjFetch(aEvent, aVar)
|
||||
{
|
||||
gVariablesView = aVar._variablesView;
|
||||
ok(gVariablesView, "variables view object");
|
||||
|
||||
findVariableViewProperties(aVar, [
|
||||
{ name: "testProp2", value: "testValue2" },
|
||||
{ name: "testProp", value: "testValue", dontMatch: true },
|
||||
], { webconsole: gWebConsole }).then(onTestPropFound);
|
||||
}
|
||||
|
||||
function onTestPropFound(aResults)
|
||||
{
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the |testProp2| property in the variables view");
|
||||
|
||||
// Check that property value updates work and that jsterm functions can be
|
||||
// used.
|
||||
updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "document.title + foo2 + $('p')",
|
||||
webconsole: gWebConsole,
|
||||
callback: onFooObjFetchAfterUpdate,
|
||||
});
|
||||
}
|
||||
|
||||
function onFooObjFetchAfterUpdate(aEvent, aVar)
|
||||
{
|
||||
info("onFooObjFetchAfterUpdate");
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
let expectedValue = content.document.title + "foo2SecondCall" + para;
|
||||
|
||||
findVariableViewProperties(aVar, [
|
||||
{ name: "testProp2", value: expectedValue },
|
||||
], { webconsole: gWebConsole }).then(onUpdatedTestPropFound);
|
||||
}
|
||||
|
||||
function onUpdatedTestPropFound(aResults)
|
||||
{
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the updated |testProp2| property value");
|
||||
|
||||
// Check that testProp2 was updated.
|
||||
gJSTerm.execute("fooObj.testProp2", onExecuteFooObjTestProp2);
|
||||
}
|
||||
|
||||
function onExecuteFooObjTestProp2()
|
||||
{
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
let expected = content.document.title + "foo2SecondCall" + para;
|
||||
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf(expected), -1,
|
||||
"fooObj.testProp2 is correct");
|
||||
|
||||
gWebConsole = gJSTerm = gDebuggerWin = gThread = gDebuggerController =
|
||||
gStackframes = gVariablesView = null;
|
||||
|
||||
finishTest();
|
||||
}
|
@ -132,14 +132,6 @@ WebConsoleActor.prototype =
|
||||
*/
|
||||
_prefs: null,
|
||||
|
||||
/**
|
||||
* Tells the current inner ID of |this.window|. When the page is navigated, we
|
||||
* need to recreate the jsterm helpers.
|
||||
* @private
|
||||
* @type number
|
||||
*/
|
||||
_globalWindowId: 0,
|
||||
|
||||
/**
|
||||
* Holds a map between inner window IDs and Debugger.Objects for the window
|
||||
* objects.
|
||||
@ -157,16 +149,6 @@ WebConsoleActor.prototype =
|
||||
*/
|
||||
_netEvents: null,
|
||||
|
||||
/**
|
||||
* Object that holds the JSTerm API, the helper functions, for the default
|
||||
* window object.
|
||||
*
|
||||
* @see this._getJSTermHelpers()
|
||||
* @private
|
||||
* @type object
|
||||
*/
|
||||
_jstermHelpers: null,
|
||||
|
||||
/**
|
||||
* A cache of prototype chains for objects that have received a
|
||||
* prototypeAndProperties request.
|
||||
@ -266,10 +248,8 @@ WebConsoleActor.prototype =
|
||||
this._netEvents.clear();
|
||||
this._protoChains.clear();
|
||||
this._dbgGlobals.clear();
|
||||
this._jstermHelpers = null;
|
||||
this.dbg.enabled = false;
|
||||
this.dbg = null;
|
||||
this._globalWindowId = 0;
|
||||
this.conn = this._window = null;
|
||||
},
|
||||
|
||||
@ -741,8 +721,14 @@ WebConsoleActor.prototype =
|
||||
*/
|
||||
_getJSTermHelpers: function WCA__getJSTermHelpers(aDebuggerGlobal)
|
||||
{
|
||||
let helpers = Object.create(this);
|
||||
helpers.sandbox = Object.create(null);
|
||||
let helpers = {
|
||||
window: this.window,
|
||||
chromeWindow: this.chromeWindow.bind(this),
|
||||
makeDebuggeeValue: aDebuggerGlobal.makeDebuggeeValue.bind(aDebuggerGlobal),
|
||||
createValueGrip: this.createValueGrip.bind(this),
|
||||
sandbox: Object.create(null),
|
||||
helperResult: null,
|
||||
};
|
||||
JSTermHelpers(helpers);
|
||||
|
||||
// Make sure the helpers can be used during eval.
|
||||
@ -816,8 +802,9 @@ WebConsoleActor.prototype =
|
||||
aString = "help()";
|
||||
}
|
||||
|
||||
// Find the Debugger.Object of the given ObjectActor. This is used as
|
||||
// a binding during eval: |_self|.
|
||||
let bindSelf = null;
|
||||
|
||||
if (aOptions.bindObjectActor) {
|
||||
let objActor = this.getActorByID(aOptions.bindObjectActor);
|
||||
if (objActor) {
|
||||
@ -825,6 +812,7 @@ WebConsoleActor.prototype =
|
||||
}
|
||||
}
|
||||
|
||||
// Find the Debugger.Frame of the given FrameActor.
|
||||
let frame = null, frameActor = null;
|
||||
if (aOptions.frameActor) {
|
||||
frameActor = this.conn.getActor(aOptions.frameActor);
|
||||
@ -837,20 +825,49 @@ WebConsoleActor.prototype =
|
||||
}
|
||||
}
|
||||
|
||||
let dbg = this.dbg;
|
||||
let dbgWindow = null;
|
||||
let helpers = null;
|
||||
let found$ = false, found$$ = false;
|
||||
|
||||
// Determine which debugger to use, depending on the presence of the
|
||||
// stackframe.
|
||||
// This helps with avoid having bindings from a different Debugger. The
|
||||
// Debugger.Frame comes from the jsdebugger's Debugger instance.
|
||||
let dbg = this.dbg;
|
||||
let dbgWindow = this._getDebuggerGlobal(this.window);
|
||||
if (frame) {
|
||||
// Avoid having bindings from a different Debugger. The Debugger.Frame
|
||||
// comes from the jsdebugger's Debugger instance.
|
||||
dbg = frameActor.threadActor.dbg;
|
||||
dbgWindow = dbg.addDebuggee(this.window);
|
||||
helpers = this._getJSTermHelpers(dbgWindow);
|
||||
}
|
||||
|
||||
// If we have an object to bind to |_self| we need to determine the
|
||||
// global of the given JavaScript object.
|
||||
if (bindSelf) {
|
||||
let jsObj = bindSelf.unsafeDereference();
|
||||
let global = Cu.getGlobalForObject(jsObj);
|
||||
|
||||
// Get the Debugger.Object for the new global.
|
||||
if (global != this.window) {
|
||||
dbgWindow = dbg.addDebuggee(global);
|
||||
|
||||
// Remove the debuggee only if the Debugger instance belongs to the
|
||||
// console actor, to avoid breaking the ThreadActor that owns the
|
||||
// Debugger object.
|
||||
if (dbg == this.dbg) {
|
||||
dbg.removeDebuggee(global);
|
||||
}
|
||||
}
|
||||
|
||||
bindSelf = dbgWindow.makeDebuggeeValue(jsObj);
|
||||
}
|
||||
|
||||
// Get the JSTerm helpers for the given debugger window.
|
||||
let helpers = this._getJSTermHelpers(dbgWindow);
|
||||
let bindings = helpers.sandbox;
|
||||
if (bindSelf) {
|
||||
bindings._self = bindSelf;
|
||||
}
|
||||
|
||||
// Check if the Debugger.Frame or Debugger.Object for the global include
|
||||
// $ or $$. We will not overwrite these functions with the jsterm helpers.
|
||||
let found$ = false, found$$ = false;
|
||||
if (frame) {
|
||||
let env = frame.environment;
|
||||
if (env) {
|
||||
found$ = !!env.find("$");
|
||||
@ -858,39 +875,10 @@ WebConsoleActor.prototype =
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Use the Web Console debugger object.
|
||||
dbgWindow = this._getDebuggerGlobal(this.window);
|
||||
|
||||
let windowId = WebConsoleUtils.getInnerWindowId(this.window);
|
||||
if (this._globalWindowId != windowId) {
|
||||
this._jstermHelpers = null;
|
||||
this._globalWindowId = windowId;
|
||||
}
|
||||
if (!this._jstermHelpers) {
|
||||
this._jstermHelpers = this._getJSTermHelpers(dbgWindow);
|
||||
}
|
||||
|
||||
helpers = this._jstermHelpers;
|
||||
found$ = !!dbgWindow.getOwnPropertyDescriptor("$");
|
||||
found$$ = !!dbgWindow.getOwnPropertyDescriptor("$$");
|
||||
}
|
||||
|
||||
let bindings = helpers.sandbox;
|
||||
if (bindSelf) {
|
||||
// Determine the global of the given JavaScript object.
|
||||
let jsObj = bindSelf.unsafeDereference();
|
||||
let global = Cu.getGlobalForObject(jsObj);
|
||||
|
||||
if (global != this.window) {
|
||||
dbgWindow = dbg.addDebuggee(global);
|
||||
if (dbg == this.dbg) {
|
||||
dbg.removeDebuggee(global);
|
||||
}
|
||||
}
|
||||
|
||||
bindings._self = dbgWindow.makeDebuggeeValue(jsObj);
|
||||
}
|
||||
|
||||
let $ = null, $$ = null;
|
||||
if (found$) {
|
||||
$ = bindings.$;
|
||||
@ -901,6 +889,7 @@ WebConsoleActor.prototype =
|
||||
delete bindings.$$;
|
||||
}
|
||||
|
||||
// Ready to evaluate the string.
|
||||
helpers.evalInput = aString;
|
||||
|
||||
let result;
|
||||
|
Loading…
Reference in New Issue
Block a user