Changeset 249078 in webkit


Ignore:
Timestamp:
Aug 23, 2019 5:46:56 PM (5 years ago)
Author:
Devin Rousso
Message:

Web Inspector: create additional command line api functions for other console methods
https://bugs.webkit.org/show_bug.cgi?id=200971

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

Expose all console.* functions in the command line API, since they're all already able to
be referenced via the console object.

Provide a simpler interface for other injected scripts to modify the command line API.

  • inspector/InjectedScriptModule.cpp:

(Inspector::InjectedScriptModule::ensureInjected):

  • inspector/InjectedScriptSource.js:

(InjectedScript.prototype.inspectObject):
(InjectedScript.prototype.addCommandLineAPIGetter): Added.
(InjectedScript.prototype.addCommandLineAPIMethod): Added.
(InjectedScript.prototype.hasInjectedModule): Added.
(InjectedScript.prototype.injectModule):
(InjectedScript.prototype._evaluateOn):
(InjectedScript.CommandLineAPI): Added.
(InjectedScript.prototype.module): Deleted.
(InjectedScript.prototype._savedResult): Deleted.
(bind): Deleted.
(BasicCommandLineAPI): Deleted.
(clear): Deleted.
(table): Deleted.
(profile): Deleted.
(profileEnd): Deleted.
(keys): Deleted.
(values): Deleted.
(queryInstances): Deleted.
(queryObjects): Deleted.
(queryHolders): Deleted.

Source/WebCore:

Expose all console.* functions in the command line API, since they're all already able to
be referenced via the console object.

Provide a simpler interface for other injected scripts to modify the command line API.

  • inspector/CommandLineAPIModuleSource.js:

(injectedScript._inspectObject): Added.
(normalizeEventTypes): Added.
(logEvent): Added.
(canQuerySelectorOnNode): Added.
(bind): Deleted.
(value): Deleted.
(this.method.toString): Deleted.
(CommandLineAPI): Deleted.
(CommandLineAPIImpl): Deleted.
(CommandLineAPIImpl.prototype): Deleted.
(CommandLineAPIImpl.prototype._canQuerySelectorOnNode): Deleted.
(CommandLineAPIImpl.prototype.x): Deleted.
(CommandLineAPIImpl.prototype.dir): Deleted.
(CommandLineAPIImpl.prototype.dirxml): Deleted.
(CommandLineAPIImpl.prototype.keys): Deleted.
(CommandLineAPIImpl.prototype.values): Deleted.
(CommandLineAPIImpl.prototype.profile): Deleted.
(CommandLineAPIImpl.prototype.profileEnd): Deleted.
(CommandLineAPIImpl.prototype.table): Deleted.
(CommandLineAPIImpl.prototype.screenshot): Deleted.
(CommandLineAPIImpl.prototype.monitorEvents): Deleted.
(CommandLineAPIImpl.prototype.unmonitorEvents): Deleted.
(CommandLineAPIImpl.prototype.inspect): Deleted.
(CommandLineAPIImpl.prototype.queryInstances): Deleted.
(CommandLineAPIImpl.prototype.queryObjects): Deleted.
(CommandLineAPIImpl.prototype.queryHolders): Deleted.
(CommandLineAPIImpl.prototype.copy): Deleted.
(CommandLineAPIImpl.prototype.clear): Deleted.
(CommandLineAPIImpl.prototype.getEventListeners): Deleted.
(CommandLineAPIImpl.prototype._inspectedObject): Deleted.
(CommandLineAPIImpl.prototype._normalizeEventTypes): Deleted.
(CommandLineAPIImpl.prototype._logEvent): Deleted.
(CommandLineAPIImpl.prototype._inspect): Deleted.

Source/WebInspectorUI:

Expose all console.* functions in the command line API, since they're all already able to
be referenced via the console object.

Provide a simpler interface for other injected scripts to modify the command line API.

  • UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js:

(WI.JavaScriptRuntimeCompletionProvider.prototype.get _commandLineAPIKeys): Added.
(WI.JavaScriptRuntimeCompletionProvider.prototype.completionControllerCompletionsNeeded.updateLastPropertyNames):
(WI.JavaScriptRuntimeCompletionProvider.prototype.completionControllerCompletionsNeeded.receivedPropertyNames):

LayoutTests:

  • http/tests/inspector/dom/cross-domain-inspected-node-access-expected.txt:
  • inspector/console/command-line-api-expected.txt:
Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r249074 r249078  
     12019-08-23  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: create additional command line api functions for other console methods
     4        https://bugs.webkit.org/show_bug.cgi?id=200971
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        * http/tests/inspector/dom/cross-domain-inspected-node-access-expected.txt:
     9        * inspector/console/command-line-api-expected.txt:
     10
    1112019-08-23  Wenson Hsieh  <wenson_hsieh@apple.com>
    212
  • trunk/LayoutTests/http/tests/inspector/dom/cross-domain-inspected-node-access-expected.txt

    r248925 r249078  
    1 CONSOLE MESSAGE: line 51: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
    2 CONSOLE MESSAGE: line 51: Blocked a frame with origin "http://localhost:8000" from accessing a frame with origin "http://127.0.0.1:8000". Protocols, domains, and ports must match.
     1CONSOLE MESSAGE: line 8: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
     2CONSOLE MESSAGE: line 8: Blocked a frame with origin "http://localhost:8000" from accessing a frame with origin "http://127.0.0.1:8000". Protocols, domains, and ports must match.
    33Test that code evaluated in the main frame cannot access $0 that resolves to a node in a frame from a different domain. Bug 105423.
    44
  • trunk/LayoutTests/inspector/console/command-line-api-expected.txt

    r248287 r249078  
    1 CONSOLE MESSAGE: line 17: The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $("#%s")
     1CONSOLE MESSAGE: line 31: The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $("#%s")
    22Tests that command line api works.
    33
  • trunk/Source/JavaScriptCore/ChangeLog

    r249075 r249078  
     12019-08-23  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: create additional command line api functions for other console methods
     4        https://bugs.webkit.org/show_bug.cgi?id=200971
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Expose all `console.*` functions in the command line API, since they're all already able to
     9        be referenced via the `console` object.
     10
     11        Provide a simpler interface for other injected scripts to modify the command line API.
     12
     13        * inspector/InjectedScriptModule.cpp:
     14        (Inspector::InjectedScriptModule::ensureInjected):
     15
     16        * inspector/InjectedScriptSource.js:
     17        (InjectedScript.prototype.inspectObject):
     18        (InjectedScript.prototype.addCommandLineAPIGetter): Added.
     19        (InjectedScript.prototype.addCommandLineAPIMethod): Added.
     20        (InjectedScript.prototype.hasInjectedModule): Added.
     21        (InjectedScript.prototype.injectModule):
     22        (InjectedScript.prototype._evaluateOn):
     23        (InjectedScript.CommandLineAPI): Added.
     24        (InjectedScript.prototype.module): Deleted.
     25        (InjectedScript.prototype._savedResult): Deleted.
     26        (bind): Deleted.
     27        (BasicCommandLineAPI): Deleted.
     28        (clear): Deleted.
     29        (table): Deleted.
     30        (profile): Deleted.
     31        (profileEnd): Deleted.
     32        (keys): Deleted.
     33        (values): Deleted.
     34        (queryInstances): Deleted.
     35        (queryObjects): Deleted.
     36        (queryHolders): Deleted.
     37
    1382019-08-23  Tadeu Zagallo  <tzagallo@apple.com>
    239
  • trunk/Source/JavaScriptCore/inspector/InjectedScriptModule.cpp

    r233122 r249078  
    6363    // FIXME: Make the InjectedScript a module itself.
    6464    JSC::JSLockHolder locker(injectedScript.scriptState());
    65     Deprecated::ScriptFunctionCall function(injectedScript.injectedScriptObject(), "module"_s, injectedScriptManager->inspectorEnvironment().functionCallHandler());
     65    Deprecated::ScriptFunctionCall function(injectedScript.injectedScriptObject(), "hasInjectedModule"_s, injectedScriptManager->inspectorEnvironment().functionCallHandler());
    6666    function.appendArgument(name());
    6767    bool hadException = false;
    6868    auto resultValue = injectedScript.callFunctionWithEvalEnabled(function, hadException);
    6969    ASSERT(!hadException);
    70     if (hadException || !resultValue || !resultValue.isObject()) {
     70    if (hadException || !resultValue || !resultValue.isBoolean() || !resultValue.asBoolean()) {
    7171        Deprecated::ScriptFunctionCall function(injectedScript.injectedScriptObject(), "injectModule"_s, injectedScriptManager->inspectorEnvironment().functionCallHandler());
    7272        function.appendArgument(name());
     
    7575        resultValue = injectedScript.callFunctionWithEvalEnabled(function, hadException);
    7676        if (hadException) {
    77             ASSERT_NOT_REACHED();
    78             return;
     77            WTFLogAlways("Failed to parse/execute %s!", name().ascii().data());
     78            WTFLogAlways("%s\n", source().ascii().data());
     79            RELEASE_ASSERT_NOT_REACHED();
    7980        }
    8081    }
  • trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js

    r248925 r249078  
    390390    inspectObject(object)
    391391    {
    392         if (this._commandLineAPIImpl)
    393             this._commandLineAPIImpl.inspect(object);
     392        if (this._inspectObject)
     393            this._inspectObject(object);
    394394    }
    395395
     
    418418    }
    419419
     420    // CommandLineAPI
     421
     422    addCommandLineAPIGetter(name, func)
     423    {
     424        InjectedScript.CommandLineAPI._getters.push({name, func});
     425    }
     426
     427    addCommandLineAPIMethod(name, func)
     428    {
     429        func.toString = function() { return "function " + name + "() { [Command Line API] }" };
     430        InjectedScript.CommandLineAPI._methods.push({name, func});
     431    }
     432
    420433    // InjectedScriptModule C++ API
    421434
    422     module(name)
     435    hasInjectedModule(name)
    423436    {
    424437        return this._modules[name];
     
    427440    injectModule(name, source, host)
    428441    {
    429         delete this._modules[name];
     442        this._modules[name] = false;
    430443
    431444        let moduleFunction = InjectedScriptHost.evaluate("(" + source + ")");
    432         if (typeof moduleFunction !== "function") {
    433             if (inspectedGlobalObject.console)
    434                 inspectedGlobalObject.console.error("Web Inspector error: A function was expected for module %s evaluation", name);
    435             return null;
    436         }
    437 
    438         let module = moduleFunction.call(inspectedGlobalObject, InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, RemoteObject, host);
    439         this._modules[name] = module;
    440         return module;
     445        if (typeof moduleFunction !== "function")
     446            throw "Error: Web Inspector: a function was expected for injectModule";
     447        moduleFunction.call(inspectedGlobalObject, InjectedScriptHost, inspectedGlobalObject, injectedScriptId, this, RemoteObject, host);
     448
     449        this._modules[name] = true;
    441450    }
    442451
     
    569578    {
    570579        let commandLineAPI = null;
    571         if (includeCommandLineAPI) {
    572             if (this.CommandLineAPI)
    573                 commandLineAPI = new this.CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
    574             else
    575                 commandLineAPI = new BasicCommandLineAPI(isEvalOnCallFrame ? object : null);
    576         }
    577 
     580        if (includeCommandLineAPI)
     581            commandLineAPI = new InjectedScript.CommandLineAPI(isEvalOnCallFrame ? object : null)
    578582        return evalFunction.call(object, expression, commandLineAPI);
    579583    }
     
    869873        if (this._nextSavedResultIndex >= 100)
    870874            this._nextSavedResultIndex = 1;
    871     }
    872 
    873     _savedResult(index)
    874     {
    875         return this._savedResults[index];
    876875    }
    877876};
     
    14581457// -------
    14591458
    1460 function bind(func, thisObject, ...outerArgs)
     1459InjectedScript.CommandLineAPI = class CommandLineAPI
    14611460{
    1462     return function(...innerArgs) {
    1463         return func.apply(thisObject, outerArgs.concat(innerArgs));
    1464     };
    1465 }
    1466 
    1467 function BasicCommandLineAPI(callFrame)
    1468 {
    1469     let savedResultAlias = InjectedScriptHost.savedResultAlias;
    1470 
    1471     let defineGetter = (key, value) => {
    1472         if (typeof value !== "function") {
    1473             let originalValue = value;
    1474             value = function() { return originalValue; };
    1475         }
    1476 
    1477         this.__defineGetter__("$" + key, value);
    1478         if (savedResultAlias)
    1479             this.__defineGetter__(savedResultAlias + key, value);
    1480     };
    1481 
    1482     if ("_lastResult" in injectedScript)
    1483         defineGetter("_", injectedScript._lastResult);
    1484 
    1485     if ("_exceptionValue" in injectedScript)
    1486         defineGetter("exception", injectedScript._exceptionValue);
    1487 
    1488     if ("_eventValue" in injectedScript)
    1489         defineGetter("event", injectedScript._eventValue);
    1490 
    1491     // $1-$99
    1492     for (let i = 1; i <= injectedScript._savedResults.length; ++i)
    1493         defineGetter(i, bind(injectedScript._savedResult, injectedScript, i));
    1494 
    1495     // Command Line API methods.
    1496     for (let i = 0; i < BasicCommandLineAPI.methods.length; ++i) {
    1497         let method = BasicCommandLineAPI.methods[i];
    1498         this[method.name] = method;
    1499     }
    1500 }
    1501 
    1502 BasicCommandLineAPI.methods = [
    1503     function dir() { return inspectedGlobalObject.console.dir(...arguments); },
    1504     function clear() { return inspectedGlobalObject.console.clear(...arguments); },
    1505     function table() { return inspectedGlobalObject.console.table(...arguments); },
    1506     function profile() { return inspectedGlobalObject.console.profile(...arguments); },
    1507     function profileEnd() { return inspectedGlobalObject.console.profileEnd(...arguments); },
    1508 
    1509     function keys(object) { return Object.keys(object); },
    1510     function values(object) {
    1511         let result = [];
    1512         for (let key in object)
    1513             result.push(object[key]);
    1514         return result;
    1515     },
    1516 
    1517     function queryInstances() {
    1518         return InjectedScriptHost.queryInstances(...arguments);
    1519     },
    1520 
    1521     function queryObjects() {
    1522         return InjectedScriptHost.queryInstances(...arguments);
    1523     },
    1524 
    1525     function queryHolders() {
    1526         return InjectedScriptHost.queryHolders(...arguments);
    1527     },
    1528 ];
    1529 
    1530 for (let i = 0; i < BasicCommandLineAPI.methods.length; ++i) {
    1531     let method = BasicCommandLineAPI.methods[i];
    1532     method.toString = function() { return "function " + method.name + "() { [Command Line API] }"; };
    1533 }
     1461    constructor(callFrame)
     1462    {
     1463        let savedResultAlias = InjectedScriptHost.savedResultAlias;
     1464
     1465        let defineGetter = (key, value) => {
     1466            if (typeof value !== "function") {
     1467                let originalValue = value;
     1468                value = function() { return originalValue; };
     1469            }
     1470
     1471            this.__defineGetter__("$" + key, value);
     1472            if (savedResultAlias)
     1473                this.__defineGetter__(savedResultAlias + key, value);
     1474        };
     1475
     1476        if ("_lastResult" in injectedScript)
     1477            defineGetter("_", injectedScript._lastResult);
     1478
     1479        if ("_exceptionValue" in injectedScript)
     1480            defineGetter("exception", injectedScript._exceptionValue);
     1481
     1482        if ("_eventValue" in injectedScript)
     1483            defineGetter("event", injectedScript._eventValue);
     1484
     1485        // $1-$99
     1486        for (let i = 1; i <= injectedScript._savedResults.length; ++i) {
     1487            defineGetter(i, function() {
     1488                return injectedScript._savedResults[i];
     1489            });
     1490        }
     1491
     1492        for (let i = 0; i < InjectedScript.CommandLineAPI._getters.length; ++i) {
     1493            let {name, func} = InjectedScript.CommandLineAPI._getters[i];
     1494            defineGetter(name, func);
     1495        }
     1496
     1497        for (let i = 0; i < InjectedScript.CommandLineAPI._methods.length; ++i) {
     1498            let {name, func} = InjectedScript.CommandLineAPI._methods[i];
     1499            this[name] = func;
     1500        }
     1501    }
     1502};
     1503
     1504InjectedScript.CommandLineAPI._getters = [];
     1505InjectedScript.CommandLineAPI._methods = [];
     1506
     1507injectedScript.addCommandLineAPIMethod("keys", function(object) { return Object.keys(object); });
     1508injectedScript.addCommandLineAPIMethod("values", function(object) { return Object.values(object); });
     1509
     1510injectedScript.addCommandLineAPIMethod("queryInstances", function() { return InjectedScriptHost.queryInstances(...arguments); });
     1511injectedScript.addCommandLineAPIMethod("queryObjects", function() { return InjectedScriptHost.queryInstances(...arguments); });
     1512injectedScript.addCommandLineAPIMethod("queryHolders", function() { return InjectedScriptHost.queryHolders(...arguments); });
     1513
     1514injectedScript.addCommandLineAPIMethod("inspect", function(object) { return injectedScript.inspectObject(object); });
     1515
     1516injectedScript.addCommandLineAPIMethod("assert", function() { return inspectedGlobalObject.console.assert(...arguments); });
     1517injectedScript.addCommandLineAPIMethod("clear", function() { return inspectedGlobalObject.console.clear(...arguments); });
     1518injectedScript.addCommandLineAPIMethod("count", function() { return inspectedGlobalObject.console.count(...arguments); });
     1519injectedScript.addCommandLineAPIMethod("countReset", function() { return inspectedGlobalObject.console.countReset(...arguments); });
     1520injectedScript.addCommandLineAPIMethod("debug", function() { return inspectedGlobalObject.console.debug(...arguments); });
     1521injectedScript.addCommandLineAPIMethod("dir", function() { return inspectedGlobalObject.console.dir(...arguments); });
     1522injectedScript.addCommandLineAPIMethod("dirxml", function() { return inspectedGlobalObject.console.dirxml(...arguments); });
     1523injectedScript.addCommandLineAPIMethod("error", function() { return inspectedGlobalObject.console.error(...arguments); });
     1524injectedScript.addCommandLineAPIMethod("group", function() { return inspectedGlobalObject.console.group(...arguments); });
     1525injectedScript.addCommandLineAPIMethod("groupCollapsed", function() { return inspectedGlobalObject.console.groupCollapsed(...arguments); });
     1526injectedScript.addCommandLineAPIMethod("groupEnd", function() { return inspectedGlobalObject.console.groupEnd(...arguments); });
     1527injectedScript.addCommandLineAPIMethod("info", function() { return inspectedGlobalObject.console.info(...arguments); });
     1528injectedScript.addCommandLineAPIMethod("log", function() { return inspectedGlobalObject.console.log(...arguments); });
     1529injectedScript.addCommandLineAPIMethod("profile", function() { return inspectedGlobalObject.console.profile(...arguments); });
     1530injectedScript.addCommandLineAPIMethod("profileEnd", function() { return inspectedGlobalObject.console.profileEnd(...arguments); });
     1531injectedScript.addCommandLineAPIMethod("record", function() { return inspectedGlobalObject.console.record(...arguments); });
     1532injectedScript.addCommandLineAPIMethod("recordEnd", function() { return inspectedGlobalObject.console.recordEnd(...arguments); });
     1533injectedScript.addCommandLineAPIMethod("screenshot", function() { return inspectedGlobalObject.console.screenshot(...arguments); });
     1534injectedScript.addCommandLineAPIMethod("table", function() { return inspectedGlobalObject.console.table(...arguments); });
     1535injectedScript.addCommandLineAPIMethod("takeHeapSnapshot", function() { return inspectedGlobalObject.console.takeHeapSnapshot(...arguments); });
     1536injectedScript.addCommandLineAPIMethod("time", function() { return inspectedGlobalObject.console.time(...arguments); });
     1537injectedScript.addCommandLineAPIMethod("timeEnd", function() { return inspectedGlobalObject.console.timeEnd(...arguments); });
     1538injectedScript.addCommandLineAPIMethod("timeLog", function() { return inspectedGlobalObject.console.timeLog(...arguments); });
     1539injectedScript.addCommandLineAPIMethod("timeStamp", function() { return inspectedGlobalObject.console.timeStamp(...arguments); });
     1540injectedScript.addCommandLineAPIMethod("trace", function() { return inspectedGlobalObject.console.trace(...arguments); });
     1541injectedScript.addCommandLineAPIMethod("warn", function() { return inspectedGlobalObject.console.warn(...arguments); });
    15341542
    15351543return injectedScript;
  • trunk/Source/WebCore/ChangeLog

    r249077 r249078  
     12019-08-23  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: create additional command line api functions for other console methods
     4        https://bugs.webkit.org/show_bug.cgi?id=200971
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Expose all `console.*` functions in the command line API, since they're all already able to
     9        be referenced via the `console` object.
     10
     11        Provide a simpler interface for other injected scripts to modify the command line API.
     12
     13        * inspector/CommandLineAPIModuleSource.js:
     14        (injectedScript._inspectObject): Added.
     15        (normalizeEventTypes): Added.
     16        (logEvent): Added.
     17        (canQuerySelectorOnNode): Added.
     18        (bind): Deleted.
     19        (value): Deleted.
     20        (this.method.toString): Deleted.
     21        (CommandLineAPI): Deleted.
     22        (CommandLineAPIImpl): Deleted.
     23        (CommandLineAPIImpl.prototype): Deleted.
     24        (CommandLineAPIImpl.prototype._canQuerySelectorOnNode): Deleted.
     25        (CommandLineAPIImpl.prototype.x): Deleted.
     26        (CommandLineAPIImpl.prototype.dir): Deleted.
     27        (CommandLineAPIImpl.prototype.dirxml): Deleted.
     28        (CommandLineAPIImpl.prototype.keys): Deleted.
     29        (CommandLineAPIImpl.prototype.values): Deleted.
     30        (CommandLineAPIImpl.prototype.profile): Deleted.
     31        (CommandLineAPIImpl.prototype.profileEnd): Deleted.
     32        (CommandLineAPIImpl.prototype.table): Deleted.
     33        (CommandLineAPIImpl.prototype.screenshot): Deleted.
     34        (CommandLineAPIImpl.prototype.monitorEvents): Deleted.
     35        (CommandLineAPIImpl.prototype.unmonitorEvents): Deleted.
     36        (CommandLineAPIImpl.prototype.inspect): Deleted.
     37        (CommandLineAPIImpl.prototype.queryInstances): Deleted.
     38        (CommandLineAPIImpl.prototype.queryObjects): Deleted.
     39        (CommandLineAPIImpl.prototype.queryHolders): Deleted.
     40        (CommandLineAPIImpl.prototype.copy): Deleted.
     41        (CommandLineAPIImpl.prototype.clear): Deleted.
     42        (CommandLineAPIImpl.prototype.getEventListeners): Deleted.
     43        (CommandLineAPIImpl.prototype._inspectedObject): Deleted.
     44        (CommandLineAPIImpl.prototype._normalizeEventTypes): Deleted.
     45        (CommandLineAPIImpl.prototype._logEvent): Deleted.
     46        (CommandLineAPIImpl.prototype._inspect): Deleted.
     47
    1482019-08-23  Chris Dumez  <cdumez@apple.com>
    249
  • trunk/Source/WebCore/inspector/CommandLineAPIModuleSource.js

    r248925 r249078  
    2929//# sourceURL=__InjectedScript_CommandLineAPIModuleSource.js
    3030
    31 (function (InjectedScriptHost, inspectedWindow, injectedScriptId, injectedScript, RemoteObject, CommandLineAPIHost) {
     31(function (InjectedScriptHost, inspectedGlobalObject, injectedScriptId, injectedScript, RemoteObject, 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 function bind(func, thisObject, ...outerArgs)
    36 {
    37     return function(...innerArgs) {
    38         return func.apply(thisObject, outerArgs.concat(innerArgs));
    39     };
     35injectedScript._inspectObject = function(object) {
     36    if (arguments.length === 0)
     37        return;
     38
     39    let objectId = RemoteObject.create(object, "");
     40    let hints = {};
     41
     42    switch (RemoteObject.describe(object)) {
     43    case "Database":
     44        let databaseId = CommandLineAPIHost.databaseId(object)
     45        if (databaseId)
     46            hints.databaseId = databaseId;
     47        break;
     48    case "Storage":
     49        let storageId = CommandLineAPIHost.storageId(object)
     50        if (storageId)
     51            hints.domStorageId = InjectedScriptHost.evaluate("(" + storageId + ")");
     52        break;
     53    }
     54
     55    CommandLineAPIHost.inspect(objectId, hints);
     56    return object;
     57};
     58
     59injectedScript.addCommandLineAPIGetter("0", function() {
     60    return CommandLineAPIHost.inspectedObject();
     61});
     62
     63injectedScript.addCommandLineAPIMethod("copy", function(object) {
     64    let string = null;
     65
     66    let subtype = RemoteObject.subtype(object);
     67    if (subtype === "node")
     68        string = object.outerHTML;
     69    else if (subtype === "regexp")
     70        string = "" + object;
     71    else if (injectedScript.isPrimitiveValue(object))
     72        string = "" + object;
     73    else if (typeof object === "symbol")
     74        string = String(object);
     75    else if (typeof object === "function")
     76        string = "" + object;
     77    else {
     78        try {
     79            string = JSON.stringify(object, null, "  ");
     80        } catch {
     81            string = "" + object;
     82        }
     83    }
     84
     85    CommandLineAPIHost.copyText(string);
     86});
     87
     88injectedScript.addCommandLineAPIMethod("getEventListeners", function(target) {
     89    return CommandLineAPIHost.getEventListeners(target);
     90});
     91
     92function normalizeEventTypes(types) {
     93    if (types === undefined)
     94        types = ["mouse", "key", "touch", "control", "abort", "blur", "change", "devicemotion", "deviceorientation", "error", "focus", "load", "reset", "resize", "scroll", "search", "select", "submit", "unload"];
     95    else if (typeof types === "string")
     96        types = [types];
     97
     98    let result = [];
     99    for (let i = 0; i < types.length; i++) {
     100        if (types[i] === "mouse")
     101            result.push("click", "dblclick", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "mousewheel");
     102        else if (types[i] === "key")
     103            result.push("keydown", "keypress", "keyup", "textInput");
     104        else if (types[i] === "touch")
     105            result.push("touchcancel", "touchend", "touchmove", "touchstart");
     106        else if (types[i] === "control")
     107            result.push("blur", "change", "focus", "reset", "resize", "scroll", "select", "submit", "zoom");
     108        else
     109            result.push(types[i]);
     110    }
     111    return result;
    40112}
    41113
    42 /**
    43  * @constructor
    44  * @param {CommandLineAPIImpl} commandLineAPIImpl
    45  * @param {Object} callFrame
    46  */
    47 function CommandLineAPI(commandLineAPIImpl, callFrame)
     114function logEvent(event)
    48115{
    49     let savedResultAlias = InjectedScriptHost.savedResultAlias;
    50 
    51     let defineGetter = (key, value) => {
    52         if (typeof value !== "function") {
    53             let originalValue = value;
    54             value = function() { return originalValue; };
    55         }
    56 
    57         this.__defineGetter__("$" + key, value);
    58         if (savedResultAlias)
    59             this.__defineGetter__(savedResultAlias + key, value);
    60     };
    61 
    62     if ("_lastResult" in injectedScript)
    63         defineGetter("_", injectedScript._lastResult);
    64 
    65     if ("_exceptionValue" in injectedScript)
    66         defineGetter("exception", injectedScript._exceptionValue);
    67 
    68     if ("_eventValue" in injectedScript)
    69         defineGetter("event", injectedScript._eventValue);
    70 
    71     // $0
    72     defineGetter("0", bind(commandLineAPIImpl._inspectedObject, commandLineAPIImpl));
    73 
    74     // $1-$99
    75     for (let i = 1; i <= injectedScript._savedResults.length; ++i)
    76         defineGetter(i, bind(injectedScript._savedResult, injectedScript, i));
    77 
    78     // Command Line API methods.
    79     for (let i = 0; i < CommandLineAPI.methods.length; ++i) {
    80         let method = CommandLineAPI.methods[i];
    81         this[method] = bind(commandLineAPIImpl[method], commandLineAPIImpl);
    82         this[method].toString = function() { return "function " + method + "() { [Command Line API] }" };
    83     }
     116    inspectedGlobalObject.console.log(event.type, event);
    84117}
    85118
    86 /**
    87  * @type {Array.<string>}
    88  * @const
    89  */
    90 CommandLineAPI.methods = [
    91     "$",
    92     "$$",
    93     "$x",
    94     "clear",
    95     "copy",
    96     "dir",
    97     "dirxml",
    98     "getEventListeners",
    99     "inspect",
    100     "keys",
    101     "monitorEvents",
    102     "profile",
    103     "profileEnd",
    104     "queryInstances",
    105     "queryObjects",
    106     "queryHolders",
    107     "screenshot",
    108     "table",
    109     "unmonitorEvents",
    110     "values",
    111 ];
     119injectedScript.addCommandLineAPIMethod("monitorEvents", function(object, types) {
     120    if (!object || !object.addEventListener || !object.removeEventListener)
     121        return;
     122    types = normalizeEventTypes(types);
     123    for (let i = 0; i < types.length; ++i) {
     124        object.removeEventListener(types[i], logEvent, false);
     125        object.addEventListener(types[i], logEvent, false);
     126    }
     127});
    112128
    113 /**
    114  * @constructor
    115  */
    116 function CommandLineAPIImpl()
    117 {
    118 }
     129injectedScript.addCommandLineAPIMethod("unmonitorEvents", function(object, types) {
     130    if (!object || !object.addEventListener || !object.removeEventListener)
     131        return;
     132    types = normalizeEventTypes(types);
     133    for (let i = 0; i < types.length; ++i)
     134        object.removeEventListener(types[i], logEvent, false);
     135});
    119136
    120 CommandLineAPIImpl.prototype = {
    121     /**
    122      * @param {string} selector
    123      * @param {Node=} start
    124      */
    125     $: function (selector, start)
    126     {
    127         if (this._canQuerySelectorOnNode(start))
     137if (inspectedGlobalObject.document && inspectedGlobalObject.Node) {
     138    function canQuerySelectorOnNode(node) {
     139        return node && InjectedScriptHost.subtype(node) === "node" && (node.nodeType === inspectedGlobalObject.Node.ELEMENT_NODE || node.nodeType === inspectedGlobalObject.Node.DOCUMENT_NODE || node.nodeType === inspectedGlobalObject.Node.DOCUMENT_FRAGMENT_NODE);
     140    }
     141
     142    injectedScript.addCommandLineAPIMethod("$", function(selector, start) {
     143        if (canQuerySelectorOnNode(start))
    128144            return start.querySelector(selector);
    129145
    130         var result = inspectedWindow.document.querySelector(selector);
     146        let result = inspectedGlobalObject.document.querySelector(selector);
    131147        if (result)
    132148            return result;
     149
    133150        if (selector && selector[0] !== "#") {
    134             result = inspectedWindow.document.getElementById(selector);
     151            result = inspectedGlobalObject.document.getElementById(selector);
    135152            if (result) {
    136                 inspectedWindow.console.warn("The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $(\"#%s\")", selector);
     153                inspectedGlobalObject.console.warn("The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $(\"#%s\")", selector);
    137154                return null;
    138155            }
    139156        }
     157
    140158        return result;
    141     },
     159    });
    142160
    143     /**
    144      * @param {string} selector
    145      * @param {Node=} start
    146      */
    147     $$: function (selector, start)
    148     {
    149         if (this._canQuerySelectorOnNode(start))
     161    injectedScript.addCommandLineAPIMethod("$$", function(selector, start) {
     162        if (canQuerySelectorOnNode(start))
    150163            return Array.from(start.querySelectorAll(selector));
    151         return Array.from(inspectedWindow.document.querySelectorAll(selector));
    152     },
     164        return Array.from(inspectedGlobalObject.document.querySelectorAll(selector));
     165    });
    153166
    154     /**
    155      * @param {Node=} node
    156      * @return {boolean}
    157      */
    158     _canQuerySelectorOnNode: function(node)
    159     {
    160         return !!node && InjectedScriptHost.subtype(node) === "node" && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE);
    161     },
    162 
    163     /**
    164      * @param {string} xpath
    165      * @param {Node=} context
    166      */
    167     $x: function(xpath, context)
    168     {
    169         var doc = (context && context.ownerDocument) || inspectedWindow.document;
     167    injectedScript.addCommandLineAPIMethod("$x", function(xpath, context) {
     168        let doc = (context && context.ownerDocument) || inspectedGlobalObject.document;
    170169        var result = doc.evaluate(xpath, context || doc, null, XPathResult.ANY_TYPE, null);
    171170        switch (result.resultType) {
     
    183182            return nodes;
    184183        }
    185     },
    186 
    187     dir: function()
    188     {
    189         return inspectedWindow.console.dir.apply(inspectedWindow.console, arguments)
    190     },
    191 
    192     dirxml: function()
    193     {
    194         return inspectedWindow.console.dirxml.apply(inspectedWindow.console, arguments)
    195     },
    196 
    197     keys: function(object)
    198     {
    199         return Object.keys(object);
    200     },
    201 
    202     values: function(object)
    203     {
    204         var result = [];
    205         for (var key in object)
    206             result.push(object[key]);
    207         return result;
    208     },
    209 
    210     profile: function()
    211     {
    212         return inspectedWindow.console.profile.apply(inspectedWindow.console, arguments)
    213     },
    214 
    215     profileEnd: function()
    216     {
    217         return inspectedWindow.console.profileEnd.apply(inspectedWindow.console, arguments)
    218     },
    219 
    220     table: function()
    221     {
    222         return inspectedWindow.console.table.apply(inspectedWindow.console, arguments)
    223     },
    224 
    225     screenshot: function()
    226     {
    227         return inspectedWindow.console.screenshot.apply(inspectedWindow.console, arguments)
    228     },
    229 
    230     /**
    231      * @param {Object} object
    232      * @param {Array.<string>|string=} types
    233      */
    234     monitorEvents: function(object, types)
    235     {
    236         if (!object || !object.addEventListener || !object.removeEventListener)
    237             return;
    238         types = this._normalizeEventTypes(types);
    239         for (var i = 0; i < types.length; ++i) {
    240             object.removeEventListener(types[i], this._logEvent, false);
    241             object.addEventListener(types[i], this._logEvent, false);
    242         }
    243     },
    244 
    245     /**
    246      * @param {Object} object
    247      * @param {Array.<string>|string=} types
    248      */
    249     unmonitorEvents: function(object, types)
    250     {
    251         if (!object || !object.addEventListener || !object.removeEventListener)
    252             return;
    253         types = this._normalizeEventTypes(types);
    254         for (var i = 0; i < types.length; ++i)
    255             object.removeEventListener(types[i], this._logEvent, false);
    256     },
    257 
    258     /**
    259      * @param {*} object
    260      * @return {*}
    261      */
    262     inspect: function(object)
    263     {
    264         return this._inspect(object);
    265     },
    266 
    267     queryInstances()
    268     {
    269         return InjectedScriptHost.queryInstances(...arguments);
    270     },
    271 
    272     queryObjects()
    273     {
    274         return InjectedScriptHost.queryInstances(...arguments);
    275     },
    276 
    277     queryHolders()
    278     {
    279         return InjectedScriptHost.queryHolders(...arguments);
    280     },
    281 
    282     copy: function(object)
    283     {
    284         var string;
    285         var subtype = RemoteObject.subtype(object);
    286         if (subtype === "node")
    287             string = object.outerHTML;
    288         else if (subtype === "regexp")
    289             string = "" + object;
    290         else if (injectedScript.isPrimitiveValue(object))
    291             string = "" + object;
    292         else if (typeof object === "symbol")
    293             string = String(object);
    294         else if (typeof object === "function")
    295             string = "" + object;
    296         else {
    297             try {
    298                 string = JSON.stringify(object, null, "  ");
    299             } catch (e) {
    300                 string = "" + object;
    301             }
    302         }
    303 
    304         CommandLineAPIHost.copyText(string);
    305     },
    306 
    307     clear: function()
    308     {
    309         CommandLineAPIHost.clearConsoleMessages();
    310     },
    311 
    312     getEventListeners: function(target)
    313     {
    314         return CommandLineAPIHost.getEventListeners(target);
    315     },
    316 
    317     _inspectedObject: function()
    318     {
    319         return CommandLineAPIHost.inspectedObject();
    320     },
    321 
    322     /**
    323      * @param {Array.<string>|string=} types
    324      * @return {Array.<string>}
    325      */
    326     _normalizeEventTypes: function(types)
    327     {
    328         if (typeof types === "undefined")
    329             types = [ "mouse", "key", "touch", "control", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll", "search", "devicemotion", "deviceorientation" ];
    330         else if (typeof types === "string")
    331             types = [ types ];
    332 
    333         var result = [];
    334         for (var i = 0; i < types.length; i++) {
    335             if (types[i] === "mouse")
    336                 result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout", "mousewheel");
    337             else if (types[i] === "key")
    338                 result.splice(0, 0, "keydown", "keyup", "keypress", "textInput");
    339             else if (types[i] === "touch")
    340                 result.splice(0, 0, "touchstart", "touchmove", "touchend", "touchcancel");
    341             else if (types[i] === "control")
    342                 result.splice(0, 0, "resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset");
    343             else
    344                 result.push(types[i]);
    345         }
    346         return result;
    347     },
    348 
    349     /**
    350      * @param {Event} event
    351      */
    352     _logEvent: function(event)
    353     {
    354         inspectedWindow.console.log(event.type, event);
    355     },
    356 
    357     /**
    358      * @param {*} object
    359      * @return {*}
    360      */
    361     _inspect: function(object)
    362     {
    363         if (arguments.length === 0)
    364             return;
    365 
    366         var objectId = RemoteObject.create(object, "");
    367         var hints = {};
    368 
    369         switch (RemoteObject.describe(object)) {
    370         case "Database":
    371             var databaseId = CommandLineAPIHost.databaseId(object)
    372             if (databaseId)
    373                 hints.databaseId = databaseId;
    374             break;
    375         case "Storage":
    376             var storageId = CommandLineAPIHost.storageId(object)
    377             if (storageId)
    378                 hints.domStorageId = InjectedScriptHost.evaluate("(" + storageId + ")");
    379             break;
    380         }
    381 
    382         CommandLineAPIHost.inspect(objectId, hints);
    383         return object;
    384     }
     184    });
    385185}
    386186
    387 injectedScript.CommandLineAPI = CommandLineAPI;
    388 injectedScript._commandLineAPIImpl = new CommandLineAPIImpl();
    389 
    390 // This Module doesn't expose an object, it just adds an extension that InjectedScript uses.
    391 // However, we return an empty object, so that InjectedScript knows this module has been loaded.
    392 return {};
    393 
    394187})
  • trunk/Source/WebInspectorUI/ChangeLog

    r249057 r249078  
     12019-08-23  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: create additional command line api functions for other console methods
     4        https://bugs.webkit.org/show_bug.cgi?id=200971
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Expose all `console.*` functions in the command line API, since they're all already able to
     9        be referenced via the `console` object.
     10
     11        Provide a simpler interface for other injected scripts to modify the command line API.
     12
     13        * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js:
     14        (WI.JavaScriptRuntimeCompletionProvider.prototype.get _commandLineAPIKeys): Added.
     15        (WI.JavaScriptRuntimeCompletionProvider.prototype.completionControllerCompletionsNeeded.updateLastPropertyNames):
     16        (WI.JavaScriptRuntimeCompletionProvider.prototype.completionControllerCompletionsNeeded.receivedPropertyNames):
     17
    1182019-08-23  Devin Rousso  <drousso@apple.com>
    219
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js

    r248925 r249078  
    4545    }
    4646
     47    // Static
     48
     49    static get _commandLineAPIKeys()
     50    {
     51        if (!JavaScriptRuntimeCompletionProvider.__cachedCommandLineAPIKeys) {
     52            JavaScriptRuntimeCompletionProvider.__cachedCommandLineAPIKeys = [
     53                "$_",
     54                "assert",
     55                "clear",
     56                "count",
     57                "countReset",
     58                "debug",
     59                "dir",
     60                "dirxml",
     61                "error",
     62                "group",
     63                "groupCollapsed",
     64                "groupEnd",
     65                "info",
     66                "inspect",
     67                "keys",
     68                "log",
     69                "profile",
     70                "profileEnd",
     71                "queryHolders",
     72                "queryInstances",
     73                "queryObjects",
     74                "record",
     75                "recordEnd",
     76                "screenshot",
     77                "table",
     78                "takeHeapSnapshot",
     79                "time",
     80                "timeEnd",
     81                "timeLog",
     82                "timeStamp",
     83                "trace",
     84                "values",
     85                "warn",
     86            ];
     87        }
     88        return JavaScriptRuntimeCompletionProvider.__cachedCommandLineAPIKeys;
     89    }
     90
    4791    // Protected
    4892
     
    114158            this._clearLastPropertiesTimeout = setTimeout(this._clearLastProperties.bind(this), WI.JavaScriptLogViewController.CachedPropertiesDuration);
    115159
    116             this._lastPropertyNames = propertyNames || {};
     160            this._lastPropertyNames = propertyNames || [];
    117161        }
    118162
     
    212256        function receivedPropertyNames(propertyNames)
    213257        {
    214             propertyNames = propertyNames || {};
     258            propertyNames = propertyNames ? Object.keys(propertyNames) : [];
    215259
    216260            updateLastPropertyNames.call(this, propertyNames);
     
    219263
    220264            if (!base) {
    221                 let commandLineAPI = WI.JavaScriptRuntimeCompletionProvider._commandLineAPI.slice(0);
     265                propertyNames.push(...JavaScriptRuntimeCompletionProvider._commandLineAPIKeys);
     266
     267                let savedResultAlias = WI.settings.consoleSavedResultAlias.value;
     268                if (savedResultAlias)
     269                    propertyNames.push(savedResultAlias + "_");
     270
     271                let target = WI.runtimeManager.activeExecutionContext.target;
     272
    222273                if (WI.debuggerManager.paused) {
    223                     let targetData = WI.debuggerManager.dataForTarget(WI.runtimeManager.activeExecutionContext.target);
    224                     if (targetData.pauseReason === WI.DebuggerManager.PauseReason.Listener || targetData.pauseReason === WI.DebuggerManager.PauseReason.EventListener)
    225                         commandLineAPI.push("$event");
    226                     else if (targetData.pauseReason === WI.DebuggerManager.PauseReason.Exception)
    227                         commandLineAPI.push("$exception");
    228                 }
    229                 for (let name of commandLineAPI)
    230                     propertyNames[name] = true;
    231 
    232                 let savedResultAlias = WI.settings.consoleSavedResultAlias.value;
    233                 if (savedResultAlias) {
    234                     propertyNames[savedResultAlias + "0"] = true;
    235                     propertyNames[savedResultAlias + "_"] = true;
     274                    let targetData = WI.debuggerManager.dataForTarget(target);
     275                    if (targetData.pauseReason === WI.DebuggerManager.PauseReason.Listener || targetData.pauseReason === WI.DebuggerManager.PauseReason.EventListener) {
     276                        propertyNames.push("$event");
     277                        if (savedResultAlias)
     278                            propertyNames.push(savedResultAlias + "event");
     279                    } else if (targetData.pauseReason === WI.DebuggerManager.PauseReason.Exception) {
     280                        propertyNames.push("$exception");
     281                        if (savedResultAlias)
     282                            propertyNames.push(savedResultAlias + "exception");
     283                    }
     284                }
     285
     286                switch (target.type) {
     287                case WI.Target.Type.Page:
     288                    propertyNames.push("$");
     289                    propertyNames.push("$$");
     290                    propertyNames.push("$0");
     291                    if (savedResultAlias)
     292                        propertyNames.push(savedResultAlias + "0");
     293                    propertyNames.push("$x");
     294                    // fallthrough
     295                case WI.Target.Type.ServiceWorker:
     296                case WI.Target.Type.Worker:
     297                    propertyNames.push("copy");
     298                    propertyNames.push("getEventListeners");
     299                    propertyNames.push("monitorEvents");
     300                    propertyNames.push("unmonitorEvents");
     301                    break;
    236302                }
    237303
    238304                // FIXME: Due to caching, sometimes old $n values show up as completion results even though they are not available. We should clear that proactively.
    239305                for (var i = 1; i <= WI.ConsoleCommandResultMessage.maximumSavedResultIndex; ++i) {
    240                     propertyNames["$" + i] = true;
    241 
     306                    propertyNames.push("$" + i);
    242307                    if (savedResultAlias)
    243                         propertyNames[savedResultAlias + i] = true;
    244                 }
    245             }
    246 
    247             propertyNames = Object.keys(propertyNames);
     308                        propertyNames.push(savedResultAlias + i);
     309                }
     310            }
    248311
    249312            var implicitSuffix = "";
     
    314377    }
    315378};
    316 
    317 WI.JavaScriptRuntimeCompletionProvider._commandLineAPI = [
    318     "$",
    319     "$$",
    320     "$0",
    321     "$_",
    322     "$x",
    323     "clear",
    324     "copy",
    325     "dir",
    326     "dirxml",
    327     "getEventListeners",
    328     "inspect",
    329     "keys",
    330     "monitorEvents",
    331     "profile",
    332     "profileEnd",
    333     "queryHolders",
    334     "queryInstances",
    335     "queryObjects",
    336     "screenshot",
    337     "table",
    338     "unmonitorEvents",
    339     "values",
    340 ];
Note: See TracChangeset for help on using the changeset viewer.