Changeset 71107 in webkit


Ignore:
Timestamp:
Nov 2, 2010 3:29:02 AM (14 years ago)
Author:
caseq@chromium.org
Message:

2010-11-01 Andrey Kosyakov <caseq@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: [Extensions API] expose API to create properties watch sidebar panes
https://bugs.webkit.org/show_bug.cgi?id=48761

  • inspector/front-end/ExtensionAPI.js: (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createSidebarPane): (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createWatchExpressionSidebarPane.callbackWrapper): (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createWatchExpressionSidebarPane): (WebInspector.injectedExtensionAPI): (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl): (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl.prototype.setExpression): (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl.prototype.setObject):
  • inspector/front-end/ExtensionPanel.js: Added ExtensionWatchSidebarPane (WebInspector.ExtensionWatchSidebarPane): (WebInspector.ExtensionWatchSidebarPane.prototype.setObject): (WebInspector.ExtensionWatchSidebarPane.prototype.setExpression): (WebInspector.ExtensionWatchSidebarPane.prototype._onEvaluate): (WebInspector.ExtensionWatchSidebarPane.prototype._setObject):
  • inspector/front-end/ExtensionServer.js: (WebInspector.ExtensionServer): (WebInspector.ExtensionServer.prototype.notifyExtensionWatchSidebarUpdated): (WebInspector.ExtensionServer.prototype._onCreateSidebar): (WebInspector.ExtensionServer.prototype._onCreateWatchExpressionSidebarPane): (WebInspector.ExtensionServer.prototype._createSidebar): (WebInspector.ExtensionServer.prototype._onSetWatchSidebarContent):
  • inspector/front-end/InjectedScript.js: (injectedScriptConstructor.):
  • inspector/front-end/RemoteObject.js: Added a wrapper for local JSON object to simulate RemoteObject interface. (WebInspector.RemoteObject.fromLocalObject): (WebInspector.LocalJSONObject): (WebInspector.LocalJSONObject.prototype.get description): (WebInspector.LocalJSONObject.prototype.get type): (WebInspector.LocalJSONObject.prototype.get hasChildren): (WebInspector.LocalJSONObject.prototype.getOwnProperties): (WebInspector.LocalJSONObject.prototype.getProperties): (WebInspector.LocalJSONObject.prototype.isError):

2010-11-01 Andrey Kosyakov <caseq@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: [Extensions API] expose API to create properties watch sidebar panes
https://bugs.webkit.org/show_bug.cgi?id=48761

  • inspector/extensions-api-expected.txt:
  • inspector/extensions-events-expected.txt:
  • inspector/extensions-expected.txt:
  • inspector/extensions-test.js: Added generic way to dispatch messages to front-end and receive callbacks. (initialize_ExtensionsTest.InspectorTest.dispatchOnMessage): (initialize_ExtensionsTest.InspectorTest.dumpSidebarContent):
  • inspector/extensions.html:
  • inspector/resources/extension-main.js: (dispatchOnFrontend.callbackWrapper): (dispatchOnFrontend):
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r71106 r71107  
     12010-11-01  Andrey Kosyakov  <caseq@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: [Extensions API] expose API to create properties watch sidebar panes
     6        https://bugs.webkit.org/show_bug.cgi?id=48761
     7
     8        * inspector/extensions-api-expected.txt:
     9        * inspector/extensions-events-expected.txt:
     10        * inspector/extensions-expected.txt:
     11        * inspector/extensions-test.js: Added generic way to dispatch messages to front-end and receive callbacks.
     12        (initialize_ExtensionsTest.InspectorTest.dispatchOnMessage):
     13        (initialize_ExtensionsTest.InspectorTest.dumpSidebarContent):
     14        * inspector/extensions.html:
     15        * inspector/resources/extension-main.js:
     16        (dispatchOnFrontend.callbackWrapper):
     17        (dispatchOnFrontend):
     18
    1192010-11-02  Philippe Normand  <pnormand@igalia.com>
    220
  • trunk/LayoutTests/inspector/extensions-api-expected.txt

    r70248 r71107  
    2828        elements : {
    2929            createSidebarPane : <function>
     30            createWatchExpressionSidebarPane : <function>
    3031            onSelectionChanged : {
    3132                addListener : <function>
     
    3536        scripts : {
    3637            createSidebarPane : <function>
     38            createWatchExpressionSidebarPane : <function>
    3739            onSelectionChanged : {
    3840                addListener : <function>
  • trunk/LayoutTests/inspector/extensions-events-expected.txt

    r69769 r71107  
    1 CONSOLE MESSAGE: line 670: [object HTMLParagraphElement]
     1CONSOLE MESSAGE: line 669: [object HTMLParagraphElement]
    22Tests WebInspector extension API
    33
  • trunk/LayoutTests/inspector/extensions-expected.txt

    r67084 r71107  
    99{
    1010    createSidebarPane : <function>
     11    createWatchExpressionSidebarPane : <function>
    1112    onSelectionChanged : {
    1213        addListener : <function>
     
    2425    setExpanded : <function>
    2526}
     27RUNNING TEST: extension_testExtensionWatchSidebarExpression
     28Sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: Objectf4: Array[0]f5: Array[3]f6: Objectf7: 42f8: Locationf9: HTMLCollection[26]f10: function () {}__proto__: Object
     29RUNNING TEST: extension_testExtensionWatchSidebarObject
     30Watch sidebar created, callback arguments dump follows:
     31{
     32    0 : {
     33        setHeight : <function>
     34        setExpanded : <function>
     35        setExpression : <function>
     36        setObject : <function>
     37        onUpdated : {
     38            addListener : <function>
     39            removeListener : <function>
     40        }
     41    }
     42}
     43Sidebar content: f0: "object"f1: undefinedf2: nullf3: { }f4: [0]f5: [3]f6: {...}f7: 42
    2644All tests done.
    2745
  • trunk/LayoutTests/inspector/extensions-test.js

    r71035 r71107  
    1818{
    1919
    20 InspectorTest.dispatchOnMessage = function(messageId, callback)
     20InspectorTest.dispatchOnMessage = function(messageId, callback, recurring)
    2121{
    2222    function onMessage(event)
    2323    {
    24         if (event.data === messageId) {
     24        if (event.data !== messageId)
     25            return;
     26        if (!recurring)
    2527            window.removeEventListener("message", onMessage, false);
    26             callback();
    27         }
     28        callback();
     29        if (event.ports && event.ports[0])
     30            event.ports[0].postMessage("");
    2831    }
    2932    window.addEventListener("message", onMessage, false);
     
    4750}
    4851
     52InspectorTest.dumpSidebarContent = function()
     53{
     54    var sidebarPanes = WebInspector.panels.scripts.sidebarPanes;
     55    // the sidebar of interest is presumed to always be last.
     56    var sidebar = sidebarPanes[Object.keys(sidebarPanes).pop()];
     57    InspectorTest.addResult("Sidebar content: " + sidebar.bodyElement.textContent);
     58}
     59
     60InspectorTest.dispatchOnMessage("dump-sidebar-content", InspectorTest.dumpSidebarContent, true);
     61
    4962}
    5063
  • trunk/LayoutTests/inspector/extensions.html

    r67084 r71107  
    2626}
    2727
     28function extension_dumpSidebarContent(nextTest)
     29{
     30    dispatchOnFrontend("dump-sidebar-content", nextTest);
     31}
     32
     33function extension_testExtensionWatchSidebarObject(nextTest)
     34{
     35    function onSidebarCreated(sidebar)
     36    {
     37        output("Watch sidebar created, callback arguments dump follows:");
     38        dumpObject(Array.prototype.slice.call(arguments));
     39        sidebar.onUpdated.addListener(bind(extension_dumpSidebarContent, this, nextTest));
     40        sidebar.setObject({
     41            f0: "object",
     42            f1: undefined,
     43            f2: null,
     44            f3: {},
     45            f4: [],
     46            f5: ["aa", "bb", "cc"],
     47            f6: { f60: 42, f61: "foo", f62: [] },
     48            f7: 42
     49        });
     50    }
     51    webInspector.panels.scripts.createWatchExpressionSidebarPane("Watch Test: Object", onSidebarCreated);
     52}
     53
     54function extension_testExtensionWatchSidebarExpression(nextTest)
     55{
     56    function onSidebarCreated(sidebar)
     57    {
     58        sidebar.onUpdated.addListener(bind(extension_dumpSidebarContent, this, nextTest));
     59        function expression()
     60        {
     61            return {
     62                f0: 'expression',
     63                f1: undefined,
     64                f2: null,
     65                f3: {},
     66                f4: [],
     67                f5: ["aa", "bb", "cc"],
     68                f6: { f60: 42, f61: "foo", f62: [] },
     69                f7: 42,
     70                f8: window.location,
     71                f9: document.body.children,
     72                f10: function() {}
     73            };
     74        }
     75        sidebar.setExpression("(" + expression.toString() + ")();", "title");
     76    }
     77    webInspector.panels.scripts.createWatchExpressionSidebarPane("Watch Test: Expression", onSidebarCreated);
     78}
     79
    2880</script>
    2981</head>
  • trunk/LayoutTests/inspector/resources/extension-main.js

    r66601 r71107  
    4141}
    4242
     43function dispatchOnFrontend(message, callback)
     44{
     45    function callbackWrapper()
     46    {
     47        channel.port1.removeEventListener("message", callbackWrapper, false);
     48        callback();
     49    }
     50    var channel = new MessageChannel();
     51    channel.port1.start();
     52    channel.port1.addEventListener("message", callbackWrapper, false);
     53    top.postMessage(message, [ channel.port2 ], "*");
     54}
     55
    4356function callbackAndNextTest(callback, nextTest)
    4457{
  • trunk/WebCore/ChangeLog

    r71105 r71107  
     12010-11-01  Andrey Kosyakov  <caseq@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: [Extensions API] expose API to create properties watch sidebar panes
     6        https://bugs.webkit.org/show_bug.cgi?id=48761
     7
     8        * inspector/front-end/ExtensionAPI.js:
     9        (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createSidebarPane):
     10        (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createWatchExpressionSidebarPane.callbackWrapper):
     11        (WebInspector.injectedExtensionAPI.PanelImpl.prototype.createWatchExpressionSidebarPane):
     12        (WebInspector.injectedExtensionAPI):
     13        (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl):
     14        (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl.prototype.setExpression):
     15        (WebInspector.injectedExtensionAPI.WatchExpressionSidebarPaneImpl.prototype.setObject):
     16        * inspector/front-end/ExtensionPanel.js: Added ExtensionWatchSidebarPane
     17        (WebInspector.ExtensionWatchSidebarPane):
     18        (WebInspector.ExtensionWatchSidebarPane.prototype.setObject):
     19        (WebInspector.ExtensionWatchSidebarPane.prototype.setExpression):
     20        (WebInspector.ExtensionWatchSidebarPane.prototype._onEvaluate):
     21        (WebInspector.ExtensionWatchSidebarPane.prototype._setObject):
     22        * inspector/front-end/ExtensionServer.js:
     23        (WebInspector.ExtensionServer):
     24        (WebInspector.ExtensionServer.prototype.notifyExtensionWatchSidebarUpdated):
     25        (WebInspector.ExtensionServer.prototype._onCreateSidebar):
     26        (WebInspector.ExtensionServer.prototype._onCreateWatchExpressionSidebarPane):
     27        (WebInspector.ExtensionServer.prototype._createSidebar):
     28        (WebInspector.ExtensionServer.prototype._onSetWatchSidebarContent):
     29        * inspector/front-end/InjectedScript.js:
     30        (injectedScriptConstructor.):
     31        * inspector/front-end/RemoteObject.js: Added a wrapper for local JSON object to simulate RemoteObject interface.
     32        (WebInspector.RemoteObject.fromLocalObject):
     33        (WebInspector.LocalJSONObject):
     34        (WebInspector.LocalJSONObject.prototype.get description):
     35        (WebInspector.LocalJSONObject.prototype.get type):
     36        (WebInspector.LocalJSONObject.prototype.get hasChildren):
     37        (WebInspector.LocalJSONObject.prototype.getOwnProperties):
     38        (WebInspector.LocalJSONObject.prototype.getProperties):
     39        (WebInspector.LocalJSONObject.prototype.isError):
     40
    1412010-11-02  Ryuan Choi  <ryuan.choi@samsung.com>
    242
  • trunk/WebCore/inspector/front-end/ExtensionAPI.js

    r69185 r71107  
    198198        }
    199199        extensionServer.sendRequest({ command: "createSidebarPane", panel: this._id, id: id, title: title, url: expandURL(url) }, callback && callbackWrapper);
     200    },
     201
     202    createWatchExpressionSidebarPane: function(title, callback)
     203    {
     204        var id = "watch-sidebar-" + extensionServer.nextObjectId();
     205        function callbackWrapper(result)
     206        {
     207            if (result.isError)
     208                callback(result);
     209            else
     210                callback(new WatchExpressionSidebarPane(id));
     211        }
     212        extensionServer.sendRequest({ command: "createWatchExpressionSidebarPane", panel: this._id, id: id, title: title }, callback && callbackWrapper);
    200213    }
    201214}
     
    205218    var impl = new PanelImpl(id);
    206219    this.createSidebarPane = bind(impl.createSidebarPane, impl);
     220    this.createWatchExpressionSidebarPane = bind(impl.createWatchExpressionSidebarPane, impl);
    207221    this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
    208222}
     
    236250}
    237251
    238 function ExtensionSidebarPane(id)
    239 {
    240     var impl = new ExtensionSidebarPaneImpl(id);
     252function ExtensionSidebarPane(id, impl)
     253{
     254    if (!impl)
     255        impl = new ExtensionSidebarPaneImpl(id);
    241256    this.setHeight = bind(impl.setHeight, impl);
    242257    this.setExpanded = bind(impl.setExpanded, impl);
     258}
     259
     260function WatchExpressionSidebarPaneImpl(id)
     261{
     262    ExtensionSidebarPaneImpl.call(this, id);
     263}
     264
     265WatchExpressionSidebarPaneImpl.prototype = {
     266    setExpression: function(expression, rootTitle)
     267    {
     268        extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true });
     269    },
     270
     271    setObject: function(jsonObject, rootTitle)
     272    {
     273        extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: jsonObject, rootTitle: rootTitle });
     274    }
     275}
     276
     277function WatchExpressionSidebarPane(id)
     278{
     279    var impl = new WatchExpressionSidebarPaneImpl(id);
     280    ExtensionSidebarPane.call(this, id, impl);
     281    this.setExpression = bind(impl.setExpression, impl);
     282    this.setObject = bind(impl.setObject, impl);
     283    this.onUpdated = new EventSink("watch-sidebar-updated-" + id);
    243284}
    244285
  • trunk/WebCore/inspector/front-end/ExtensionPanel.js

    r64458 r71107  
    8181
    8282WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype;
     83
     84WebInspector.ExtensionWatchSidebarPane = function(title, id)
     85{
     86    WebInspector.SidebarPane.call(this, title);
     87    this._id = id;
     88}
     89
     90WebInspector.ExtensionWatchSidebarPane.prototype = {
     91    setObject: function(object, title)
     92    {
     93        this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title);
     94    },
     95
     96    setExpression: function(expression, title)
     97    {
     98        InjectedScriptAccess.getDefault().evaluate(expression, this._onEvaluate.bind(this, title));
     99    },
     100
     101    _onEvaluate: function(title, result)
     102    {
     103        this._setObject(WebInspector.RemoteObject.fromPayload(result), title);
     104    },
     105
     106    _setObject: function(object, title)
     107    {
     108        this.bodyElement.removeChildren();
     109        var section = new WebInspector.ObjectPropertiesSection(object, title, null, true);
     110        if (!title)
     111            section.headerElement.addStyleClass("hidden");
     112        section.expanded = true;
     113        this.bodyElement.appendChild(section.element);
     114        WebInspector.extensionServer.notifyExtensionWatchSidebarUpdated(this._id);
     115    }
     116}
     117
     118WebInspector.ExtensionWatchSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
  • trunk/WebCore/inspector/front-end/ExtensionServer.js

    r71035 r71107  
    4343    this._registerHandler("createPanel", this._onCreatePanel.bind(this));
    4444    this._registerHandler("createSidebarPane", this._onCreateSidebar.bind(this));
     45    this._registerHandler("createWatchExpressionSidebarPane", this._onCreateWatchExpressionSidebarPane.bind(this));
    4546    this._registerHandler("log", this._onLog.bind(this));
    4647    this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this));
    4748    this._registerHandler("setSidebarHeight", this._onSetSidebarHeight.bind(this));
    4849    this._registerHandler("setSidebarExpanded", this._onSetSidebarExpansion.bind(this));
     50    this._registerHandler("setWatchSidebarContent", this._onSetWatchSidebarContent.bind(this));
    4951
    5052    this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this));
     
    8991    {
    9092        this._postNotification("reset");
     93    },
     94
     95    notifyExtensionWatchSidebarUpdated: function(id)
     96    {
     97        this._postNotification("watch-sidebar-updated-" + id);
    9198    },
    9299
     
    162169    },
    163170
    164     _onCreateSidebar: function(message, port)
     171    _onCreateSidebar: function(message)
     172    {
     173        var sidebar = this._createSidebar(message, WebInspector.SidebarPane);
     174        if (sidebar.isError)
     175            return sidebar;
     176        this._createClientIframe(sidebar.bodyElement, message.url);
     177        return this._status.OK();
     178    },
     179
     180    _onCreateWatchExpressionSidebarPane: function(message)
     181    {
     182        var sidebar = this._createSidebar(message, WebInspector.ExtensionWatchSidebarPane);
     183        return sidebar.isError ? sidebar : this._status.OK();
     184    },
     185
     186    _createSidebar: function(message, constructor)
    165187    {
    166188        var panel = WebInspector.panels[message.panel];
     
    170192            return this._status.E_NOTSUPPORTED();
    171193        var id = message.id;
    172         var sidebar = new WebInspector.SidebarPane(message.title);
     194        var sidebar = new constructor(message.title, message.id);
    173195        this._clientObjects[id] = sidebar;
    174196        panel.sidebarPanes[id] = sidebar;
    175197        panel.sidebarElement.appendChild(sidebar.element);
    176         this._createClientIframe(sidebar.bodyElement, message.url);
    177         return this._status.OK();
     198
     199        return sidebar;
    178200    },
    179201
     
    204226        else
    205227            sidebar.collapse();
     228    },
     229
     230    _onSetWatchSidebarContent: function(message)
     231    {
     232        var sidebar = this._clientObjects[message.id];
     233        if (!sidebar)
     234            return this._status.E_NOTFOUND(message.id);
     235        if (message.evaluateOnPage)
     236            sidebar.setExpression(message.expression, message.rootTitle);
     237        else
     238            sidebar.setObject(message.expression, message.rootTitle);
    206239    },
    207240
  • trunk/WebCore/inspector/front-end/InjectedScript.js

    r70565 r71107  
    5353            if (typeof object === "object" || typeof object === "function" || this._isHTMLAllCollection(object)) {
    5454                var id = this._lastBoundObjectId++;
    55                 objectId = id;
    5655                this._idToWrappedObject[id] = object;
    5756   
  • trunk/WebCore/inspector/front-end/RemoteObject.js

    r65597 r71107  
    4242}
    4343
     44WebInspector.RemoteObject.fromLocalObject = function(value)
     45{
     46    return new WebInspector.LocalJSONObject(value);
     47}
     48
    4449WebInspector.RemoteObject.resolveNode = function(node, callback)
    4550{
     
    137142    this.value = value;
    138143}
     144
     145// The below is a wrapper around a local object that provides an interface comaptible
     146// with RemoteObject, to be used by the UI code (primarily ObjectPropertiesSection).
     147// Note that only JSON-compliant objects are currently supported, as there's no provision
     148// for traversing prototypes, extracting class names via constuctor, handling properties
     149// or functions.
     150
     151WebInspector.LocalJSONObject = function(value)
     152{
     153    this._value = value;
     154}
     155
     156WebInspector.LocalJSONObject.prototype = {
     157    get description()
     158    {
     159        var type = this.type;
     160        switch (type) {
     161            case "array":
     162                return "[" + this._value.length + "]";
     163            case "object":
     164                return this.hasChildren ? "{...}" : "{ }";
     165            default:
     166                return JSON.stringify(this._value);
     167        }
     168    },
     169
     170    get type()
     171    {
     172        if (this._value === null)
     173            return "null";
     174        if (this._value instanceof Array)
     175            return "array";
     176        return typeof this._value;
     177    },
     178
     179    get hasChildren()
     180    {
     181        return typeof this._value === "object" && this._value !== null && Object.keys(this._value).length;
     182    },
     183
     184    getOwnProperties: function(abbreviate, callback)
     185    {
     186        return this.getProperties(false, abbreviate, callback);
     187    },
     188
     189    getProperties: function(ignoreHasOwnProperty, abbreviate, callback)
     190    {
     191        function buildProperty(propName)
     192        {
     193            return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
     194        }
     195        callback(Object.keys(this._value).map(buildProperty.bind(this)));
     196    },
     197
     198    isError: function()
     199    {
     200        return false;
     201    }
     202}
Note: See TracChangeset for help on using the changeset viewer.