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 <[email protected]>
+
+ 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 <[email protected]>
[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 <[email protected]>
+
+ 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 <[email protected]>
[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*);