[Inspector] Add events for tracking page loads and scheduled navigations.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Jan 2013 09:50:19 +0000 (09:50 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Jan 2013 09:50:19 +0000 (09:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=104168

Patch by Ken Kania <kkania@chromium.org> on 2013-01-16
Reviewed by Pavel Feldman.

These events are needed for clients who need to be aware of when a page is
navigating or about to navigate. Some clients may wish to prevent interaction
with the page during this time. Two of the new events track loading start and
stop, as measured by the ProgressTracker. The other two events track when a
page has a new scheduled navigation and when it no longer has a scheduled
navigation. These latter two events won't allow the client to determine if
a load is going to happen in all circumstances, but is sufficient for many cases.

Source/WebCore:

Tests: inspector-protocol/page/frameScheduledNavigation.html
       inspector-protocol/page/frameStartedLoading.html

* inspector/Inspector.json:
* inspector/InspectorInstrumentation.cpp:
(WebCore):
(WebCore::InspectorInstrumentation::frameStartedLoadingImpl):
(WebCore::InspectorInstrumentation::frameStoppedLoadingImpl):
(WebCore::InspectorInstrumentation::frameScheduledNavigationImpl):
(WebCore::InspectorInstrumentation::frameClearedScheduledNavigationImpl):
* inspector/InspectorInstrumentation.h:
(InspectorInstrumentation):
(WebCore::InspectorInstrumentation::frameStartedLoading):
(WebCore):
(WebCore::InspectorInstrumentation::frameStoppedLoading):
(WebCore::InspectorInstrumentation::frameScheduledNavigation):
(WebCore::InspectorInstrumentation::frameClearedScheduledNavigation):
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::frameStartedLoading):
(WebCore):
(WebCore::InspectorPageAgent::frameStoppedLoading):
(WebCore::InspectorPageAgent::frameScheduledNavigation):
(WebCore::InspectorPageAgent::frameClearedScheduledNavigation):
* inspector/InspectorPageAgent.h:
* inspector/front-end/ResourceTreeModel.js:
(WebInspector.PageDispatcher.prototype.frameDetached):
(WebInspector.PageDispatcher.prototype.frameStartedLoading):
(WebInspector.PageDispatcher.prototype.frameStoppedLoading):
(WebInspector.PageDispatcher.prototype.frameScheduledNavigation):
(WebInspector.PageDispatcher.prototype.frameClearedScheduledNavigation):
* loader/NavigationScheduler.cpp:
(WebCore::NavigationScheduler::clear):
(WebCore::NavigationScheduler::timerFired):
(WebCore::NavigationScheduler::startTimer):
(WebCore::NavigationScheduler::cancel):
* loader/ProgressTracker.cpp:
(WebCore::ProgressTracker::progressStarted):
(WebCore::ProgressTracker::finalProgressComplete):

LayoutTests:

* inspector-protocol/page/frameScheduledNavigation-expected.txt: Added.
* inspector-protocol/page/frameScheduledNavigation.html: Added.
* inspector-protocol/page/frameStartedLoading-expected.txt: Added.
* inspector-protocol/page/frameStartedLoading.html: Added.

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector-protocol/page/frameScheduledNavigation-expected.txt [new file with mode: 0644]
LayoutTests/inspector-protocol/page/frameScheduledNavigation.html [new file with mode: 0644]
LayoutTests/inspector-protocol/page/frameStartedLoading-expected.txt [new file with mode: 0644]
LayoutTests/inspector-protocol/page/frameStartedLoading.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.h
Source/WebCore/inspector/front-end/ResourceTreeModel.js
Source/WebCore/loader/NavigationScheduler.cpp
Source/WebCore/loader/ProgressTracker.cpp

index 12f82db..e7e6ebb 100644 (file)
@@ -1,3 +1,23 @@
+2013-01-16  Ken Kania  <kkania@chromium.org>
+
+        [Inspector] Add events for tracking page loads and scheduled navigations.
+        https://bugs.webkit.org/show_bug.cgi?id=104168
+
+        Reviewed by Pavel Feldman.
+
+        These events are needed for clients who need to be aware of when a page is
+        navigating or about to navigate. Some clients may wish to prevent interaction
+        with the page during this time. Two of the new events track loading start and
+        stop, as measured by the ProgressTracker. The other two events track when a
+        page has a new scheduled navigation and when it no longer has a scheduled
+        navigation. These latter two events won't allow the client to determine if
+        a load is going to happen in all circumstances, but is sufficient for many cases.
+
+        * inspector-protocol/page/frameScheduledNavigation-expected.txt: Added.
+        * inspector-protocol/page/frameScheduledNavigation.html: Added.
+        * inspector-protocol/page/frameStartedLoading-expected.txt: Added.
+        * inspector-protocol/page/frameStartedLoading.html: Added.
+
 2013-01-16  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed GTK gardening.
diff --git a/LayoutTests/inspector-protocol/page/frameScheduledNavigation-expected.txt b/LayoutTests/inspector-protocol/page/frameScheduledNavigation-expected.txt
new file mode 100644 (file)
index 0000000..4ff01d8
--- /dev/null
@@ -0,0 +1,5 @@
+
+Scheduled navigation with delay 0
+Started loading
+Cleared scheduled navigation
+
diff --git a/LayoutTests/inspector-protocol/page/frameScheduledNavigation.html b/LayoutTests/inspector-protocol/page/frameScheduledNavigation.html
new file mode 100644 (file)
index 0000000..f427cbe
--- /dev/null
@@ -0,0 +1,43 @@
+<html>
+<head>
+<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/protocol-test.js"></script>
+<script>
+
+function load()
+{
+    document.querySelector("iframe").src = "../resources/blank.html";
+}
+
+function test()
+{
+    InspectorTest.eventHandler["Page.frameScheduledNavigation"] = onScheduled;
+    InspectorTest.eventHandler["Page.frameStartedLoading"] = onStarted;
+    InspectorTest.eventHandler["Page.frameClearedScheduledNavigation"] = onCleared;
+    InspectorTest.sendCommand("Page.enable", {});
+
+    function onScheduled(msg)
+    {
+        InspectorTest.log("Scheduled navigation with delay " + msg.params.delay);
+    }
+
+    function onStarted(msg)
+    {
+        // This event should be received before the scheduled navigation is cleared.
+        InspectorTest.log("Started loading");
+    }
+
+    function onCleared(msg)
+    {
+        InspectorTest.log("Cleared scheduled navigation");
+        InspectorTest.completeTest();
+    }
+
+    InspectorTest.sendCommand("Runtime.evaluate", { "expression": "load()" });
+}
+
+</script>
+</head>
+<body onload="runTest()">
+<iframe>
+</body>
+</html>
diff --git a/LayoutTests/inspector-protocol/page/frameStartedLoading-expected.txt b/LayoutTests/inspector-protocol/page/frameStartedLoading-expected.txt
new file mode 100644 (file)
index 0000000..560ef57
--- /dev/null
@@ -0,0 +1,4 @@
+
+Started loading
+Stopped loading
+
diff --git a/LayoutTests/inspector-protocol/page/frameStartedLoading.html b/LayoutTests/inspector-protocol/page/frameStartedLoading.html
new file mode 100644 (file)
index 0000000..7571bc6
--- /dev/null
@@ -0,0 +1,36 @@
+<html>
+<head>
+<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/protocol-test.js"></script>
+<script>
+
+function load()
+{
+    var frame = document.createElement("iframe");
+    frame.src = "../resources/blank.html";
+    document.body.appendChild(frame);
+}
+
+function test()
+{
+    InspectorTest.eventHandler["Page.frameStartedLoading"] = onStart;
+    InspectorTest.eventHandler["Page.frameStoppedLoading"] = onStop;
+    InspectorTest.sendCommand("Page.enable", {});
+
+    function onStart()
+    {
+        InspectorTest.log("Started loading");
+    }
+    function onStop()
+    {
+        InspectorTest.log("Stopped loading");
+        InspectorTest.completeTest();
+    }
+
+    InspectorTest.sendCommand("Runtime.evaluate", { "expression": "load()" });
+}
+
+</script>
+</head>
+<body onload="runTest()">
+</body>
+</html>
index 1e8c581..7f47c13 100644 (file)
@@ -1,3 +1,57 @@
+2013-01-16  Ken Kania  <kkania@chromium.org>
+
+        [Inspector] Add events for tracking page loads and scheduled navigations.
+        https://bugs.webkit.org/show_bug.cgi?id=104168
+
+        Reviewed by Pavel Feldman.
+
+        These events are needed for clients who need to be aware of when a page is
+        navigating or about to navigate. Some clients may wish to prevent interaction
+        with the page during this time. Two of the new events track loading start and
+        stop, as measured by the ProgressTracker. The other two events track when a
+        page has a new scheduled navigation and when it no longer has a scheduled
+        navigation. These latter two events won't allow the client to determine if
+        a load is going to happen in all circumstances, but is sufficient for many cases.
+
+        Tests: inspector-protocol/page/frameScheduledNavigation.html
+               inspector-protocol/page/frameStartedLoading.html
+
+        * inspector/Inspector.json:
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore):
+        (WebCore::InspectorInstrumentation::frameStartedLoadingImpl):
+        (WebCore::InspectorInstrumentation::frameStoppedLoadingImpl):
+        (WebCore::InspectorInstrumentation::frameScheduledNavigationImpl):
+        (WebCore::InspectorInstrumentation::frameClearedScheduledNavigationImpl):
+        * inspector/InspectorInstrumentation.h:
+        (InspectorInstrumentation):
+        (WebCore::InspectorInstrumentation::frameStartedLoading):
+        (WebCore):
+        (WebCore::InspectorInstrumentation::frameStoppedLoading):
+        (WebCore::InspectorInstrumentation::frameScheduledNavigation):
+        (WebCore::InspectorInstrumentation::frameClearedScheduledNavigation):
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::frameStartedLoading):
+        (WebCore):
+        (WebCore::InspectorPageAgent::frameStoppedLoading):
+        (WebCore::InspectorPageAgent::frameScheduledNavigation):
+        (WebCore::InspectorPageAgent::frameClearedScheduledNavigation):
+        * inspector/InspectorPageAgent.h:
+        * inspector/front-end/ResourceTreeModel.js:
+        (WebInspector.PageDispatcher.prototype.frameDetached):
+        (WebInspector.PageDispatcher.prototype.frameStartedLoading):
+        (WebInspector.PageDispatcher.prototype.frameStoppedLoading):
+        (WebInspector.PageDispatcher.prototype.frameScheduledNavigation):
+        (WebInspector.PageDispatcher.prototype.frameClearedScheduledNavigation):
+        * loader/NavigationScheduler.cpp:
+        (WebCore::NavigationScheduler::clear):
+        (WebCore::NavigationScheduler::timerFired):
+        (WebCore::NavigationScheduler::startTimer):
+        (WebCore::NavigationScheduler::cancel):
+        * loader/ProgressTracker.cpp:
+        (WebCore::ProgressTracker::progressStarted):
+        (WebCore::ProgressTracker::finalProgressComplete):
+
 2013-01-16  Tommy Widenflycht  <tommyw@google.com>
 
         MediaStream API: Update MediaStreamTrack::readyState to match specification
index c182cd1..4790b19 100644 (file)
                     { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has been detached." }
                 ],
                 "hidden": true
+            },
+            {
+                "name": "frameStartedLoading",
+                "description": "Fired when frame has started loading.",
+                "parameters": [
+                    { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has started loading." }
+                ],
+                "hidden": true
+            },
+            {
+                "name": "frameStoppedLoading",
+                "description": "Fired when frame has stopped loading.",
+                "parameters": [
+                    { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has stopped loading." }
+                ],
+                "hidden": true
+            },
+            {
+                "name": "frameScheduledNavigation",
+                "description": "Fired when frame schedules a potential navigation.",
+                "parameters": [
+                    { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has scheduled a navigation." },
+                    { "name": "delay", "type": "number", "description": "Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start." }
+                ],
+                "hidden": true
+            },
+            {
+                "name": "frameClearedScheduledNavigation",
+                "description": "Fired when frame no longer has a scheduled navigation.",
+                "parameters": [
+                    { "name": "frameId", "$ref": "Network.FrameId", "description": "Id of the frame that has cleared its scheduled navigation." }
+                ],
+                "hidden": true
             }
         ]
     },
index 88db54c..93aa913 100644 (file)
@@ -927,6 +927,30 @@ void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents*
         inspectorPageAgent->loaderDetachedFromFrame(loader);
 }
 
+void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents* instrumentingAgents, Frame* frame)
+{
+    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents->inspectorPageAgent())
+        inspectorPageAgent->frameStartedLoading(frame);
+}
+
+void InspectorInstrumentation::frameStoppedLoadingImpl(InstrumentingAgents* instrumentingAgents, Frame* frame)
+{
+    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents->inspectorPageAgent())
+        inspectorPageAgent->frameStoppedLoading(frame);
+}
+
+void InspectorInstrumentation::frameScheduledNavigationImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, double delay)
+{
+    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents->inspectorPageAgent())
+        inspectorPageAgent->frameScheduledNavigation(frame, delay);
+}
+
+void InspectorInstrumentation::frameClearedScheduledNavigationImpl(InstrumentingAgents* instrumentingAgents, Frame* frame)
+{
+    if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents->inspectorPageAgent())
+        inspectorPageAgent->frameClearedScheduledNavigation(frame);
+}
+
 void InspectorInstrumentation::willDestroyCachedResourceImpl(CachedResource* cachedResource)
 {
     if (!instrumentingAgentsSet)
index 2ee690e..fc93804 100644 (file)
@@ -191,6 +191,10 @@ public:
     static void frameDetachedFromParent(Frame*);
     static void didCommitLoad(Frame*, DocumentLoader*);
     static void loaderDetachedFromFrame(Frame*, DocumentLoader*);
+    static void frameStartedLoading(Frame*);
+    static void frameStoppedLoading(Frame*);
+    static void frameScheduledNavigation(Frame*, double delay);
+    static void frameClearedScheduledNavigation(Frame*);
     static void willDestroyCachedResource(CachedResource*);
 
     static InspectorInstrumentationCookie willWriteHTML(Document*, unsigned int length, unsigned int startLine);
@@ -390,6 +394,10 @@ private:
     static void frameDetachedFromParentImpl(InstrumentingAgents*, Frame*);
     static void didCommitLoadImpl(InstrumentingAgents*, Page*, DocumentLoader*);
     static void loaderDetachedFromFrameImpl(InstrumentingAgents*, DocumentLoader*);
+    static void frameStartedLoadingImpl(InstrumentingAgents*, Frame*);
+    static void frameStoppedLoadingImpl(InstrumentingAgents*, Frame*);
+    static void frameScheduledNavigationImpl(InstrumentingAgents*, Frame*, double delay);
+    static void frameClearedScheduledNavigationImpl(InstrumentingAgents*, Frame*);
     static void willDestroyCachedResourceImpl(CachedResource*);
 
     static InspectorInstrumentationCookie willWriteHTMLImpl(InstrumentingAgents*, unsigned int length, unsigned int startLine, Frame*);
@@ -1651,6 +1659,38 @@ inline void InspectorInstrumentation::loaderDetachedFromFrame(Frame* frame, Docu
 #endif
 }
 
+inline void InspectorInstrumentation::frameStartedLoading(Frame* frame)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+        frameStartedLoadingImpl(instrumentingAgents, frame);
+#endif
+}
+
+inline void InspectorInstrumentation::frameStoppedLoading(Frame* frame)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+        frameStoppedLoadingImpl(instrumentingAgents, frame);
+#endif
+}
+
+inline void InspectorInstrumentation::frameScheduledNavigation(Frame* frame, double delay)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+        frameScheduledNavigationImpl(instrumentingAgents, frame, delay);
+#endif
+}
+
+inline void InspectorInstrumentation::frameClearedScheduledNavigation(Frame* frame)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+        frameClearedScheduledNavigationImpl(instrumentingAgents, frame);
+#endif
+}
+
 inline void InspectorInstrumentation::willDestroyCachedResource(CachedResource* cachedResource)
 {
 #if ENABLE(INSPECTOR)
index 104222d..c47b5e2 100644 (file)
@@ -900,6 +900,26 @@ void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
         m_loaderToIdentifier.remove(iterator);
 }
 
+void InspectorPageAgent::frameStartedLoading(Frame* frame)
+{
+    m_frontend->frameStartedLoading(frameId(frame));
+}
+
+void InspectorPageAgent::frameStoppedLoading(Frame* frame)
+{
+    m_frontend->frameStoppedLoading(frameId(frame));
+}
+
+void InspectorPageAgent::frameScheduledNavigation(Frame* frame, double delay)
+{
+    m_frontend->frameScheduledNavigation(frameId(frame), delay);
+}
+
+void InspectorPageAgent::frameClearedScheduledNavigation(Frame* frame)
+{
+    m_frontend->frameClearedScheduledNavigation(frameId(frame));
+}
+
 void InspectorPageAgent::applyScreenWidthOverride(long* width)
 {
     long widthOverride = m_state->getLong(PageAgentState::pageAgentScreenWidthOverride);
index 27f1e0a..973e15c 100644 (file)
@@ -138,6 +138,10 @@ public:
     void frameNavigated(DocumentLoader*);
     void frameDetached(Frame*);
     void loaderDetachedFromFrame(DocumentLoader*);
+    void frameStartedLoading(Frame*);
+    void frameStoppedLoading(Frame*);
+    void frameScheduledNavigation(Frame*, double delay);
+    void frameClearedScheduledNavigation(Frame*);
     void applyScreenWidthOverride(long*);
     void applyScreenHeightOverride(long*);
     void applyEmulatedMedia(String*);
index e9e12b9..4d7a1a1 100644 (file)
@@ -596,6 +596,18 @@ WebInspector.PageDispatcher.prototype = {
     frameDetached: function(frameId)
     {
         this._resourceTreeModel._frameDetached(frameId);
+    },
+
+    frameStartedLoading: function(frameId) {
+    },
+
+    frameStoppedLoading: function(frameId) {
+    },
+
+    frameScheduledNavigation: function(frameId, delay) {
+    },
+
+    frameClearedScheduledNavigation: function(frameId) {
     }
 }
 
index acbeb78..076abbd 100644 (file)
@@ -45,6 +45,7 @@
 #include "HTMLFormElement.h"
 #include "HTMLFrameOwnerElement.h"
 #include "HistoryItem.h"
+#include "InspectorInstrumentation.h"
 #include "Page.h"
 #include "UserGestureIndicator.h"
 #include <wtf/CurrentTime.h>
@@ -286,6 +287,8 @@ bool NavigationScheduler::locationChangePending()
 
 void NavigationScheduler::clear()
 {
+    if (m_timer.isActive())
+        InspectorInstrumentation::frameClearedScheduledNavigation(m_frame);
     m_timer.stop();
     m_redirect.clear();
 }
@@ -411,11 +414,14 @@ void NavigationScheduler::timerFired(Timer<NavigationScheduler>*)
 {
     if (!m_frame->page())
         return;
-    if (m_frame->page()->defersLoading())
+    if (m_frame->page()->defersLoading()) {
+        InspectorInstrumentation::frameClearedScheduledNavigation(m_frame);
         return;
+    }
 
     OwnPtr<ScheduledNavigation> redirect(m_redirect.release());
     redirect->fire(m_frame);
+    InspectorInstrumentation::frameClearedScheduledNavigation(m_frame);
 }
 
 void NavigationScheduler::schedule(PassOwnPtr<ScheduledNavigation> redirect)
@@ -458,10 +464,13 @@ void NavigationScheduler::startTimer()
 
     m_timer.startOneShot(m_redirect->delay());
     m_redirect->didStartTimer(m_frame, &m_timer);
+    InspectorInstrumentation::frameScheduledNavigation(m_frame, m_redirect->delay());
 }
 
 void NavigationScheduler::cancel(bool newLoadInProgress)
 {
+    if (m_timer.isActive())
+        InspectorInstrumentation::frameClearedScheduledNavigation(m_frame);
     m_timer.stop();
 
     OwnPtr<ScheduledNavigation> redirect(m_redirect.release());
index 4f2b7ec..92388ec 100644 (file)
@@ -31,6 +31,7 @@
 #include "FrameLoader.h"
 #include "FrameLoaderStateMachine.h"
 #include "FrameLoaderClient.h"
+#include "InspectorInstrumentation.h"
 #include "Logging.h"
 #include "ResourceResponse.h"
 #include <wtf/text/CString.h>
@@ -120,6 +121,7 @@ void ProgressTracker::progressStarted(Frame* frame)
     m_numProgressTrackedFrames++;
 
     frame->loader()->client()->didChangeEstimatedProgress();
+    InspectorInstrumentation::frameStartedLoading(frame);
 }
 
 void ProgressTracker::progressCompleted(Frame* frame)
@@ -155,6 +157,7 @@ void ProgressTracker::finalProgressComplete()
 
     frame->loader()->client()->setMainFrameDocumentReady(true);
     frame->loader()->client()->postProgressFinishedNotification();
+    InspectorInstrumentation::frameStoppedLoading(frame.get());
 }
 
 void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response)