summaryrefslogtreecommitdiffstats
path: root/devtools/shared/gcli/commands/calllog.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/gcli/commands/calllog.js')
-rw-r--r--devtools/shared/gcli/commands/calllog.js219
1 files changed, 219 insertions, 0 deletions
diff --git a/devtools/shared/gcli/commands/calllog.js b/devtools/shared/gcli/commands/calllog.js
new file mode 100644
index 000000000..c0f21aeab
--- /dev/null
+++ b/devtools/shared/gcli/commands/calllog.js
@@ -0,0 +1,219 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { Cu } = require("chrome");
+const l10n = require("gcli/l10n");
+const gcli = require("gcli/index");
+const Debugger = require("Debugger");
+
+loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
+loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
+
+var debuggers = [];
+var chromeDebuggers = [];
+var sandboxes = [];
+
+exports.items = [
+ {
+ name: "calllog",
+ description: l10n.lookup("calllogDesc")
+ },
+ {
+ item: "command",
+ runAt: "client",
+ name: "calllog start",
+ description: l10n.lookup("calllogStartDesc"),
+
+ exec: function(args, context) {
+ let contentWindow = context.environment.window;
+
+ let dbg = new Debugger(contentWindow);
+ dbg.onEnterFrame = function(frame) {
+ // BUG 773652 - Make the output from the GCLI calllog command nicer
+ contentWindow.console.log("Method call: " + this.callDescription(frame));
+ }.bind(this);
+
+ debuggers.push(dbg);
+
+ let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
+ let target = TargetFactory.forTab(gBrowser.selectedTab);
+ gDevTools.showToolbox(target, "webconsole");
+
+ return l10n.lookup("calllogStartReply");
+ },
+
+ callDescription: function(frame) {
+ let name = "<anonymous>";
+ if (frame.callee.name) {
+ name = frame.callee.name;
+ }
+ else {
+ let desc = frame.callee.getOwnPropertyDescriptor("displayName");
+ if (desc && desc.value && typeof desc.value == "string") {
+ name = desc.value;
+ }
+ }
+
+ let args = frame.arguments.map(this.valueToString).join(", ");
+ return name + "(" + args + ")";
+ },
+
+ valueToString: function(value) {
+ if (typeof value !== "object" || value === null) {
+ return uneval(value);
+ }
+ return "[object " + value.class + "]";
+ }
+ },
+ {
+ item: "command",
+ runAt: "client",
+ name: "calllog stop",
+ description: l10n.lookup("calllogStopDesc"),
+
+ exec: function(args, context) {
+ let numDebuggers = debuggers.length;
+ if (numDebuggers == 0) {
+ return l10n.lookup("calllogStopNoLogging");
+ }
+
+ for (let dbg of debuggers) {
+ dbg.onEnterFrame = undefined;
+ }
+ debuggers = [];
+
+ return l10n.lookupFormat("calllogStopReply", [ numDebuggers ]);
+ }
+ },
+ {
+ item: "command",
+ runAt: "client",
+ name: "calllog chromestart",
+ description: l10n.lookup("calllogChromeStartDesc"),
+ get hidden() {
+ return gcli.hiddenByChromePref();
+ },
+ params: [
+ {
+ name: "sourceType",
+ type: {
+ name: "selection",
+ data: ["content-variable", "chrome-variable", "jsm", "javascript"]
+ }
+ },
+ {
+ name: "source",
+ type: "string",
+ description: l10n.lookup("calllogChromeSourceTypeDesc"),
+ manual: l10n.lookup("calllogChromeSourceTypeManual"),
+ }
+ ],
+ exec: function(args, context) {
+ let globalObj;
+ let contentWindow = context.environment.window;
+
+ if (args.sourceType == "jsm") {
+ try {
+ globalObj = Cu.import(args.source, {});
+ } catch (e) {
+ return l10n.lookup("callLogChromeInvalidJSM");
+ }
+ } else if (args.sourceType == "content-variable") {
+ if (args.source in contentWindow) {
+ globalObj = Cu.getGlobalForObject(contentWindow[args.source]);
+ } else {
+ throw new Error(l10n.lookup("callLogChromeVarNotFoundContent"));
+ }
+ } else if (args.sourceType == "chrome-variable") {
+ let chromeWin = context.environment.chromeDocument.defaultView;
+ if (args.source in chromeWin) {
+ globalObj = Cu.getGlobalForObject(chromeWin[args.source]);
+ } else {
+ return l10n.lookup("callLogChromeVarNotFoundChrome");
+ }
+ } else {
+ let chromeWin = context.environment.chromeDocument.defaultView;
+ let sandbox = new Cu.Sandbox(chromeWin,
+ {
+ sandboxPrototype: chromeWin,
+ wantXrays: false,
+ sandboxName: "gcli-cmd-calllog-chrome"
+ });
+ let returnVal;
+ try {
+ returnVal = Cu.evalInSandbox(args.source, sandbox, "ECMAv5");
+ sandboxes.push(sandbox);
+ } catch(e) {
+ // We need to save the message before cleaning up else e contains a dead
+ // object.
+ let msg = l10n.lookup("callLogChromeEvalException") + ": " + e;
+ Cu.nukeSandbox(sandbox);
+ return msg;
+ }
+
+ if (typeof returnVal == "undefined") {
+ return l10n.lookup("callLogChromeEvalNeedsObject");
+ }
+
+ globalObj = Cu.getGlobalForObject(returnVal);
+ }
+
+ let dbg = new Debugger(globalObj);
+ chromeDebuggers.push(dbg);
+
+ dbg.onEnterFrame = function(frame) {
+ // BUG 773652 - Make the output from the GCLI calllog command nicer
+ contentWindow.console.log(l10n.lookup("callLogChromeMethodCall") +
+ ": " + this.callDescription(frame));
+ }.bind(this);
+
+ let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
+ let target = TargetFactory.forTab(gBrowser.selectedTab);
+ gDevTools.showToolbox(target, "webconsole");
+
+ return l10n.lookup("calllogChromeStartReply");
+ },
+
+ valueToString: function(value) {
+ if (typeof value !== "object" || value === null)
+ return uneval(value);
+ return "[object " + value.class + "]";
+ },
+
+ callDescription: function(frame) {
+ let name = frame.callee.name || l10n.lookup("callLogChromeAnonFunction");
+ let args = frame.arguments.map(this.valueToString).join(", ");
+ return name + "(" + args + ")";
+ }
+ },
+ {
+ item: "command",
+ runAt: "client",
+ name: "calllog chromestop",
+ description: l10n.lookup("calllogChromeStopDesc"),
+ get hidden() {
+ return gcli.hiddenByChromePref();
+ },
+ exec: function(args, context) {
+ let numDebuggers = chromeDebuggers.length;
+ if (numDebuggers == 0) {
+ return l10n.lookup("calllogChromeStopNoLogging");
+ }
+
+ for (let dbg of chromeDebuggers) {
+ dbg.onEnterFrame = undefined;
+ dbg.enabled = false;
+ }
+ for (let sandbox of sandboxes) {
+ Cu.nukeSandbox(sandbox);
+ }
+ chromeDebuggers = [];
+ sandboxes = [];
+
+ return l10n.lookupFormat("calllogChromeStopReply", [ numDebuggers ]);
+ }
+ }
+];