Changeset 249445 in webkit


Ignore:
Timestamp:
Sep 3, 2019 4:37:12 PM (5 years ago)
Author:
Devin Rousso
Message:

REGRESSION (r249078): Flaky crash in com.apple.JavaScriptCore: Inspector::InjectedScriptModule::ensureInjected
https://bugs.webkit.org/show_bug.cgi?id=201201
<rdar://problem/54771560>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

  • inspector/InjectedScriptSource.js:

(let.InjectedScript.prototype.injectModule):
(let.InjectedScript.prototype._evaluateOn):
(CommandLineAPI):
(let.InjectedScript.prototype.setInspectObject): Deleted.
(let.InjectedScript.prototype.addCommandLineAPIGetter): Deleted.
(let.InjectedScript.prototype.addCommandLineAPIMethod.func.toString): Deleted.
(let.InjectedScript.prototype.addCommandLineAPIMethod): Deleted.
(InjectedScript.CommandLineAPI): Deleted.
Allow injected script "extensions" (e.g. CommandLineAPIModuleSource.js) to modify objects
directly, instead of having them call functions.

  • inspector/InjectedScriptModule.cpp:

(Inspector::InjectedScriptModule::ensureInjected):
Make sure to reset hadException to false before making another call.

Source/WebCore:

Tests: inspector/debugger/tail-deleted-frames-this-value.html

inspector/heap/getRemoteObject.html

  • inspector/CommandLineAPIModuleSource.js:

Avoid executing functions when injecting. Instead, modify the CommandLineAPI directly.

LayoutTests:

  • inspector/debugger/tail-deleted-frames-this-value.html:
  • inspector/debugger/tail-deleted-frames-this-value-expected.txt:
  • inspector/debugger/resources/tail-deleted-frames-this-value.js:
  • inspector/timeline/line-column-expected.txt:
Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r249436 r249445  
     12019-09-03  Devin Rousso  <drousso@apple.com>
     2
     3        REGRESSION (r249078): Flaky crash in com.apple.JavaScriptCore: Inspector::InjectedScriptModule::ensureInjected
     4        https://bugs.webkit.org/show_bug.cgi?id=201201
     5        <rdar://problem/54771560>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/debugger/tail-deleted-frames-this-value.html:
     10        * inspector/debugger/tail-deleted-frames-this-value-expected.txt:
     11        * inspector/debugger/resources/tail-deleted-frames-this-value.js:
     12        * inspector/timeline/line-column-expected.txt:
     13
    1142019-09-03  Jiewen Tan  <jiewen_tan@apple.com>
    215
  • trunk/LayoutTests/inspector/debugger/resources/tail-deleted-frames-this-value.js

    r200981 r249445  
    77function b() {
    88    let y = 40;
    9     return a.call({aThis: 2});
     9    return a.call({aThis: 3});
    1010}
    1111function c() {
    1212    let z = 60;
    13     return b.call({bThis: 1});
     13    return b.call({bThis: 2});
    1414}
    1515function startABC() {
    16     c.call({cThis: 0});
     16    c.call({cThis: 1});
    1717}
  • trunk/LayoutTests/inspector/debugger/tail-deleted-frames-this-value-expected.txt

    r200981 r249445  
    77Hit breakpoint at line: 3, column: 4
    88------------------------------------
    9 Expected frame: {"functionName":"a","thisValue":["aThis",2],"isTailDeleted":false}
     9Expected frame: {"functionName":"a","thisValue":["aThis",3],"isTailDeleted":false}
    1010PASS: 'this' value should have expected property: aThis
    1111PASS: Call Frame 0 'this' value is correct.
    12 Expected frame: {"functionName":"b","thisValue":["bThis",1],"isTailDeleted":true}
     12Expected frame: {"functionName":"b","thisValue":["bThis",2],"isTailDeleted":true}
    1313PASS: 'this' value should have expected property: bThis
    1414PASS: Call Frame 1 'this' value is correct.
    15 Expected frame: {"functionName":"c","thisValue":["cThis",0],"isTailDeleted":true}
     15Expected frame: {"functionName":"c","thisValue":["cThis",1],"isTailDeleted":true}
    1616PASS: 'this' value should have expected property: cThis
    1717PASS: Call Frame 2 'this' value is correct.
  • trunk/LayoutTests/inspector/debugger/tail-deleted-frames-this-value.html

    r249129 r249445  
    3535        // top down list
    3636        let expectedFrames = [
    37             {functionName: 'a', thisValue: ['aThis', 2], isTailDeleted: false},
    38             {functionName: 'b', thisValue: ['bThis', 1], isTailDeleted: true},
    39             {functionName: 'c', thisValue: ['cThis', 0], isTailDeleted: true}
     37            {functionName: 'a', thisValue: ['aThis', 3], isTailDeleted: false},
     38            {functionName: 'b', thisValue: ['bThis', 2], isTailDeleted: true},
     39            {functionName: 'c', thisValue: ['cThis', 1], isTailDeleted: true}
    4040        ];
    4141
  • trunk/LayoutTests/inspector/timeline/line-column-expected.txt

    r249220 r249445  
    4646          "url": "",
    4747          "scriptId": "<filtered>",
    48           "lineNumber": 146,
     48          "lineNumber": 140,
    4949          "columnNumber": 97
    5050        }
     
    108108              "url": "",
    109109              "scriptId": "<filtered>",
    110               "lineNumber": 146,
     110              "lineNumber": 140,
    111111              "columnNumber": 97
    112112            }
     
    161161          "url": "",
    162162          "scriptId": "<filtered>",
    163           "lineNumber": 146,
     163          "lineNumber": 140,
    164164          "columnNumber": 97
    165165        }
     
    221221          "url": "",
    222222          "scriptId": "<filtered>",
    223           "lineNumber": 146,
     223          "lineNumber": 140,
    224224          "columnNumber": 97
    225225        }
  • trunk/Source/JavaScriptCore/ChangeLog

    r249418 r249445  
     12019-09-03  Devin Rousso  <drousso@apple.com>
     2
     3        REGRESSION (r249078): Flaky crash in com.apple.JavaScriptCore: Inspector::InjectedScriptModule::ensureInjected
     4        https://bugs.webkit.org/show_bug.cgi?id=201201
     5        <rdar://problem/54771560>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/InjectedScriptSource.js:
     10        (let.InjectedScript.prototype.injectModule):
     11        (let.InjectedScript.prototype._evaluateOn):
     12        (CommandLineAPI):
     13        (let.InjectedScript.prototype.setInspectObject): Deleted.
     14        (let.InjectedScript.prototype.addCommandLineAPIGetter): Deleted.
     15        (let.InjectedScript.prototype.addCommandLineAPIMethod.func.toString): Deleted.
     16        (let.InjectedScript.prototype.addCommandLineAPIMethod): Deleted.
     17        (InjectedScript.CommandLineAPI): Deleted.
     18        Allow injected script "extensions" (e.g. CommandLineAPIModuleSource.js) to modify objects
     19        directly, instead of having them call functions.
     20
     21        * inspector/InjectedScriptModule.cpp:
     22        (Inspector::InjectedScriptModule::ensureInjected):
     23        Make sure to reset `hadException` to `false` before making another call.
     24
    1252019-09-03  Yusuke Suzuki  <ysuzuki@apple.com>
    226
  • trunk/Source/JavaScriptCore/inspector/InjectedScriptModule.cpp

    r249078 r249445  
    7373        function.appendArgument(source());
    7474        function.appendArgument(host(injectedScriptManager, injectedScript.scriptState()));
     75        hadException = false;
    7576        resultValue = injectedScript.callFunctionWithEvalEnabled(function, hadException);
    7677        if (hadException) {
  • trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js

    r249173 r249445  
    420420    }
    421421
    422     setInspectObject(callback)
    423     {
    424         this._inspectObject = callback;
    425     }
    426 
    427     addCommandLineAPIGetter(name, func)
    428     {
    429         InjectedScript.CommandLineAPI._getters.push({name, func});
    430     }
    431 
    432     addCommandLineAPIMethod(name, func)
    433     {
    434         func.toString = function() { return "function " + name + "() { [Command Line API] }" };
    435         InjectedScript.CommandLineAPI._methods.push({name, func});
    436     }
    437 
    438422    // InjectedScriptModule C++ API
    439423
     
    450434        if (typeof moduleFunction !== "function")
    451435            throw "Error: Web Inspector: a function was expected for injectModule";
    452         moduleFunction.call(inspectedGlobalObject, InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, RemoteObject, host);
     436        moduleFunction(InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, {RemoteObject, CommandLineAPI}, host);
    453437
    454438        this._modules[name] = true;
     
    584568        let commandLineAPI = null;
    585569        if (includeCommandLineAPI)
    586             commandLineAPI = new InjectedScript.CommandLineAPI(isEvalOnCallFrame ? object : null);
     570            commandLineAPI = new CommandLineAPI(isEvalOnCallFrame ? object : null);
    587571        return evalFunction.call(object, expression, commandLineAPI);
    588572    }
     
    14621446// -------
    14631447
    1464 InjectedScript.CommandLineAPI = class CommandLineAPI
     1448function CommandLineAPI(callFrame)
    14651449{
    1466     constructor(callFrame)
    1467     {
    1468         let savedResultAlias = InjectedScriptHost.savedResultAlias;
    1469 
    1470         let defineGetter = (key, value) => {
    1471             if (typeof value !== "function") {
    1472                 let originalValue = value;
    1473                 value = function() { return originalValue; };
    1474             }
    1475 
    1476             this.__defineGetter__("$" + key, value);
    1477             if (savedResultAlias)
    1478                 this.__defineGetter__(savedResultAlias + key, value);
    1479         };
    1480 
    1481         if ("_lastResult" in injectedScript)
    1482             defineGetter("_", injectedScript._lastResult);
    1483 
    1484         if ("_exceptionValue" in injectedScript)
    1485             defineGetter("exception", injectedScript._exceptionValue);
    1486 
    1487         if ("_eventValue" in injectedScript)
    1488             defineGetter("event", injectedScript._eventValue);
    1489 
    1490         // $1-$99
    1491         for (let i = 1; i <= injectedScript._savedResults.length; ++i) {
    1492             defineGetter(i, function() {
    1493                 return injectedScript._savedResults[i];
    1494             });
    1495         }
    1496 
    1497         for (let i = 0; i < InjectedScript.CommandLineAPI._getters.length; ++i) {
    1498             let {name, func} = InjectedScript.CommandLineAPI._getters[i];
    1499             defineGetter(name, func);
    1500         }
    1501 
    1502         for (let i = 0; i < InjectedScript.CommandLineAPI._methods.length; ++i) {
    1503             let {name, func} = InjectedScript.CommandLineAPI._methods[i];
    1504             this[name] = func;
    1505         }
    1506     }
    1507 };
    1508 
    1509 InjectedScript.CommandLineAPI._getters = [];
    1510 InjectedScript.CommandLineAPI._methods = [];
    1511 
    1512 injectedScript.addCommandLineAPIMethod("keys", function(object) { return Object.keys(object); });
    1513 injectedScript.addCommandLineAPIMethod("values", function(object) { return Object.values(object); });
    1514 
    1515 injectedScript.addCommandLineAPIMethod("queryInstances", function() { return InjectedScriptHost.queryInstances(...arguments); });
    1516 injectedScript.addCommandLineAPIMethod("queryObjects", function() { return InjectedScriptHost.queryInstances(...arguments); });
    1517 injectedScript.addCommandLineAPIMethod("queryHolders", function() { return InjectedScriptHost.queryHolders(...arguments); });
    1518 
    1519 injectedScript.addCommandLineAPIMethod("inspect", function(object) { return injectedScript.inspectObject(object); });
    1520 
    1521 injectedScript.addCommandLineAPIMethod("assert", function() { return inspectedGlobalObject.console.assert(...arguments); });
    1522 injectedScript.addCommandLineAPIMethod("clear", function() { return inspectedGlobalObject.console.clear(...arguments); });
    1523 injectedScript.addCommandLineAPIMethod("count", function() { return inspectedGlobalObject.console.count(...arguments); });
    1524 injectedScript.addCommandLineAPIMethod("countReset", function() { return inspectedGlobalObject.console.countReset(...arguments); });
    1525 injectedScript.addCommandLineAPIMethod("debug", function() { return inspectedGlobalObject.console.debug(...arguments); });
    1526 injectedScript.addCommandLineAPIMethod("dir", function() { return inspectedGlobalObject.console.dir(...arguments); });
    1527 injectedScript.addCommandLineAPIMethod("dirxml", function() { return inspectedGlobalObject.console.dirxml(...arguments); });
    1528 injectedScript.addCommandLineAPIMethod("error", function() { return inspectedGlobalObject.console.error(...arguments); });
    1529 injectedScript.addCommandLineAPIMethod("group", function() { return inspectedGlobalObject.console.group(...arguments); });
    1530 injectedScript.addCommandLineAPIMethod("groupCollapsed", function() { return inspectedGlobalObject.console.groupCollapsed(...arguments); });
    1531 injectedScript.addCommandLineAPIMethod("groupEnd", function() { return inspectedGlobalObject.console.groupEnd(...arguments); });
    1532 injectedScript.addCommandLineAPIMethod("info", function() { return inspectedGlobalObject.console.info(...arguments); });
    1533 injectedScript.addCommandLineAPIMethod("log", function() { return inspectedGlobalObject.console.log(...arguments); });
    1534 injectedScript.addCommandLineAPIMethod("profile", function() { return inspectedGlobalObject.console.profile(...arguments); });
    1535 injectedScript.addCommandLineAPIMethod("profileEnd", function() { return inspectedGlobalObject.console.profileEnd(...arguments); });
    1536 injectedScript.addCommandLineAPIMethod("record", function() { return inspectedGlobalObject.console.record(...arguments); });
    1537 injectedScript.addCommandLineAPIMethod("recordEnd", function() { return inspectedGlobalObject.console.recordEnd(...arguments); });
    1538 injectedScript.addCommandLineAPIMethod("screenshot", function() { return inspectedGlobalObject.console.screenshot(...arguments); });
    1539 injectedScript.addCommandLineAPIMethod("table", function() { return inspectedGlobalObject.console.table(...arguments); });
    1540 injectedScript.addCommandLineAPIMethod("takeHeapSnapshot", function() { return inspectedGlobalObject.console.takeHeapSnapshot(...arguments); });
    1541 injectedScript.addCommandLineAPIMethod("time", function() { return inspectedGlobalObject.console.time(...arguments); });
    1542 injectedScript.addCommandLineAPIMethod("timeEnd", function() { return inspectedGlobalObject.console.timeEnd(...arguments); });
    1543 injectedScript.addCommandLineAPIMethod("timeLog", function() { return inspectedGlobalObject.console.timeLog(...arguments); });
    1544 injectedScript.addCommandLineAPIMethod("timeStamp", function() { return inspectedGlobalObject.console.timeStamp(...arguments); });
    1545 injectedScript.addCommandLineAPIMethod("trace", function() { return inspectedGlobalObject.console.trace(...arguments); });
    1546 injectedScript.addCommandLineAPIMethod("warn", function() { return inspectedGlobalObject.console.warn(...arguments); });
     1450    let savedResultAlias = InjectedScriptHost.savedResultAlias;
     1451
     1452    let defineGetter = (key, value) => {
     1453        if (typeof value !== "function") {
     1454            let originalValue = value;
     1455            value = function() { return originalValue; };
     1456        }
     1457
     1458        this.__defineGetter__("$" + key, value);
     1459        if (savedResultAlias && savedResultAlias !== "$")
     1460            this.__defineGetter__(savedResultAlias + key, value);
     1461    };
     1462
     1463    if ("_lastResult" in injectedScript)
     1464        defineGetter("_", injectedScript._lastResult);
     1465
     1466    if ("_exceptionValue" in injectedScript)
     1467        defineGetter("exception", injectedScript._exceptionValue);
     1468
     1469    if ("_eventValue" in injectedScript)
     1470        defineGetter("event", injectedScript._eventValue);
     1471
     1472    // $1-$99
     1473    for (let i = 1; i < injectedScript._savedResults.length; ++i)
     1474        defineGetter(i, injectedScript._savedResults[i]);
     1475
     1476    for (let name in CommandLineAPI.getters)
     1477        defineGetter(name, CommandLineAPI.getters[name]);
     1478
     1479    for (let name in CommandLineAPI.methods)
     1480        this[name] = CommandLineAPI.methods[name];
     1481}
     1482
     1483CommandLineAPI.getters = {};
     1484
     1485CommandLineAPI.methods = {};
     1486
     1487CommandLineAPI.methods["keys"] = function(object) { return Object.keys(object); };
     1488CommandLineAPI.methods["values"] = function(object) { return Object.values(object); };
     1489
     1490CommandLineAPI.methods["queryInstances"] = function() { return InjectedScriptHost.queryInstances(...arguments); };
     1491CommandLineAPI.methods["queryObjects"] = function() { return InjectedScriptHost.queryInstances(...arguments); };
     1492CommandLineAPI.methods["queryHolders"] = function() { return InjectedScriptHost.queryHolders(...arguments); };
     1493
     1494CommandLineAPI.methods["inspect"] = function(object) { return injectedScript.inspectObject(object); };
     1495
     1496CommandLineAPI.methods["assert"] = function() { return inspectedGlobalObject.console.assert(...arguments); };
     1497CommandLineAPI.methods["clear"] = function() { return inspectedGlobalObject.console.clear(...arguments); };
     1498CommandLineAPI.methods["count"] = function() { return inspectedGlobalObject.console.count(...arguments); };
     1499CommandLineAPI.methods["countReset"] = function() { return inspectedGlobalObject.console.countReset(...arguments); };
     1500CommandLineAPI.methods["debug"] = function() { return inspectedGlobalObject.console.debug(...arguments); };
     1501CommandLineAPI.methods["dir"] = function() { return inspectedGlobalObject.console.dir(...arguments); };
     1502CommandLineAPI.methods["dirxml"] = function() { return inspectedGlobalObject.console.dirxml(...arguments); };
     1503CommandLineAPI.methods["error"] = function() { return inspectedGlobalObject.console.error(...arguments); };
     1504CommandLineAPI.methods["group"] = function() { return inspectedGlobalObject.console.group(...arguments); };
     1505CommandLineAPI.methods["groupCollapsed"] = function() { return inspectedGlobalObject.console.groupCollapsed(...arguments); };
     1506CommandLineAPI.methods["groupEnd"] = function() { return inspectedGlobalObject.console.groupEnd(...arguments); };
     1507CommandLineAPI.methods["info"] = function() { return inspectedGlobalObject.console.info(...arguments); };
     1508CommandLineAPI.methods["log"] = function() { return inspectedGlobalObject.console.log(...arguments); };
     1509CommandLineAPI.methods["profile"] = function() { return inspectedGlobalObject.console.profile(...arguments); };
     1510CommandLineAPI.methods["profileEnd"] = function() { return inspectedGlobalObject.console.profileEnd(...arguments); };
     1511CommandLineAPI.methods["record"] = function() { return inspectedGlobalObject.console.record(...arguments); };
     1512CommandLineAPI.methods["recordEnd"] = function() { return inspectedGlobalObject.console.recordEnd(...arguments); };
     1513CommandLineAPI.methods["screenshot"] = function() { return inspectedGlobalObject.console.screenshot(...arguments); };
     1514CommandLineAPI.methods["table"] = function() { return inspectedGlobalObject.console.table(...arguments); };
     1515CommandLineAPI.methods["takeHeapSnapshot"] = function() { return inspectedGlobalObject.console.takeHeapSnapshot(...arguments); };
     1516CommandLineAPI.methods["time"] = function() { return inspectedGlobalObject.console.time(...arguments); };
     1517CommandLineAPI.methods["timeEnd"] = function() { return inspectedGlobalObject.console.timeEnd(...arguments); };
     1518CommandLineAPI.methods["timeLog"] = function() { return inspectedGlobalObject.console.timeLog(...arguments); };
     1519CommandLineAPI.methods["timeStamp"] = function() { return inspectedGlobalObject.console.timeStamp(...arguments); };
     1520CommandLineAPI.methods["trace"] = function() { return inspectedGlobalObject.console.trace(...arguments); };
     1521CommandLineAPI.methods["warn"] = function() { return inspectedGlobalObject.console.warn(...arguments); };
     1522
     1523for (let name in CommandLineAPI.methods)
     1524    CommandLineAPI.methods[name].toString = function() { return "function " + name + "() { [Command Line API] }"; };
    15471525
    15481526return injectedScript;
  • trunk/Source/WebCore/ChangeLog

    r249442 r249445  
     12019-09-03  Devin Rousso  <drousso@apple.com>
     2
     3        REGRESSION (r249078): Flaky crash in com.apple.JavaScriptCore: Inspector::InjectedScriptModule::ensureInjected
     4        https://bugs.webkit.org/show_bug.cgi?id=201201
     5        <rdar://problem/54771560>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        Tests: inspector/debugger/tail-deleted-frames-this-value.html
     10               inspector/heap/getRemoteObject.html
     11
     12        * inspector/CommandLineAPIModuleSource.js:
     13        Avoid executing functions when injecting. Instead, modify the `CommandLineAPI` directly.
     14
    1152019-09-03  Zalan Bujtas  <zalan@apple.com>
    216
  • trunk/Source/WebCore/inspector/CommandLineAPIModuleSource.js

    r249173 r249445  
    2929//# sourceURL=__InjectedScript_CommandLineAPIModuleSource.js
    3030
    31 (function (InjectedScriptHost, inspectedGlobalObject, injectedScriptId, injectedScript, RemoteObject, CommandLineAPIHost) {
     31(function (InjectedScriptHost, inspectedGlobalObject, injectedScriptId, injectedScript, {RemoteObject, CommandLineAPI}, CommandLineAPIHost) {
    3232
    3333// FIXME: <https://webkit.org/b/152294> Web Inspector: Parse InjectedScriptSource as a built-in to get guaranteed non-user-overridden built-ins
    3434
    35 injectedScript.setInspectObject(function(object) {
     35injectedScript._inspectObject = function(object) {
    3636    if (arguments.length === 0)
    3737        return;
     
    5454
    5555    CommandLineAPIHost.inspect(objectId, hints);
    56 });
     56};
    5757
    58 injectedScript.addCommandLineAPIGetter("0", function() {
     58CommandLineAPI.getters["0"] = function() {
    5959    return CommandLineAPIHost.inspectedObject();
    60 });
     60};
    6161
    62 injectedScript.addCommandLineAPIMethod("copy", function(object) {
     62CommandLineAPI.methods["copy"] = function(object) {
    6363    let string = null;
    6464
     
    7171        string = "" + object;
    7272    else if (typeof object === "symbol")
    73         string = String(object);
     73        string = inspectedGlobalObject.String(object);
    7474    else if (typeof object === "function")
    7575        string = "" + object;
    7676    else {
    7777        try {
    78             string = JSON.stringify(object, null, "  ");
     78            string = inspectedGlobalObject.JSON.stringify(object, null, "  ");
    7979        } catch {
    8080            string = "" + object;
     
    8383
    8484    CommandLineAPIHost.copyText(string);
    85 });
     85};
    8686
    87 injectedScript.addCommandLineAPIMethod("getEventListeners", function(target) {
     87CommandLineAPI.methods["getEventListeners"] = function(target) {
    8888    return CommandLineAPIHost.getEventListeners(target);
    89 });
     89};
    9090
    9191function normalizeEventTypes(types) {
     
    116116}
    117117
    118 injectedScript.addCommandLineAPIMethod("monitorEvents", function(object, types) {
     118CommandLineAPI.methods["monitorEvents"] = function(object, types) {
    119119    if (!object || !object.addEventListener || !object.removeEventListener)
    120120        return;
     
    124124        object.addEventListener(types[i], logEvent, false);
    125125    }
    126 });
     126};
    127127
    128 injectedScript.addCommandLineAPIMethod("unmonitorEvents", function(object, types) {
     128CommandLineAPI.methods["unmonitorEvents"] = function(object, types) {
    129129    if (!object || !object.addEventListener || !object.removeEventListener)
    130130        return;
     
    132132    for (let i = 0; i < types.length; ++i)
    133133        object.removeEventListener(types[i], logEvent, false);
    134 });
     134};
    135135
    136136if (inspectedGlobalObject.document && inspectedGlobalObject.Node) {
     
    139139    }
    140140
    141     injectedScript.addCommandLineAPIMethod("$", function(selector, start) {
     141    CommandLineAPI.methods["$"] = function(selector, start) {
    142142        if (canQuerySelectorOnNode(start))
    143143            return start.querySelector(selector);
     
    156156
    157157        return result;
    158     });
     158    };
    159159
    160     injectedScript.addCommandLineAPIMethod("$$", function(selector, start) {
     160    CommandLineAPI.methods["$$"] = function(selector, start) {
    161161        if (canQuerySelectorOnNode(start))
    162             return Array.from(start.querySelectorAll(selector));
    163         return Array.from(inspectedGlobalObject.document.querySelectorAll(selector));
    164     });
     162            return inspectedGlobalObject.Array.from(start.querySelectorAll(selector));
     163        return inspectedGlobalObject.Array.from(inspectedGlobalObject.document.querySelectorAll(selector));
     164    };
    165165
    166     injectedScript.addCommandLineAPIMethod("$x", function(xpath, context) {
     166    CommandLineAPI.methods["$x"] = function(xpath, context) {
    167167        let doc = (context && context.ownerDocument) || inspectedGlobalObject.document;
    168         var result = doc.evaluate(xpath, context || doc, null, XPathResult.ANY_TYPE, null);
     168        let result = doc.evaluate(xpath, context || doc, null, inspectedGlobalObject.XPathResult.ANY_TYPE, null);
    169169        switch (result.resultType) {
    170         case XPathResult.NUMBER_TYPE:
     170        case inspectedGlobalObject.XPathResult.NUMBER_TYPE:
    171171            return result.numberValue;
    172         case XPathResult.STRING_TYPE:
     172        case inspectedGlobalObject.XPathResult.STRING_TYPE:
    173173            return result.stringValue;
    174         case XPathResult.BOOLEAN_TYPE:
     174        case inspectedGlobalObject.XPathResult.BOOLEAN_TYPE:
    175175            return result.booleanValue;
    176         default:
    177             var nodes = [];
    178             var node;
    179             while (node = result.iterateNext())
    180                 nodes.push(node);
    181             return nodes;
    182176        }
    183     });
     177
     178        let nodes = [];
     179        let node = null;
     180        while (node = result.iterateNext())
     181            nodes.push(node);
     182        return nodes;
     183    };
    184184}
    185185
     186for (let name in CommandLineAPI.methods)
     187    CommandLineAPI.methods[name].toString = function() { return "function " + name + "() { [Command Line API] }"; };
     188
    186189})
Note: See TracChangeset for help on using the changeset viewer.