WebKit Bugzilla
Attachment 340518 Details for
Bug 185615
: Storage Access API: Allow documents that have been granted storage access to also do a popup
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185615-20180516131140.patch (text/plain), 15.60 KB, created by
Brent Fulgham
on 2018-05-16 13:11:41 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Brent Fulgham
Created:
2018-05-16 13:11:41 PDT
Size:
15.60 KB
patch
obsolete
>Subversion Revision: 231849 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 1adef6425cb6f8bf058ae5f9b2d00a707cd1ca8a..50d19b2a995dc8dfa21045690a505aba8516db09 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,30 @@ >+2018-05-16 Brent Fulgham <bfulgham@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 NOBODY (OOPS!). >+ >+ * dom/Document.cpp: >+ (WebCore::Document::consumeOneTimeUserGesture): Added. Clear the document's active one-time user >+ activity (for window opening) state. >+ (WebCore::Document::enableOneTimeUserGesture): 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. >+ * dom/UserGestureIndicator.cpp: >+ (WebCore::UserGestureIndicator::processingUserGestureForPopup): Added. >+ having consumed its one-time access. >+ * dom/UserGestureIndicator.h: >+ (WebCore::UserGestureToken::processingUserGestureForPopup const): Added. >+ (WebCore::UserGestureIndicator::processingUserGestureForPopup): Added. >+ * page/DOMWindow.cpp: >+ (WebCore::DOMWindow::allowPopUp): Use the new processingUserGestureForPopup predicate. >+ (WebCore::DOMWindow::open): Mark the one-time user interaction gesture as consumed (if appropriate) before >+ returning the newly-opened window. >+ > 2018-05-16 Chris Nardi <cnardi@chromium.org> > > Remove Document#selectedStylesheetSet/preferredStylesheetSet >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index ce96ae1d3eeb0827f052549f29d29e3d0d7536f9..38e77e0df2624a9c9d8695737cd1c242f76bab30 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -7609,14 +7609,20 @@ void Document::requestStorageAccess(Ref<DeferredPromise>&& promise) > 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; > > if (wasGranted) { > document->setHasFrameSpecificStorageAccess(true); >+ document->enableOneTimeUserGesture(); > promise->resolve(); >+ >+ document->postTask([documentReference = WTFMove(documentReference)] (auto&) { >+ if (auto* document = documentReference.get()) >+ document->consumeOneTimeUserGesture(); >+ }); > } else > promise->reject(); > }); >@@ -7625,6 +7631,16 @@ void Document::requestStorageAccess(Ref<DeferredPromise>&& promise) > #endif > } > >+void Document::enableOneTimeUserGesture() >+{ >+ m_oneTimeUserGesture = std::make_unique<UserGestureIndicator>(ProcessingUserGesture, this); >+} >+ >+void Document::consumeOneTimeUserGesture() >+{ >+ m_oneTimeUserGesture = nullptr; >+} >+ > #if HAVE(CFNETWORK_STORAGE_PARTITIONING) > bool Document::hasFrameSpecificStorageAccess() const > { >diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h >index 8e8cab95a7fa5ea112224145c4f48d06937fad62..17c0d832ff054c7a52f82740551ef0ad037b22a6 100644 >--- a/Source/WebCore/dom/Document.h >+++ b/Source/WebCore/dom/Document.h >@@ -1429,6 +1429,8 @@ public: > > String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL&); > >+ WEBCORE_EXPORT void consumeOneTimeUserGesture(); >+ > protected: > enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 }; > Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0); >@@ -1542,6 +1544,8 @@ private: > > bool domainIsRegisterable(const String&) const; > >+ void enableOneTimeUserGesture(); >+ > const Ref<Settings> m_settings; > > std::unique_ptr<StyleResolver> m_userAgentShadowTreeStyleResolver; >@@ -1919,6 +1923,8 @@ private: > #if HAVE(CFNETWORK_STORAGE_PARTITIONING) > String m_primaryDomainRequestedPageSpecificStorageAccessWithUserInteraction { }; > #endif >+ >+ std::unique_ptr<UserGestureIndicator> m_oneTimeUserGesture; > }; > > Element* eventTargetElementForDocument(Document*); >diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp >index ffb07b8232278c340ae23b617b5f2435513d1cbf..a850575ba0c54b1919eaa2c10cf7427e8836fd2e 100644 >--- a/Source/WebCore/page/DOMWindow.cpp >+++ b/Source/WebCore/page/DOMWindow.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2006-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2006-2018 Apple Inc. All rights reserved. > * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) > * > * Redistribution and use in source and binary forms, with or without >@@ -2380,8 +2380,13 @@ RefPtr<WindowProxy> DOMWindow::open(DOMWindow& activeWindow, DOMWindow& firstWin > return &targetFrame->windowProxy(); > } > >- auto newFrame = createWindow(urlString, frameName, parseWindowFeatures(windowFeaturesString), activeWindow, *firstFrame, *m_frame); >- return newFrame ? &newFrame->windowProxy() : nullptr; >+ if (auto newFrame = createWindow(urlString, frameName, parseWindowFeatures(windowFeaturesString), activeWindow, *firstFrame, *m_frame)) { >+ ASSERT(document()); >+ document()->consumeOneTimeUserGesture(); >+ return &newFrame->windowProxy(); >+ } >+ >+ return nullptr; > } > > void DOMWindow::showModalDialog(const String& urlString, const String& dialogFeaturesString, DOMWindow& activeWindow, DOMWindow& firstWindow, const WTF::Function<void (DOMWindow&)>& prepareDialogFunction) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index a6c15b8b7a27d001780540b48b336fbca6010b0c..37dd7c40d20894286eeb79cc8e055087a2aa83dc 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,16 @@ >+2018-05-16 Brent Fulgham <bfulgham@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 NOBODY (OOPS!). >+ >+ * 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-16 Chris Nardi <cnardi@chromium.org> > > Remove Document#selectedStylesheetSet/preferredStylesheetSet >diff --git a/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt b/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d7ec4cf7f7841d57c68ddb5fa66cb5634b31da3b >--- /dev/null >+++ b/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window-expected.txt >@@ -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 >+ >diff --git a/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html b/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d1e18138c5f2bd95c25bba2402ebcd80c66fda43 >--- /dev/null >+++ b/LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-pop-window.html >@@ -0,0 +1,83 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <script src="/js-test-resources/js-test.js"></script> >+ <script src="/js-test-resources/ui-helper.js"></script> >+ <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="http://localhost:8000/storageAccess/resources/request-storage-access-iframe-and-pop-window.html#userShouldGrantAccess,userShouldBeConsulted,policyShouldGrantAccess,isNotSameOriginIframe"></iframe> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html b/LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html >new file mode 100644 >index 0000000000000000000000000000000000000000..236478b92d126b51bcb33710bbf5318d6ffbe68e >--- /dev/null >+++ b/LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe-and-pop-window.html >@@ -0,0 +1,64 @@ >+<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("http://localhost:8000/storageAccess/resources/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 >diff --git a/LayoutTests/http/tests/storageAccess/resources/request-storage-access-second-window.html b/LayoutTests/http/tests/storageAccess/resources/request-storage-access-second-window.html >new file mode 100644 >index 0000000000000000000000000000000000000000..adcc57623419e107bafdcea3f5fbc4e799c9d6f2 >--- /dev/null >+++ b/LayoutTests/http/tests/storageAccess/resources/request-storage-access-second-window.html >@@ -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>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185615
:
340346
|
340353
|
340462
|
340469
|
340518
|
340536
|
340596