2011-05-09 Shishir Agrawal <shishir@chromium.org>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 May 2011 11:00:47 +0000 (11:00 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 May 2011 11:00:47 +0000 (11:00 +0000)
        Reviewed by Tony Gentilcore.

        Implement Page Visibility API.
        https://bugs.webkit.org/show_bug.cgi?id=54181

        * fast/events/page-visibility-iframe-delete-test-expected.txt: Added.
        * fast/events/page-visibility-iframe-delete-test.html: Added.
        * fast/events/page-visibility-iframe-move-test-expected.txt: Added.
        * fast/events/page-visibility-iframe-move-test.html: Added.
        * fast/events/page-visibility-iframe-propagation-test-expected.txt: Added.
        * fast/events/page-visibility-iframe-propagation-test.html: Added.
        * fast/events/page-visibility-transition-test-expected.txt: Added.
        * fast/events/page-visibility-transition-test.html: Added.
        * fast/events/resources/page-visibility-iframe-delete-test-frame.html: Added.
        * fast/events/resources/page-visibility-iframe-move-new-page.html: Added.
        * platform/chromium/test_expectations.txt:
        * platform/gtk/Skipped:
        * platform/mac/Skipped:
        * platform/qt/Skipped:
        * platform/win/Skipped:
2011-05-09  Shishir Agrawal  <shishir@chromium.org>

        Reviewed by Tony Gentilcore.

        Implement Page Visibility API.
        https://bugs.webkit.org/show_bug.cgi?id=54181

        Tests: fast/events/page-visibility-iframe-delete-test.html
               fast/events/page-visibility-iframe-move-test.html
               fast/events/page-visibility-iframe-propagation-test.html
               fast/events/page-visibility-transition-test.html

        * CMakeLists.txt:
        * GNUmakefile.list.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * dom/Document.cpp:
        (WebCore::Document::visibilityState):
        (WebCore::Document::webkitVisibilityState):
        (WebCore::Document::webkitIsVisible):
        (WebCore::Document::dispatchVisibilityStateChangeEvent):
        * dom/Document.h:
        * dom/Document.idl:
        * dom/EventNames.h:
        * page/Frame.cpp:
        (WebCore::Frame::dispatchVisibilityStateChangeEvent):
        * page/Frame.h:
        * page/Page.cpp:
        (WebCore::Page::Page):
        (WebCore::Page::setVisibilityState):
        (WebCore::Page::visibilityState):
        * page/Page.h:
        * page/PageVisibilityState.cpp: Added.
        (WebCore::GetPageVisibilityStateString):
        * page/PageVisibilityState.h: Added.
2011-05-09  Shishir Agrawal  <shishir@chromium.org>

        Reviewed by Tony Gentilcore.

        Implement Page Visibility API.
        https://bugs.webkit.org/show_bug.cgi?id=54181

        * WebKit.gyp:
        * public/WebPageVisibilityState.h: Added.
        * public/WebView.h:
        (WebKit::WebView::setVisibilityState):
        * public/WebViewClient.h:
        (WebKit::WebViewClient::visibilityState):
        * src/AssertMatchingEnums.cpp:
        * src/WebViewImpl.cpp:
        (WebKit::WebViewImpl::WebViewImpl):
        (WebKit::WebViewImpl::setVisibilityState):
        * src/WebViewImpl.h:
2011-05-09  Shishir Agrawal  <shishir@chromium.org>

        Reviewed by Tony Gentilcore.

        Implement Page Visibility API.
        https://bugs.webkit.org/show_bug.cgi?id=54181

        * DumpRenderTree/LayoutTestController.cpp:
        (setPageVisibilityCallback):
        (resetPageVisibilityCallback):
        (LayoutTestController::staticFunctions):
        * DumpRenderTree/LayoutTestController.h:
        (LayoutTestController::setPageVisibility):
        (LayoutTestController::resetPageVisibility):
        * DumpRenderTree/chromium/LayoutTestController.cpp:
        (LayoutTestController::LayoutTestController):
        (LayoutTestController::resetPageVisibility):
        (LayoutTestController::setPageVisibility):
        * DumpRenderTree/chromium/LayoutTestController.h:

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

46 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/page-visibility-iframe-delete-test-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-iframe-delete-test.html [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-iframe-move-test-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-iframe-move-test.html [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-iframe-propagation-test-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-iframe-propagation-test.html [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-transition-test-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/page-visibility-transition-test.html [new file with mode: 0644]
LayoutTests/fast/events/resources/page-visibility-iframe-delete-test-frame.html [new file with mode: 0644]
LayoutTests/fast/events/resources/page-visibility-iframe-move-new-page.html [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/mac/Skipped
LayoutTests/platform/qt/Skipped
LayoutTests/platform/win/Skipped
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Document.idl
Source/WebCore/dom/EventNames.h
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Frame.h
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/page/PageVisibilityState.cpp [new file with mode: 0644]
Source/WebCore/page/PageVisibilityState.h [new file with mode: 0644]
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/WebKit.gyp
Source/WebKit/chromium/public/WebPageVisibilityState.h [new file with mode: 0644]
Source/WebKit/chromium/public/WebView.h
Source/WebKit/chromium/public/WebViewClient.h
Source/WebKit/chromium/src/AssertMatchingEnums.cpp
Source/WebKit/chromium/src/WebViewImpl.cpp
Source/WebKit/chromium/src/WebViewImpl.h
Tools/ChangeLog
Tools/DumpRenderTree/LayoutTestController.cpp
Tools/DumpRenderTree/LayoutTestController.h
Tools/DumpRenderTree/chromium/LayoutTestController.cpp
Tools/DumpRenderTree/chromium/LayoutTestController.h

index 5202b70..3b63f3d 100644 (file)
@@ -1,3 +1,26 @@
+2011-05-09  Shishir Agrawal  <shishir@chromium.org>
+
+        Reviewed by Tony Gentilcore.
+
+        Implement Page Visibility API.
+        https://bugs.webkit.org/show_bug.cgi?id=54181
+
+        * fast/events/page-visibility-iframe-delete-test-expected.txt: Added.
+        * fast/events/page-visibility-iframe-delete-test.html: Added.
+        * fast/events/page-visibility-iframe-move-test-expected.txt: Added.
+        * fast/events/page-visibility-iframe-move-test.html: Added.
+        * fast/events/page-visibility-iframe-propagation-test-expected.txt: Added.
+        * fast/events/page-visibility-iframe-propagation-test.html: Added.
+        * fast/events/page-visibility-transition-test-expected.txt: Added.
+        * fast/events/page-visibility-transition-test.html: Added.
+        * fast/events/resources/page-visibility-iframe-delete-test-frame.html: Added.
+        * fast/events/resources/page-visibility-iframe-move-new-page.html: Added.
+        * platform/chromium/test_expectations.txt:
+        * platform/gtk/Skipped:
+        * platform/mac/Skipped:
+        * platform/qt/Skipped:
+        * platform/win/Skipped:
+
 2011-05-09  Venkat Penukonda  <venkat.2.penukonda@nokia.com>
 
         Reviewed by Csaba Osztrogon√°c.
diff --git a/LayoutTests/fast/events/page-visibility-iframe-delete-test-expected.txt b/LayoutTests/fast/events/page-visibility-iframe-delete-test-expected.txt
new file mode 100644 (file)
index 0000000..1d20a39
--- /dev/null
@@ -0,0 +1,12 @@
+This test checks that the page visibility event proagation does not crash the browser when frames are added / deleted.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Loaded all frames.
+Visibility of main document changed.
+Visibility of sub frame 2 changed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+   
diff --git a/LayoutTests/fast/events/page-visibility-iframe-delete-test.html b/LayoutTests/fast/events/page-visibility-iframe-delete-test.html
new file mode 100644 (file)
index 0000000..88ccb62
--- /dev/null
@@ -0,0 +1,111 @@
+<html>
+<body onload="startTest()">
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script src="../js/resources/js-test-pre.js"></script>
+
+<script>
+
+description("This test checks that the page visibility event proagation does not crash the browser when frames are added / deleted.");
+
+var jsTestIsAsync = true;
+
+var numVisibilityChanges = 0;
+var frame1, frame2, frame3, frame4, frame5, subframe1, subFrame2, subFrame3;
+
+var docsLoaded = 0;
+var mainPageVisibilityChangeDone = false;
+var frame2VisiblityChangeDone = false;
+
+function startTest() {
+    ++docsLoaded;
+    if (docsLoaded < 8) {
+      return;
+   }
+
+    debug("Loaded all frames.");
+
+    frame1 = document.getElementById("topFrame1");
+    frame2 = document.getElementById("topFrame2");
+    frame3 = document.getElementById("topFrame3");
+    frame4 = document.getElementById("topFrame4");
+    subFrame1 = frame3.contentDocument.getElementById("subIframe1");
+    subFrame2 = frame3.contentDocument.getElementById("subIframe2");
+
+    document.addEventListener(
+        "webkitvisibilitystatechange", onMainPageVisibilityChange, false);
+    frame2.contentDocument.addEventListener(
+        "webkitvisibilitystatechange", onFrame2VisibilityChange, false);
+    // Change the visibility of the current page to invisible.
+    if (window.layoutTestController) {
+        numVisibilityChanges++;
+        layoutTestController.setPageVisibility("hidden");
+    }
+}
+
+function finishTest() {
+    if (window.layoutTestController)
+        layoutTestController.resetPageVisibility();
+    finishJSTest();
+}
+
+function onMainPageVisibilityChange() {
+    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
+        finishTest();
+    } else if (!mainPageVisibilityChangeDone) {
+        debug("Visibility of main document changed.");
+        // Delete frame 4.
+        document.body.removeChild(frame4);
+
+        // Delete subframe 2.
+        frame3.contentDocument.body.removeChild(subFrame2);
+
+        // Add a new frame to top level.
+        frame5 = document.createElement("iframe");
+        frame5.src = '';
+        document.body.appendChild(frame5);
+
+        // Add a new frame to frame2.
+        subFrame3 = frame2.contentDocument.createElement("iframe");
+        subFrame3.src = '';
+        frame2.contentDocument.body.appendChild(subFrame3);
+
+        mainPageVisibilityChangeDone = true;
+    }
+
+    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
+        finishTest();
+    }
+}
+
+function onFrame2VisibilityChange() {
+    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
+        finishTest();
+    } else if (!frame2VisiblityChangeDone) {
+        debug("Visibility of sub frame 2 changed.");
+
+        // Delete frame 1.
+        document.body.removeChild(frame1);
+
+        frame2VisiblityChangeDone = true;
+    }
+
+    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
+        finishTest();
+    }
+}
+    
+var successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+<iframe id="topFrame1" onload="startTest()" ></iframe>
+<iframe id="topFrame2" onload="startTest()" ></iframe>
+<iframe id="topFrame3" onload="startTest()" src="resources/page-visibility-iframe-delete-test-frame.html"></iframe>
+<iframe id="topFrame4" onload="startTest()" ></iframe>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/page-visibility-iframe-move-test-expected.txt b/LayoutTests/fast/events/page-visibility-iframe-move-test-expected.txt
new file mode 100644 (file)
index 0000000..79440cf
--- /dev/null
@@ -0,0 +1,21 @@
+This test checks that an iframe that moves between pages with different visibility will have the correct visibility value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Window 1 Loaded
+Window 2 Loaded
+PASS window.document.webkitIsVisible is true
+PASS window2.document.webkitIsVisible is true
+PASS iframe.contentDocument.webkitIsVisible is true
+PASS window.document.webkitIsVisible is false
+PASS window2.document.webkitIsVisible is true
+PASS iframe.contentDocument.webkitIsVisible is true
+Adopted iframe to Window 1
+PASS window.document.webkitIsVisible is false
+PASS window2.document.webkitIsVisible is true
+PASS iframe.contentDocument.webkitIsVisible is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/page-visibility-iframe-move-test.html b/LayoutTests/fast/events/page-visibility-iframe-move-test.html
new file mode 100644 (file)
index 0000000..5163892
--- /dev/null
@@ -0,0 +1,80 @@
+<html>
+<body onload="startTest()">
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script src="../js/resources/js-test-pre.js"></script>
+
+<script>
+
+description("This test checks that an iframe that moves between pages with different visibility will have the correct visibility value.");
+
+var jsTestIsAsync = true;
+
+var window2, iframe;
+var numVisibilityChanges = 0;
+
+function window2Loaded() {
+    debug("Window 2 Loaded");
+
+    iframe = window2.document.getElementById("iframe");
+
+    shouldBeTrue("window.document.webkitIsVisible");
+    shouldBeTrue("window2.document.webkitIsVisible");
+    shouldBeTrue("iframe.contentDocument.webkitIsVisible");
+
+    // Change the visibility of the current page to invisible.
+    if (window.layoutTestController) {
+        numVisibilityChanges++;
+        window.layoutTestController.setPageVisibility("hidden");
+    }
+}
+
+function onVisibilityChange() {
+    shouldBeFalse("window.document.webkitIsVisible");
+    shouldBeTrue("window2.document.webkitIsVisible");
+    shouldBeTrue("iframe.contentDocument.webkitIsVisible");
+
+    window.document.adoptNode(iframe);
+    window.document.body.appendChild(iframe);
+    debug("Adopted iframe to Window 1");
+
+    shouldBeFalse("window.document.webkitIsVisible");
+    shouldBeTrue("window2.document.webkitIsVisible");
+    shouldBeFalse("iframe.contentDocument.webkitIsVisible");
+
+    window2.close();
+
+    finishTest();
+}
+
+function startTest() {
+    if (window.layoutTestController) {
+        layoutTestController.waitUntilDone();
+        layoutTestController.setCanOpenWindows();
+    }
+
+    debug("Window 1 Loaded");
+    document.addEventListener("webkitvisibilitystatechange",
+                              onVisibilityChange, false);
+
+    window2 = window.open("resources/page-visibility-iframe-move-new-page.html");
+    window2.addEventListener("load", window2Loaded, false);
+}
+
+function finishTest() {
+    if (window.layoutTestController) {
+        layoutTestController.resetPageVisibility();
+    }
+    finishJSTest();
+}
+
+var successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/events/page-visibility-iframe-propagation-test-expected.txt b/LayoutTests/fast/events/page-visibility-iframe-propagation-test-expected.txt
new file mode 100644 (file)
index 0000000..95b79ba
--- /dev/null
@@ -0,0 +1,27 @@
+This test checks that Page Visibility state events are propagated to child frames.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Main Page:
+PASS document.webkitVisibilityState is "visible"
+PASS document.webkitIsVisible is true
+Child Frame:
+PASS childFrame.contentDocument.webkitVisibilityState is "visible"
+PASS childFrame.contentDocument.webkitIsVisible is true
+Main Page:
+PASS document.webkitVisibilityState is "hidden"
+PASS document.webkitIsVisible is false
+Child Frame:
+PASS childFrame.contentDocument.webkitVisibilityState is "hidden"
+PASS childFrame.contentDocument.webkitIsVisible is false
+Main Page:
+PASS document.webkitVisibilityState is "visible"
+PASS document.webkitIsVisible is true
+Child Frame:
+PASS childFrame.contentDocument.webkitVisibilityState is "visible"
+PASS childFrame.contentDocument.webkitIsVisible is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/page-visibility-iframe-propagation-test.html b/LayoutTests/fast/events/page-visibility-iframe-propagation-test.html
new file mode 100644 (file)
index 0000000..a016567
--- /dev/null
@@ -0,0 +1,125 @@
+<html>
+<body>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script src="../js/resources/js-test-pre.js"></script>
+
+<script>
+
+description("This test checks that Page Visibility state events are propagated to child frames.");
+
+var jsTestIsAsync = true;
+
+function makePageVisible() {
+    if (window.layoutTestController)
+        layoutTestController.setPageVisibility("visible");
+}
+
+function makePageHidden() {
+    if (window.layoutTestController)
+        layoutTestController.setPageVisibility("hidden");
+}
+
+function checkIsPageVisible() {
+    debug("Main Page:");
+    shouldBeEqualToString("document.webkitVisibilityState", "visible");
+    shouldBeTrue("document.webkitIsVisible");
+}
+
+function checkIsPageHidden() {
+    debug("Main Page:");
+    shouldBeEqualToString("document.webkitVisibilityState", "hidden");
+    shouldBeFalse("document.webkitIsVisible");
+}
+
+function checkIsChildFrameVisible() {
+    debug("Child Frame:");
+    shouldBeEqualToString("childFrame.contentDocument.webkitVisibilityState",
+                          "visible");
+    shouldBeTrue("childFrame.contentDocument.webkitIsVisible");
+}
+
+function checkIsChildFrameHidden() {
+    debug("Child Frame:");
+    shouldBeEqualToString("childFrame.contentDocument.webkitVisibilityState",
+                          "hidden");
+    shouldBeFalse("childFrame.contentDocument.webkitIsVisible");
+}
+
+// We will try to change the visibility states as:
+//  0 - visible. (Initial - i.e. on load).
+//  1 - hidden
+//  2 - visible
+var numVisibilityChanges = 0;
+
+var childFrame;
+
+function startTest() {
+    childFrame = document.getElementById("childFrame");
+    childFrame.contentDocument.addEventListener(
+        "webkitvisibilitystatechange", onChildFrameVisibilityChange, false);
+    document.addEventListener("webkitvisibilitystatechange",
+                              onVisibilityChange, false);
+
+    checkIsPageVisible();
+    checkIsChildFrameVisible();
+
+    numVisibilityChanges++;
+    makePageHidden();
+}
+
+var numFinishes = 0;
+function finishTest() {
+    numFinishes++;
+    if (numFinishes < 2) {
+      return;
+    }
+
+    if (window.layoutTestController) {
+        layoutTestController.resetPageVisibility();
+    }
+    finishJSTest();
+}
+
+function onVisibilityChange() {
+    if (numVisibilityChanges == 1) {
+        checkIsPageHidden();
+        return;
+    } else if (numVisibilityChanges == 2) {
+        checkIsPageVisible();
+        finishTest();
+        return;
+    } else {
+        testFailed("Too many visibility transitions");
+        finishTest();
+        return;
+    }
+}
+
+function onChildFrameVisibilityChange() {
+    if (numVisibilityChanges == 1) {
+        checkIsChildFrameHidden();
+        numVisibilityChanges++;
+        makePageVisible();
+        return;
+    } else if (numVisibilityChanges == 2) {
+        checkIsChildFrameVisible();
+        finishTest();
+        return;
+    } else {
+        testFailed("Child Frame: Too many visibility transitions");
+        finishTest();
+    }
+}
+
+var successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+<iframe id="childFrame" onload="startTest()"></iframe>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/page-visibility-transition-test-expected.txt b/LayoutTests/fast/events/page-visibility-transition-test-expected.txt
new file mode 100644 (file)
index 0000000..25a9b5e
--- /dev/null
@@ -0,0 +1,17 @@
+This test checks that Page Visibility state values are correct and the event changes are fired correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.webkitVisibilityState is "visible"
+PASS document.webkitIsVisible is true
+PASS document.webkitVisibilityState is "hidden"
+PASS document.webkitIsVisible is false
+PASS document.webkitVisibilityState is "hidden"
+PASS document.webkitIsVisible is false
+PASS document.webkitVisibilityState is "visible"
+PASS document.webkitIsVisible is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/page-visibility-transition-test.html b/LayoutTests/fast/events/page-visibility-transition-test.html
new file mode 100644 (file)
index 0000000..42abcb0
--- /dev/null
@@ -0,0 +1,89 @@
+<html>
+<body onload='startTest()'>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script src="../js/resources/js-test-pre.js"></script>
+
+<script>
+
+description("This test checks that Page Visibility state values are correct and the event changes are fired correctly.");
+
+var jsTestIsAsync = true;
+
+function makePageVisible() {
+    if (window.layoutTestController)
+        layoutTestController.setPageVisibility("visible");
+}
+
+function makePageHidden() {
+    if (window.layoutTestController)
+        layoutTestController.setPageVisibility("hidden");
+}
+
+function checkIsPageVisible() {
+    shouldBeEqualToString("document.webkitVisibilityState", "visible");
+    shouldBeTrue("document.webkitIsVisible");
+}
+
+function checkIsPageHidden() {
+    shouldBeEqualToString("document.webkitVisibilityState", "hidden");
+    shouldBeFalse("document.webkitIsVisible");
+}
+
+// We will try to change the visibility states as:
+//  0 - visible. (Initial - i.e. on load).
+//  1 - hidden (should fire event).
+//  2 - hidden (no event).
+//  3 - visible (should fire event).
+var numVisibilityChanges = 0;
+
+function startTest() {
+    document.addEventListener(
+        "webkitvisibilitystatechange", onVisibilityChange, false);
+    checkIsPageVisible();
+    numVisibilityChanges++;
+    makePageHidden();
+}
+
+function finishTest() {
+    if (window.layoutTestController) {
+        layoutTestController.resetPageVisibility();
+    }
+    finishJSTest();
+}
+
+function onVisibilityChange() {
+    if (numVisibilityChanges == 1) {
+        checkIsPageHidden();
+        numVisibilityChanges++;
+        makePageHidden();
+        checkIsPageHidden();
+        numVisibilityChanges++;
+        makePageVisible();
+        return;
+    } else if (numVisibilityChanges == 2) {
+        testFailed("Invalid event fired on same state change.");
+        finishTest();
+        return;
+    } else if (numVisibilityChanges == 3) {
+        checkIsPageVisible();
+        numVisibilityChanges++;
+        finishTest();
+        return;
+    } else {
+        testFailed("Too many visibility transitions");
+        finishTest();
+        return;
+    }
+}
+        
+var successfullyParsed = true;
+
+</script>
+
+<script src="../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/events/resources/page-visibility-iframe-delete-test-frame.html b/LayoutTests/fast/events/resources/page-visibility-iframe-delete-test-frame.html
new file mode 100644 (file)
index 0000000..febb954
--- /dev/null
@@ -0,0 +1,6 @@
+<html>
+<body onload="parent.startTest()">
+<iframe id="subIframe1" onload="parent.parent.startTest()"></iframe>
+<iframe id="subIframe2" onload="parent.parent.startTest()"></iframe>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/resources/page-visibility-iframe-move-new-page.html b/LayoutTests/fast/events/resources/page-visibility-iframe-move-new-page.html
new file mode 100644 (file)
index 0000000..6d28ccc
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+<iframe id="iframe"></iframe>
+</body>
+</html>
index 9e73e6d..17b6d77 100644 (file)
@@ -4039,3 +4039,9 @@ BUGWK60351 DEBUG : http/tests/local/formdata/send-form-data-with-sliced-file.htm
 
 // The test is added at r85961.
 BUGWK60414 WIN : platform/win/plugins/visibility-hidden.html = CRASH
+
+// Page visibility API not turned on.
+BUGWK54181 : fast/events/page-visibility-iframe-delete-test.html = TIMEOUT
+BUGWK54181 : fast/events/page-visibility-iframe-move-test.html = TIMEOUT
+BUGWK54181 : fast/events/page-visibility-iframe-propagation-test.html = TIMEOUT
+BUGWK54181 : fast/events/page-visibility-transition-test.html = TIMEOUT
index 82fcefb..2a7df99 100644 (file)
@@ -1408,3 +1408,9 @@ tables/mozilla_expected_failures/bugs/bug85016.html
 # HTTP 204 (No Content) should be ignored
 # https://bugs.webkit.org/show_bug.cgi?id=60206
 http/tests/navigation/response204.html
+
+# This platform does not support the Page Visibility API.
+fast/events/page-visibility-iframe-delete-test.html
+fast/events/page-visibility-iframe-move-test.html
+fast/events/page-visibility-iframe-propagation-test.html
+fast/events/page-visibility-transition-test.html
index c28ec75..34f6fcd 100644 (file)
@@ -354,3 +354,9 @@ animations/animation-api-1.html
 # HTTP 204 (No Content) should be ignored
 # https://bugs.webkit.org/show_bug.cgi?id=60206
 http/tests/navigation/response204.html
+
+# This platform does not support the Page Visibility API.
+fast/events/page-visibility-iframe-delete-test.html
+fast/events/page-visibility-iframe-move-test.html
+fast/events/page-visibility-iframe-propagation-test.html
+fast/events/page-visibility-transition-test.html
index 5687c7b..18694ec 100644 (file)
@@ -2689,3 +2689,9 @@ http/tests/security/contentSecurityPolicy/media-src-blocked.html
 
 # Animation API is disabled by default
 animations/animation-api-1.html
+
+# This platform does not support the Page Visibility API.
+fast/events/page-visibility-iframe-delete-test.html
+fast/events/page-visibility-iframe-move-test.html
+fast/events/page-visibility-iframe-propagation-test.html
+fast/events/page-visibility-transition-test.html
index 92a5ad9..048f28f 100644 (file)
@@ -1283,3 +1283,9 @@ animations/animation-api-1.html
 # HTTP 204 (No Content) should be ignored
 # https://bugs.webkit.org/show_bug.cgi?id=60206
 http/tests/navigation/response204.html
+
+# This platform does not support the Page Visibility API.
+fast/events/page-visibility-iframe-delete-test.html
+fast/events/page-visibility-iframe-move-test.html
+fast/events/page-visibility-iframe-propagation-test.html
+fast/events/page-visibility-transition-test.html
index 2cfa5e9..c37ad14 100644 (file)
@@ -1010,6 +1010,7 @@ SET(WebCore_SOURCES
     page/PageGroup.cpp
     page/PageGroupLoadDeferrer.cpp
     page/PageSerializer.cpp
+    page/PageVisibilityState.cpp
     page/Performance.cpp
     page/PerformanceNavigation.cpp
     page/PerformanceTiming.cpp
index 556d92e..561f79e 100644 (file)
@@ -1,3 +1,41 @@
+2011-05-09  Shishir Agrawal  <shishir@chromium.org>
+
+        Reviewed by Tony Gentilcore.
+
+        Implement Page Visibility API.
+        https://bugs.webkit.org/show_bug.cgi?id=54181
+
+        Tests: fast/events/page-visibility-iframe-delete-test.html
+               fast/events/page-visibility-iframe-move-test.html
+               fast/events/page-visibility-iframe-propagation-test.html
+               fast/events/page-visibility-transition-test.html
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Document.cpp:
+        (WebCore::Document::visibilityState):
+        (WebCore::Document::webkitVisibilityState):
+        (WebCore::Document::webkitIsVisible):
+        (WebCore::Document::dispatchVisibilityStateChangeEvent):
+        * dom/Document.h:
+        * dom/Document.idl:
+        * dom/EventNames.h:
+        * page/Frame.cpp:
+        (WebCore::Frame::dispatchVisibilityStateChangeEvent):
+        * page/Frame.h:
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+        (WebCore::Page::setVisibilityState):
+        (WebCore::Page::visibilityState):
+        * page/Page.h:
+        * page/PageVisibilityState.cpp: Added.
+        (WebCore::GetPageVisibilityStateString):
+        * page/PageVisibilityState.h: Added.
+
 2011-05-09  Luke Macpherson   <macpherson@chromium.org>
 
         Reviewed by Eric Seidel.
index 4dd7655..9f72a27 100644 (file)
@@ -2218,6 +2218,8 @@ webcore_sources += \
        Source/WebCore/page/PageGroupLoadDeferrer.h \
        Source/WebCore/page/PageSerializer.cpp \
        Source/WebCore/page/PageSerializer.h \
+       Source/WebCore/page/PageVisibilityState.cpp \
+       Source/WebCore/page/PageVisibilityState.h \
        Source/WebCore/page/Performance.cpp \
        Source/WebCore/page/Performance.h \
        Source/WebCore/page/PerformanceNavigation.cpp \
index 9affc52..6a7a8fb 100644 (file)
             'page/Page.h',
             'page/PageGroup.h',
             'page/PageSerializer.h',
+            'page/PageVisibilityState.h',
             'page/PluginHalterClient.h',
             'page/PositionCallback.h',
             'page/PositionError.h',
             'page/PageGroupLoadDeferrer.cpp',
             'page/PageGroupLoadDeferrer.h',
             'page/PageSerializer.cpp',
+            'page/PageVisibilityState.cpp',
             'page/Performance.cpp',
             'page/Performance.h',
             'page/PerformanceNavigation.cpp',
index d6fb251..0a030ba 100644 (file)
@@ -920,6 +920,7 @@ SOURCES += \
     page/PageGroup.cpp \
     page/PageGroupLoadDeferrer.cpp \
     page/PageSerializer.cpp \
+    page/PageVisibilityState.cpp \
     page/Performance.cpp \
     page/PerformanceNavigation.cpp \
     page/PerformanceTiming.cpp \
@@ -1861,6 +1862,7 @@ HEADERS += \
     page/PageGroupLoadDeferrer.h \
     page/Page.h \
     page/PageSerializer.h \
+    page/PageVisibilityState.h \
     page/PluginHalter.h \
     page/PluginHalterClient.h \
     page/PrintContext.h \
index c33f8c2..49de4fe 100755 (executable)
                                >
                        </File>
                        <File
+                               RelativePath="..\page\PageVisibilityState.cpp"
+                               >
+                       <File
+                               RelativePath="..\page\PageVisibilityState.h"
+                               >
+                       <File
                                RelativePath="..\page\Performance.cpp"
                                >
                        </File>
index 12fd79b..ec7596d 100644 (file)
                FE80DA660E9C4703000D6F75 /* JSGeoposition.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA620E9C4703000D6F75 /* JSGeoposition.h */; };
                FE80DA710E9C472F000D6F75 /* JSPositionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */; };
                FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; };
+               FFD5B97A135CC97800D5E92A /* PageVisibilityState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */; };
+               FFD5B97B135CC97800D5E92A /* PageVisibilityState.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD5B978135CC97800D5E92A /* PageVisibilityState.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                FE80DA620E9C4703000D6F75 /* JSGeoposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGeoposition.h; sourceTree = "<group>"; };
                FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPositionError.cpp; sourceTree = "<group>"; };
                FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPositionError.h; sourceTree = "<group>"; };
+               FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageVisibilityState.cpp; sourceTree = "<group>"; };
+               FFD5B978135CC97800D5E92A /* PageVisibilityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageVisibilityState.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                7A674BDA0F9EBF4E006CF099 /* PageGroupLoadDeferrer.h */,
                                371E65CD13661EED00BEEDB0 /* PageSerializer.cpp */,
                                371E65CB13661EDC00BEEDB0 /* PageSerializer.h */,
+                               FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */,
+                               FFD5B978135CC97800D5E92A /* PageVisibilityState.h */,
                                8A844D0111D3C18E0014065C /* Performance.cpp */,
                                8A844D0211D3C18E0014065C /* Performance.h */,
                                8A844D0311D3C18E0014065C /* Performance.idl */,
                                F34742E51343633C00531BC2 /* PageScriptDebugServer.h in Headers */,
                                371E65CC13661EDC00BEEDB0 /* PageSerializer.h in Headers */,
                                E1284AE110447D4500EAEB52 /* PageTransitionEvent.h in Headers */,
+                               FFD5B97B135CC97800D5E92A /* PageVisibilityState.h in Headers */,
                                51E1ECC30C91C90400DC255B /* PageURLRecord.h in Headers */,
                                0885067F11DA045B00182B98 /* PaintInfo.h in Headers */,
                                0885068011DA045B00182B98 /* PaintPhase.h in Headers */,
                                371E65CE13661EED00BEEDB0 /* PageSerializer.cpp in Sources */,
                                E1284AEA10447DEE00EAEB52 /* PageTransitionEvent.cpp in Sources */,
                                51E1ECC20C91C90400DC255B /* PageURLRecord.cpp in Sources */,
+                               FFD5B97A135CC97800D5E92A /* PageVisibilityState.cpp in Sources */,
                                FD3160A212B026F700C1A359 /* Panner.cpp in Sources */,
                                F55B3DC91251F12D003EF269 /* PasswordInputType.cpp in Sources */,
                                4B2709830AF2E5E00065127F /* PasteboardMac.mm in Sources */,
index ae05a38..29fa2e2 100644 (file)
@@ -1354,6 +1354,34 @@ void Document::removeTitle(Element* titleElement)
         updateTitle(StringWithDirection());
 }
 
+#if ENABLE(PAGE_VISIBILITY_API)
+PageVisibilityState Document::visibilityState() const
+{
+    // The visibility of the document is inherited from the visibility of the
+    // page. If there is no page associated with the document, we will assume
+    // that the page is visible i.e. invisibility has to be explicitly
+    // specified by the embedder.
+    if (!m_frame || !m_frame->page())
+        return PageVisibilityStateVisible;
+    return m_frame->page()->visibilityState();
+}
+
+String Document::webkitVisibilityState() const
+{
+    return GetPageVisibilityStateString(visibilityState());
+}
+
+bool Document::webkitIsVisible() const
+{
+    return visibilityState() == PageVisibilityStateVisible;
+}
+
+void Document::dispatchVisibilityStateChangeEvent()
+{
+    dispatchEvent(Event::create(eventNames().webkitvisibilitystatechangeEvent, false, false));
+}
+#endif
+
 String Document::nodeName() const
 {
     return "#document";
index 2315e79..71b7af7 100644 (file)
@@ -34,6 +34,7 @@
 #include "DOMTimeStamp.h"
 #include "DocumentTiming.h"
 #include "IconURL.h"
+#include "PageVisibilityState.h"
 #include "QualifiedName.h"
 #include "ScriptExecutionContext.h"
 #include "StringWithDirection.h"
@@ -304,6 +305,9 @@ public:
 #if ENABLE(FULLSCREEN_API)
     DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
 #endif
+#if ENABLE(PAGE_VISIBILITY_API)
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitvisibilitystatechange);
+#endif
 
     ViewportArguments viewportArguments() const { return m_viewportArguments; }
 
@@ -379,6 +383,12 @@ public:
 
     virtual KURL baseURI() const;
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    String webkitVisibilityState() const;
+    bool webkitIsVisible() const;
+    void dispatchVisibilityStateChangeEvent();
+#endif
+
     PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&);
 
     PassRefPtr<HTMLCollection> images();
@@ -1132,6 +1142,10 @@ private:
 
     void loadEventDelayTimerFired(Timer<Document>*);
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    PageVisibilityState visibilityState() const;
+#endif
+
     int m_guardRefCount;
 
     OwnPtr<CSSStyleSelector> m_styleSelector;
index 5cfab24..89ae65e 100644 (file)
@@ -334,6 +334,10 @@ module core {
         boolean isHTMLDocument();
 #endif
 
+        // Page visibility API.
+        readonly attribute [Conditional=PAGE_VISIBILITY_API] DOMString webkitVisibilityState;
+        readonly attribute [Conditional=PAGE_VISIBILITY_API] boolean webkitIsVisible;
+
     };
 
 }
index ece2a08..96f0383 100644 (file)
@@ -106,6 +106,7 @@ namespace WebCore {
     macro(unload) \
     macro(updateready) \
     macro(versionchange) \
+    macro(webkitvisibilitystatechange) \
     macro(write) \
     macro(writeend) \
     macro(writestart) \
index af440dc..3a8d3b5 100644 (file)
@@ -718,6 +718,16 @@ void Frame::setDOMWindow(DOMWindow* domWindow)
     m_domWindow = domWindow;
 }
 
+#if ENABLE(PAGE_VISIBILITY_API)
+void Frame::dispatchVisibilityStateChangeEvent()
+{
+    if (m_doc)
+        m_doc->dispatchVisibilityStateChangeEvent();
+    for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
+        child->dispatchVisibilityStateChangeEvent();
+}
+#endif
+
 DOMWindow* Frame::domWindow() const
 {
     if (!m_domWindow)
index bed3411..7da9c49 100644 (file)
@@ -119,6 +119,10 @@ namespace WebCore {
 
         void transferChildFrameToNewDocument();
 
+#if ENABLE(PAGE_VISIBILITY_API)
+        void dispatchVisibilityStateChangeEvent();
+#endif
+
     // ======== All public functions below this point are candidates to move out of Frame into another class. ========
 
         bool isDisconnected() const;
index 88c7568..8607112 100644 (file)
@@ -163,6 +163,9 @@ Page::Page(const PageClients& pageClients)
     , m_viewMode(ViewModeWindowed)
     , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval())
     , m_isEditable(false)
+#if ENABLE(PAGE_VISIBILITY_API)
+    , m_visibilityState(PageVisibilityStateVisible)
+#endif
 {
     if (!allPages) {
         allPages = new HashSet<Page*>;
@@ -934,6 +937,23 @@ void Page::checkFrameCountConsistency() const
 }
 #endif
 
+#if ENABLE(PAGE_VISIBILITY_API)
+void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
+{
+    if (m_visibilityState == visibilityState)
+        return;
+    m_visibilityState = visibilityState;
+
+    if (!isInitialState && m_mainFrame)
+        m_mainFrame->dispatchVisibilityStateChangeEvent();
+}
+
+PageVisibilityState Page::visibilityState() const
+{
+    return m_visibilityState;
+}
+#endif
+
 Page::PageClients::PageClients()
     : chromeClient(0)
     , contextMenuClient(0)
index 6212b52..0121b34 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "FrameLoaderTypes.h"
 #include "FindOptions.h"
+#include "PageVisibilityState.h"
 #include "PlatformString.h"
 #include "ViewportArguments.h"
 #include <wtf/Forward.h>
@@ -301,6 +302,11 @@ namespace WebCore {
         void setEditable(bool isEditable) { m_isEditable = isEditable; }
         bool isEditable() { return m_isEditable; }
 
+#if ENABLE(PAGE_VISIBILITY_API)
+        PageVisibilityState visibilityState() const;
+        void setVisibilityState(PageVisibilityState, bool);
+#endif
+
     private:
         void initGroup();
 
@@ -406,6 +412,10 @@ namespace WebCore {
         OwnPtr<ScrollableAreaSet> m_scrollableAreaSet;
 
         bool m_isEditable;
+
+#if ENABLE(PAGE_VISIBILITY_API)
+        PageVisibilityState m_visibilityState;
+#endif
     };
 
 } // namespace WebCore
diff --git a/Source/WebCore/page/PageVisibilityState.cpp b/Source/WebCore/page/PageVisibilityState.cpp
new file mode 100644 (file)
index 0000000..fe18dfa
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "PageVisibilityState.h"
+
+#if ENABLE(PAGE_VISIBILITY_API)
+
+namespace WebCore {
+
+String GetPageVisibilityStateString(PageVisibilityState state)
+{
+    DEFINE_STATIC_LOCAL(const String, visible, ("visible"));
+    DEFINE_STATIC_LOCAL(const String, hidden, ("hidden"));
+
+    switch (state) {
+    case PageVisibilityStateVisible:
+        return visible;
+    case PageVisibilityStateHidden:
+        return hidden;
+    }
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+} // namespace WebCore
+
+#endif // if ENABLE(PAGE_VISIBILITY_API)
diff --git a/Source/WebCore/page/PageVisibilityState.h b/Source/WebCore/page/PageVisibilityState.h
new file mode 100644 (file)
index 0000000..a7d7021
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifndef PageVisibilityState_h
+#define PageVisibilityState_h
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// The enum is not flag protected as it is used in the WebKit chromium API
+// without flag protection.
+enum PageVisibilityState {
+    PageVisibilityStateVisible,
+    PageVisibilityStateHidden
+};
+
+#if ENABLE(PAGE_VISIBILITY_API)
+String GetPageVisibilityStateString(PageVisibilityState);
+#endif
+
+} // namespace WebCore
+
+#endif // ifndef PageVisibilityState_h
index 9e67cb3..fdea3a6 100644 (file)
@@ -1,3 +1,22 @@
+2011-05-09  Shishir Agrawal  <shishir@chromium.org>
+
+        Reviewed by Tony Gentilcore.
+
+        Implement Page Visibility API.
+        https://bugs.webkit.org/show_bug.cgi?id=54181
+
+        * WebKit.gyp:
+        * public/WebPageVisibilityState.h: Added.
+        * public/WebView.h:
+        (WebKit::WebView::setVisibilityState):
+        * public/WebViewClient.h:
+        (WebKit::WebViewClient::visibilityState):
+        * src/AssertMatchingEnums.cpp:
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::WebViewImpl):
+        (WebKit::WebViewImpl::setVisibilityState):
+        * src/WebViewImpl.h:
+
 2011-05-07  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r85974.
index 3e0b0d9..a6e9b27 100644 (file)
                 'public/WebOptionElement.h',
                 'public/WebPageSerializer.h',
                 'public/WebPageSerializerClient.h',
+                'public/WebPageVisibilityState.h',
                 'public/WebPasswordAutocompleteListener.h',
                 'public/WebPasswordFormData.h',
                 'public/WebPerformance.h',
diff --git a/Source/WebKit/chromium/public/WebPageVisibilityState.h b/Source/WebKit/chromium/public/WebPageVisibilityState.h
new file mode 100644 (file)
index 0000000..5474be4
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef WebPageVisibilityState_h
+#define WebPageVisibilityState_h
+
+namespace WebKit {
+
+// The following enum should be consistent with the PageVisibilityState enum
+// defined in WebCore.
+enum WebPageVisibilityState {
+    WebPageVisibilityStateVisible,
+    WebPageVisibilityStateHidden
+};
+
+} // namespace WebKit
+
+#endif
index 3e9b3d6..4a3ab58 100644 (file)
@@ -32,6 +32,7 @@
 #define WebView_h
 
 #include "WebDragOperation.h"
+#include "WebPageVisibilityState.h"
 #include "WebString.h"
 #include "WebVector.h"
 #include "WebWidget.h"
@@ -357,6 +358,12 @@ public:
     // APIs.
     virtual WebGraphicsContext3D* graphicsContext3D() = 0;
 
+    // Visibility -----------------------------------------------------------
+
+    // Sets the visibility of the WebView.
+    virtual void setVisibilityState(WebPageVisibilityState visibilityState,
+                                    bool isInitialState) { }
+
 protected:
     ~WebView() {}
 };
index 5174351..f3be3ca 100644 (file)
@@ -36,6 +36,7 @@
 #include "WebEditingAction.h"
 #include "WebFileChooserCompletion.h"
 #include "WebFileChooserParams.h"
+#include "WebPageVisibilityState.h"
 #include "WebPopupType.h"
 #include "WebString.h"
 #include "WebTextAffinity.h"
@@ -315,6 +316,14 @@ public:
                                          const WebString& url,
                                          const WebString& title) { }
 
+    // Visibility -----------------------------------------------------------
+
+    // Returns the current visibility of the WebView.
+    virtual WebPageVisibilityState visibilityState() const
+    {
+        return WebPageVisibilityStateVisible;
+    }
+
 protected:
     ~WebViewClient() { }
 };
index 533e8ec..38310b6 100644 (file)
@@ -50,6 +50,7 @@
 #include "IDBKey.h"
 #include "MediaPlayer.h"
 #include "NotificationPresenter.h"
+#include "PageVisibilityState.h"
 #include "PasteboardPrivate.h"
 #include "PlatformCursor.h"
 #include "Settings.h"
@@ -75,6 +76,7 @@
 #include "WebInputElement.h"
 #include "WebMediaPlayer.h"
 #include "WebNotificationPresenter.h"
+#include "WebPageVisibilityState.h"
 #include "WebScrollbar.h"
 #include "WebSettings.h"
 #include "WebStorageQuotaError.h"
@@ -445,3 +447,6 @@ COMPILE_ASSERT_MATCHING_ENUM(WebThemeEngine::ScrollbarOrientationVertical, Platf
 COMPILE_ASSERT_MATCHING_ENUM(WebThemeEngine::ScrollbarParentScrollView, PlatformBridge::ScrollbarParentScrollView);
 COMPILE_ASSERT_MATCHING_ENUM(WebThemeEngine::ScrollbarParentRenderLayer, PlatformBridge::ScrollbarParentRenderLayer);
 #endif
+
+COMPILE_ASSERT_MATCHING_ENUM(WebPageVisibilityStateVisible, PageVisibilityStateVisible);
+COMPILE_ASSERT_MATCHING_ENUM(WebPageVisibilityStateHidden, PageVisibilityStateHidden);
index e67251d..968de56 100644 (file)
@@ -366,6 +366,10 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
 
     m_page->setGroupName(pageGroupName);
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    setVisibilityState(m_client->visibilityState(), true);
+#endif
+
     m_inspectorSettingsMap = adoptPtr(new SettingsMap);
 }
 
@@ -2559,4 +2563,16 @@ WebGraphicsContext3D* WebViewImpl::graphicsContext3D()
     return 0;
 }
 
+
+void WebViewImpl::setVisibilityState(WebPageVisibilityState visibilityState,
+                                     bool isInitialState) {
+#if ENABLE(PAGE_VISIBILITY_API)
+    if (!page())
+        return;
+
+    ASSERT(visibilityState == WebPageVisibilityStateVisible || visibilityState == WebPageVisibilityStateHidden);
+    m_page->setVisibilityState(static_cast<PageVisibilityState>(static_cast<int>(visibilityState)), isInitialState);
+#endif
+}
+
 } // namespace WebKit
index d8d92a8..f290827 100644 (file)
@@ -355,6 +355,8 @@ public:
     // WebGL. Returns 0 if compositing support is not compiled in.
     virtual WebGraphicsContext3D* graphicsContext3D();
 
+    virtual void setVisibilityState(WebPageVisibilityState, bool);
+
     WebCore::PopupContainer* selectPopup() const { return m_selectPopup.get(); }
 
     // Returns true if the event leads to scrolling.
index 3005bd2..24df2a7 100644 (file)
@@ -1,3 +1,23 @@
+2011-05-09  Shishir Agrawal  <shishir@chromium.org>
+
+        Reviewed by Tony Gentilcore.
+
+        Implement Page Visibility API.
+        https://bugs.webkit.org/show_bug.cgi?id=54181
+
+        * DumpRenderTree/LayoutTestController.cpp:
+        (setPageVisibilityCallback):
+        (resetPageVisibilityCallback):
+        (LayoutTestController::staticFunctions):
+        * DumpRenderTree/LayoutTestController.h:
+        (LayoutTestController::setPageVisibility):
+        (LayoutTestController::resetPageVisibility):
+        * DumpRenderTree/chromium/LayoutTestController.cpp:
+        (LayoutTestController::LayoutTestController):
+        (LayoutTestController::resetPageVisibility):
+        (LayoutTestController::setPageVisibility):
+        * DumpRenderTree/chromium/LayoutTestController.h:
+
 2011-05-07  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Eric Seidel.
index 69a4c81..20e3a83 100644 (file)
@@ -1670,6 +1670,37 @@ static JSValueRef setPluginsEnabledCallback(JSContextRef context, JSObjectRef fu
     return JSValueMakeUndefined(context);
 }    
 
+static JSValueRef setPageVisibilityCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    // Has mac & windows implementation
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    JSRetainPtr<JSStringRef> visibility(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+    ASSERT(!*exception);
+
+    size_t maxLength = JSStringGetMaximumUTF8CStringSize(visibility.get());
+    char* visibilityBuffer = new char[maxLength + 1];
+    JSStringGetUTF8CString(visibility.get(), visibilityBuffer, maxLength + 1);
+    
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->setPageVisibility(visibilityBuffer);
+    delete[] visibilityBuffer;
+    
+    return JSValueMakeUndefined(context);
+}    
+
+static JSValueRef resetPageVisibilityCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    // Has mac & windows implementation
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->resetPageVisibility();
+    return JSValueMakeUndefined(context);
+}    
+
 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     if (argumentCount < 1)
@@ -2266,6 +2297,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "removeAllVisitedLinks", removeAllVisitedLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "removeOriginAccessWhitelistEntry", removeOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "resetPageVisibility", resetPageVisibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setAllowUniversalAccessFromFileURLs", setAllowUniversalAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setAllowFileAccessFromFileURLs", setAllowFileAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -2298,6 +2330,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "addMockSpeechInputResult", addMockSpeechInputResultCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "setPageVisibility", setPageVisibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
index a8179e1..099a641 100644 (file)
@@ -124,6 +124,9 @@ public:
     void setScrollbarPolicy(JSStringRef orientation, JSStringRef policy);
     void setEditingBehavior(const char* editingBehavior);
 
+    void setPageVisibility(const char* visibility) { }
+    void resetPageVisibility() { }
+
     JSValueRef shadowRoot(JSContextRef, JSValueRef);
     JSValueRef ensureShadowRoot(JSContextRef, JSValueRef);
     void removeShadowRoot(JSContextRef, JSValueRef);
index 6450ae7..2c70465 100644 (file)
@@ -134,6 +134,7 @@ LayoutTestController::LayoutTestController(TestShell* shell)
     bindMethod("removeOriginAccessWhitelistEntry", &LayoutTestController::removeOriginAccessWhitelistEntry);
     bindMethod("removeShadowRoot", &LayoutTestController::removeShadowRoot);
     bindMethod("repaintSweepHorizontally", &LayoutTestController::repaintSweepHorizontally);
+    bindMethod("resetPageVisibility", &LayoutTestController::resetPageVisibility);
     bindMethod("resumeAnimations", &LayoutTestController::resumeAnimations);
     bindMethod("sampleSVGAnimationForElementAtTime", &LayoutTestController::sampleSVGAnimationForElementAtTime);
     bindMethod("setAcceptsEditing", &LayoutTestController::setAcceptsEditing);
@@ -157,6 +158,7 @@ LayoutTestController::LayoutTestController(TestShell* shell)
     bindMethod("setMockGeolocationError", &LayoutTestController::setMockGeolocationError);
     bindMethod("setMockGeolocationPosition", &LayoutTestController::setMockGeolocationPosition);
     bindMethod("addMockSpeechInputResult", &LayoutTestController::addMockSpeechInputResult);
+    bindMethod("setPageVisibility", &LayoutTestController::setPageVisibility);
     bindMethod("setPluginsEnabled", &LayoutTestController::setPluginsEnabled);
     bindMethod("setPopupBlockingEnabled", &LayoutTestController::setPopupBlockingEnabled);
     bindMethod("setPOSIXLocale", &LayoutTestController::setPOSIXLocale);
@@ -1776,3 +1778,19 @@ void LayoutTestController::setPluginsEnabled(const CppArgumentList& arguments, C
     }
     result->setNull();
 }
+
+void LayoutTestController::resetPageVisibility(const CppArgumentList& arguments, CppVariant* result)
+{
+    m_shell->webView()->setVisibilityState(WebPageVisibilityStateVisible, true);
+}
+
+void LayoutTestController::setPageVisibility(const CppArgumentList& arguments, CppVariant* result)
+{
+    if (arguments.size() > 0 && arguments[0].isString()) {
+        string newVisibility = arguments[0].toString();
+        if (newVisibility == "visible")
+            m_shell->webView()->setVisibilityState(WebPageVisibilityStateVisible, false);
+        else if (newVisibility == "hidden")
+            m_shell->webView()->setVisibilityState(WebPageVisibilityStateHidden, false);
+    }
+}
index 33cfaac..fc3c633 100644 (file)
@@ -366,6 +366,10 @@ public:
     // Enable or disable plugins.
     void setPluginsEnabled(const CppArgumentList&, CppVariant*);
 
+    // Switch the visibility of the page.
+    void setPageVisibility(const CppArgumentList&, CppVariant*);
+    void resetPageVisibility(const CppArgumentList&, CppVariant*);
+
 public:
     // The following methods are not exposed to JavaScript.
     void setWorkQueueFrozen(bool frozen) { m_workQueue.setFrozen(frozen); }