WebKit Bugzilla
Attachment 340469 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-20180515222655.patch (text/plain), 18.69 KB, created by
Brent Fulgham
on 2018-05-15 22:26:56 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Brent Fulgham
Created:
2018-05-15 22:26:56 PDT
Size:
18.69 KB
patch
obsolete
>Subversion Revision: 231727 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index efb1d0346ebcbc57e71ad9ff5d0299431c0794f4..edcfbdb1aaba0ecad9e1ca6680b1c7079ace0344 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,30 @@ >+2018-05-14 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-11 Daniel Bates <dabates@apple.com> > > [iOS] Text decoration of dragged content does not paint with opacity >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index 95a3033408177ab8d2f4b3bd9bd5b7cac39aa12a..7fcb6ef186f53cb50cc4b025205b41093d761a6d 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -7613,14 +7613,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(); > }); >@@ -7629,6 +7635,16 @@ void Document::requestStorageAccess(Ref<DeferredPromise>&& promise) > #endif > } > >+void Document::enableOneTimeUserGesture() >+{ >+ m_oneTimeUserGesture = std::make_unique<UserGestureIndicator>(ProcessingOneTimeUserGesture, 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 b9eff10963e4b428e0ed238c93c5babc541b9a58..06dfc4ff7ca6e0e14a7471c99501d6a899f98470 100644 >--- a/Source/WebCore/dom/Document.h >+++ b/Source/WebCore/dom/Document.h >@@ -1430,6 +1430,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); >@@ -1543,6 +1545,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/dom/UserGestureIndicator.cpp b/Source/WebCore/dom/UserGestureIndicator.cpp >index 23c936f91b139a4e17ccd22b5cdf7d97815c9217..0bf291c73b00974add5490d2853a2b357336547c 100644 >--- a/Source/WebCore/dom/UserGestureIndicator.cpp >+++ b/Source/WebCore/dom/UserGestureIndicator.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2010 Apple Inc. All rights reserved. >+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -107,4 +107,12 @@ bool UserGestureIndicator::processingUserGestureForMedia() > return currentToken() ? currentToken()->processingUserGestureForMedia() : false; > } > >+bool UserGestureIndicator::processingUserGestureForPopup() >+{ >+ if (!isMainThread()) >+ return false; >+ >+ return currentToken() ? currentToken()->processingUserGestureForPopup() : false; >+} >+ > } >diff --git a/Source/WebCore/dom/UserGestureIndicator.h b/Source/WebCore/dom/UserGestureIndicator.h >index cf8e393b863f7e4993cd20a23f9ae8552539e7ca..c2871c3de91981b1eecda0051ff12910e5559301 100644 >--- a/Source/WebCore/dom/UserGestureIndicator.h >+++ b/Source/WebCore/dom/UserGestureIndicator.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2010-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -39,6 +39,7 @@ class Document; > enum ProcessingUserGestureState { > ProcessingUserGesture, > ProcessingPotentialUserGesture, >+ ProcessingOneTimeUserGesture, > NotProcessingUserGesture > }; > >@@ -56,6 +57,7 @@ public: > ProcessingUserGestureState state() const { return m_state; } > bool processingUserGesture() const { return m_state == ProcessingUserGesture; } > bool processingUserGestureForMedia() const { return m_state == ProcessingUserGesture || m_state == ProcessingPotentialUserGesture; } >+ bool processingUserGestureForPopup() const { return m_state == ProcessingUserGesture || m_state == ProcessingPotentialUserGesture || m_state == ProcessingOneTimeUserGesture; } > UserGestureType gestureType() const { return m_gestureType; } > > void addDestructionObserver(WTF::Function<void (UserGestureToken&)>&& observer) >@@ -82,6 +84,7 @@ public: > > WEBCORE_EXPORT static bool processingUserGesture(); > WEBCORE_EXPORT static bool processingUserGestureForMedia(); >+ WEBCORE_EXPORT static bool processingUserGestureForPopup(); > > // If a document is provided, its last known user gesture timestamp is updated. > enum class ProcessInteractionStyle { Immediate, Delayed }; >diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp >index ffb07b8232278c340ae23b617b5f2435513d1cbf..05ea959e90c0f6e3de332be8f19361c9929e998d 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 >@@ -369,7 +369,7 @@ bool DOMWindow::allowPopUp(Frame& firstFrame) > return false; > } > >- return UserGestureIndicator::processingUserGesture() >+ return UserGestureIndicator::processingUserGestureForPopup() > || firstFrame.settings().javaScriptCanOpenWindowsAutomatically(); > } > >@@ -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 749bac8317659afcc4fc39fae2716d27ead3e629..ba4900cb2425e63c899e00a1cda286236f3f00df 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,16 @@ >+2018-05-15 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-11 Nan Wang <n_wang@apple.com> > > AX: In role=dialog elements with aria-modal=true VoiceOver iOS/macOS can't manually focus or read dialog paragraph description text inside the modal. >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