WebKit Bugzilla
Attachment 361837 Details for
Bug 194271
: Allow pages to trigger programmatic paste from script on iOS
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Part 1 (for landing)
bug-194271-20190212135942.patch (text/plain), 49.90 KB, created by
Wenson Hsieh
on 2019-02-12 13:59:42 PST
(
hide
)
Description:
Part 1 (for landing)
Filename:
MIME Type:
Creator:
Wenson Hsieh
Created:
2019-02-12 13:59:42 PST
Size:
49.90 KB
patch
obsolete
>Subversion Revision: 241315 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 1befc7c8b13f33cd6493854daca4d32dfa9408dd..1586f5552dd4fb3fda2e82e2bdfc542ffea619d8 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,59 @@ >+2019-02-12 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ Allow pages to trigger programmatic paste from script on iOS >+ https://bugs.webkit.org/show_bug.cgi?id=194271 >+ <rdar://problem/47808810> >+ >+ Reviewed by Ryosuke Niwa. >+ >+ Add support for allowing script to trigger programmatic paste commands. Currently on macOS and iOS, the ability >+ to trigger programmatic paste (i.e. `document.execCommand('Paste');`) is disabled by default, such that >+ execCommand is simply a no-op that returns false. This policy is a privacy measure (common among other major >+ browsers) that prevents untrusted web content from sniffing content from the system pasteboard (even on user >+ interaction, since unintended user interaction occasionally happens as well!). >+ >+ In order to make it possible for web pages to programmatically paste without opening the door to privacy and >+ security issues, we make paste commands triggered from bindings present platform UI on iOS, in the form of a >+ callout bar with the single option to paste. This UI is dismissed upon any user interaction; furthermore, any >+ user interaction short of explicitly triggering the "Paste" action subsequently prevents the page from executing >+ the paste (and causes execCommand to return false). However, if the paste action is chosen by the user, we >+ instead follow through with the programmatic paste command. >+ >+ New tests to come in a followup patch. >+ >+ * WebCore.xcodeproj/project.pbxproj: >+ * dom/DOMPasteAccessPolicy.h: Added. >+ * dom/UserGestureIndicator.h: >+ (WebCore::UserGestureToken::domPasteAccessPolicy const): >+ (WebCore::UserGestureToken::didRequestDOMPasteAccess): >+ >+ Add helpers on UserGestureToken to update and query the current DOM paste access policy. The access policies are >+ "NotRequestedYet" (i.e. pending a response from the user), "Granted" (the user has granted DOM paste access to >+ the page), or "Denied" (the user has prevented the page from reading the contents of the clipboard). When DOM >+ paste access is granted or rejected, make this decision sticky until the end of the current user gesture. >+ >+ * editing/EditorCommand.cpp: >+ (WebCore::executePaste): >+ (WebCore::executePasteAndMatchStyle): >+ (WebCore::executePasteAsPlainText): >+ (WebCore::executePasteAsQuotation): >+ >+ When executing a paste command where the source is DOM bindings, request DOM paste if needed before proceeding >+ with the paste. >+ >+ (WebCore::supportedPaste): >+ * loader/EmptyClients.cpp: >+ * page/EditorClient.h: >+ * page/Frame.cpp: >+ (WebCore::Frame::requestDOMPasteAccess): >+ >+ Add a helper method that requests access to the clipboard on behalf of script when pasting. >+ >+ * page/Frame.h: >+ * page/Settings.yaml: >+ >+ Introduce a new WebCore setting, used to gate DOM paste access requests. >+ > 2019-02-12 Justin Fan <justin_fan@apple.com> > > [Web GPU] DepthStencilAttachment implementation >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index a4f86254d1b6995ed8196842b65943862172916e..acd0e85573e141b1ec4cc9d24ba6f89087ced835 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,129 @@ >+2019-02-12 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ Allow pages to trigger programmatic paste from script on iOS >+ https://bugs.webkit.org/show_bug.cgi?id=194271 >+ <rdar://problem/47808810> >+ >+ Reviewed by Ryosuke Niwa. >+ >+ * Shared/WebPreferences.yaml: >+ * Shared/WebPreferencesDefaultValues.h: >+ >+ Add an internal setting to enable or disable DOM paste access requests. This is on by default in iOS only >+ (excluding watchOS and Apple TV), and is additionally disabled on macOS. >+ >+ * UIProcess/API/gtk/PageClientImpl.cpp: >+ (WebKit::PageClientImpl::requestDOMPasteAccess): >+ * UIProcess/API/gtk/PageClientImpl.h: >+ * UIProcess/API/wpe/PageClientImpl.cpp: >+ (WebKit::PageClientImpl::requestDOMPasteAccess): >+ >+ Plumb DOM paste access requests from the web process (WebEditorClient) to the view (WKContentView). As per the >+ usual, this involves WebEditorClient, WebPage, WebPageProxy, PageClient and finally WKContentView. >+ >+ * UIProcess/API/wpe/PageClientImpl.h: >+ * UIProcess/PageClient.h: >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::WebPageProxy::requestDOMPasteAccess): >+ * UIProcess/WebPageProxy.h: >+ * UIProcess/WebPageProxy.messages.in: >+ * UIProcess/ios/PageClientImplIOS.h: >+ * UIProcess/ios/PageClientImplIOS.mm: >+ (WebKit::PageClientImpl::requestDOMPasteAccess): >+ * UIProcess/ios/WKContentViewInteraction.h: >+ * UIProcess/ios/WKContentViewInteraction.mm: >+ (-[WKContentView setupInteraction]): >+ (-[WKContentView cleanupInteraction]): >+ (-[WKContentView resignFirstResponderForWebView]): >+ (-[WKContentView _webTouchEventsRecognized:]): >+ >+ Bail from any pending DOM paste access handler the moment we start handling touches on the web view, or if the >+ web view resigns first responder, or if the web process crashes. >+ >+ (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]): >+ >+ Reject text selection gestures while waiting for DOM paste access. >+ >+ (-[WKContentView canPerformAction:withSender:]): >+ (-[WKContentView canPerformActionForWebView:withSender:]): >+ >+ If we're handling a DOM paste, always return YES to allow the callout bar to show the "Paste" option. >+ >+ (-[WKContentView _didHideMenu:]): >+ >+ If the menu is programmatically hidden by the app while handling a DOM paste request, immediately reject the DOM >+ paste request. >+ >+ (-[WKContentView pasteForWebView:]): >+ >+ Adjust -pasteForWebView: on WKContentView to first check whether there's an outstanding DOM paste completion >+ handler to invoke, instead of telling the page to execute a paste command. >+ >+ (-[WKContentView _handleDOMPasteRequestWithResult:]): >+ >+ Add a helper to take and invoke the current DOM paste completion handler (if it exists) with the given result, >+ and then dismiss the shared callout bar. Returns whether or not the paste completion handler exists. Invoked >+ from various sources of user interaction or significant state changes (e.g. following a web process crash in >+ -cleanupInteraction). >+ >+ (-[WKContentView _willPerformAction:sender:]): >+ (-[WKContentView _didPerformAction:sender:]): >+ >+ Add hooks to detect when WKContentView is executing an editing action. This is to ensure that the page doesn't >+ get stuck in a bad state in the case where WKWebView has been subclassed, overrides `-paste:`, and does not >+ invoke the superclass method (which calls back into `-[WKContentView pasteForWebView:]`). There are a few >+ possibilities here: >+ 1. WKWebView's `-paste:` action is not overridden. In this case, we will call back into `-pasteForWebView:`, >+ which will notice that we have a pending paste completion handler and invoke it. >+ 2. WKWebView's `-paste:` action is overridden and does not call back into the content view. In this case, we >+ will invoke the paste completion handler in `-_didPerformAction:sender:`. >+ 3. WKWebView's `-canPerformAction:withSender:` is overridden to include additional actions. In this case, we may >+ get a call to invoke a different action selector while waiting for a potential paste action. If this happens, >+ prevent the DOM paste in `-_willPerformAction:sender:` prior to handling the other action. >+ >+ (-[WKContentView handleKeyWebEvent:withCompletionHandler:]): >+ >+ Dismiss DOM paste UI upon handling any key event. >+ >+ (-[WKContentView showGlobalMenuControllerInRect:]): >+ (-[WKContentView hideGlobalMenuController]): >+ >+ Helper methods to present and dismiss the global UIMenuController, that accounts for available platform APIs for >+ presenting or dismissing the menu controller on iOS. >+ >+ (-[WKContentView _requestDOMPasteAccessWithElementRect:completionHandler:]): >+ >+ Attempt to find a good target presentation rect when showing the callout menu. First, we will try to use the >+ rect of the element the user has interacted with when triggering the paste. If such an element is too large or >+ does not exist, we fall back to presenting the callout menu near the user's last touch location (with a small >+ amount of margin, such that the action doesn't overlap with the user's finger, stylus, etc.). >+ >+ (-[WKContentView _resetShowingTextStyle:]): Deleted. >+ >+ Rename this to `-_didHideMenu:`. >+ >+ * UIProcess/mac/PageClientImplMac.h: >+ * UIProcess/win/PageClientImpl.cpp: >+ (WebKit::PageClientImpl::requestDOMPasteAccess): >+ * UIProcess/win/PageClientImpl.h: >+ * WebProcess/WebCoreSupport/WebEditorClient.cpp: >+ (WebKit::WebEditorClient::requestDOMPasteAccess): >+ * WebProcess/WebCoreSupport/WebEditorClient.h: >+ * WebProcess/WebPage/WebPage.cpp: >+ (WebKit::WebPage::requestDOMPasteAccess): >+ >+ Add more plumbing and method stubs. >+ >+ (WebKit::WebPage::updateCurrentModifierState): >+ (WebKit::WebPage::rectForElementAtInteractionLocation const): >+ * WebProcess/WebPage/WebPage.h: >+ * WebProcess/WebPage/ios/WebPageIOS.mm: >+ (WebKit::WebPage::rectForElementAtInteractionLocation const): >+ (WebKit::WebPage::rectForElementAtInteractionLocation): Deleted. >+ >+ Mark this method as const, add a platform-agnostic stub, and adopt it for the purposes of determining where to >+ position the callout bar when pasting. >+ > 2019-02-12 Tim Horton <timothy_horton@apple.com> > > Switching focus from a UITextField to an editable WKWebView causes the keyboard to dance >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index b91e9460a02cb183e68ed524ee691e3f4b81b8f6..a0f8691eb377d1450cfc8127704875f347ceafb6 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,15 @@ >+2019-02-12 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ Allow pages to trigger programmatic paste from script on iOS >+ https://bugs.webkit.org/show_bug.cgi?id=194271 >+ <rdar://problem/47808810> >+ >+ Reviewed by Ryosuke Niwa. >+ >+ See WebCore and WebKit ChangeLogs for more details. >+ >+ * WebCoreSupport/WebEditorClient.h: >+ > 2019-02-12 Andy Estes <aestes@apple.com> > > [iOSMac] Enable Parental Controls Content Filtering >diff --git a/Source/WebKitLegacy/win/ChangeLog b/Source/WebKitLegacy/win/ChangeLog >index e90cf1ac20f5f5080875b617bc64b8d4bda63d01..cc72d9b3e40e43add4f12d9e590a38408c623b56 100644 >--- a/Source/WebKitLegacy/win/ChangeLog >+++ b/Source/WebKitLegacy/win/ChangeLog >@@ -1,3 +1,13 @@ >+2019-02-12 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ Allow pages to trigger programmatic paste from script on iOS >+ https://bugs.webkit.org/show_bug.cgi?id=194271 >+ <rdar://problem/47808810> >+ >+ Reviewed by Ryosuke Niwa. >+ >+ * WebCoreSupport/WebEditorClient.h: >+ > 2019-02-06 Daniel Bates <dabates@apple.com> > > Standardize on ControlKey instead of CtrlKey >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 9162abc6eed41232ac184c16ff5dc09a6d7b265e..571fc37e705f9e60f66c1a6f30bb82514295c9f5 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -4952,6 +4952,7 @@ > F48D2A7E2157182600C6752B /* FontAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2A712156DC0A00C6752B /* FontAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F48D2AA52159740D00C6752B /* ColorCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = F48D2AA32159740D00C6752B /* ColorCocoa.h */; }; > F49786881FF45FA500E060AB /* PasteboardItemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F49786871FF45FA500E060AB /* PasteboardItemInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ F4B422C4220C0568009E1E7D /* DOMPasteAccessPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = F4B422C2220C0000009E1E7D /* DOMPasteAccessPolicy.h */; settings = {ATTRIBUTES = (Private, ); }; }; > F4BFB9851E1DDF9B00862C24 /* DumpEditingHistory.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */; }; > F4BFB9861E1DDF9B00862C24 /* EditingHistoryUtil.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389841E1DDF2B0076B7EA /* EditingHistoryUtil.js */; }; > F4D43D662188038B00ECECAC /* SerializedAttachmentData.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D43D64218802E600ECECAC /* SerializedAttachmentData.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -15186,6 +15187,7 @@ > F48D2AA42159740D00C6752B /* ColorCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ColorCocoa.mm; sourceTree = "<group>"; }; > F49786871FF45FA500E060AB /* PasteboardItemInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PasteboardItemInfo.h; sourceTree = "<group>"; }; > F49E98E421DEE6C1009AE55E /* EditAction.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EditAction.cpp; sourceTree = "<group>"; }; >+ F4B422C2220C0000009E1E7D /* DOMPasteAccessPolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DOMPasteAccessPolicy.h; sourceTree = "<group>"; }; > F4D43D64218802E600ECECAC /* SerializedAttachmentData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SerializedAttachmentData.h; sourceTree = "<group>"; }; > F4D9817D2195FBF6008230FC /* ChangeListTypeCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChangeListTypeCommand.h; sourceTree = "<group>"; }; > F4D9817E2195FBF6008230FC /* ChangeListTypeCommand.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ChangeListTypeCommand.cpp; sourceTree = "<group>"; }; >@@ -27515,6 +27517,7 @@ > A8185F3609765765005826D9 /* DOMImplementation.cpp */, > A8185F3309765765005826D9 /* DOMImplementation.h */, > 93EEC1E909C2877700C515D1 /* DOMImplementation.idl */, >+ F4B422C2220C0000009E1E7D /* DOMPasteAccessPolicy.h */, > 0F4966991DB408C100A274BB /* DOMPoint.h */, > 0F49669A1DB408C100A274BB /* DOMPoint.idl */, > 0F4966A21DB4091000A274BB /* DOMPointInit.h */, >@@ -29089,6 +29092,7 @@ > A9C6E4E40D745E05006442E9 /* DOMMimeType.h in Headers */, > A9C6E4E80D745E18006442E9 /* DOMMimeTypeArray.h in Headers */, > 1ACE53E80A8D18E70022947D /* DOMParser.h in Headers */, >+ F4B422C4220C0568009E1E7D /* DOMPasteAccessPolicy.h in Headers */, > 7A54881714E432A1006AE05A /* DOMPatchSupport.h in Headers */, > A9C6E4EC0D745E2B006442E9 /* DOMPlugin.h in Headers */, > A9C6E4F00D745E38006442E9 /* DOMPluginArray.h in Headers */, >diff --git a/Source/WebCore/dom/DOMPasteAccessPolicy.h b/Source/WebCore/dom/DOMPasteAccessPolicy.h >new file mode 100644 >index 0000000000000000000000000000000000000000..80018b921ca27dd76c2ca9293cb00432bb582463 >--- /dev/null >+++ b/Source/WebCore/dom/DOMPasteAccessPolicy.h >@@ -0,0 +1,36 @@ >+/* >+ * Copyright (C) 2019 Apple 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: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. 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. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. >+ */ >+ >+#pragma once >+ >+namespace WebCore { >+ >+enum class DOMPasteAccessPolicy : uint8_t { >+ NotRequestedYet, >+ Denied, >+ Granted >+}; >+ >+} >diff --git a/Source/WebCore/dom/UserGestureIndicator.h b/Source/WebCore/dom/UserGestureIndicator.h >index c18cdc0c6cedc1b8281a7b0d742105065381f4fc..3e5ea4306325a245b76de5236ce56604de9df6e6 100644 >--- a/Source/WebCore/dom/UserGestureIndicator.h >+++ b/Source/WebCore/dom/UserGestureIndicator.h >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "DOMPasteAccessPolicy.h" > #include <wtf/Function.h> > #include <wtf/Noncopyable.h> > #include <wtf/Optional.h> >@@ -63,6 +64,9 @@ public: > m_destructionObservers.append(WTFMove(observer)); > } > >+ DOMPasteAccessPolicy domPasteAccessPolicy() const { return m_domPasteAccessPolicy; } >+ void didRequestDOMPasteAccess(bool granted) { m_domPasteAccessPolicy = granted ? DOMPasteAccessPolicy::Granted : DOMPasteAccessPolicy::Denied; } >+ > private: > UserGestureToken(ProcessingUserGestureState state, UserGestureType gestureType) > : m_state(state) >@@ -73,6 +77,7 @@ private: > ProcessingUserGestureState m_state = NotProcessingUserGesture; > Vector<WTF::Function<void (UserGestureToken&)>> m_destructionObservers; > UserGestureType m_gestureType; >+ DOMPasteAccessPolicy m_domPasteAccessPolicy { DOMPasteAccessPolicy::NotRequestedYet }; > }; > > class UserGestureIndicator { >diff --git a/Source/WebCore/editing/EditorCommand.cpp b/Source/WebCore/editing/EditorCommand.cpp >index 0b3bbb9be69569eb82cf054dc24c715e7e4ad438..9494709dc6f159c08172b6bfcb22873165d46525 100644 >--- a/Source/WebCore/editing/EditorCommand.cpp >+++ b/Source/WebCore/editing/EditorCommand.cpp >@@ -908,8 +908,13 @@ static bool executePaste(Frame& frame, Event*, EditorCommandSource source, const > if (source == CommandFromMenuOrKeyBinding) { > UserTypingGestureIndicator typingGestureIndicator(frame); > frame.editor().paste(); >- } else >- frame.editor().paste(); >+ return true; >+ } >+ >+ if (!frame.requestDOMPasteAccess()) >+ return false; >+ >+ frame.editor().paste(); > return true; > } > >@@ -934,8 +939,13 @@ static bool executePasteAndMatchStyle(Frame& frame, Event*, EditorCommandSource > if (source == CommandFromMenuOrKeyBinding) { > UserTypingGestureIndicator typingGestureIndicator(frame); > frame.editor().pasteAsPlainText(); >- } else >- frame.editor().pasteAsPlainText(); >+ return true; >+ } >+ >+ if (!frame.requestDOMPasteAccess()) >+ return false; >+ >+ frame.editor().pasteAsPlainText(); > return true; > } > >@@ -944,8 +954,13 @@ static bool executePasteAsPlainText(Frame& frame, Event*, EditorCommandSource so > if (source == CommandFromMenuOrKeyBinding) { > UserTypingGestureIndicator typingGestureIndicator(frame); > frame.editor().pasteAsPlainText(); >- } else >- frame.editor().pasteAsPlainText(); >+ return true; >+ } >+ >+ if (!frame.requestDOMPasteAccess()) >+ return false; >+ >+ frame.editor().pasteAsPlainText(); > return true; > } > >@@ -954,8 +969,13 @@ static bool executePasteAsQuotation(Frame& frame, Event*, EditorCommandSource so > if (source == CommandFromMenuOrKeyBinding) { > UserTypingGestureIndicator typingGestureIndicator(frame); > frame.editor().pasteAsQuotation(); >- } else >- frame.editor().pasteAsQuotation(); >+ return true; >+ } >+ >+ if (!frame.requestDOMPasteAccess()) >+ return false; >+ >+ frame.editor().pasteAsQuotation(); > return true; > } > >@@ -1220,7 +1240,8 @@ static bool supportedPaste(Frame* frame) > if (!frame) > return false; > >- bool defaultValue = frame->settings().javaScriptCanAccessClipboard() && frame->settings().DOMPasteAllowed(); >+ auto& settings = frame->settings(); >+ bool defaultValue = (settings.javaScriptCanAccessClipboard() && settings.DOMPasteAllowed()) || settings.domPasteAccessRequestsEnabled(); > > EditorClient* client = frame->editor().client(); > return client ? client->canPaste(frame, defaultValue) : defaultValue; >diff --git a/Source/WebCore/loader/EmptyClients.cpp b/Source/WebCore/loader/EmptyClients.cpp >index fb02baf6755590846fc0279a333aca3c1fd07093..6c2dbdf67211a0b8b15283bf0b74cb863b0a6d2c 100644 >--- a/Source/WebCore/loader/EmptyClients.cpp >+++ b/Source/WebCore/loader/EmptyClients.cpp >@@ -190,6 +190,8 @@ private: > void registerRedoStep(UndoStep&) final; > void clearUndoRedoOperations() final { } > >+ bool requestDOMPasteAccess() final { return false; } >+ > bool canCopyCut(Frame*, bool defaultValue) const final { return defaultValue; } > bool canPaste(Frame*, bool defaultValue) const final { return defaultValue; } > bool canUndo() const final { return false; } >diff --git a/Source/WebCore/page/EditorClient.h b/Source/WebCore/page/EditorClient.h >index 37bf1823a98c2d9e52f3d02cbf5bcffaee358c44..6e0d0bee67a4d4590423b17e92e201847ab84a5c 100644 >--- a/Source/WebCore/page/EditorClient.h >+++ b/Source/WebCore/page/EditorClient.h >@@ -98,6 +98,8 @@ public: > virtual void requestCandidatesForSelection(const VisibleSelection&) { } > virtual void handleAcceptedCandidateWithSoftSpaces(TextCheckingResult) { } > >+ virtual bool requestDOMPasteAccess() = 0; >+ > // Notify an input method that a composition was voluntarily discarded by WebCore, so that it could clean up too. > // This function is not called when a composition is closed per a request from an input method. > virtual void discardedComposition(Frame*) = 0; >diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp >index a4f83b27f0b6ecaf653321d6a554457ece669daa..b51e44442563962bedf3d7b7da9c6ebaeae71438 100644 >--- a/Source/WebCore/page/Frame.cpp >+++ b/Source/WebCore/page/Frame.cpp >@@ -95,6 +95,7 @@ > #include "TextResourceDecoder.h" > #include "UserContentController.h" > #include "UserContentURLPattern.h" >+#include "UserGestureIndicator.h" > #include "UserScript.h" > #include "UserTypingGestureIndicator.h" > #include "VisibleUnits.h" >@@ -658,6 +659,35 @@ bool Frame::selectionChangeCallbacksDisabled() const > } > #endif // PLATFORM(IOS_FAMILY) > >+bool Frame::requestDOMPasteAccess() >+{ >+ if (m_settings->javaScriptCanAccessClipboard() && m_settings->DOMPasteAllowed()) >+ return true; >+ >+ if (!m_settings->domPasteAccessRequestsEnabled() || !m_doc) >+ return false; >+ >+ auto gestureToken = UserGestureIndicator::currentUserGesture(); >+ if (!gestureToken || !gestureToken->processingUserGesture()) >+ return false; >+ >+ switch (gestureToken->domPasteAccessPolicy()) { >+ case DOMPasteAccessPolicy::Granted: >+ return true; >+ case DOMPasteAccessPolicy::Denied: >+ return false; >+ case DOMPasteAccessPolicy::NotRequestedYet: { >+ auto* client = m_editor->client(); >+ if (!client) >+ return false; >+ >+ bool granted = client->requestDOMPasteAccess(); >+ gestureToken->didRequestDOMPasteAccess(granted); >+ return granted; >+ } >+ } >+} >+ > void Frame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot shouldAdjustViewSize) > { > if (!view()) >diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h >index 8ad13d6e1ccc27a638157d811ab1cf48ce2e2069..74f6f4f03638c6b2a4736119153e5f34dbfa46a0 100644 >--- a/Source/WebCore/page/Frame.h >+++ b/Source/WebCore/page/Frame.h >@@ -175,6 +175,8 @@ public: > bool hasHadUserInteraction() const { return m_hasHadUserInteraction; } > void setHasHadUserInteraction() { m_hasHadUserInteraction = true; } > >+ bool requestDOMPasteAccess(); >+ > // ======== All public functions below this point are candidates to move out of Frame into another class. ======== > > WEBCORE_EXPORT void injectUserScripts(UserScriptInjectionTime); >diff --git a/Source/WebCore/page/Settings.yaml b/Source/WebCore/page/Settings.yaml >index 976c84c4a0f1873754de891c4f678a14e9192a00..54585beb664dd11980692e95195a0c203fc2f173 100644 >--- a/Source/WebCore/page/Settings.yaml >+++ b/Source/WebCore/page/Settings.yaml >@@ -344,6 +344,9 @@ mediaEnabled: > DOMPasteAllowed: > initial: false > >+domPasteAccessRequestsEnabled: >+ initial: false >+ > # When enabled, window.blur() does not change focus, and > # window.focus() only changes focus when invoked from the context that > # created the window. >diff --git a/Source/WebKit/Shared/WebPreferences.yaml b/Source/WebKit/Shared/WebPreferences.yaml >index cce4ace8356325e7a0a00e523f9e4c992f9152ff..405b7a18b138c4bb5bc97aeea5e1c7790730d60b 100644 >--- a/Source/WebKit/Shared/WebPreferences.yaml >+++ b/Source/WebKit/Shared/WebPreferences.yaml >@@ -1534,6 +1534,13 @@ AdClickAttributionEnabled: > webcoreBinding: RuntimeEnabledFeatures > category: internal > >+DOMPasteAccessRequestsEnabled: >+ type: bool >+ defaultValue: DEFAULT_DOM_PASTE_ACCESS_REQUESTS_ENABLED >+ humanReadableName: "DOM Paste Access Requests" >+ humanReadableDescription: "Enable DOM Paste Access Requests" >+ category: internal >+ > # Deprecated > > ICECandidateFilteringEnabled: >diff --git a/Source/WebKit/Shared/WebPreferencesDefaultValues.h b/Source/WebKit/Shared/WebPreferencesDefaultValues.h >index 0a52167c20fa5ae0404734784a49ec91c9106ff7..6e82173b0cb2cbe91531041dec2708c50dfbfe83 100644 >--- a/Source/WebKit/Shared/WebPreferencesDefaultValues.h >+++ b/Source/WebKit/Shared/WebPreferencesDefaultValues.h >@@ -242,3 +242,9 @@ bool defaultCustomPasteboardDataEnabled(); > #define DEFAULT_INPUT_TYPE_COLOR_ENABLED true > #define DEFAULT_DATALIST_ELEMENT_ENABLED true > #endif >+ >+#if PLATFORM(IOS) >+#define DEFAULT_DOM_PASTE_ACCESS_REQUESTS_ENABLED true >+#else >+#define DEFAULT_DOM_PASTE_ACCESS_REQUESTS_ENABLED false >+#endif >diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp >index 4c734e31d5b12b113b206f2f452ae294468e6079..0fb8802ff3b39d7d98b161b836a88e2efd82dafc 100644 >--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp >+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp >@@ -514,4 +514,9 @@ bool PageClientImpl::decidePolicyForInstallMissingMediaPluginsPermissionRequest( > } > #endif > >+void PageClientImpl::requestDOMPasteAccess(const IntRect&, CompletionHandler<void(bool)>&& completionHandler) >+{ >+ completionHandler(false); >+} >+ > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h >index 93ca18f59f22d35c91663097b07b78590fefc092..c7dd6f265272556efbe42e52bbc14401a43652d7 100644 >--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h >+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h >@@ -148,6 +148,8 @@ private: > > void didFinishProcessingAllPendingMouseEvents() final { } > >+ void requestDOMPasteAccess(const WebCore::IntRect&, CompletionHandler<void(bool)>&&) final; >+ > #if ENABLE(VIDEO) && USE(GSTREAMER) > bool decidePolicyForInstallMissingMediaPluginsPermissionRequest(InstallMissingMediaPluginsPermissionRequest&) override; > #endif >diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp >index c34810ec8768064d6e2031642b4e53eafe41c3a9..74548d9bf52fe3da07cbe22466374bc1de67b266 100644 >--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp >+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp >@@ -389,4 +389,9 @@ void PageClientImpl::beganExitFullScreen(const WebCore::IntRect& /* initialFrame > > #endif // ENABLE(FULLSCREEN_API) > >+void PageClientImpl::requestDOMPasteAccess(const WebCore::IntRect&, CompletionHandler<void(bool)>&& completionHandler) >+{ >+ completionHandler(false); >+} >+ > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h >index f9e25b79a8c47671a670035550ea5e01e2ec765c..469d0155a915f9dcbad585781606f28ae10fc65f 100644 >--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h >+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h >@@ -144,6 +144,7 @@ private: > void didFinishProcessingAllPendingMouseEvents() final { } > > IPC::Attachment hostFileDescriptor() final; >+ void requestDOMPasteAccess(const WebCore::IntRect&, CompletionHandler<void(bool)>&&) final; > > WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override; > >diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h >index 3c2dc0198cc7dfed9f740796e24f4bf5288b9f28..413518477fe3a60ab59cfbf0edd2f4bc62968cae 100644 >--- a/Source/WebKit/UIProcess/PageClient.h >+++ b/Source/WebKit/UIProcess/PageClient.h >@@ -465,6 +465,8 @@ public: > virtual void didChangeDragCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) = 0; > #endif > >+ virtual void requestDOMPasteAccess(const WebCore::IntRect& elementRect, CompletionHandler<void(bool)>&&) = 0; >+ > #if ENABLE(ATTACHMENT_ELEMENT) > virtual void didInsertAttachment(API::Attachment&, const String& source) { } > virtual void didRemoveAttachment(API::Attachment&) { } >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index 6a177453fdcd25a99eeca01e799c5c5e24834b3c..7a3f352c86a852506bbb38e86712c3c3e44ac560 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -5439,6 +5439,11 @@ void WebPageProxy::setNeedsPlainTextQuirk(bool needsPlainTextQuirk) > m_needsPlainTextQuirk = needsPlainTextQuirk; > } > >+void WebPageProxy::requestDOMPasteAccess(const WebCore::IntRect& elementRect, CompletionHandler<void(bool)>&& completionHandler) >+{ >+ m_pageClient->requestDOMPasteAccess(elementRect, WTFMove(completionHandler)); >+} >+ > // BackForwardList > > void WebPageProxy::backForwardAddItem(BackForwardListItemState&& itemState) >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 0ba2936cf74c6df85fb0e1e53414accfa7754546..9740e5d5eb21db4c2a3eef3b569d26ca174ba009 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -1659,6 +1659,8 @@ private: > void setNeedsHiddenContentEditableQuirk(bool); > void setNeedsPlainTextQuirk(bool); > >+ void requestDOMPasteAccess(const WebCore::IntRect&, CompletionHandler<void(bool)>&&); >+ > // Back/Forward list management > void backForwardAddItem(BackForwardListItemState&&); > void backForwardGoToItem(const WebCore::BackForwardItemIdentifier&, SandboxExtension::Handle&); >diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in >index 302e7df67b44fcbdfb2a308b74dbe9da5f4df3e4..b984ea3b7ab7d618265f83432fbe01a074d64145 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in >+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in >@@ -254,6 +254,7 @@ messages -> WebPageProxy { > SetHasHadSelectionChangesFromUserInteraction(bool hasHadUserSelectionChanges) > SetNeedsHiddenContentEditableQuirk(bool needsHiddenContentEditableQuirk) > SetNeedsPlainTextQuirk(bool needsPlainTextQuirk) >+ RequestDOMPasteAccess(WebCore::IntRect elementRect) -> (bool granted) Delayed > > # Find messages > DidCountStringMatches(String string, uint32_t matchCount) >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.h b/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >index a3c6d3af89d506677958704dd901667db41e96e1..d0d03847d0e2e3b57c75338267aaa204a02a3366 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >@@ -224,6 +224,8 @@ private: > void requestPasswordForQuickLookDocument(const String& fileName, WTF::Function<void(const String&)>&&) override; > #endif > >+ void requestDOMPasteAccess(const WebCore::IntRect& elementRect, CompletionHandler<void(bool)>&&) final; >+ > #if ENABLE(DATA_INTERACTION) > void didPerformDragOperation(bool handled) override; > void didHandleDragStartRequest(bool started) override; >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >index 1509cc27429943acbdc35a68f255f9eebbad6272..5e0a6907b80336778858fb050ec010a0fc98b25c 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >@@ -837,6 +837,11 @@ void PageClientImpl::requestPasswordForQuickLookDocument(const String& fileName, > } > #endif > >+void PageClientImpl::requestDOMPasteAccess(const WebCore::IntRect& elementRect, CompletionHandler<void(bool)>&& completionHandler) >+{ >+ [m_contentView _requestDOMPasteAccessWithElementRect:elementRect completionHandler:WTFMove(completionHandler)]; >+} >+ > #if HAVE(PENCILKIT) > RetainPtr<WKDrawingView> PageClientImpl::createDrawingView(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID) > { >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >index 9189ebdcf59aa1353b4424ef3754cbb105f22b0d..2cc7d0079db944765b3c03d12c34f912edcbbe28 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >@@ -49,6 +49,7 @@ > #import <WebCore/Color.h> > #import <WebCore/FloatQuad.h> > #import <wtf/BlockPtr.h> >+#import <wtf/CompletionHandler.h> > #import <wtf/Forward.h> > #import <wtf/OptionSet.h> > #import <wtf/Vector.h> >@@ -313,6 +314,7 @@ struct WKAutoCorrectionData { > BOOL _focusRequiresStrongPasswordAssistance; > > BOOL _hasSetUpInteractions; >+ CompletionHandler<void(bool)> _domPasteRequestHandler; > > #if ENABLE(DATA_INTERACTION) > WebKit::DragDropInteractionState _dragDropInteractionState; >@@ -434,6 +436,8 @@ FOR_EACH_PRIVATE_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW) > - (void)_accessibilityClearSelection; > - (WKFormInputSession *)_formInputSession; > >+- (void)_requestDOMPasteAccessWithElementRect:(const WebCore::IntRect&)elementRect completionHandler:(CompletionHandler<void(bool)>&&)completionHandler; >+ > @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation; > - (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request; > - (BOOL)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request; >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index c4804b2ae2d344d09f0730cf057cb0565ffaaf8e..a0a77c8f65189930d73b5dffce4881b4fe83a33f 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -740,7 +740,7 @@ - (void)setupInteraction > #endif > > NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; >- [center addObserver:self selector:@selector(_resetShowingTextStyle:) name:UIMenuControllerDidHideMenuNotification object:nil]; >+ [center addObserver:self selector:@selector(_didHideMenu:) name:UIMenuControllerDidHideMenuNotification object:nil]; > [center addObserver:self selector:@selector(_keyboardDidRequestDismissal:) name:UIKeyboardPrivateDidRequestDismissalNotification object:nil]; > > _showingTextStyleOptions = NO; >@@ -886,6 +886,7 @@ - (void)cleanupInteraction > #if ENABLE(POINTER_EVENTS) > [self _resetPanningPreventionFlags]; > #endif >+ [self _handleDOMPasteRequestWithResult:NO]; > } > > - (void)_removeDefaultGestureRecognizers >@@ -1143,8 +1144,10 @@ - (BOOL)resignFirstResponderForWebView > > bool superDidResign = [super resignFirstResponder]; > >- if (superDidResign) >+ if (superDidResign) { >+ [self _handleDOMPasteRequestWithResult:NO]; > _page->activityStateDidChange(WebCore::ActivityState::IsFocused); >+ } > > return superDidResign; > } >@@ -1178,8 +1181,10 @@ - (void)_webTouchEventsRecognized:(UIWebTouchEventsGestureRecognizer *)gestureRe > const _UIWebTouchEvent* lastTouchEvent = gestureRecognizer.lastTouchEvent; > > _lastInteractionLocation = lastTouchEvent->locationInDocumentCoordinates; >- if (lastTouchEvent->type == UIWebTouchEventTouchBegin) >+ if (lastTouchEvent->type == UIWebTouchEventTouchBegin) { >+ [self _handleDOMPasteRequestWithResult:NO]; > _layerTreeTransactionIdAtLastTouchStart = downcast<WebKit::RemoteLayerTreeDrawingAreaProxy>(*_page->drawingArea()).lastCommittedLayerTreeTransactionID(); >+ } > > #if ENABLE(TOUCH_EVENTS) > WebKit::NativeWebTouchEvent nativeWebTouchEvent { lastTouchEvent, gestureRecognizerModifierFlags(gestureRecognizer) }; >@@ -1980,6 +1985,9 @@ - (BOOL)textInteractionGesture:(UIWKGestureType)gesture shouldBeginAtPoint:(CGPo > if (!_webView.configuration._textInteractionGesturesEnabled) > return NO; > >+ if (_domPasteRequestHandler) >+ return NO; >+ > if (_suppressSelectionAssistantReasons) > return NO; > >@@ -2397,7 +2405,10 @@ - (NSArray *)supportedPasteboardTypesForCurrentSelection > #define FORWARD_ACTION_TO_WKWEBVIEW(_action) \ > - (void)_action:(id)sender \ > { \ >+ SEL action = @selector(_action:);\ >+ [self _willPerformAction:action sender:sender];\ > [_webView _action:sender]; \ >+ [self _didPerformAction:action sender:sender];\ > } > > FOR_EACH_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKWEBVIEW) >@@ -2642,11 +2653,17 @@ - (void)tintColorDidChange > > - (BOOL)canPerformAction:(SEL)action withSender:(id)sender > { >+ if (_domPasteRequestHandler) >+ return action == @selector(paste:); >+ > return [_webView canPerformAction:action withSender:sender]; > } > > - (BOOL)canPerformActionForWebView:(SEL)action withSender:(id)sender > { >+ if (_domPasteRequestHandler) >+ return action == @selector(paste:); >+ > if (action == @selector(_nextAccessoryTab:)) > return hasFocusedElement(_focusedElementInformation) && _focusedElementInformation.hasNextNode; > if (action == @selector(_previousAccessoryTab:)) >@@ -2793,10 +2810,11 @@ - (id)targetForActionForWebView:(SEL)action withSender:(id)sender > return [super targetForAction:action withSender:sender]; > } > >-- (void)_resetShowingTextStyle:(NSNotification *)notification >+- (void)_didHideMenu:(NSNotification *)notification > { > _showingTextStyleOptions = NO; > [_textSelectionAssistant hideTextStyleOptions]; >+ [self _handleDOMPasteRequestWithResult:NO]; > } > > - (void)_keyboardDidRequestDismissal:(NSNotification *)notification >@@ -2818,6 +2836,9 @@ - (void)cutForWebView:(id)sender > > - (void)pasteForWebView:(id)sender > { >+ if (sender == UIMenuController.sharedMenuController && [self _handleDOMPasteRequestWithResult:YES]) >+ return; >+ > _page->executeEditCommand("paste"_s); > } > >@@ -2947,6 +2968,28 @@ - (void)_accessibilityClearSelection > _page->storeSelectionForAccessibility(false); > } > >+- (BOOL)_handleDOMPasteRequestWithResult:(BOOL)allowPaste >+{ >+ if (auto pasteHandler = WTFMove(_domPasteRequestHandler)) { >+ [self hideGlobalMenuController]; >+ pasteHandler(allowPaste); >+ return YES; >+ } >+ return NO; >+} >+ >+- (void)_willPerformAction:(SEL)action sender:(id)sender >+{ >+ if (action != @selector(paste:)) >+ [self _handleDOMPasteRequestWithResult:NO]; >+} >+ >+- (void)_didPerformAction:(SEL)action sender:(id)sender >+{ >+ if (action == @selector(paste:)) >+ [self _handleDOMPasteRequestWithResult:NO]; >+} >+ > // UIWKInteractionViewProtocol > > static inline WebKit::GestureType toGestureType(UIWKGestureType gestureType) >@@ -4094,6 +4137,8 @@ - (void)handleKeyWebEvent:(::WebEvent *)theEvent > > - (void)handleKeyWebEvent:(::WebEvent *)theEvent withCompletionHandler:(void (^)(::WebEvent *theEvent, BOOL wasHandled))completionHandler > { >+ [self _handleDOMPasteRequestWithResult:NO]; >+ > _keyWebEventHandler = makeBlockPtr(completionHandler); > _page->handleKeyboardEvent(WebKit::NativeWebKeyboardEvent(theEvent)); > } >@@ -4793,6 +4838,47 @@ - (void)_didUpdateInputMode:(WebCore::InputMode)mode > #endif > } > >+- (void)showGlobalMenuControllerInRect:(CGRect)rect >+{ >+ UIMenuController *controller = UIMenuController.sharedMenuController; >+#if HAVE(MENU_CONTROLLER_SHOW_HIDE_API) >+ [controller showMenuFromView:self rect:rect]; >+#else >+ [controller setTargetRect:rect inView:self]; >+ [controller setMenuVisible:YES animated:YES]; >+#endif >+} >+ >+- (void)hideGlobalMenuController >+{ >+ UIMenuController *controller = UIMenuController.sharedMenuController; >+#if HAVE(MENU_CONTROLLER_SHOW_HIDE_API) >+ [controller hideMenuFromView:self]; >+#else >+ [controller setMenuVisible:NO animated:YES]; >+#endif >+} >+ >+- (void)_requestDOMPasteAccessWithElementRect:(const WebCore::IntRect&)elementRect completionHandler:(CompletionHandler<void(bool)>&&)completionHandler >+{ >+ if (auto existingCompletionHandler = std::exchange(_domPasteRequestHandler, WTFMove(completionHandler))) { >+ ASSERT_NOT_REACHED(); >+ existingCompletionHandler(false); >+ } >+ >+ WebCore::IntRect menuControllerRect = elementRect; >+ >+ const CGFloat maximumElementWidth = 300; >+ const CGFloat maximumElementHeight = 120; >+ if (elementRect.isEmpty() || elementRect.width() > maximumElementWidth || elementRect.height() > maximumElementHeight) { >+ const CGFloat interactionLocationMargin = 10; >+ menuControllerRect = { WebCore::IntPoint(_lastInteractionLocation), { } }; >+ menuControllerRect.inflate(interactionLocationMargin); >+ } >+ >+ [self showGlobalMenuControllerInRect:menuControllerRect]; >+} >+ > - (void)_didReceiveEditorStateUpdateAfterFocus > { > [self _updateInitialWritingDirectionIfNecessary]; >diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.h b/Source/WebKit/UIProcess/mac/PageClientImplMac.h >index 4707a0202e42a828d5a50ed58be4e30f3a88a0b9..d242c05c1d26c4380a27d044d54dc6cbf4eb22cb 100644 >--- a/Source/WebKit/UIProcess/mac/PageClientImplMac.h >+++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.h >@@ -30,6 +30,7 @@ > #include "CorrectionPanel.h" > #include "PageClientImplCocoa.h" > #include "WebFullScreenManagerProxy.h" >+#include <wtf/CompletionHandler.h> > #include <wtf/RetainPtr.h> > > @class WKEditorUndoTarget; >@@ -215,6 +216,8 @@ private: > void willRecordNavigationSnapshot(WebBackForwardListItem&) override; > void didRemoveNavigationGestureSnapshot() override; > >+ void requestDOMPasteAccess(const WebCore::IntRect&, CompletionHandler<void(bool)>&& completion) final { completion(false); } >+ > NSView *activeView() const; > NSWindow *activeWindow() const; > >diff --git a/Source/WebKit/UIProcess/win/PageClientImpl.cpp b/Source/WebKit/UIProcess/win/PageClientImpl.cpp >index 170c2d7763962af02f32b4f8b5ed029b679f6ff1..912b4a99c724d62d3a547ba5b4367b1bb31abcb8 100644 >--- a/Source/WebKit/UIProcess/win/PageClientImpl.cpp >+++ b/Source/WebKit/UIProcess/win/PageClientImpl.cpp >@@ -357,4 +357,9 @@ HWND PageClientImpl::viewWidget() > return m_view.window(); > } > >+void PageClientImpl::requestDOMPasteAccess(const IntRect&, CompletionHandler<void(bool)>&& completionHandler) >+{ >+ completionHandler(false); >+} >+ > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/win/PageClientImpl.h b/Source/WebKit/UIProcess/win/PageClientImpl.h >index 66572bb14058aacff5fac3fdd75106c8b075ef5a..e8426c963ecb6117c40d2a2482a3aefe2c08ff03 100644 >--- a/Source/WebKit/UIProcess/win/PageClientImpl.h >+++ b/Source/WebKit/UIProcess/win/PageClientImpl.h >@@ -142,6 +142,8 @@ private: > > void didFinishProcessingAllPendingMouseEvents() final { } > >+ void requestDOMPasteAccess(const WebCore::IntRect&, CompletionHandler<void(bool)>&&) final; >+ > // Members of PageClientImpl class > DefaultUndoController m_undoController; > >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp >index 8f2181bebf181c3dcd787fb4b9fbd620c9d00d7f..96a4dd18f214b594328c5078d7e22555ed7e7f3e 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp >@@ -359,6 +359,11 @@ void WebEditorClient::redo() > m_page->sendSync(Messages::WebPageProxy::ExecuteUndoRedo(UndoOrRedo::Redo), Messages::WebPageProxy::ExecuteUndoRedo::Reply()); > } > >+bool WebEditorClient::requestDOMPasteAccess() >+{ >+ return m_page->requestDOMPasteAccess(); >+} >+ > #if PLATFORM(WIN) > void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) > { >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h b/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h >index 4720b71175412a59a229bc47106dab2da3c8756e..7be8ddfca3f6d0ca897b7e685ce1993fb80023d8 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h >@@ -89,6 +89,8 @@ private: > void registerRedoStep(WebCore::UndoStep&) final; > void clearUndoRedoOperations() final; > >+ bool requestDOMPasteAccess() final; >+ > bool canCopyCut(WebCore::Frame*, bool defaultValue) const final; > bool canPaste(WebCore::Frame*, bool defaultValue) const final; > bool canUndo() const final; >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >index a611b268775862c7f84a4e2e3c495fefe29fd061..dfaab22a4ed8e35d0540066b2327ef072c7ca5d2 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >@@ -6424,6 +6424,15 @@ void WebPage::didCompleteShareSheet(bool wasGranted, ShareSheetCallbackID callba > callback(wasGranted); > } > >+bool WebPage::requestDOMPasteAccess() >+{ >+ bool granted = false; >+ if (!sendSyncWithDelayedReply(Messages::WebPageProxy::RequestDOMPasteAccess(rectForElementAtInteractionLocation()), Messages::WebPageProxy::RequestDOMPasteAccess::Reply(granted))) >+ return false; >+ >+ return granted; >+} >+ > void WebPage::simulateDeviceOrientationChange(double alpha, double beta, double gamma) > { > #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY) >@@ -6497,7 +6506,16 @@ void WebPage::didFinishLoadingApplicationManifest(uint64_t coreCallbackID, const > void WebPage::updateCurrentModifierState(OptionSet<PlatformEvent::Modifier> modifiers) > { > PlatformKeyboardEvent::setCurrentModifierState(modifiers); >-} >+} >+ >+#if !PLATFORM(IOS_FAMILY) >+ >+WebCore::IntRect WebPage::rectForElementAtInteractionLocation() const >+{ >+ return { }; >+} >+ >+#endif // !PLATFORM(IOS_FAMILY) > > } // namespace WebKit > >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index 03b4d3e71862d964bc0783ce1b5b9dc124f2b02d..4a99b91bce74c75651813b7fdfc157aa2fd28cbe 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -658,7 +658,6 @@ public: > void setFocusedElementValue(const String&); > void setFocusedElementValueAsNumber(double); > void setFocusedElementSelectedIndex(uint32_t index, bool allowMultipleSelection); >- WebCore::IntRect rectForElementAtInteractionLocation(); > void updateSelectionAppearance(); > void getSelectionContext(CallbackID); > void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t requestID); >@@ -1149,6 +1148,9 @@ public: > return sendSync(WTFMove(message), WTFMove(reply), m_pageID, Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend); > } > >+ bool requestDOMPasteAccess(); >+ WebCore::IntRect rectForElementAtInteractionLocation() const; >+ > private: > WebPage(uint64_t pageID, WebPageCreationParameters&&); > >diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >index 9d1f2de9c51b45ea204e853ca5831e14339ce43f..f18f19a42c244fa16d281e83364f7713eb298975 100644 >--- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >+++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >@@ -511,7 +511,7 @@ void WebPage::advanceToNextMisspelling(bool) > notImplemented(); > } > >-IntRect WebPage::rectForElementAtInteractionLocation() >+IntRect WebPage::rectForElementAtInteractionLocation() const > { > HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_lastInteractionLocation, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent); > Node* hitNode = result.innerNode(); >diff --git a/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h b/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h >index f0f968b7e2b66c891dc14b6c1faaf0b8bbe1d19e..55f40e0b53b1266b68fce4e3898e883cce9a72a7 100644 >--- a/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h >+++ b/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h >@@ -81,6 +81,7 @@ private: > String replacementURLForResource(Ref<WebCore::SharedBuffer>&& resourceData, const String& mimeType) final; > > void setInsertionPasteboard(const String&) final; >+ bool requestDOMPasteAccess() final { return false; } > > #if USE(APPKIT) > void uppercaseWord() final; >diff --git a/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h b/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h >index 7a6edde8193613859a31d2f0d2ebb35f822c5d2b..cc5e4d645be56704a092d11fc006c32313995adb 100644 >--- a/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h >+++ b/Source/WebKitLegacy/win/WebCoreSupport/WebEditorClient.h >@@ -115,6 +115,8 @@ private: > void requestCheckingOfString(WebCore::TextCheckingRequest&, const WebCore::VisibleSelection&) final { } > bool performTwoStepDrop(WebCore::DocumentFragment&, WebCore::Range&, bool) final { return false; } > >+ bool requestDOMPasteAccess() final { return false; } >+ > WebCore::TextCheckerClient* textChecker() final { return this; } > > WebView* m_webView;
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 194271
:
361202
|
361212
|
361252
|
361305
|
361306
|
361316
|
361350
|
361351
|
361397
|
361398
|
361537
|
361547
|
361582
|
361702
| 361837 |
361847