mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 783499 - Web Console should use the debugger API; r=past
This commit is contained in:
parent
73fe13b2fe
commit
6f15b1eb06
@ -404,6 +404,40 @@ WebConsole.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve information about the JavaScript debugger's stackframes list. This
|
||||
* is used to allow the Web Console to evaluate code in the selected
|
||||
* stackframe.
|
||||
*
|
||||
* @return object|null
|
||||
* An object which holds:
|
||||
* - frames: the active ThreadClient.cachedFrames array.
|
||||
* - selected: depth/index of the selected stackframe in the debugger
|
||||
* UI.
|
||||
* If the debugger is not open or if it's not paused, then |null| is
|
||||
* returned.
|
||||
*/
|
||||
getDebuggerFrames: function WC_getDebuggerFrames()
|
||||
{
|
||||
let toolbox = gDevTools.getToolbox(this.target);
|
||||
if (!toolbox) {
|
||||
return null;
|
||||
}
|
||||
let panel = toolbox.getPanel("jsdebugger");
|
||||
if (!panel) {
|
||||
return null;
|
||||
}
|
||||
let framesController = panel.panelWin.gStackFrames;
|
||||
let thread = framesController.activeThread;
|
||||
if (thread && thread.paused) {
|
||||
return {
|
||||
frames: thread.cachedFrames,
|
||||
selected: framesController.currentFrame,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the object. Call this method to avoid memory leaks when the Web
|
||||
* Console is closed.
|
||||
|
@ -13,7 +13,8 @@ const Cr = Components.results;
|
||||
this.EXPORTED_SYMBOLS = ["DebuggerTransport",
|
||||
"DebuggerClient",
|
||||
"debuggerSocketConnect",
|
||||
"LongStringClient"];
|
||||
"LongStringClient",
|
||||
"GripClient"];
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
@ -173,7 +174,6 @@ const UnsolicitedNotifications = {
|
||||
"consoleAPICall": "consoleAPICall",
|
||||
"eventNotification": "eventNotification",
|
||||
"fileActivity": "fileActivity",
|
||||
"locationChange": "locationChange",
|
||||
"networkEvent": "networkEvent",
|
||||
"networkEventUpdate": "networkEventUpdate",
|
||||
"newGlobal": "newGlobal",
|
||||
@ -514,7 +514,7 @@ DebuggerClient.prototype = {
|
||||
}
|
||||
} catch(ex) {
|
||||
dumpn("Error handling response: " + ex + " - stack:\n" + ex.stack);
|
||||
Cu.reportError(ex.message + "\n" + ex.stack);
|
||||
Cu.reportError(ex + "\n" + ex.stack);
|
||||
}
|
||||
|
||||
this._sendRequests();
|
||||
|
@ -900,7 +900,7 @@ ThreadActor.prototype = {
|
||||
return this.threadLifetimePool.objectActors.get(aValue).grip();
|
||||
}
|
||||
|
||||
let actor = new ObjectActor(aValue, this);
|
||||
let actor = new PauseScopedObjectActor(aValue, this);
|
||||
aPool.addActor(actor);
|
||||
aPool.objectActors.set(aValue, actor);
|
||||
return actor.grip();
|
||||
@ -1515,10 +1515,7 @@ function ObjectActor(aObj, aThreadActor)
|
||||
this.threadActor = aThreadActor;
|
||||
}
|
||||
|
||||
ObjectActor.prototype = Object.create(PauseScopedActor.prototype);
|
||||
|
||||
update(ObjectActor.prototype, {
|
||||
constructor: ObjectActor,
|
||||
ObjectActor.prototype = {
|
||||
actorPrefix: "obj",
|
||||
|
||||
/**
|
||||
@ -1552,7 +1549,9 @@ update(ObjectActor.prototype, {
|
||||
* Releases this actor from the pool.
|
||||
*/
|
||||
release: function OA_release() {
|
||||
this.registeredPool.objectActors.delete(this.obj);
|
||||
if (this.registeredPool.objectActors) {
|
||||
this.registeredPool.objectActors.delete(this.obj);
|
||||
}
|
||||
this.registeredPool.removeActor(this);
|
||||
this.disconnect();
|
||||
},
|
||||
@ -1568,11 +1567,10 @@ update(ObjectActor.prototype, {
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onOwnPropertyNames:
|
||||
PauseScopedActor.withPaused(function OA_onOwnPropertyNames(aRequest) {
|
||||
onOwnPropertyNames: function OA_onOwnPropertyNames(aRequest) {
|
||||
return { from: this.actorID,
|
||||
ownPropertyNames: this.obj.getOwnPropertyNames() };
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to provide the prototype and own properties of
|
||||
@ -1581,8 +1579,7 @@ update(ObjectActor.prototype, {
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onPrototypeAndProperties:
|
||||
PauseScopedActor.withPaused(function OA_onPrototypeAndProperties(aRequest) {
|
||||
onPrototypeAndProperties: function OA_onPrototypeAndProperties(aRequest) {
|
||||
if (this.obj.proto) {
|
||||
// Store the object and its prototype to the prototype chain cache, so that
|
||||
// we can evaluate native getter methods for WebIDL attributes that are
|
||||
@ -1608,7 +1605,7 @@ update(ObjectActor.prototype, {
|
||||
return { from: this.actorID,
|
||||
prototype: this.threadActor.createValueGrip(this.obj.proto),
|
||||
ownProperties: ownProperties };
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to provide the prototype of the object.
|
||||
@ -1616,10 +1613,10 @@ update(ObjectActor.prototype, {
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onPrototype: PauseScopedActor.withPaused(function OA_onPrototype(aRequest) {
|
||||
onPrototype: function OA_onPrototype(aRequest) {
|
||||
return { from: this.actorID,
|
||||
prototype: this.threadActor.createValueGrip(this.obj.proto) };
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to provide the property descriptor of the
|
||||
@ -1628,7 +1625,7 @@ update(ObjectActor.prototype, {
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onProperty: PauseScopedActor.withPaused(function OA_onProperty(aRequest) {
|
||||
onProperty: function OA_onProperty(aRequest) {
|
||||
if (!aRequest.name) {
|
||||
return { error: "missingParameter",
|
||||
message: "no property name was specified" };
|
||||
@ -1636,7 +1633,7 @@ update(ObjectActor.prototype, {
|
||||
|
||||
return { from: this.actorID,
|
||||
descriptor: this._propertyDescriptor(aRequest.name) };
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* A helper method that creates a property descriptor for the provided object,
|
||||
@ -1724,7 +1721,7 @@ update(ObjectActor.prototype, {
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onDecompile: PauseScopedActor.withPaused(function OA_onDecompile(aRequest) {
|
||||
onDecompile: function OA_onDecompile(aRequest) {
|
||||
if (this.obj.class !== "Function") {
|
||||
return { error: "objectNotFunction",
|
||||
message: "decompile request is only valid for object grips " +
|
||||
@ -1733,7 +1730,75 @@ update(ObjectActor.prototype, {
|
||||
|
||||
return { from: this.actorID,
|
||||
decompiledCode: this.obj.decompile(!!aRequest.pretty) };
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to provide the parameters of a function.
|
||||
*
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onParameterNames: function OA_onParameterNames(aRequest) {
|
||||
if (this.obj.class !== "Function") {
|
||||
return { error: "objectNotFunction",
|
||||
message: "'parameterNames' request is only valid for object " +
|
||||
"grips with a 'Function' class." };
|
||||
}
|
||||
|
||||
return { parameterNames: this.obj.parameterNames };
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to release a thread-lifetime grip.
|
||||
*
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onRelease: function OA_onRelease(aRequest) {
|
||||
this.release();
|
||||
return {};
|
||||
},
|
||||
};
|
||||
|
||||
ObjectActor.prototype.requestTypes = {
|
||||
"parameterNames": ObjectActor.prototype.onParameterNames,
|
||||
"prototypeAndProperties": ObjectActor.prototype.onPrototypeAndProperties,
|
||||
"prototype": ObjectActor.prototype.onPrototype,
|
||||
"property": ObjectActor.prototype.onProperty,
|
||||
"ownPropertyNames": ObjectActor.prototype.onOwnPropertyNames,
|
||||
"decompile": ObjectActor.prototype.onDecompile,
|
||||
"release": ObjectActor.prototype.onRelease,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a pause-scoped actor for the specified object.
|
||||
* @see ObjectActor
|
||||
*/
|
||||
function PauseScopedObjectActor()
|
||||
{
|
||||
ObjectActor.apply(this, arguments);
|
||||
}
|
||||
|
||||
PauseScopedObjectActor.prototype = Object.create(PauseScopedActor.prototype);
|
||||
|
||||
update(PauseScopedObjectActor.prototype, ObjectActor.prototype);
|
||||
|
||||
update(PauseScopedObjectActor.prototype, {
|
||||
constructor: PauseScopedObjectActor,
|
||||
|
||||
onOwnPropertyNames:
|
||||
PauseScopedActor.withPaused(ObjectActor.prototype.onOwnPropertyNames),
|
||||
|
||||
onPrototypeAndProperties:
|
||||
PauseScopedActor.withPaused(ObjectActor.prototype.onPrototypeAndProperties),
|
||||
|
||||
onPrototype: PauseScopedActor.withPaused(ObjectActor.prototype.onPrototype),
|
||||
onProperty: PauseScopedActor.withPaused(ObjectActor.prototype.onProperty),
|
||||
onDecompile: PauseScopedActor.withPaused(ObjectActor.prototype.onDecompile),
|
||||
|
||||
onParameterNames:
|
||||
PauseScopedActor.withPaused(ObjectActor.prototype.onParameterNames),
|
||||
|
||||
/**
|
||||
* Handle a protocol request to provide the lexical scope of a function.
|
||||
@ -1758,22 +1823,6 @@ update(ObjectActor.prototype, {
|
||||
return { from: this.actorID, scope: envActor.form() };
|
||||
}),
|
||||
|
||||
/**
|
||||
* Handle a protocol request to provide the parameters of a function.
|
||||
*
|
||||
* @param aRequest object
|
||||
* The protocol request object.
|
||||
*/
|
||||
onParameterNames: PauseScopedActor.withPaused(function OA_onParameterNames(aRequest) {
|
||||
if (this.obj.class !== "Function") {
|
||||
return { error: "objectNotFunction",
|
||||
message: "'parameterNames' request is only valid for object " +
|
||||
"grips with a 'Function' class." };
|
||||
}
|
||||
|
||||
return { parameterNames: this.obj.parameterNames };
|
||||
}),
|
||||
|
||||
/**
|
||||
* Handle a protocol request to promote a pause-lifetime grip to a
|
||||
* thread-lifetime grip.
|
||||
@ -1803,17 +1852,10 @@ update(ObjectActor.prototype, {
|
||||
}),
|
||||
});
|
||||
|
||||
ObjectActor.prototype.requestTypes = {
|
||||
"parameterNames": ObjectActor.prototype.onParameterNames,
|
||||
"prototypeAndProperties": ObjectActor.prototype.onPrototypeAndProperties,
|
||||
"prototype": ObjectActor.prototype.onPrototype,
|
||||
"property": ObjectActor.prototype.onProperty,
|
||||
"ownPropertyNames": ObjectActor.prototype.onOwnPropertyNames,
|
||||
"scope": ObjectActor.prototype.onScope,
|
||||
"decompile": ObjectActor.prototype.onDecompile,
|
||||
"threadGrip": ObjectActor.prototype.onThreadGrip,
|
||||
"release": ObjectActor.prototype.onRelease,
|
||||
};
|
||||
update(PauseScopedObjectActor.prototype.requestTypes, {
|
||||
"scope": PauseScopedObjectActor.prototype.onScope,
|
||||
"threadGrip": PauseScopedObjectActor.prototype.onThreadGrip,
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
|
@ -81,13 +81,35 @@ WebConsoleClient.prototype = {
|
||||
* The code you want to evaluate.
|
||||
* @param function aOnResponse
|
||||
* The function invoked when the response is received.
|
||||
* @param object [aOptions={}]
|
||||
* Options for evaluation:
|
||||
*
|
||||
* - bindObjectActor: an ObjectActor ID. The OA holds a reference to
|
||||
* a Debugger.Object that wraps a content object. This option allows
|
||||
* you to bind |_self| to the D.O of the given OA, during string
|
||||
* evaluation.
|
||||
*
|
||||
* See: Debugger.Object.evalInGlobalWithBindings() for information
|
||||
* about bindings.
|
||||
*
|
||||
* Use case: the variable view needs to update objects and it does so
|
||||
* by knowing the ObjectActor it inspects and binding |_self| to the
|
||||
* D.O of the OA. As such, variable view sends strings like these for
|
||||
* eval:
|
||||
* _self["prop"] = value;
|
||||
*
|
||||
* - frameActor: a FrameActor ID. The FA holds a reference to
|
||||
* a Debugger.Frame. This option allows you to evaluate the string in
|
||||
* the frame of the given FA.
|
||||
*/
|
||||
evaluateJS: function WCC_evaluateJS(aString, aOnResponse)
|
||||
evaluateJS: function WCC_evaluateJS(aString, aOnResponse, aOptions = {})
|
||||
{
|
||||
let packet = {
|
||||
to: this._actor,
|
||||
type: "evaluateJS",
|
||||
text: aString,
|
||||
bindObjectActor: aOptions.bindObjectActor,
|
||||
frameActor: aOptions.frameActor,
|
||||
};
|
||||
this._client.request(packet, aOnResponse);
|
||||
},
|
||||
|
@ -28,12 +28,17 @@ XPCOMUtils.defineLazyServiceGetter(this, "gActivityDistributor",
|
||||
"@mozilla.org/network/http-activity-distributor;1",
|
||||
"nsIHttpActivityDistributor");
|
||||
|
||||
// TODO: Bug 842672 - toolkit/ imports modules from browser/.
|
||||
// Note that these are only used in JSTermHelpers, see $0 and pprint().
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
|
||||
"resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
||||
"resource:///modules/devtools/Target.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
|
||||
"resource:///modules/devtools/VariablesView.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["WebConsoleUtils", "JSPropertyProvider", "JSTermHelpers",
|
||||
"PageErrorListener", "ConsoleAPIListener",
|
||||
"NetworkResponseListener", "NetworkMonitor",
|
||||
@ -786,7 +791,7 @@ this.WebConsoleUtils = {
|
||||
* @return string
|
||||
* The object class name.
|
||||
*/
|
||||
getObjectClassName: function WCF_getObjectClassName(aObject)
|
||||
getObjectClassName: function WCU_getObjectClassName(aObject)
|
||||
{
|
||||
if (aObject === null) {
|
||||
return "null";
|
||||
@ -859,6 +864,19 @@ this.WebConsoleUtils = {
|
||||
|
||||
return val.displayString || val.type;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the given value is a grip with an actor.
|
||||
*
|
||||
* @param mixed aGrip
|
||||
* Value you want to check if it is a grip with an actor.
|
||||
* @return boolean
|
||||
* True if the given value is a grip with an actor.
|
||||
*/
|
||||
isActorGrip: function WCU_isActorGrip(aGrip)
|
||||
{
|
||||
return aGrip && typeof(aGrip) == "object" && aGrip.actor;
|
||||
},
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -1542,20 +1560,15 @@ this.JSTermHelpers = function JSTermHelpers(aOwner)
|
||||
*/
|
||||
aOwner.sandbox.$x = function JSTH_$x(aXPath, aContext)
|
||||
{
|
||||
let nodes = [];
|
||||
let nodes = new aOwner.window.wrappedJSObject.Array();
|
||||
let doc = aOwner.window.document;
|
||||
let aContext = aContext || doc;
|
||||
|
||||
try {
|
||||
let results = doc.evaluate(aXPath, aContext, null,
|
||||
Ci.nsIDOMXPathResult.ANY_TYPE, null);
|
||||
let node;
|
||||
while (node = results.iterateNext()) {
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
aOwner.window.console.error(ex.message);
|
||||
let results = doc.evaluate(aXPath, aContext, null,
|
||||
Ci.nsIDOMXPathResult.ANY_TYPE, null);
|
||||
let node;
|
||||
while (node = results.iterateNext()) {
|
||||
nodes.push(node);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
@ -1572,20 +1585,18 @@ this.JSTermHelpers = function JSTermHelpers(aOwner)
|
||||
* @return nsIDOMElement|null
|
||||
* The DOM element currently selected in the highlighter.
|
||||
*/
|
||||
Object.defineProperty(aOwner.sandbox, "$0", {
|
||||
Object.defineProperty(aOwner.sandbox, "$0", {
|
||||
get: function() {
|
||||
try {
|
||||
let window = aOwner.chromeWindow();
|
||||
let target = TargetFactory.forTab(window.gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let window = aOwner.chromeWindow();
|
||||
if (!window) {
|
||||
return null;
|
||||
}
|
||||
let target = TargetFactory.forTab(window.gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let panel = toolbox ? toolbox.getPanel("inspector") : null;
|
||||
let node = panel ? panel.selection.node : null;
|
||||
|
||||
return toolbox == null ?
|
||||
undefined :
|
||||
toolbox.getPanel("inspector").selection.node;
|
||||
}
|
||||
catch (ex) {
|
||||
aOwner.window.console.error(ex.message);
|
||||
}
|
||||
return node ? aOwner.makeDebuggeeValue(node) : null;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
@ -1610,7 +1621,7 @@ this.JSTermHelpers = function JSTermHelpers(aOwner)
|
||||
*/
|
||||
aOwner.sandbox.keys = function JSTH_keys(aObject)
|
||||
{
|
||||
return Object.keys(WebConsoleUtils.unwrap(aObject));
|
||||
return aOwner.window.wrappedJSObject.Object.keys(WebConsoleUtils.unwrap(aObject));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1622,16 +1633,11 @@ this.JSTermHelpers = function JSTermHelpers(aOwner)
|
||||
*/
|
||||
aOwner.sandbox.values = function JSTH_values(aObject)
|
||||
{
|
||||
let arrValues = [];
|
||||
let arrValues = new aOwner.window.wrappedJSObject.Array();
|
||||
let obj = WebConsoleUtils.unwrap(aObject);
|
||||
|
||||
try {
|
||||
for (let prop in obj) {
|
||||
arrValues.push(obj[prop]);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
aOwner.window.console.error(ex.message);
|
||||
for (let prop in obj) {
|
||||
arrValues.push(obj[prop]);
|
||||
}
|
||||
|
||||
return arrValues;
|
||||
@ -1653,15 +1659,12 @@ this.JSTermHelpers = function JSTermHelpers(aOwner)
|
||||
*/
|
||||
aOwner.sandbox.inspect = function JSTH_inspect(aObject)
|
||||
{
|
||||
let obj = WebConsoleUtils.unwrap(aObject);
|
||||
if (!WebConsoleUtils.isObjectInspectable(obj)) {
|
||||
return aObject;
|
||||
}
|
||||
|
||||
let dbgObj = aOwner.makeDebuggeeValue(aObject);
|
||||
let grip = aOwner.createValueGrip(dbgObj);
|
||||
aOwner.helperResult = {
|
||||
type: "inspectObject",
|
||||
input: aOwner.evalInput,
|
||||
object: aOwner.createValueGrip(obj),
|
||||
object: grip,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1690,13 +1693,24 @@ this.JSTermHelpers = function JSTermHelpers(aOwner)
|
||||
}
|
||||
|
||||
let output = [];
|
||||
let getObjectGrip = WebConsoleUtils.getObjectGrip.bind(WebConsoleUtils);
|
||||
|
||||
let obj = WebConsoleUtils.unwrap(aObject);
|
||||
let props = WebConsoleUtils.inspectObject(obj, getObjectGrip);
|
||||
props.forEach(function(aProp) {
|
||||
output.push(aProp.name + ": " +
|
||||
WebConsoleUtils.getPropertyPanelValue(aProp));
|
||||
});
|
||||
for (let name in obj) {
|
||||
let desc = WebConsoleUtils.getPropertyDescriptor(obj, name) || {};
|
||||
if (desc.get || desc.set) {
|
||||
// TODO: Bug 842672 - toolkit/ imports modules from browser/.
|
||||
let getGrip = VariablesView.getGrip(desc.get);
|
||||
let setGrip = VariablesView.getGrip(desc.set);
|
||||
let getString = VariablesView.getString(getGrip);
|
||||
let setString = VariablesView.getString(setGrip);
|
||||
output.push(name + ":", " get: " + getString, " set: " + setString);
|
||||
}
|
||||
else {
|
||||
let valueGrip = VariablesView.getGrip(obj[name]);
|
||||
let valueString = VariablesView.getString(valueGrip);
|
||||
output.push(name + ": " + valueString);
|
||||
}
|
||||
}
|
||||
|
||||
return " " + output.join("\n ");
|
||||
};
|
||||
|
@ -71,10 +71,22 @@ function WebConsoleActor(aConnection, aParentActor)
|
||||
this.conn.addActorPool(this._actorPool);
|
||||
|
||||
this._prefs = {};
|
||||
|
||||
this.dbg = new Debugger();
|
||||
this._createGlobal();
|
||||
|
||||
this._protoChains = new Map();
|
||||
}
|
||||
|
||||
WebConsoleActor.prototype =
|
||||
{
|
||||
/**
|
||||
* Debugger instance.
|
||||
*
|
||||
* @see jsdebugger.jsm
|
||||
*/
|
||||
dbg: null,
|
||||
|
||||
/**
|
||||
* Tells if this Web Console actor is a global actor or not.
|
||||
* @private
|
||||
@ -98,18 +110,39 @@ WebConsoleActor.prototype =
|
||||
_prefs: null,
|
||||
|
||||
/**
|
||||
* Tells the current inner window associated to the sandbox. When the page
|
||||
* is navigated, we recreate the sandbox.
|
||||
* Tells the current inner window of the window of |this._dbgWindow|. When the
|
||||
* page is navigated, we recreate the debugger object.
|
||||
* @private
|
||||
* @type object
|
||||
*/
|
||||
_sandboxWindowId: 0,
|
||||
_globalWindowId: 0,
|
||||
|
||||
/**
|
||||
* The JavaScript Sandbox where code is evaluated.
|
||||
* The Debugger.Object that wraps the content window.
|
||||
* @private
|
||||
* @type object
|
||||
*/
|
||||
sandbox: null,
|
||||
_dbgWindow: null,
|
||||
|
||||
/**
|
||||
* Object that holds the API we give to the JSTermHelpers constructor. This is
|
||||
* where the JSTerm helper functions are added.
|
||||
*
|
||||
* @see this._getJSTermHelpers()
|
||||
* @private
|
||||
* @type object
|
||||
*/
|
||||
_jstermHelpers: null,
|
||||
|
||||
/**
|
||||
* A cache of prototype chains for objects that have received a
|
||||
* prototypeAndProperties request.
|
||||
*
|
||||
* @private
|
||||
* @type Map
|
||||
* @see dbg-script-actors.js, ThreadActor._protoChains
|
||||
*/
|
||||
_protoChains: null,
|
||||
|
||||
/**
|
||||
* The debugger server connection instance.
|
||||
@ -162,6 +195,11 @@ WebConsoleActor.prototype =
|
||||
|
||||
hasNativeConsoleAPI: BrowserTabActor.prototype.hasNativeConsoleAPI,
|
||||
|
||||
_createValueGrip: ThreadActor.prototype.createValueGrip,
|
||||
_stringIsLong: ThreadActor.prototype._stringIsLong,
|
||||
_findProtoChain: ThreadActor.prototype._findProtoChain,
|
||||
_removeFromProtoChain: ThreadActor.prototype._removeFromProtoChain,
|
||||
|
||||
/**
|
||||
* Destroy the current WebConsoleActor instance.
|
||||
*/
|
||||
@ -185,22 +223,36 @@ WebConsoleActor.prototype =
|
||||
}
|
||||
this.conn.removeActorPool(this._actorPool);
|
||||
this._actorPool = null;
|
||||
this.sandbox = null;
|
||||
this._sandboxWindowId = 0;
|
||||
this._protoChains.clear();
|
||||
this.dbg.enabled = false;
|
||||
this.dbg = null;
|
||||
this._dbgWindow = null;
|
||||
this._globalWindowId = 0;
|
||||
this.conn = this._window = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a grip for the given value. If the value is an object,
|
||||
* a WebConsoleObjectActor will be created.
|
||||
* Create a grip for the given value.
|
||||
*
|
||||
* @param mixed aValue
|
||||
* @return object
|
||||
*/
|
||||
createValueGrip: function WCA_createValueGrip(aValue)
|
||||
{
|
||||
return WebConsoleUtils.createValueGrip(aValue,
|
||||
this.createObjectActor.bind(this));
|
||||
return this._createValueGrip(aValue, this._actorPool);
|
||||
},
|
||||
|
||||
/**
|
||||
* Make a debuggee value for the given value.
|
||||
*
|
||||
* @param mixed aValue
|
||||
* The value you want to get a debuggee value for.
|
||||
* @return object
|
||||
* Debuggee value for |aValue|.
|
||||
*/
|
||||
makeDebuggeeValue: function WCA_makeDebuggeeValue(aValue)
|
||||
{
|
||||
return this._dbgWindow.makeDebuggeeValue(aValue);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -208,41 +260,33 @@ WebConsoleActor.prototype =
|
||||
*
|
||||
* @param object aObject
|
||||
* The object you want.
|
||||
* @param object aPool
|
||||
* An ActorPool where the new actor instance is added.
|
||||
* @param object
|
||||
* The object grip.
|
||||
*/
|
||||
createObjectActor: function WCA_createObjectActor(aObject)
|
||||
objectGrip: function WCA_objectGrip(aObject, aPool)
|
||||
{
|
||||
if (typeof aObject == "string") {
|
||||
return this.createStringGrip(aObject);
|
||||
}
|
||||
|
||||
// We need to unwrap the object, otherwise we cannot access the properties
|
||||
// and methods added by the content scripts.
|
||||
let obj = WebConsoleUtils.unwrap(aObject);
|
||||
let actor = new WebConsoleObjectActor(obj, this);
|
||||
this._actorPool.addActor(actor);
|
||||
let actor = new ObjectActor(aObject, this);
|
||||
aPool.addActor(actor);
|
||||
return actor.grip();
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a grip for the given string. If the given string is a long string,
|
||||
* then a LongStringActor grip will be used.
|
||||
* Create a grip for the given string.
|
||||
*
|
||||
* @param string aString
|
||||
* The string you want to create the grip for.
|
||||
* @return string|object
|
||||
* The same string, as is, or a LongStringActor object that wraps the
|
||||
* given string.
|
||||
* @param object aPool
|
||||
* An ActorPool where the new actor instance is added.
|
||||
* @return object
|
||||
* A LongStringActor object that wraps the given string.
|
||||
*/
|
||||
createStringGrip: function WCA_createStringGrip(aString)
|
||||
longStringGrip: function WCA_longStringGrip(aString, aPool)
|
||||
{
|
||||
if (aString.length >= DebuggerServer.LONG_STRING_LENGTH) {
|
||||
let actor = new LongStringActor(aString, this);
|
||||
this._actorPool.addActor(actor);
|
||||
return actor.grip();
|
||||
}
|
||||
return aString;
|
||||
let actor = new LongStringActor(aString, this);
|
||||
aPool.addActor(actor);
|
||||
return actor.grip();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -452,30 +496,42 @@ WebConsoleActor.prototype =
|
||||
onEvaluateJS: function WCA_onEvaluateJS(aRequest)
|
||||
{
|
||||
let input = aRequest.text;
|
||||
let result, error = null;
|
||||
let timestamp;
|
||||
let timestamp = Date.now();
|
||||
|
||||
this.helperResult = null;
|
||||
this.evalInput = input;
|
||||
try {
|
||||
timestamp = Date.now();
|
||||
result = this.evalInSandbox(input);
|
||||
}
|
||||
catch (ex) {
|
||||
error = ex;
|
||||
}
|
||||
let evalOptions = {
|
||||
bindObjectActor: aRequest.bindObjectActor,
|
||||
frameActor: aRequest.frameActor,
|
||||
};
|
||||
let evalInfo = this.evalWithDebugger(input, evalOptions);
|
||||
let evalResult = evalInfo.result;
|
||||
let helperResult = this._jstermHelpers.helperResult;
|
||||
delete this._jstermHelpers.helperResult;
|
||||
|
||||
let helperResult = this.helperResult;
|
||||
delete this.helperResult;
|
||||
delete this.evalInput;
|
||||
let result, error, errorMessage;
|
||||
if (evalResult) {
|
||||
if ("return" in evalResult) {
|
||||
result = evalResult.return;
|
||||
}
|
||||
else if ("yield" in evalResult) {
|
||||
result = evalResult.yield;
|
||||
}
|
||||
else if ("throw" in evalResult) {
|
||||
error = evalResult.throw;
|
||||
let errorToString = evalInfo.window
|
||||
.evalInGlobalWithBindings("ex + ''", {ex: error});
|
||||
if (errorToString && typeof errorToString.return == "string") {
|
||||
errorMessage = errorToString.return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
from: this.actorID,
|
||||
input: input,
|
||||
result: this.createValueGrip(result),
|
||||
timestamp: timestamp,
|
||||
error: error,
|
||||
errorMessage: error ? String(error) : null,
|
||||
exception: error ? this.createValueGrip(error) : null,
|
||||
exceptionMessage: errorMessage,
|
||||
helperResult: helperResult,
|
||||
};
|
||||
},
|
||||
@ -490,6 +546,8 @@ WebConsoleActor.prototype =
|
||||
*/
|
||||
onAutocomplete: function WCA_onAutocomplete(aRequest)
|
||||
{
|
||||
// TODO: Bug 842682 - use the debugger API for autocomplete in the Web
|
||||
// Console, and provide suggestions from the selected debugger stack frame.
|
||||
let result = JSPropertyProvider(this.window, aRequest.text) || {};
|
||||
return {
|
||||
from: this.actorID,
|
||||
@ -529,68 +587,201 @@ WebConsoleActor.prototype =
|
||||
//////////////////
|
||||
|
||||
/**
|
||||
* Create the JavaScript sandbox where user input is evaluated.
|
||||
* Create the Debugger.Object for the current window.
|
||||
* @private
|
||||
*/
|
||||
_createSandbox: function WCA__createSandbox()
|
||||
_createGlobal: function WCA__createGlobal()
|
||||
{
|
||||
this._sandboxWindowId = WebConsoleUtils.getInnerWindowId(this.window);
|
||||
this.sandbox = new Cu.Sandbox(this.window, {
|
||||
sandboxPrototype: this.window,
|
||||
wantXrays: false,
|
||||
});
|
||||
let windowId = WebConsoleUtils.getInnerWindowId(this.window);
|
||||
if (this._globalWindowId == windowId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.sandbox.console = this.window.console;
|
||||
this._globalWindowId = windowId;
|
||||
|
||||
JSTermHelpers(this);
|
||||
this._dbgWindow = this.dbg.addDebuggee(this.window);
|
||||
this.dbg.removeDebuggee(this.window);
|
||||
|
||||
// Update the JSTerm helpers.
|
||||
this._jstermHelpers = this._getJSTermHelpers(this._dbgWindow);
|
||||
},
|
||||
|
||||
/**
|
||||
* Evaluates a string in the sandbox.
|
||||
* Create an object with the API we expose to the JSTermHelpers constructor.
|
||||
* This object inherits properties and methods from the Web Console actor.
|
||||
*
|
||||
* @private
|
||||
* @param object aDebuggerObject
|
||||
* A Debugger.Object that wraps a content global. This is used for the
|
||||
* JSTerm helpers.
|
||||
* @return object
|
||||
*/
|
||||
_getJSTermHelpers: function WCA__getJSTermHelpers(aDebuggerObject)
|
||||
{
|
||||
let helpers = Object.create(this);
|
||||
helpers.sandbox = Object.create(null);
|
||||
helpers._dbgWindow = aDebuggerObject;
|
||||
JSTermHelpers(helpers);
|
||||
|
||||
// Make sure the helpers can be used during eval.
|
||||
for (let name in helpers.sandbox) {
|
||||
let desc = Object.getOwnPropertyDescriptor(helpers.sandbox, name);
|
||||
if (desc.get || desc.set) {
|
||||
continue;
|
||||
}
|
||||
helpers.sandbox[name] = helpers.makeDebuggeeValue(desc.value);
|
||||
}
|
||||
return helpers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Evaluates a string using the debugger API.
|
||||
*
|
||||
* To allow the variables view to update properties from the web console we
|
||||
* provide the "bindObjectActor" mechanism: the Web Console tells the
|
||||
* ObjectActor ID for which it desires to evaluate an expression. The
|
||||
* Debugger.Object pointed at by the actor ID is bound such that it is
|
||||
* available during expression evaluation (evalInGlobalWithBindings()).
|
||||
*
|
||||
* Example:
|
||||
* _self['foobar'] = 'test'
|
||||
* where |_self| refers to the desired object.
|
||||
*
|
||||
* The |frameActor| property allows the Web Console client to provide the
|
||||
* frame actor ID, such that the expression can be evaluated in the
|
||||
* user-selected stack frame.
|
||||
*
|
||||
* For the above to work we need the debugger and the web console to share
|
||||
* a connection, otherwise the Web Console actor will not find the frame
|
||||
* actor.
|
||||
*
|
||||
* The Debugger.Frame comes from the jsdebugger's Debugger instance, which
|
||||
* is different from the Web Console's Debugger instance. This means that
|
||||
* for evaluation to work, we need to create a new instance for the jsterm
|
||||
* helpers - they need to be Debugger.Objects coming from the jsdebugger's
|
||||
* Debugger instance.
|
||||
*
|
||||
* @param string aString
|
||||
* String to evaluate in the sandbox.
|
||||
* @return mixed
|
||||
* The result of the evaluation.
|
||||
* String to evaluate.
|
||||
* @param object [aOptions]
|
||||
* Options for evaluation:
|
||||
* - bindObjectActor: the ObjectActor ID to use for evaluation.
|
||||
* |evalWithBindings()| will be called with one additional binding:
|
||||
* |_self| which will point to the Debugger.Object of the given
|
||||
* ObjectActor.
|
||||
* - frameActor: the FrameActor ID to use for evaluation. The given
|
||||
* debugger frame is used for evaluation, instead of the global window.
|
||||
* @return object
|
||||
* An object that holds the following properties:
|
||||
* - dbg: the debugger where the string was evaluated.
|
||||
* - frame: (optional) the frame where the string was evaluated.
|
||||
* - window: the Debugger.Object for the global where the string was
|
||||
* evaluated.
|
||||
* - result: the result of the evaluation.
|
||||
*/
|
||||
evalInSandbox: function WCA_evalInSandbox(aString)
|
||||
evalWithDebugger: function WCA_evalWithDebugger(aString, aOptions = {})
|
||||
{
|
||||
// If the user changed to a different location, we need to update the
|
||||
// sandbox.
|
||||
if (this._sandboxWindowId !== WebConsoleUtils.getInnerWindowId(this.window)) {
|
||||
this._createSandbox();
|
||||
}
|
||||
this._createGlobal();
|
||||
|
||||
// The help function needs to be easy to guess, so we make the () optional
|
||||
// The help function needs to be easy to guess, so we make the () optional.
|
||||
if (aString.trim() == "help" || aString.trim() == "?") {
|
||||
aString = "help()";
|
||||
}
|
||||
|
||||
let window = WebConsoleUtils.unwrap(this.sandbox.window);
|
||||
let bindSelf = null;
|
||||
|
||||
if (aOptions.bindObjectActor) {
|
||||
let objActor = this.getActorByID(aOptions.bindObjectActor);
|
||||
if (objActor) {
|
||||
bindSelf = objActor.obj;
|
||||
}
|
||||
}
|
||||
|
||||
let helpers = this._jstermHelpers;
|
||||
let found$ = false, found$$ = false;
|
||||
let frame = null, frameActor = null;
|
||||
if (aOptions.frameActor) {
|
||||
frameActor = this.conn.getActor(aOptions.frameActor);
|
||||
if (frameActor) {
|
||||
frame = frameActor.frame;
|
||||
}
|
||||
else {
|
||||
Cu.reportError("Web Console Actor: the frame actor was not found: " +
|
||||
aOptions.frameActor);
|
||||
}
|
||||
}
|
||||
|
||||
let dbg = this.dbg;
|
||||
let dbgWindow = this._dbgWindow;
|
||||
|
||||
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);
|
||||
|
||||
let env = frame.environment;
|
||||
if (env) {
|
||||
found$ = !!env.find("$");
|
||||
found$$ = !!env.find("$$");
|
||||
}
|
||||
}
|
||||
else {
|
||||
found$ = !!this._dbgWindow.getOwnPropertyDescriptor("$");
|
||||
found$$ = !!this._dbgWindow.getOwnPropertyDescriptor("$$");
|
||||
}
|
||||
|
||||
let bindings = helpers.sandbox;
|
||||
if (bindSelf) {
|
||||
let jsObj = bindSelf.unsafeDereference();
|
||||
bindings._self = helpers.makeDebuggeeValue(jsObj);
|
||||
}
|
||||
|
||||
let $ = null, $$ = null;
|
||||
|
||||
// We prefer to execute the page-provided implementations for the $() and
|
||||
// $$() functions.
|
||||
if (typeof window.$ == "function") {
|
||||
$ = this.sandbox.$;
|
||||
delete this.sandbox.$;
|
||||
if (found$) {
|
||||
$ = bindings.$;
|
||||
delete bindings.$;
|
||||
}
|
||||
if (typeof window.$$ == "function") {
|
||||
$$ = this.sandbox.$$;
|
||||
delete this.sandbox.$$;
|
||||
if (found$$) {
|
||||
$$ = bindings.$$;
|
||||
delete bindings.$$;
|
||||
}
|
||||
|
||||
let result = Cu.evalInSandbox(aString, this.sandbox, "1.8",
|
||||
"Web Console", 1);
|
||||
helpers.helperResult = null;
|
||||
helpers.evalInput = aString;
|
||||
|
||||
let result;
|
||||
if (frame) {
|
||||
result = frame.evalWithBindings(aString, bindings);
|
||||
}
|
||||
else {
|
||||
result = this._dbgWindow.evalInGlobalWithBindings(aString, bindings);
|
||||
}
|
||||
|
||||
delete helpers.evalInput;
|
||||
if (helpers != this._jstermHelpers) {
|
||||
this._jstermHelpers.helperResult = helpers.helperResult;
|
||||
delete helpers.helperResult;
|
||||
}
|
||||
|
||||
if ($) {
|
||||
this.sandbox.$ = $;
|
||||
bindings.$ = $;
|
||||
}
|
||||
if ($$) {
|
||||
this.sandbox.$$ = $$;
|
||||
bindings.$$ = $$;
|
||||
}
|
||||
|
||||
return result;
|
||||
if (bindings._self) {
|
||||
delete bindings._self;
|
||||
}
|
||||
|
||||
return {
|
||||
result: result,
|
||||
dbg: dbg,
|
||||
frame: frame,
|
||||
window: dbgWindow,
|
||||
};
|
||||
},
|
||||
|
||||
//////////////////
|
||||
@ -726,18 +917,10 @@ WebConsoleActor.prototype =
|
||||
|
||||
result.arguments = Array.map(aMessage.arguments || [],
|
||||
function(aObj) {
|
||||
return this.createValueGrip(aObj);
|
||||
let dbgObj = this.makeDebuggeeValue(aObj);
|
||||
return this.createValueGrip(dbgObj);
|
||||
}, this);
|
||||
|
||||
if (result.level == "dir") {
|
||||
result.objectProperties = [];
|
||||
let first = result.arguments[0];
|
||||
if (typeof first == "object" && first && first.inspectable) {
|
||||
let actor = this.getActorByID(first.actor);
|
||||
result.objectProperties = actor.onInspectProperties().properties;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
@ -749,9 +932,18 @@ WebConsoleActor.prototype =
|
||||
*/
|
||||
chromeWindow: function WCA_chromeWindow()
|
||||
{
|
||||
return this.window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler.ownerDocument.defaultView;
|
||||
let window = null;
|
||||
try {
|
||||
window = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler.ownerDocument.defaultView;
|
||||
}
|
||||
catch (ex) {
|
||||
// The above can fail because chromeEventHandler is not available for all
|
||||
// kinds of |this.window|.
|
||||
}
|
||||
|
||||
return window;
|
||||
},
|
||||
};
|
||||
|
||||
@ -766,79 +958,6 @@ WebConsoleActor.prototype.requestTypes =
|
||||
setPreferences: WebConsoleActor.prototype.onSetPreferences,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an actor for the specified object.
|
||||
*
|
||||
* @constructor
|
||||
* @param object aObj
|
||||
* The object you want.
|
||||
* @param object aWebConsoleActor
|
||||
* The parent WebConsoleActor instance for this object.
|
||||
*/
|
||||
function WebConsoleObjectActor(aObj, aWebConsoleActor)
|
||||
{
|
||||
this.obj = aObj;
|
||||
this.parent = aWebConsoleActor;
|
||||
}
|
||||
|
||||
WebConsoleObjectActor.prototype =
|
||||
{
|
||||
actorPrefix: "consoleObj",
|
||||
|
||||
/**
|
||||
* Returns a grip for this actor for returning in a protocol message.
|
||||
*/
|
||||
grip: function WCOA_grip()
|
||||
{
|
||||
let grip = WebConsoleUtils.getObjectGrip(this.obj);
|
||||
grip.actor = this.actorID;
|
||||
grip.displayString = this.parent.createStringGrip(grip.displayString);
|
||||
return grip;
|
||||
},
|
||||
|
||||
/**
|
||||
* Releases this actor from the pool.
|
||||
*/
|
||||
release: function WCOA_release()
|
||||
{
|
||||
this.parent.releaseActor(this);
|
||||
this.parent = this.obj = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to inspect the properties of the object.
|
||||
*
|
||||
* @return object
|
||||
* Message to send to the client. This holds the 'properties' property
|
||||
* - an array with a descriptor for each property in the object.
|
||||
*/
|
||||
onInspectProperties: function WCOA_onInspectProperties()
|
||||
{
|
||||
let createObjectActor = this.parent.createObjectActor.bind(this.parent);
|
||||
let props = WebConsoleUtils.inspectObject(this.obj, createObjectActor);
|
||||
return {
|
||||
from: this.actorID,
|
||||
properties: props,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a protocol request to release a grip.
|
||||
*/
|
||||
onRelease: function WCOA_onRelease()
|
||||
{
|
||||
this.release();
|
||||
return {};
|
||||
},
|
||||
};
|
||||
|
||||
WebConsoleObjectActor.prototype.requestTypes =
|
||||
{
|
||||
"inspectProperties": WebConsoleObjectActor.prototype.onInspectProperties,
|
||||
"release": WebConsoleObjectActor.prototype.onRelease,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates an actor for a network event.
|
||||
*
|
||||
@ -1083,7 +1202,7 @@ NetworkEventActor.prototype =
|
||||
addRequestPostData: function NEA_addRequestPostData(aPostData)
|
||||
{
|
||||
this._request.postData = aPostData;
|
||||
aPostData.text = this.parent.createStringGrip(aPostData.text);
|
||||
aPostData.text = this._createStringGrip(aPostData.text);
|
||||
if (typeof aPostData.text == "object") {
|
||||
this._longStringActors.add(aPostData.text);
|
||||
}
|
||||
@ -1178,7 +1297,7 @@ NetworkEventActor.prototype =
|
||||
function NEA_addResponseContent(aContent, aDiscardedResponseBody)
|
||||
{
|
||||
this._response.content = aContent;
|
||||
aContent.text = this.parent.createStringGrip(aContent.text);
|
||||
aContent.text = this._createStringGrip(aContent.text);
|
||||
if (typeof aContent.text == "object") {
|
||||
this._longStringActors.add(aContent.text);
|
||||
}
|
||||
@ -1228,12 +1347,30 @@ NetworkEventActor.prototype =
|
||||
_prepareHeaders: function NEA__prepareHeaders(aHeaders)
|
||||
{
|
||||
for (let header of aHeaders) {
|
||||
header.value = this.parent.createStringGrip(header.value);
|
||||
header.value = this._createStringGrip(header.value);
|
||||
if (typeof header.value == "object") {
|
||||
this._longStringActors.add(header.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a long string grip if needed for the given string.
|
||||
*
|
||||
* @private
|
||||
* @param string aString
|
||||
* The string you want to create a long string grip for.
|
||||
* @return string|object
|
||||
* A string is returned if |aString| is not a long string.
|
||||
* A LongStringActor grip is returned if |aString| is a long string.
|
||||
*/
|
||||
_createStringGrip: function NEA__createStringGrip(aString)
|
||||
{
|
||||
if (this.parent._stringIsLong(aString)) {
|
||||
return this.parent.longStringGrip(aString, this.parent._actorPool);
|
||||
}
|
||||
return aString;
|
||||
},
|
||||
};
|
||||
|
||||
NetworkEventActor.prototype.requestTypes =
|
||||
|
@ -34,33 +34,33 @@ function onEvaluate(aState, aResponse)
|
||||
result: {
|
||||
type: "object",
|
||||
actor: /[a-z]/,
|
||||
inspectable: true,
|
||||
},
|
||||
});
|
||||
|
||||
ok(!aResponse.error, "no js error");
|
||||
ok(!aResponse.exception, "no eval exception");
|
||||
ok(!aResponse.helperResult, "no helper result");
|
||||
|
||||
onInspect = onInspect.bind(null, aState);
|
||||
aState.client.inspectObjectProperties(aResponse.result.actor, onInspect);
|
||||
let client = new GripClient(aState.dbgClient, aResponse.result);
|
||||
client.getPrototypeAndProperties(onInspect);
|
||||
}
|
||||
|
||||
function onInspect(aState, aResponse)
|
||||
{
|
||||
ok(!aResponse.error, "no response error");
|
||||
|
||||
let expectedProps = [
|
||||
{ name: "ATTRIBUTE_NODE", value: 2 },
|
||||
{ name: "CDATA_SECTION_NODE", value: 4 },
|
||||
{ name: "COMMENT_NODE", value: 8 },
|
||||
{ name: "DOCUMENT_FRAGMENT_NODE", value: 11 },
|
||||
];
|
||||
let expectedProps = {
|
||||
"addBroadcastListenerFor": { value: { type: "object" } },
|
||||
"commandDispatcher": { get: { type: "object" } },
|
||||
"getBoxObjectFor": { value: { type: "object" } },
|
||||
"getElementsByAttribute": { value: { type: "object" } },
|
||||
};
|
||||
|
||||
let props = aResponse.properties;
|
||||
let props = aResponse.ownProperties;
|
||||
ok(props, "response properties available");
|
||||
|
||||
if (props) {
|
||||
ok(props.length > expectedProps.length,
|
||||
ok(Object.keys(props).length > Object.keys(expectedProps).length,
|
||||
"number of enumerable properties");
|
||||
checkObject(props, expectedProps);
|
||||
}
|
||||
|
@ -20,13 +20,13 @@ function doConsoleCalls(aState)
|
||||
{
|
||||
let longString = (new Array(DebuggerServer.LONG_STRING_LENGTH + 2)).join("a");
|
||||
|
||||
console.log("foobarBaz-log", undefined);
|
||||
console.info("foobarBaz-info", null);
|
||||
console.warn("foobarBaz-warn", document.body);
|
||||
console.debug(null);
|
||||
console.trace();
|
||||
console.dir(document, window);
|
||||
console.log("foo", longString);
|
||||
top.console.log("foobarBaz-log", undefined);
|
||||
top.console.info("foobarBaz-info", null);
|
||||
top.console.warn("foobarBaz-warn", top.document.documentElement);
|
||||
top.console.debug(null);
|
||||
top.console.trace();
|
||||
top.console.dir(top.document, top.location);
|
||||
top.console.log("foo", longString);
|
||||
|
||||
expectedConsoleCalls = [
|
||||
{
|
||||
@ -82,24 +82,14 @@ function doConsoleCalls(aState)
|
||||
{
|
||||
type: "object",
|
||||
actor: /[a-z]/,
|
||||
className: "HTMLDocument",
|
||||
class: "XULDocument",
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
actor: /[a-z]/,
|
||||
className: "Window",
|
||||
class: "Location",
|
||||
}
|
||||
],
|
||||
objectProperties: [
|
||||
{
|
||||
name: "ATTRIBUTE_NODE",
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
name: "CDATA_SECTION_NODE",
|
||||
value: 4,
|
||||
}, // ...
|
||||
],
|
||||
},
|
||||
{
|
||||
level: "log",
|
||||
@ -124,7 +114,7 @@ function startTest()
|
||||
{
|
||||
removeEventListener("load", startTest);
|
||||
|
||||
attachConsole(["ConsoleAPI"], onAttach);
|
||||
attachConsole(["ConsoleAPI"], onAttach, true);
|
||||
}
|
||||
|
||||
function onAttach(aState, aResponse)
|
||||
|
@ -91,7 +91,7 @@ function onSimpleEval(aResponse)
|
||||
result: 4,
|
||||
});
|
||||
|
||||
ok(!aResponse.error, "no js error");
|
||||
ok(!aResponse.exception, "no eval exception");
|
||||
ok(!aResponse.helperResult, "no helper result");
|
||||
|
||||
nextTest();
|
||||
@ -99,23 +99,23 @@ function onSimpleEval(aResponse)
|
||||
|
||||
function doWindowEval()
|
||||
{
|
||||
info("test eval 'window'");
|
||||
gState.client.evaluateJS("window", onWindowEval);
|
||||
info("test eval 'document'");
|
||||
gState.client.evaluateJS("document", onWindowEval);
|
||||
}
|
||||
|
||||
function onWindowEval(aResponse)
|
||||
{
|
||||
checkObject(aResponse, {
|
||||
from: gState.actor,
|
||||
input: "window",
|
||||
input: "document",
|
||||
result: {
|
||||
type: "object",
|
||||
className: "Window",
|
||||
class: "XULDocument",
|
||||
actor: /[a-z]/,
|
||||
},
|
||||
});
|
||||
|
||||
ok(!aResponse.error, "no js error");
|
||||
ok(!aResponse.exception, "no eval exception");
|
||||
ok(!aResponse.helperResult, "no helper result");
|
||||
|
||||
nextTest();
|
||||
@ -135,10 +135,10 @@ function onEvalWithException(aResponse)
|
||||
result: {
|
||||
type: "undefined",
|
||||
},
|
||||
errorMessage: /doTheImpossible/,
|
||||
exceptionMessage: /doTheImpossible/,
|
||||
});
|
||||
|
||||
ok(aResponse.error, "js error object");
|
||||
ok(aResponse.exception, "js eval exception");
|
||||
ok(!aResponse.helperResult, "no helper result");
|
||||
|
||||
nextTest();
|
||||
@ -161,7 +161,7 @@ function onEvalWithHelper(aResponse)
|
||||
helperResult: { type: "clearOutput" },
|
||||
});
|
||||
|
||||
ok(!aResponse.error, "no js error");
|
||||
ok(!aResponse.exception, "no eval exception");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
@ -30,121 +30,95 @@ function onAttach(aState, aResponse)
|
||||
|
||||
let longString = (new Array(DebuggerServer.LONG_STRING_LENGTH + 3)).join("\u0629");
|
||||
|
||||
window.foobarObject = Object.create(null);
|
||||
// Here we put the objects in the correct window, to avoid having them all
|
||||
// wrapped by proxies for cross-compartment access.
|
||||
|
||||
let foobarObject = top.Object.create(null);
|
||||
foobarObject.tamarbuta = longString;
|
||||
foobarObject.foo = 1;
|
||||
foobarObject.foobar = "hello";
|
||||
foobarObject.foobaz = document;
|
||||
foobarObject.omg = null;
|
||||
foobarObject.testfoo = false;
|
||||
foobarObject.notInspectable = {};
|
||||
foobarObject.omgfn = function _omgfn() {
|
||||
return "myResult";
|
||||
};
|
||||
foobarObject.abArray = ["a", "b"];
|
||||
foobarObject.notInspectable = top.Object.create(null);
|
||||
foobarObject.omgfn = new top.Function("return 'myResult'");
|
||||
foobarObject.abArray = new top.Array("a", "b");
|
||||
foobarObject.foobaz = top.document;
|
||||
|
||||
Object.defineProperty(foobarObject, "getterAndSetter", {
|
||||
top.Object.defineProperty(foobarObject, "getterAndSetter", {
|
||||
enumerable: true,
|
||||
get: function fooGet() { return "foo"; },
|
||||
set: function fooSet() { 1+2 },
|
||||
get: new top.Function("return 'foo';"),
|
||||
set: new top.Function("1+2"),
|
||||
});
|
||||
|
||||
foobarObject.longStringObj = {
|
||||
toSource: function() longString,
|
||||
toString: function() longString,
|
||||
boom: "explode",
|
||||
};
|
||||
foobarObject.longStringObj = top.Object.create(null);
|
||||
foobarObject.longStringObj.toSource = new top.Function("'" + longString + "'");
|
||||
foobarObject.longStringObj.toString = new top.Function("'" + longString + "'");
|
||||
foobarObject.longStringObj.boom = "explode";
|
||||
|
||||
console.log("hello", foobarObject);
|
||||
top.wrappedJSObject.foobarObject = foobarObject;
|
||||
top.console.log("hello", top.wrappedJSObject.foobarObject);
|
||||
|
||||
expectedProps = [
|
||||
{
|
||||
name: "abArray",
|
||||
expectedProps = {
|
||||
"abArray": {
|
||||
value: {
|
||||
type: "object",
|
||||
className: "Array",
|
||||
class: "Array",
|
||||
actor: /[a-z]/,
|
||||
inspectable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "foo",
|
||||
"foo": {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
name: "foobar",
|
||||
"foobar": {
|
||||
value: "hello",
|
||||
},
|
||||
{
|
||||
name: "foobaz",
|
||||
"foobaz": {
|
||||
value: {
|
||||
type: "object",
|
||||
className: "HTMLDocument",
|
||||
displayString: /\[object HTMLDocument/,
|
||||
inspectable: true,
|
||||
class: "XULDocument",
|
||||
actor: /[a-z]/,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "getterAndSetter",
|
||||
"getterAndSetter": {
|
||||
get: {
|
||||
type: "function",
|
||||
className: "Function",
|
||||
displayString: /function fooGet/,
|
||||
type: "object",
|
||||
class: "Function",
|
||||
actor: /[a-z]/,
|
||||
inspectable: false,
|
||||
},
|
||||
set: {
|
||||
type: "function",
|
||||
className: "Function",
|
||||
displayString: /function fooSet/,
|
||||
type: "object",
|
||||
class: "Function",
|
||||
actor: /[a-z]/,
|
||||
inspectable: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "longStringObj",
|
||||
"longStringObj": {
|
||||
value: {
|
||||
type: "object",
|
||||
className: "Object",
|
||||
class: "Object",
|
||||
actor: /[a-z]/,
|
||||
inspectable: true,
|
||||
displayString: {
|
||||
type: "longString",
|
||||
initial: longString.substring(0,
|
||||
DebuggerServer.LONG_STRING_INITIAL_LENGTH),
|
||||
length: longString.length,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "notInspectable",
|
||||
"notInspectable": {
|
||||
value: {
|
||||
type: "object",
|
||||
className: "Object",
|
||||
class: "Object",
|
||||
actor: /[a-z]/,
|
||||
inspectable: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "omg",
|
||||
"omg": {
|
||||
value: { type: "null" },
|
||||
},
|
||||
{
|
||||
name: "omgfn",
|
||||
"omgfn": {
|
||||
value: {
|
||||
type: "function",
|
||||
className: "Function",
|
||||
displayString: /function _omgfn/,
|
||||
type: "object",
|
||||
class: "Function",
|
||||
actor: /[a-z]/,
|
||||
inspectable: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tamarbuta",
|
||||
"tamarbuta": {
|
||||
value: {
|
||||
type: "longString",
|
||||
initial: longString.substring(0,
|
||||
@ -152,11 +126,10 @@ function onAttach(aState, aResponse)
|
||||
length: longString.length,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "testfoo",
|
||||
"testfoo": {
|
||||
value: false,
|
||||
},
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
function onConsoleCall(aState, aType, aPacket)
|
||||
@ -172,7 +145,6 @@ function onConsoleCall(aState, aType, aPacket)
|
||||
arguments: ["hello", {
|
||||
type: "object",
|
||||
actor: /[a-z]/,
|
||||
inspectable: true,
|
||||
}],
|
||||
});
|
||||
|
||||
@ -181,13 +153,15 @@ function onConsoleCall(aState, aType, aPacket)
|
||||
info("inspecting object properties");
|
||||
let args = aPacket.message.arguments;
|
||||
onProperties = onProperties.bind(null, aState);
|
||||
aState.client.inspectObjectProperties(args[1].actor, onProperties);
|
||||
|
||||
let client = new GripClient(aState.dbgClient, args[1]);
|
||||
client.getPrototypeAndProperties(onProperties);
|
||||
}
|
||||
|
||||
function onProperties(aState, aResponse)
|
||||
{
|
||||
let props = aResponse.properties;
|
||||
is(props.length, expectedProps.length,
|
||||
let props = aResponse.ownProperties;
|
||||
is(Object.keys(props).length, Object.keys(expectedProps).length,
|
||||
"number of enumerable properties");
|
||||
checkObject(props, expectedProps);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user