2011-05-26 Michael Schneider <michschn@google.com>
authorcaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 May 2011 17:16:28 +0000 (17:16 +0000)
committercaseq@chromium.org <caseq@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 May 2011 17:16:28 +0000 (17:16 +0000)
        Reviewed by Pavel Feldman.

        WebInspector: Added API to access the timeline data in a inspector extension.
        https://bugs.webkit.org/show_bug.cgi?id=61098

        * WebCore.gypi:
        * WebCore.vcproj/WebCore.vcproj:
        * inspector/front-end/ExtensionAPI.js:
        (WebInspector.injectedExtensionAPI.InspectorExtensionAPI):
        (WebInspector.injectedExtensionAPI):
        * inspector/front-end/ExtensionServer.js:
        (WebInspector.ExtensionServer):
        (WebInspector.ExtensionServer.prototype._addRecordToTimeline):
        (WebInspector.ExtensionServer.prototype._onSubscribe):
        (WebInspector.ExtensionServer.prototype._onUnsubscribe):
        (WebInspector.ExtensionServer.prototype._registerHandler):
        (WebInspector.ExtensionServer.prototype._registerSubscriptionHandler):
        * inspector/front-end/TimelineManager.js: Added.
        (WebInspector.TimelineManager):
        (WebInspector.TimelineManager.prototype.start):
        (WebInspector.TimelineManager.prototype.stop):
        (WebInspector.TimelineDispatcher):
        (WebInspector.TimelineDispatcher.prototype.started):
        (WebInspector.TimelineDispatcher.prototype.stopped):
        (WebInspector.TimelineDispatcher.prototype.eventRecorded):
        * inspector/front-end/TimelinePanel.js:
        (WebInspector.TimelinePanel):
        (WebInspector.TimelinePanel.prototype._toggleTimelineButtonClicked):
        (WebInspector.TimelinePanel.prototype._onTimelineEventRecorded):
        * inspector/front-end/WebKit.qrc:
        * inspector/front-end/inspector.html:

2011-05-26  Michael Schneider  <michschn@google.com>

        Reviewed by Pavel Feldman.

        WebInspector: Added tests for timeline data API in a inspector extension.
        https://bugs.webkit.org/show_bug.cgi?id=61098

        * inspector/extensions/extensions-api-expected.txt:
        * inspector/extensions/extensions-events-expected.txt:
        * inspector/extensions/extensions-events.html:
        * inspector/timeline/timeline-test.js:
        (initialize_Timeline.InspectorTest.startTimeline):
        (initialize_Timeline.InspectorTest.stopTimeline):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87399 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/extensions/extensions-api-expected.txt
LayoutTests/inspector/extensions/extensions-events-expected.txt
LayoutTests/inspector/extensions/extensions-events.html
LayoutTests/inspector/timeline/timeline-test.js
Source/WebCore/ChangeLog
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/inspector/front-end/ExtensionAPI.js
Source/WebCore/inspector/front-end/ExtensionServer.js
Source/WebCore/inspector/front-end/TimelineManager.js [new file with mode: 0644]
Source/WebCore/inspector/front-end/TimelinePanel.js
Source/WebCore/inspector/front-end/WebKit.qrc
Source/WebCore/inspector/front-end/inspector.html

index 5848c33..08b8f70 100644 (file)
@@ -1,3 +1,17 @@
+2011-05-26  Michael Schneider  <michschn@google.com>
+
+        Reviewed by Pavel Feldman.
+
+        WebInspector: Added tests for timeline data API in a inspector extension.
+        https://bugs.webkit.org/show_bug.cgi?id=61098
+
+        * inspector/extensions/extensions-api-expected.txt:
+        * inspector/extensions/extensions-events-expected.txt:
+        * inspector/extensions/extensions-events.html:
+        * inspector/timeline/timeline-test.js:
+        (initialize_Timeline.InspectorTest.startTimeline):
+        (initialize_Timeline.InspectorTest.stopTimeline):
+
 2011-05-26  Adam Klein  <adamk@chromium.org>
 
         Unreviewed. Added baselines after r87387.
index 5f295f7..e54cae4 100644 (file)
@@ -41,6 +41,12 @@ RUNNING TEST: extension_testAPI
         getHAR : <function>
         addRequestHeaders : <function>
     }
+    timeline : {
+        onEventRecorded : {
+            addListener : <function>
+            removeListener : <function>
+        }
+    }
     onReset : {
         addListener : <function>
         removeListener : <function>
index 6b7d22c..c02084d 100644 (file)
@@ -16,5 +16,7 @@ Got onHidden event for panel elements
 Got onShown event for panel extension
 Got onHidden event for panel extension
 Got onShown event for panel elements
+RUNNING TEST: extension_testTimelineEvents
+Got Layout event from timeline
 All tests done.
 
index 404c0b8..bfed381 100644 (file)
@@ -102,6 +102,23 @@ function extension_testPanelShowHide(nextTest)
     webInspector.panels.create("Test Panel", "extension-panel.png", "extension-panel.html", onPanelCreated);
 }
 
+function extension_testTimelineEvents(nextTest)
+{
+    function onTimelineEvent(record)
+    {
+        if (record.type === "Layout") {
+            output("Got Layout event from timeline");
+            webInspector.timeline.onEventRecorded.removeListener(onTimelineEvent);
+            nextTest();
+        }
+    }
+
+    webInspector.timeline.onEventRecorded.addListener(onTimelineEvent);
+
+    // Trigger a relayout.
+    webInspector.inspectedWindow.eval("document.body.style.float = 'left';");
+}
+
 </script>
 </head>
 <body onload="runTest()">
index db5f3a5..ca1b0cc 100644 (file)
@@ -18,6 +18,7 @@ InspectorTest.timelineNonDeterministicProps = {
 InspectorTest.startTimeline = function(callback)
 {
     InspectorTest._timelineRecords = [];
+    WebInspector.panels.timeline.toggleTimelineButton.toggled = true;
     TimelineAgent.start(callback);
     function addRecord(record)
     {
@@ -25,13 +26,16 @@ InspectorTest.startTimeline = function(callback)
         for (var i = 0; record.children && i < record.children.length; ++i)
             addRecord(record.children[i]);
     }
-    InspectorTest.addSniffer(WebInspector.TimelineDispatcher.prototype, "eventRecorded", addRecord, true);
+    WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, function(event) {
+        addRecord(event.data);
+    });
 };
 
 InspectorTest.stopTimeline = function(callback)
 {
     function didStop()
     {
+        WebInspector.panels.timeline.toggleTimelineButton.toggled = false;
         callback(InspectorTest._timelineRecords);
     }
     TimelineAgent.stop(didStop);
index 72a1092..b7096db 100644 (file)
@@ -1,3 +1,37 @@
+2011-05-26  Michael Schneider  <michschn@google.com>
+
+        Reviewed by Pavel Feldman.
+
+        WebInspector: Added API to access the timeline data in a inspector extension.
+        https://bugs.webkit.org/show_bug.cgi?id=61098
+
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * inspector/front-end/ExtensionAPI.js:
+        (WebInspector.injectedExtensionAPI.InspectorExtensionAPI):
+        (WebInspector.injectedExtensionAPI):
+        * inspector/front-end/ExtensionServer.js:
+        (WebInspector.ExtensionServer):
+        (WebInspector.ExtensionServer.prototype._addRecordToTimeline):
+        (WebInspector.ExtensionServer.prototype._onSubscribe):
+        (WebInspector.ExtensionServer.prototype._onUnsubscribe):
+        (WebInspector.ExtensionServer.prototype._registerHandler):
+        (WebInspector.ExtensionServer.prototype._registerSubscriptionHandler):
+        * inspector/front-end/TimelineManager.js: Added.
+        (WebInspector.TimelineManager):
+        (WebInspector.TimelineManager.prototype.start):
+        (WebInspector.TimelineManager.prototype.stop):
+        (WebInspector.TimelineDispatcher):
+        (WebInspector.TimelineDispatcher.prototype.started):
+        (WebInspector.TimelineDispatcher.prototype.stopped):
+        (WebInspector.TimelineDispatcher.prototype.eventRecorded):
+        * inspector/front-end/TimelinePanel.js:
+        (WebInspector.TimelinePanel):
+        (WebInspector.TimelinePanel.prototype._toggleTimelineButtonClicked):
+        (WebInspector.TimelinePanel.prototype._onTimelineEventRecorded):
+        * inspector/front-end/WebKit.qrc:
+        * inspector/front-end/inspector.html:
+
 2011-05-26  Andrey Kosyakov  <caseq@chromium.org>
 
         Reviewed by Yury Semikhatsky.
index 56e32bb..126ed14 100644 (file)
             'inspector/front-end/TextPrompt.js',
             'inspector/front-end/TextViewer.js',
             'inspector/front-end/TimelineAgent.js',
+            'inspector/front-end/TimelineManager.js',
             'inspector/front-end/TimelineOverviewPane.js',
             'inspector/front-end/TimelineGrid.js',
             'inspector/front-end/TimelinePanel.js',
index 7db1c58..f18573b 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\inspector\front-end\TimelineManager.js"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\inspector\front-end\TimelineOverviewPane.js"
                                        >
                                </File>
index 940e340..38b7f0c 100644 (file)
@@ -91,6 +91,7 @@ function InspectorExtensionAPI()
     this.inspectedWindow = new InspectedWindow();
     this.panels = new Panels();
     this.resources = new Resources();
+    this.timeline = new Timeline();
 
     this.onReset = new EventSink("reset");
 }
@@ -378,6 +379,11 @@ InspectedWindow.prototype = {
     }
 }
 
+function TimelineImpl()
+{
+    this.onEventRecorded = new EventSink("timeline-event-recorded");
+}
+
 function ExtensionServerClient()
 {
     this._callbacks = {};
@@ -484,6 +490,7 @@ var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
 var Panel = declareInterfaceClass(PanelImpl);
 var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
 var Resource = declareInterfaceClass(ResourceImpl);
+var Timeline = declareInterfaceClass(TimelineImpl);
 
 var extensionServer = new ExtensionServerClient();
 
index 1c811ec..d27b4db 100644 (file)
@@ -33,6 +33,8 @@ WebInspector.ExtensionServer = function()
     this._clientObjects = {};
     this._handlers = {};
     this._subscribers = {};
+    this._subscriptionStartHandlers = {};
+    this._subscriptionStopHandlers = {};
     this._extraHeaders = {};
     this._resources = {};
     this._lastResourceId = 0;
@@ -55,10 +57,19 @@ WebInspector.ExtensionServer = function()
     this._registerHandler("subscribe", this._onSubscribe.bind(this));
     this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
 
+    this._registerSubscriptionHandler("timeline-event-recorded", WebInspector.timelineManager.start.bind(WebInspector.timelineManager), WebInspector.timelineManager.stop.bind(WebInspector.timelineManager));
+
     window.addEventListener("message", this._onWindowMessage.bind(this), false);
+
+    WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._addRecordToTimeline, this);
 }
 
 WebInspector.ExtensionServer.prototype = {
+    _addRecordToTimeline: function(event)
+    {
+        this._postNotification("timeline-event-recorded", event.data);
+    },
+
     notifyObjectSelected: function(panelId, objectId)
     {
         this._postNotification("panel-objectSelected-" + panelId, objectId);
@@ -141,8 +152,11 @@ WebInspector.ExtensionServer.prototype = {
         var subscribers = this._subscribers[message.type];
         if (subscribers)
             subscribers.push(port);
-        else
+        else {
             this._subscribers[message.type] = [ port ];
+            if (this._subscriptionStartHandlers[message.type])
+                this._subscriptionStartHandlers[message.type]()
+        }
     },
 
     _onUnsubscribe: function(message, port)
@@ -151,8 +165,11 @@ WebInspector.ExtensionServer.prototype = {
         if (!subscribers)
             return;
         subscribers.remove(port);
-        if (!subscribers.length)
+        if (!subscribers.length) {
             delete this._subscribers[message.type];
+            if (this._subscriptionStopHandlers[message.type])
+                this._subscriptionStopHandlers[message.type]()
+        }
     },
 
     _onAddRequestHeaders: function(message)
@@ -446,6 +463,12 @@ WebInspector.ExtensionServer.prototype = {
     _registerHandler: function(command, callback)
     {
         this._handlers[command] = callback;
+    },
+
+    _registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
+    {
+        this._subscriptionStartHandlers[eventTopic] =  onSubscribeFirst;
+        this._subscriptionStopHandlers[eventTopic] =  onUnsubscribeLast;
     }
 }
 
diff --git a/Source/WebCore/inspector/front-end/TimelineManager.js b/Source/WebCore/inspector/front-end/TimelineManager.js
new file mode 100644 (file)
index 0000000..a629ad6
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.TimelineManager = function()
+{
+    WebInspector.Object.call(this);
+    this._dispatcher = new WebInspector.TimelineDispatcher(this);
+    this._enablementCount = 0;
+}
+
+WebInspector.TimelineManager.EventTypes = {
+    TimelineStarted: "TimelineStarted",
+    TimelineStopped: "TimelineStopped",
+    TimelineEventRecorded: "TimelineEventRecorded"
+}
+
+WebInspector.TimelineManager.prototype = {
+    start: function()
+    {
+        this._enablementCount++;
+        if (this._enablementCount === 1)
+            TimelineAgent.start();
+    },
+
+    stop: function()
+    {
+        if (!this._enablementCount) {
+            console.error("WebInspector.TimelineManager start/stop calls are unbalanced");
+            return;
+        }
+        this._enablementCount--;
+        if (!this._enablementCount)
+            TimelineAgent.stop();
+    }
+}
+
+WebInspector.TimelineManager.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.TimelineDispatcher = function(manager)
+{
+    this._manager = manager;
+    InspectorBackend.registerDomainDispatcher("Timeline", this);
+}
+
+WebInspector.TimelineDispatcher.prototype = {
+    started: function()
+    {
+        this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted);
+    },
+
+    stopped: function()
+    {
+        this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped);
+    },
+
+    eventRecorded: function(record)
+    {
+        this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, record);
+    }
+}
+
+WebInspector.timelineManager = new WebInspector.TimelineManager();
index 900ba65..a09dcb3 100644 (file)
@@ -99,7 +99,7 @@ WebInspector.TimelinePanel = function()
     this._markTimelineRecords = [];
     this._expandOffset = 15;
 
-    InspectorBackend.registerDomainDispatcher("Timeline", new WebInspector.TimelineDispatcher(this));
+    WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._onTimelineEventRecorded, this);
 }
 
 // Define row height, should be in sync with styles for timeline graphs.
@@ -273,11 +273,12 @@ WebInspector.TimelinePanel.prototype = {
     _toggleTimelineButtonClicked: function()
     {
         if (this.toggleTimelineButton.toggled)
-            TimelineAgent.stop();
+            WebInspector.timelineManager.stop();
         else {
             this._clearPanel();
-            TimelineAgent.start();
+            WebInspector.timelineManager.start();
         }
+        this.toggleTimelineButton.toggled = !this.toggleTimelineButton.toggled;
     },
 
     _toggleFilterButtonClicked: function()
@@ -293,14 +294,10 @@ WebInspector.TimelinePanel.prototype = {
         ProfilerAgent.collectGarbage();
     },
 
-    _timelineProfilerWasStarted: function()
+    _onTimelineEventRecorded: function(event)
     {
-        this.toggleTimelineButton.toggled = true;
-    },
-
-    _timelineProfilerWasStopped: function()
-    {
-        this.toggleTimelineButton.toggled = false;
+        if (this.toggleTimelineButton.toggled)
+            this._addRecordToTimeline(event.data);
     },
 
     _addRecordToTimeline: function(record)
@@ -660,28 +657,6 @@ WebInspector.TimelinePanel.prototype = {
 
 WebInspector.TimelinePanel.prototype.__proto__ = WebInspector.Panel.prototype;
 
-WebInspector.TimelineDispatcher = function(timelinePanel)
-{
-    this._timelinePanel = timelinePanel;
-}
-
-WebInspector.TimelineDispatcher.prototype = {
-    started: function()
-    {
-        this._timelinePanel._timelineProfilerWasStarted();
-    },
-
-    stopped: function()
-    {
-        this._timelinePanel._timelineProfilerWasStopped();
-    },
-
-    eventRecorded: function(record)
-    {
-        this._timelinePanel._addRecordToTimeline(record);
-    }
-}
-
 WebInspector.TimelineCategory = function(name, title, color)
 {
     this.name = name;
index 31a671e..10dbe06 100644 (file)
     <file>TextPrompt.js</file>
     <file>TextViewer.js</file>
     <file>TimelineAgent.js</file>
+    <file>TimelineManager.js</file>
     <file>TimelineGrid.js</file>
     <file>TimelineOverviewPane.js</file>
     <file>TimelinePanel.js</file>
index 263bc20..b122c8b 100644 (file)
@@ -65,6 +65,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     <script type="text/javascript" src="NetworkManager.js"></script>
     <script type="text/javascript" src="ResourceTreeModel.js"></script>
     <script type="text/javascript" src="ResourceCategory.js"></script>
+    <script type="text/javascript" src="TimelineManager.js"></script>
     <script type="text/javascript" src="Database.js"></script>
     <script type="text/javascript" src="DOMStorage.js"></script>
     <script type="text/javascript" src="DOMStorageItemsView.js"></script>