~ubuntu-branches/debian/stretch/firebug/stretch

« back to all changes in this revision

Viewing changes to content/firebug/console/commandLineExposed.js

  • Committer: Package Import Robot
  • Author(s): David Prévot
  • Date: 2013-09-10 17:46:52 UTC
  • mfrom: (0.5.4 experimental)
  • Revision ID: package-import@ubuntu.com-20130910174652-5lfrk4v10r8507yd
Tags: 1.12.1-2
* Team upload
* Upload this stable version to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* See license.txt for terms of usage */
2
 
 
3
 
define([
4
 
    "firebug/firebug",
5
 
    "firebug/lib/wrapper",
6
 
    "firebug/lib/events",
7
 
],
8
 
function(Firebug, Wrapper, Events) {
9
 
 
10
 
// ********************************************************************************************* //
11
 
// Command Line APIs
12
 
 
13
 
/**
14
 
 * Returns a command line object (bundled with passed window through closure). The object
15
 
 * provides all necessary APIs as described here:
16
 
 * http://getfirebug.com/wiki/index.php/Command_Line_API
17
 
 *
18
 
 * @param {Object} context
19
 
 * @param {Object} win
20
 
 */
21
 
function createFirebugCommandLine(context, win)
22
 
{
23
 
    var contentView = Wrapper.getContentView(win);
24
 
    if (!contentView)
25
 
    {
26
 
        if (FBTrace.DBG_COMMANDLINE || FBTrace.DBG_ERRORS)
27
 
            FBTrace.sysout("createFirebugCommandLine ERROR no contentView "+context.getName())
28
 
            return null;
29
 
    }
30
 
 
31
 
    // The commandLine object
32
 
    var commandLine = {
33
 
        __exposedProps__: {}
34
 
    };
35
 
 
36
 
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37
 
    // Exposed Properties
38
 
 
39
 
    // List of command line APIs
40
 
    var commands = ["$", "$$", "$x", "$n", "cd", "clear", "inspect", "keys",
41
 
        "values", "debug", "undebug", "monitor", "unmonitor", "traceCalls", "untraceCalls",
42
 
        "traceAll", "untraceAll", "monitorEvents", "unmonitorEvents", "profile", "profileEnd",
43
 
        "copy", "memoryProfile", "memoryProfileEnd"];
44
 
 
45
 
    // Define command line methods
46
 
    for (var i=0; i<commands.length; i++)
47
 
    {
48
 
        var command = commands[i];
49
 
 
50
 
        // If the method is already defined, don't override it.
51
 
        if (contentView[command])
52
 
            continue;
53
 
 
54
 
        function createCommandHandler(cmd) {
55
 
            return function() {
56
 
                return notifyFirebug(arguments, cmd, 'firebugExecuteCommand');
57
 
            }
58
 
        }
59
 
 
60
 
        commandLine[command] = createCommandHandler(command);
61
 
        commandLine.__exposedProps__[command] = "rw";
62
 
    }
63
 
 
64
 
    // Define shortcuts for some console methods
65
 
    var consoleShortcuts = ["dir", "dirxml", "table"];
66
 
    for (var i=0; i<consoleShortcuts.length; i++)
67
 
    {
68
 
        var command = consoleShortcuts[i];
69
 
 
70
 
        // If the method is already defined, don't override it.
71
 
        if (contentView[command])
72
 
            continue;
73
 
 
74
 
        function createShortcutHandler(cmd) {
75
 
            return function() {
76
 
                return contentView.console[cmd].apply(contentView.console, arguments);
77
 
            }
78
 
        }
79
 
 
80
 
        commandLine[command] = createShortcutHandler(command);
81
 
        commandLine.__exposedProps__[command] = "rw";
82
 
    }
83
 
 
84
 
    // Define console variables (inspector history).
85
 
    var props = ["$0", "$1"];
86
 
    for (var i=0; i<props.length; i++)
87
 
    {
88
 
        var prop = props[i];
89
 
        if (contentView[prop])
90
 
            continue;
91
 
 
92
 
        function createVariableHandler(prop) {
93
 
            return function() {
94
 
                return notifyFirebug(arguments, prop, 'firebugExecuteCommand');
95
 
            }
96
 
        }
97
 
 
98
 
        commandLine.__defineGetter__(prop, createVariableHandler(prop));
99
 
        commandLine.__exposedProps__[prop] = "r";
100
 
    }
101
 
 
102
 
    attachCommandLine();
103
 
 
104
 
    // xxxHonza: TODO make this private.
105
 
    commandLine["detachCommandLine"] = detachCommandLine;
106
 
    commandLine.__exposedProps__["detachCommandLine"] = "r";
107
 
 
108
 
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
109
 
    // Helpers (not accessible from web content)
110
 
 
111
 
    function attachCommandLine()
112
 
    {
113
 
        if (FBTrace.DBG_COMMANDLINE)
114
 
            FBTrace.sysout("commandLine.Exposed.attachCommandLine; "+window.location);
115
 
 
116
 
        if (!contentView.console)
117
 
        {
118
 
            var console = createFirebugConsole(context, win);
119
 
            contentView.console = console;
120
 
        }
121
 
 
122
 
        Events.addEventListener(contentView.document, "firebugCommandLine", firebugEvalEvent, true);
123
 
    }
124
 
 
125
 
    function detachCommandLine()
126
 
    {
127
 
        Events.removeEventListener(contentView.document, "firebugCommandLine", firebugEvalEvent, true);
128
 
        delete contentView._FirebugCommandLine; // suicide!
129
 
 
130
 
        if (FBTrace.DBG_COMMANDLINE)
131
 
            FBTrace.sysout("commandLine.Exposed.detachCommandLine; "+window.location);
132
 
    }
133
 
 
134
 
    function firebugEvalEvent(event)
135
 
    {
136
 
        if (FBTrace.DBG_COMMANDLINE)
137
 
            FBTrace.sysout("commandLine.Exposed.firebugEvalEvent "+window.location);
138
 
 
139
 
        var expr = contentView.document.getUserData("firebug-expr"); // see commandLine.js
140
 
        evaluate(expr);
141
 
 
142
 
        if (FBTrace.DBG_COMMANDLINE)
143
 
            FBTrace.sysout("commandLine.Exposed; did evaluate on "+expr);
144
 
    }
145
 
 
146
 
    function evaluate(expr)
147
 
    {
148
 
        try
149
 
        {
150
 
            var line = Components.stack.lineNumber;
151
 
            var result = contentView.eval(expr);
152
 
            notifyFirebug([result], "evaluated", "firebugAppendConsole");
153
 
        }
154
 
        catch(exc)
155
 
        {
156
 
            // change source and line number of exeptions from commandline code
157
 
            // create new error since properties of nsIXPCException are not modifiable
158
 
            var shouldModify, isXPCException;
159
 
            if (exc.filename == Components.stack.filename)
160
 
                shouldModify = isXPCException = true;
161
 
            else if(exc.fileName == Components.stack.filename)
162
 
                shouldModify = true;
163
 
 
164
 
            if (shouldModify)
165
 
            {
166
 
                var result = new Error;
167
 
                result.stack = null;
168
 
                result.source = expr;
169
 
                result.message = exc.message;
170
 
                result.lineNumber = exc.lineNumber - line;
171
 
                result.fileName = "data:," + encodeURIComponent(expr);
172
 
                if(!isXPCException)
173
 
                    result.name = exc.name;
174
 
            }
175
 
            else
176
 
            {
177
 
                result = exc;
178
 
            }
179
 
            notifyFirebug([result], "evaluateError", "firebugAppendConsole");
180
 
        }
181
 
    }
182
 
 
183
 
    function notifyFirebug(objs, methodName, eventID)
184
 
    {
185
 
        var event = contentView.document.createEvent("Events");
186
 
        event.initEvent(eventID, true, false);
187
 
 
188
 
        commandLine.userObjects = [];
189
 
        for (var i=0; i<objs.length; i++)
190
 
            commandLine.userObjects.push(objs[i]);
191
 
 
192
 
        var length = commandLine.userObjects.length;
193
 
        contentView.document.setUserData("firebug-methodName", methodName, null);
194
 
 
195
 
        contentView.document.dispatchEvent(event);
196
 
 
197
 
        if (FBTrace.DBG_COMMANDLINE)
198
 
            FBTrace.sysout("commandLine.Exposed; dispatched event "+methodName+" via "+
199
 
                eventID+" with "+objs.length+ " user objects, [0]:"+commandLine.userObjects[0]);
200
 
 
201
 
        var result;
202
 
        if (contentView.document.getUserData("firebug-retValueType") == "array")
203
 
            result = [];
204
 
 
205
 
        if (!result && commandLine.userObjects.length == length+1)
206
 
            return commandLine.userObjects[length];
207
 
 
208
 
        for (var i=length; i<commandLine.userObjects.length && result; i++)
209
 
            result.push(commandLine.userObjects[i]);
210
 
 
211
 
        return result;
212
 
    }
213
 
 
214
 
    return commandLine;
215
 
};
216
 
 
217
 
// ********************************************************************************************* //
218
 
// Registration
219
 
 
220
 
Firebug.CommandLineExposed =
221
 
{
222
 
    createFirebugCommandLine: createFirebugCommandLine
223
 
};
224
 
 
225
 
return Firebug.CommandLineExposed;
226
 
 
227
 
// ********************************************************************************************* //
228
 
});
 
1
/* See license.txt for terms of usage */
 
2
/*jshint esnext:true, es5:true, curly:false, evil:true, forin: false*/
 
3
/*global Firebug:true, FBTrace:true, Components:true, define:true */
 
4
 
 
5
define([
 
6
    "firebug/lib/wrapper",
 
7
    "firebug/debugger/debuggerLib",
 
8
    "firebug/lib/object",
 
9
    "firebug/console/commandLineAPI",
 
10
    "firebug/lib/locale",
 
11
],
 
12
function(Wrapper, DebuggerLib, Obj, CommandLineAPI, Locale) {
 
13
"use strict";
 
14
 
 
15
// ********************************************************************************************* //
 
16
// Constants
 
17
 
 
18
const Cu = Components.utils;
 
19
 
 
20
// ********************************************************************************************* //
 
21
// Command Line APIs
 
22
 
 
23
// List of command line APIs
 
24
var commandNames = ["$", "$$", "$n", "$x", "cd", "clear", "inspect", "keys",
 
25
    "values", "debug", "undebug", "monitor", "unmonitor", "traceCalls", "untraceCalls",
 
26
    "traceAll", "untraceAll", "copy" /*, "memoryProfile", "memoryProfileEnd"*/];
 
27
 
 
28
// List of shortcuts for some console methods
 
29
var consoleShortcuts = ["dir", "dirxml", "table"];
 
30
 
 
31
// List of console variables.
 
32
var props = ["$0", "$1", "$2", "$3", "$4"];
 
33
 
 
34
// Registered commands, name -> config object.
 
35
var userCommands = Object.create(null);
 
36
 
 
37
// List of command line APIs to auto-complete, kept equal to the concatenation
 
38
// of the above minus trace*.
 
39
var completionList = [
 
40
    "$", "$$", "$n", "$x", "cd", "clear", "inspect", "keys",
 
41
    "values", "debug", "undebug", "monitor", "unmonitor", "copy"
 
42
].concat(consoleShortcuts, props);
 
43
var unsortedCompletionList = true;
 
44
 
 
45
// ********************************************************************************************* //
 
46
// Command Line Implementation
 
47
 
 
48
/**
 
49
 * Returns a command line object (bundled with passed window through closure). The object
 
50
 * provides all necessary APIs as described here:
 
51
 * http://getfirebug.com/wiki/index.php/Command_Line_API
 
52
 *
 
53
 * @param {Object} context
 
54
 * @param {Object} win
 
55
 */
 
56
function createFirebugCommandLine(context, win)
 
57
{
 
58
    var contentView = Wrapper.getContentView(win);
 
59
    if (!contentView)
 
60
    {
 
61
        if (FBTrace.DBG_COMMANDLINE || FBTrace.DBG_ERRORS)
 
62
            FBTrace.sysout("createFirebugCommandLine ERROR no contentView " + context.getName());
 
63
 
 
64
        return null;
 
65
    }
 
66
 
 
67
    // The debuggee global.
 
68
    var dglobal = DebuggerLib.getDebuggeeGlobal(context, win);
 
69
 
 
70
    if (!context.commandLineCache)
 
71
        context.commandLineCache = new WeakMap();
 
72
    var commandLineCache = context.commandLineCache;
 
73
 
 
74
    var commandLine = commandLineCache.get(win.document);
 
75
    if (commandLine)
 
76
        return copyCommandLine(commandLine, dglobal);
 
77
 
 
78
    // The commandLine object.
 
79
    commandLine = dglobal.makeDebuggeeValue(Object.create(null));
 
80
 
 
81
    var console = Firebug.ConsoleExposed.createFirebugConsole(context, win);
 
82
    // The command line API instance.
 
83
    var commands = CommandLineAPI.getCommandLineAPI(context);
 
84
 
 
85
    // Helpers for command creation.
 
86
    function createCommandHandler(command)
 
87
    {
 
88
        var wrappedCommand = function()
 
89
        {
 
90
            try
 
91
            {
 
92
                return command.apply(null, arguments);
 
93
            }
 
94
            catch(ex)
 
95
            {
 
96
                throw new Error(ex.message, ex.fileName, ex.lineNumber);
 
97
            }
 
98
        };
 
99
        return dglobal.makeDebuggeeValue(wrappedCommand);
 
100
    }
 
101
 
 
102
    function createVariableHandler(handler, config)
 
103
    {
 
104
        var debuggeeObj = {}, object;
 
105
 
 
106
        // Callable getters are commands whose syntax are both `command` and `command()`.
 
107
        // The help command has this syntax for example.
 
108
        if (config.isCallableGetter === true)
 
109
            debuggeeObj = function(){ return object.handle(); };
 
110
 
 
111
        object = dglobal.makeDebuggeeValue(debuggeeObj);
 
112
        object.handle = function()
 
113
        {
 
114
            try
 
115
            {
 
116
                return handler(context);
 
117
            }
 
118
            catch(ex)
 
119
            {
 
120
                throw new Error(ex.message, ex.fileName, ex.lineNumber);
 
121
            }
 
122
        };
 
123
        return object;
 
124
    }
 
125
 
 
126
    function createUserCommandHandler(config, name)
 
127
    {
 
128
        return function()
 
129
        {
 
130
            try
 
131
            {
 
132
                return config.handler.call(null, context, arguments);
 
133
            }
 
134
            catch(ex)
 
135
            {
 
136
                throw new Error(ex.message, ex.fileName, ex.lineNumber);
 
137
            }
 
138
        };
 
139
    }
 
140
 
 
141
    // Define command line methods.
 
142
    for (var commandName in commands)
 
143
    {
 
144
        var command = commands[commandName];
 
145
        commandLine[commandName] = createCommandHandler(command);
 
146
    }
 
147
 
 
148
    // Register shortcut.
 
149
    consoleShortcuts.forEach(function(name)
 
150
    {
 
151
        var command = console[name].bind(console);
 
152
        commandLine[name] = createCommandHandler(command);
 
153
    });
 
154
 
 
155
    // Register user commands.
 
156
    for (var name in userCommands)
 
157
    {
 
158
        var config = userCommands[name];
 
159
        var command = createUserCommandHandler(config, name);
 
160
        if (userCommands[name].getter)
 
161
            commandLine[name] = createVariableHandler(command, config);
 
162
        else
 
163
            commandLine[name] = createCommandHandler(command);
 
164
    }
 
165
 
 
166
    commandLineCache.set(win.document, commandLine);
 
167
 
 
168
    // Return a copy so the original one is preserved from changes.
 
169
    return copyCommandLine(commandLine, dglobal);
 
170
}
 
171
 
 
172
// ********************************************************************************************* //
 
173
// User Commands
 
174
 
 
175
/**
 
176
 * Registers a command.
 
177
 *
 
178
 * @param {string} name The name of the command
 
179
 * @param {object} config The configuration. See some examples in commandLineHelp.js 
 
180
 *      and commandLineInclude.js
 
181
 */
 
182
function registerCommand(name, config)
 
183
{
 
184
    if (commandNames[name] || consoleShortcuts[name] || props[name] || userCommands[name])
 
185
    {
 
186
        if (FBTrace.DBG_ERRORS)
 
187
        {
 
188
            FBTrace.sysout("firebug.registerCommand; ERROR This command is already " +
 
189
                "registered: " + name);
 
190
        }
 
191
 
 
192
        return false;
 
193
    }
 
194
 
 
195
    userCommands[name] = config;
 
196
    completionList.push(name);
 
197
    unsortedCompletionList = true;
 
198
    return true;
 
199
}
 
200
 
 
201
/**
 
202
 * Unregisters a command.
 
203
 *
 
204
 * @param {string} name The name of the command to unregister
 
205
 */
 
206
function unregisterCommand(name)
 
207
{
 
208
    if (!userCommands[name])
 
209
    {
 
210
        if (FBTrace.DBG_ERRORS)
 
211
        {
 
212
            FBTrace.sysout("firebug.unregisterCommand; ERROR This command is not " +
 
213
                "registered: " + name);
 
214
        }
 
215
 
 
216
        return false;
 
217
    }
 
218
 
 
219
    delete userCommands[name];
 
220
    var ind = completionList.indexOf(name);
 
221
    if (ind !== -1)
 
222
        completionList.splice(ind, 1);
 
223
    return true;
 
224
}
 
225
 
 
226
/**
 
227
 * Evaluates an expression in the thread of the webpage, so the Firebug UI is not frozen
 
228
 * when the expression calls a function which will be paused.
 
229
 *
 
230
 *
 
231
 * @param {object} context
 
232
 * @param {Window} win
 
233
 * @param {string} expr The expression (transformed if needed)
 
234
 * @param {string} origExpr The expression as typed by the user
 
235
 * @param {function} onSuccess The function to trigger in case of success
 
236
 * @param {function} onError The function to trigger in case of exception
 
237
 *
 
238
 * @see CommandLine.evaluate
 
239
 */
 
240
function evaluateInPageContext(context, win)
 
241
{
 
242
    executeInWindowContext(win, evaluate, arguments);
 
243
}
 
244
 
 
245
/**
 
246
 * Evaluates an expression.
 
247
 *
 
248
 * @param {object} context
 
249
 * @param {Window} win
 
250
 * @param {string} expr The expression (transformed if needed)
 
251
 * @param {string} origExpr The expression as typed by the user
 
252
 * @param {function} onSuccess The function to trigger in case of success
 
253
 * @param {function} onError The function to trigger in case of exception
 
254
 */
 
255
function evaluate(context, win, expr, origExpr, onSuccess, onError)
 
256
{
 
257
    var result;
 
258
    var contentView = Wrapper.getContentView(win);
 
259
    var commandLine = createFirebugCommandLine(context, win);
 
260
    var dglobal = DebuggerLib.getDebuggeeGlobal(context, win);
 
261
    var resObj;
 
262
 
 
263
    updateVars(commandLine, dglobal, context);
 
264
    removeConflictingNames(commandLine, context, contentView);
 
265
 
 
266
    resObj = dglobal.evalInGlobalWithBindings(expr, commandLine);
 
267
 
 
268
    var unwrap = function(obj)
 
269
    {
 
270
        return DebuggerLib.unwrapDebuggeeValue(obj, contentView, dglobal);
 
271
    };
 
272
 
 
273
    // In case of abnormal termination, as if by the "slow script" dialog box,
 
274
    // do not print anything in the console.
 
275
    if (!resObj)
 
276
    {
 
277
        if (FBTrace.DBG_ERROR)
 
278
            FBTrace.sysout("CommandLineExposed.evaluate; something went wrong when evaluating this"+
 
279
                " expression: "+expr);
 
280
        return;
 
281
    }
 
282
 
 
283
    if (resObj.hasOwnProperty("return"))
 
284
    {
 
285
        result = unwrap(resObj.return);
 
286
        if (resObj.return && resObj.return.handle)
 
287
        {
 
288
            resObj.return.handle();
 
289
            // Do not print anything in the console in case of getter commands.
 
290
            return;
 
291
        }
 
292
    }
 
293
    else if (resObj.hasOwnProperty("yield"))
 
294
    {
 
295
        result = unwrap(resObj.yield);
 
296
    }
 
297
    else if (resObj.hasOwnProperty("throw"))
 
298
    {
 
299
        // Change source and line number of exceptions from commandline code
 
300
        // create new error since properties of nsIXPCException are not modifiable.
 
301
        // Example of code raising nsIXPCException: `alert({toString: function(){ throw "blah"; }})`
 
302
 
 
303
        // xxxFlorent: FIXME: we can't get the right stack trace with this example:
 
304
        //     function a(){
 
305
        //          throw new Error("error");
 
306
        //     }
 
307
        //     <ENTER>
 
308
        //     a();
 
309
        //     <ENTER>
 
310
        var exc = unwrap(resObj.throw);
 
311
 
 
312
        if (exc === null || exc === undefined)
 
313
            return;
 
314
 
 
315
        if (typeof exc !== "object")
 
316
        {
 
317
            exc = new Error(exc, null, null);
 
318
            exc.fileName = exc.lineNumber = exc.stack = null;
 
319
        }
 
320
 
 
321
        var shouldModify = false, isXPCException = false;
 
322
        var fileName = exc.filename || exc.fileName || "";
 
323
        var isInternalError = fileName.lastIndexOf("chrome://", 0) === 0;
 
324
        var lineNumber = null;
 
325
        var stack = null;
 
326
        var splitStack;
 
327
        var isFileNameMasked = DebuggerLib.isFrameLocationEval(fileName);
 
328
        if (isInternalError || isFileNameMasked)
 
329
        {
 
330
            shouldModify = true;
 
331
            isXPCException = (exc.filename !== undefined);
 
332
 
 
333
            // Lie and show the pre-transformed expression instead.
 
334
            fileName = "data:,/* " + Locale.$STR("commandline.errorSourceHeader") + " */"+
 
335
                encodeURIComponent("\n"+origExpr);
 
336
 
 
337
            if (isInternalError && typeof exc.stack === "string")
 
338
            {
 
339
                splitStack = exc.stack.split("\n");
 
340
                var correctionSucceeded = correctStackTrace(splitStack);
 
341
                if (correctionSucceeded)
 
342
                {
 
343
                    // correct the line number so we take into account the comment prepended above
 
344
                    lineNumber = findLineNumberInExceptionStack(splitStack) + 1;
 
345
 
 
346
                    // correct the first trace
 
347
                    splitStack.splice(0, 1, "@" + fileName + ":" + lineNumber);
 
348
                    stack = splitStack.join("\n");
 
349
                }
 
350
                else
 
351
                    shouldModify = false;
 
352
            }
 
353
            else
 
354
            {
 
355
                // correct the line number so we take into account the comment prepended above
 
356
                lineNumber = exc.lineNumber + 1;
 
357
            }
 
358
        }
 
359
 
 
360
        result = new Error();
 
361
 
 
362
        if (shouldModify)
 
363
        {
 
364
            result.stack = stack;
 
365
            result.source = origExpr;
 
366
            result.message = exc.message;
 
367
            result.lineNumber = lineNumber;
 
368
            result.fileName = fileName;
 
369
 
 
370
            // The error message can also contain post-transform details about the
 
371
            // source, but it's harder to lie about. Make it prettier, at least.
 
372
            if (typeof result.message === "string")
 
373
                result.message = result.message.replace(/__fb_scopedVars\(/g, "<get closure>(");
 
374
 
 
375
            if (!isXPCException)
 
376
                result.name = exc.name;
 
377
        }
 
378
        else
 
379
        {
 
380
            Obj.getPropertyNames(exc).forEach(function(prop)
 
381
            {
 
382
                result[prop] = exc[prop];
 
383
            });
 
384
            result.stack = exc.stack;
 
385
            result.source = exc.source;
 
386
        }
 
387
 
 
388
        executeInWindowContext(window, onError, [result, context]);
 
389
        return;
 
390
    }
 
391
 
 
392
    executeInWindowContext(window, onSuccess, [result, context]);
 
393
}
 
394
 
 
395
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
396
// Helpers (not accessible from web content)
 
397
 
 
398
function copyCommandLine(commandLine, dglobal)
 
399
{
 
400
    var copy = dglobal.makeDebuggeeValue(Object.create(null));
 
401
    for (var name in commandLine)
 
402
        copy[name] = commandLine[name];
 
403
    return copy;
 
404
}
 
405
 
 
406
function findLineNumberInExceptionStack(splitStack)
 
407
{
 
408
    var m = splitStack[0].match(/:(\d+)$/);
 
409
    return m !== null ? +m[1] : null;
 
410
}
 
411
 
 
412
function correctStackTrace(splitStack)
 
413
{
 
414
    var filename = Components.stack.filename;
 
415
    // remove the frames over the evaluated expression
 
416
    for (var i = 0; i < splitStack.length-1 &&
 
417
        splitStack[i+1].indexOf(evaluate.name + "@" + filename, 0) === -1 ; i++);
 
418
 
 
419
    if (i >= splitStack.length)
 
420
        return false;
 
421
    splitStack.splice(0, i);
 
422
    return true;
 
423
}
 
424
 
 
425
function updateVars(commandLine, dglobal, context)
 
426
{
 
427
    var htmlPanel = context.getPanel("html", true);
 
428
    var vars = htmlPanel ? htmlPanel.getInspectorVars() : null;
 
429
 
 
430
    for (var prop in vars)
 
431
        commandLine[prop] = dglobal.makeDebuggeeValue(vars[prop]);
 
432
 
 
433
    // Iterate all registered commands and pick those which represents a 'variable'.
 
434
    // These needs to be available as variables within the Command Line namespace.
 
435
    for (var prop in userCommands)
 
436
    {
 
437
        var cmd = userCommands[prop];
 
438
        if (cmd.variable)
 
439
        {
 
440
            var value = cmd.handler.call(null, context);
 
441
            commandLine[prop] = dglobal.makeDebuggeeValue(value);
 
442
        }
 
443
    }
 
444
}
 
445
 
 
446
function removeConflictingNames(commandLine, context, contentView)
 
447
{
 
448
    for (var name in commandLine)
 
449
    {
 
450
        // Note: we cannot trust contentView.hasOwnProperty, so we use the "in" operator.
 
451
        if (name in contentView)
 
452
            delete commandLine[name];
 
453
    }
 
454
}
 
455
 
 
456
/**
 
457
 * Executes a function in another window execution context.
 
458
 *
 
459
 * Useful when we have to pause some debuggee functions without freezing
 
460
 * the Firebug UI.
 
461
 *
 
462
 * @param {Window} win The window having the thread in which we want to execute the function
 
463
 * @param {function} func The function to execute
 
464
 * @param {Array or Array-Like object} args The arguments to pass to the function
 
465
 */
 
466
function executeInWindowContext(win, func, args)
 
467
{
 
468
    var listener = function()
 
469
    {
 
470
        win.document.removeEventListener("firebugCommandLine", listener);
 
471
        func.apply(null, args);
 
472
    };
 
473
    win.document.addEventListener("firebugCommandLine", listener);
 
474
    var event = document.createEvent("Events");
 
475
    event.initEvent("firebugCommandLine", true, false);
 
476
    win.document.dispatchEvent(event);
 
477
}
 
478
 
 
479
function getAutoCompletionList()
 
480
{
 
481
    if (unsortedCompletionList)
 
482
    {
 
483
        unsortedCompletionList = false;
 
484
        completionList.sort();
 
485
    }
 
486
    return completionList;
 
487
}
 
488
 
 
489
// ********************************************************************************************* //
 
490
// Registration
 
491
 
 
492
Firebug.CommandLineExposed =
 
493
{
 
494
    createFirebugCommandLine: createFirebugCommandLine,
 
495
    commands: commandNames,
 
496
    consoleShortcuts: consoleShortcuts,
 
497
    properties: props,
 
498
    userCommands: userCommands,
 
499
    registerCommand: registerCommand,
 
500
    unregisterCommand: unregisterCommand,
 
501
    evaluate: evaluateInPageContext,
 
502
    getAutoCompletionList: getAutoCompletionList,
 
503
};
 
504
 
 
505
return Firebug.CommandLineExposed;
 
506
 
 
507
// ********************************************************************************************* //
 
508
});