Title: [231910] trunk
Revision
231910
Author
bfulg...@apple.com
Date
2018-05-17 11:16:56 -0700 (Thu, 17 May 2018)

Log Message

Storage Access API: Allow documents that have been granted storage access to also do a popup
https://bugs.webkit.org/show_bug.cgi?id=185615
<rdar://problem/39105791>

Reviewed by Chris Dumez.

Source/WebCore:

* dom/Document.cpp:
(WebCore::Document::consumeTemporaryUserGesture): Added. Clear the document's active one-time user
activity (for window opening) state.
(WebCore::Document::enableTemporaryUserGesture): Added. Establish a new active one-time user
activity (for window opening) state.
(WebCore::Document::requestStorageAccess): If the user approves Storage Access, establish a new
UserInteraction scope, then resolve the promise. Also post a task to clear the one-time user
gesture state.

LayoutTests:

* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt: Added.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html: Added.
* http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html: Added.
* http/tests/storageAccess/resources/request-storage-access-second-window.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (231909 => 231910)


--- trunk/LayoutTests/ChangeLog	2018-05-17 17:54:57 UTC (rev 231909)
+++ trunk/LayoutTests/ChangeLog	2018-05-17 18:16:56 UTC (rev 231910)
@@ -1,3 +1,16 @@
+2018-05-17  Brent Fulgham  <bfulg...@apple.com>
+
+        Storage Access API: Allow documents that have been granted storage access to also do a popup
+        https://bugs.webkit.org/show_bug.cgi?id=185615
+        <rdar://problem/39105791>
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt: Added.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html: Added.
+        * http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html: Added.
+        * http/tests/storageAccess/resources/request-storage-access-second-window.html: Added.
+
 2018-05-17  Antoine Quint  <grao...@apple.com>
 
         [modern-media-controls] AirPlaySupport should be disabled by default

Added: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt (0 => 231910)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt	2018-05-17 18:16:56 UTC (rev 231910)
@@ -0,0 +1,10 @@
+Tests that cross-origin iframe can display a window if storage access is granted.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Window was successfully opened with user interaction.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html (0 => 231910)


--- trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html	2018-05-17 18:16:56 UTC (rev 231910)
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+    <script src=""
+    <script>
+        description("Tests that cross-origin iframe can display a window if storage access is granted.");
+        jsTestIsAsync = true;
+
+        const hostUnderTest = "localhost:8000";
+        const statisticsUrl = "http://" + hostUnderTest + "/temp";
+
+        window.addEventListener("message", receiveMessage, false);
+
+        function setEnableFeature(enable) {
+            if (!window.testRunner)
+                return;
+
+            if (!enable)
+                testRunner.statisticsResetToConsistentState();
+            internals.setResourceLoadStatisticsEnabled(enable);
+            testRunner.setCookieStoragePartitioningEnabled(enable);
+            testRunner.setStorageAccessAPIEnabled(enable);
+        }
+
+        function receiveMessage(event) {
+            if (event.origin === "http://localhost:8000") {
+                if (event.data.indexOf("PASS ") !== -1)
+                    testPassed(event.data.replace("PASS ", ""));
+                else
+                    testFailed(event.data);
+            } else
+                testFailed("Received a message from an unexpected origin: " + event.origin);
+            finishJSTest();
+            setEnableFeature(false);
+        }
+
+        function activateElement(elementId) {
+            var element = document.getElementById(elementId);
+            var centerX = element.offsetLeft + element.offsetWidth / 2;
+            var centerY = element.offsetTop + element.offsetHeight / 2;
+            UIHelper.activateAt(centerX, centerY).then(
+                function () {
+                    if (window.eventSender)
+                        eventSender.keyDown("escape");
+                    else {
+                        testFailed("No eventSender.");
+                        finishJSTest();
+                        setEnableFeature(false);
+                    }
+                },
+                function () {
+                    testFailed("Promise rejected.");
+                    finishJSTest();
+                    setEnableFeature(false);
+                }
+            );
+        }
+
+        function runTest() {
+            setEnableFeature(true);
+
+            if (!window.testRunner)
+                return;
+
+            testRunner.setCanOpenWindows(false);
+            testRunner.setPopupBlockingEnabled(true);
+            testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+            if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+                testFailed("Host did not get set as prevalent resource.");
+            testRunner.setStatisticsHasHadNonRecentUserInteraction(statisticsUrl);
+            if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+                testFailed("Host did not get logged for user interaction.");
+            testRunner.statisticsUpdateCookiePartitioning();
+ 
+            activateElement("theIframe");
+        }
+    </script>
+</head>
+<body>
+    <iframe _onload_="runTest()" id="theIframe" src=""
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html (0 => 231910)


--- trunk/LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html	2018-05-17 18:16:56 UTC (rev 231910)
@@ -0,0 +1,63 @@
+<html>
+<head>
+    <script>
+        const hashArguments = document.location.hash.substring(1).split(",");
+        const userShouldGrantAccess = hashArguments[0] === "userShouldGrantAccess";
+        const userShouldBeConsulted = hashArguments[1] === "userShouldBeConsulted";
+        const policyShouldGrantAccess = hashArguments[2] === "policyShouldGrantAccess";
+        const isSameOriginIframe = hashArguments[3] === "isSameOriginIframe";
+        const originIsNull = hashArguments[4] === "originIsNull";
+
+        if (window.internals)
+            internals.setUserGrantsStorageAccess(userShouldGrantAccess);
+
+        if (window.testRunner) {
+            testRunner.setCanOpenWindows(false);
+            testRunner.setPopupBlockingEnabled(true);
+            testRunner.setCloseRemainingWindowsWhenComplete(true);
+        }
+
+        var requestStorageAccessResolved;
+
+        function messageToTop(message) {
+            top.postMessage(message, "http://127.0.0.1:8000");
+        }
+
+        function windowWasOpened()
+        {
+            if (userShouldGrantAccess)
+                messageToTop("PASS Window was successfully opened with user interaction.");
+            else
+                messageToTop("Window was opened even though the user declined permission.");
+        }
+
+        function makeRequestWithUserGesture() {
+            var promise = document.requestStorageAccess();
+            promise.then(
+                function () {
+                    requestStorageAccessResolved = true;
+                    continueAfterRequestWithUserGesture();
+                },
+                function () {
+                    requestStorageAccessResolved = false;
+                    continueAfterRequestWithUserGesture();
+                }
+            );
+        }
+
+        function continueAfterRequestWithUserGesture() {
+            var win = window.open("request-storage-access-second-window.html", "test window");
+            if (!win) {
+                if (userShouldGrantAccess)
+                    messageToTop("Window was not opened even though the user granted permission.");
+                else
+                    messageToTop("PASS Window was blocked from opening.");
+            } else if (!userShouldGrantAccess) {
+                messageToTop("Window was opened even though the user did not grant permission.");
+            }
+        }
+    </script>
+</head>
+<body _onclick_="makeRequestWithUserGesture()">
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/storageAccess/resources/request-storage-access-second-window.html (0 => 231910)


--- trunk/LayoutTests/http/tests/storageAccess/resources/request-storage-access-second-window.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/storageAccess/resources/request-storage-access-second-window.html	2018-05-17 18:16:56 UTC (rev 231910)
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<title>Event handlers in isolated worlds for user gesture generated events should should the same permissions as handlers within the page (resource)</title>
+<script>
+
+// success!
+window.opener.windowWasOpened();
+window.close();
+
+</script>
+<body>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (231909 => 231910)


--- trunk/Source/WebCore/ChangeLog	2018-05-17 17:54:57 UTC (rev 231909)
+++ trunk/Source/WebCore/ChangeLog	2018-05-17 18:16:56 UTC (rev 231910)
@@ -1,3 +1,20 @@
+2018-05-17  Brent Fulgham  <bfulg...@apple.com>
+
+        Storage Access API: Allow documents that have been granted storage access to also do a popup
+        https://bugs.webkit.org/show_bug.cgi?id=185615
+        <rdar://problem/39105791>
+
+        Reviewed by Chris Dumez.
+
+        * dom/Document.cpp:
+        (WebCore::Document::consumeTemporaryUserGesture): Added. Clear the document's active one-time user
+        activity (for window opening) state.
+        (WebCore::Document::enableTemporaryUserGesture): Added. Establish a new active one-time user
+        activity (for window opening) state.
+        (WebCore::Document::requestStorageAccess): If the user approves Storage Access, establish a new
+        UserInteraction scope, then resolve the promise. Also post a task to clear the one-time user
+        gesture state.
+
 2018-05-17  Zalan Bujtas  <za...@apple.com>
 
         [LFC] Introduce DisplayBox::Style

Modified: trunk/Source/WebCore/dom/Document.cpp (231909 => 231910)


--- trunk/Source/WebCore/dom/Document.cpp	2018-05-17 17:54:57 UTC (rev 231909)
+++ trunk/Source/WebCore/dom/Document.cpp	2018-05-17 18:16:56 UTC (rev 231910)
@@ -122,6 +122,7 @@
 #include "MediaQueryList.h"
 #include "MediaQueryMatcher.h"
 #include "MessageEvent.h"
+#include "Microtasks.h"
 #include "MouseEventWithHitTestResults.h"
 #include "MutationEvent.h"
 #include "NameNodeList.h"
@@ -7609,7 +7610,7 @@
         return;
     }
 
-    page->chrome().client().requestStorageAccess(WTFMove(iframeHost), WTFMove(topHost), frameID.value(), pageID.value(), [documentReference = m_weakFactory.createWeakPtr(*this), promise = WTFMove(promise)] (bool wasGranted) {
+    page->chrome().client().requestStorageAccess(WTFMove(iframeHost), WTFMove(topHost), frameID.value(), pageID.value(), [documentReference = m_weakFactory.createWeakPtr(*this), promise = WTFMove(promise)] (bool wasGranted) mutable {
         Document* document = documentReference.get();
         if (!document)
             return;
@@ -7616,7 +7617,15 @@
         
         if (wasGranted) {
             document->setHasFrameSpecificStorageAccess(true);
+            MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrotask>([documentReference = document->m_weakFactory.createWeakPtr(*document)] () {
+                if (auto* document = documentReference.get())
+                    document->enableTemporaryTimeUserGesture();
+            }));
             promise->resolve();
+            MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrotask>([documentReference = WTFMove(documentReference)] () {
+                if (auto* document = documentReference.get())
+                    document->consumeTemporaryTimeUserGesture();
+            }));
         } else
             promise->reject();
     });
@@ -7625,6 +7634,16 @@
 #endif
 }
 
+void Document::enableTemporaryTimeUserGesture()
+{
+    m_temporaryUserGesture = std::make_unique<UserGestureIndicator>(ProcessingUserGesture, this);
+}
+
+void Document::consumeTemporaryTimeUserGesture()
+{
+    m_temporaryUserGesture = nullptr;
+}
+
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 bool Document::hasFrameSpecificStorageAccess() const
 {

Modified: trunk/Source/WebCore/dom/Document.h (231909 => 231910)


--- trunk/Source/WebCore/dom/Document.h	2018-05-17 17:54:57 UTC (rev 231909)
+++ trunk/Source/WebCore/dom/Document.h	2018-05-17 18:16:56 UTC (rev 231910)
@@ -1429,6 +1429,8 @@
 
     String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL&);
 
+    void consumeTemporaryTimeUserGesture();
+
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
@@ -1542,6 +1544,8 @@
 
     bool domainIsRegisterable(const String&) const;
 
+    void enableTemporaryTimeUserGesture();
+
     const Ref<Settings> m_settings;
 
     std::unique_ptr<StyleResolver> m_userAgentShadowTreeStyleResolver;
@@ -1919,6 +1923,8 @@
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     String m_primaryDomainRequestedPageSpecificStorageAccessWithUserInteraction { };
 #endif
+    
+    std::unique_ptr<UserGestureIndicator> m_temporaryUserGesture;
 };
 
 Element* eventTargetElementForDocument(Document*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to