WebKit Bugzilla
Attachment 368878 Details for
Bug 197452
: Add quirks to emulate undo and redo in hidden editable areas on some websites
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197452-20190502201311.patch (text/plain), 30.24 KB, created by
Megan Gardner
on 2019-05-02 20:13:12 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Megan Gardner
Created:
2019-05-02 20:13:12 PDT
Size:
30.24 KB
patch
obsolete
>Subversion Revision: 244620 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8b5be61cd4d2706b12662b305733fcfe8586ad9b..36db5d527dbf7ff0f3232cde8907ba8d7335b9e4 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,30 @@ >+2019-04-30 Megan Gardner <megan_gardner@apple.com> >+ >+ Add quirks to emulate undo and redo in hidden editable areas on some websites >+ https://bugs.webkit.org/show_bug.cgi?id=197452 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ UI change, not testable. >+ >+ We need to send synthetic keyboard events to the web process to emulate undo and redo >+ key combinations for when we are trying to get our undo and redo UI to work >+ on rich editing websites that only listen to keystrokes, and don't let us use our >+ undo manager to help manage the input content. >+ >+ * page/EventHandler.cpp: >+ (WebCore::EventHandler::keyEvent): >+ * platform/PlatformKeyboardEvent.h: >+ (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent): >+ (WebCore::PlatformKeyboardEvent::isSyntheticEvent): >+ (WebCore::PlatformKeyboardEvent::setSyntheticEvent): >+ * platform/ios/KeyEventIOS.mm: >+ (WebCore::PlatformKeyboardEvent::currentStateOfModifierKeys): >+ * platform/ios/PlatformEventFactoryIOS.mm: >+ (WebCore::PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder): >+ * platform/mac/PlatformEventFactoryMac.mm: >+ (WebCore::PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder): >+ > 2019-04-24 Brady Eidson <beidson@apple.com> > > XMLHTTPRequest POSTs to a custom WKURLSchemeHandler protocol are missing the HTTP body. >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 8739f5dc09ac96a9b523b151b25e7bf5cff3814b..8ab9e25e695fb9abd9f7734e634cb3ec42bf16a4 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,37 @@ >+2019-04-30 Megan Gardner <megan_gardner@apple.com> >+ >+ Add quirks to emulate undo and redo in hidden editable areas on some websites >+ https://bugs.webkit.org/show_bug.cgi?id=197452 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We need to make our own undo manager to allow undo even when >+ the manager is empty. This is to interface with rich editing >+ websites that don't actually interface with our undo abilities. >+ Then we need to generate synthetic undo and redo in the web process. >+ >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::WebPageProxy::isCurrentURLHost const): >+ * UIProcess/WebPageProxy.h: >+ * UIProcess/ios/WKContentView.mm: >+ (-[WKNSUndoManager initWithContentView:]): >+ (-[WKNSUndoManager canUndo]): >+ (-[WKNSUndoManager canRedo]): >+ (-[WKNSUndoManager undo]): >+ (-[WKNSUndoManager redo]): >+ (-[WKContentView undoManager]): >+ * UIProcess/ios/WKContentViewInteraction.h: >+ * UIProcess/ios/WKContentViewInteraction.mm: >+ (-[WKContentView generateSyntheticUndoRedo:]): >+ (-[WKContentView hasHiddenContentEditable]): >+ * UIProcess/ios/WebPageProxyIOS.mm: >+ (WebKit::WebPageProxy::generateSyntheticUndoRedo): >+ * WebProcess/WebPage/WebPage.h: >+ * WebProcess/WebPage/WebPage.messages.in: >+ * WebProcess/WebPage/ios/WebPageIOS.mm: >+ (WebKit::WebPage::handleEditingKeyboardEvent): >+ (WebKit::WebPage::generateSyntheticUndoRedo): >+ > 2019-04-24 Per Arne Vollan <pvollan@apple.com> > > [macOS] Fix syscall sandbox violation >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index d756cb39da9e5dc9c251b7ec34f037a24d766dfb..c8beee27c02902c9a358305fa58df9ae71a1deef 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -3161,6 +3161,9 @@ void Document::setURL(const URL& url) > m_url = newURL; > m_documentURI = m_url.string(); > updateBaseURL(); >+ >+ if (quirks().shouldEmulateUndoRedoInHiddenEditableAreas()) >+ page()->chrome().client().setNeedsQuirkyNSUndoManager(settings().needsSiteSpecificQuirks()); > } > > void Document::updateBaseURL() >diff --git a/Source/WebCore/loader/EmptyClients.h b/Source/WebCore/loader/EmptyClients.h >index d794efbc54e3fee738d5e3ee18b3ed46a422b7e7..e0ac1a956852c5bc0f2c0c9d9117a4f24d0c0004 100644 >--- a/Source/WebCore/loader/EmptyClients.h >+++ b/Source/WebCore/loader/EmptyClients.h >@@ -179,6 +179,8 @@ class EmptyChromeClient : public ChromeClient { > > void webAppOrientationsUpdated() final { }; > void showPlaybackTargetPicker(bool, RouteSharingPolicy, const String&) final { }; >+ >+ void setNeedsQuirkyNSUndoManager(bool) final { }; > #endif // PLATFORM(IOS_FAMILY) > > #if ENABLE(ORIENTATION_EVENTS) >diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h >index 540d78aa2bf855070b86292ef179296829476b5f..aa5c4ec084616cb96a40dad79cd597d8b17e5895 100644 >--- a/Source/WebCore/page/ChromeClient.h >+++ b/Source/WebCore/page/ChromeClient.h >@@ -269,6 +269,8 @@ public: > > virtual void webAppOrientationsUpdated() = 0; > virtual void showPlaybackTargetPicker(bool hasVideo, RouteSharingPolicy, const String&) = 0; >+ >+ virtual void setNeedsQuirkyNSUndoManager(bool) = 0; > #endif > > #if ENABLE(ORIENTATION_EVENTS) >diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp >index 22f099cb2b85e0859b1974be9d3336667d48b9f1..27901f73cc22bcaa453c49d423391a5d60a314f9 100644 >--- a/Source/WebCore/page/EventHandler.cpp >+++ b/Source/WebCore/page/EventHandler.cpp >@@ -3155,6 +3155,9 @@ bool EventHandler::isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent& ke > > bool EventHandler::keyEvent(const PlatformKeyboardEvent& keyEvent) > { >+ bool shiftKey, ctrlKey, altKey, metaKey; >+ keyEvent.getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey); >+ > Document* topDocument = m_frame.document() ? &m_frame.document()->topDocument() : nullptr; > MonotonicTime savedLastHandledUserGestureTimestamp; > bool savedUserDidInteractWithPage = topDocument ? topDocument->userDidInteractWithPage() : false; >diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp >index 965eb475a85abaef1a91a7257137f57ab71f0ec7..16aaadde1f8d7f660dce6e1d9d3940043fa3aebf 100644 >--- a/Source/WebCore/page/Page.cpp >+++ b/Source/WebCore/page/Page.cpp >@@ -1385,6 +1385,11 @@ void Page::userStyleSheetLocationChanged() > frame->document()->extensionStyleSheets().updatePageUserSheet(); > } > } >+ >+void Page::needsSiteSpecificQuirksChanged() >+{ >+ chrome().client().setNeedsQuirkyNSUndoManager(m_settings->needsSiteSpecificQuirks()); >+} > > const String& Page::userStyleSheet() const > { >diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h >index dcd1f2dfba3b1246dd395f57f718c179b9c3b4be..3d27a4b2612dd45f40e9a83495f007603acb4b5b 100644 >--- a/Source/WebCore/page/Page.h >+++ b/Source/WebCore/page/Page.h >@@ -477,6 +477,7 @@ public: > bool scriptedAnimationsSuspended() const { return m_scriptedAnimationsSuspended; } > > void userStyleSheetLocationChanged(); >+ void needsSiteSpecificQuirksChanged(); > const String& userStyleSheet() const; > > WEBCORE_EXPORT void userAgentChanged(); >diff --git a/Source/WebCore/page/Quirks.cpp b/Source/WebCore/page/Quirks.cpp >index 57c0546dfdd4b2eddeb81eb92440467c8fa3ab71..57adc82d793efc8587038b5c4915063f8e750538 100644 >--- a/Source/WebCore/page/Quirks.cpp >+++ b/Source/WebCore/page/Quirks.cpp >@@ -204,8 +204,21 @@ static bool shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAre > return false; > } > >+bool Quirks::shouldEmulateUndoRedoInHiddenEditableAreasForHost(const StringView&) >+{ >+ return false; >+} >+ > #endif > >+bool Quirks::shouldEmulateUndoRedoInHiddenEditableAreas() const >+{ >+ if (!needsQuirks()) >+ return false; >+ >+ return shouldEmulateUndoRedoInHiddenEditableAreasForHost(m_document->topDocument().url().host()); >+} >+ > bool Quirks::shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAreas() const > { > if (!needsQuirks()) >diff --git a/Source/WebCore/page/Quirks.h b/Source/WebCore/page/Quirks.h >index 6fb60a03caede84e68d115a68a372539a98f5b8e..ce45efeb0099f9a686c6ff9d6bcd56b5fa971f2f 100644 >--- a/Source/WebCore/page/Quirks.h >+++ b/Source/WebCore/page/Quirks.h >@@ -49,9 +49,12 @@ public: > bool shouldDisablePointerEventsQuirk() const; > > WEBCORE_EXPORT bool shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAreas() const; >+ WEBCORE_EXPORT bool shouldEmulateUndoRedoInHiddenEditableAreas() const; > WEBCORE_EXPORT bool isTouchBarUpdateSupressedForHiddenContentEditable() const; > WEBCORE_EXPORT bool isNeverRichlyEditableForTouchBar() const; > >+ WEBCORE_EXPORT static bool shouldEmulateUndoRedoInHiddenEditableAreasForHost(const StringView&); >+ > private: > bool needsQuirks() const; > >diff --git a/Source/WebCore/page/Settings.yaml b/Source/WebCore/page/Settings.yaml >index e3e09eead5c005a84635342802ee3bcca93b0d59..4597e13653e8dd015e7156fc24e8f556d7795816 100644 >--- a/Source/WebCore/page/Settings.yaml >+++ b/Source/WebCore/page/Settings.yaml >@@ -181,6 +181,7 @@ scriptMarkupEnabled: > needsSiteSpecificQuirks: > initial: false > inspectorOverride: true >+ onChange: needsSiteSpecificQuirksChanged > domTimersThrottlingEnabled: > initial: true > webArchiveDebugModeEnabled: >diff --git a/Source/WebCore/page/SettingsBase.cpp b/Source/WebCore/page/SettingsBase.cpp >index 3d59d30195a2d2d91b9daa4612cde6ae05e2962c..4d4201988e486c2ab28bf412fa753b4547c2ff62 100644 >--- a/Source/WebCore/page/SettingsBase.cpp >+++ b/Source/WebCore/page/SettingsBase.cpp >@@ -361,6 +361,12 @@ void SettingsBase::userStyleSheetLocationChanged() > if (m_page) > m_page->userStyleSheetLocationChanged(); > } >+ >+void SettingsBase::needsSiteSpecificQuirksChanged() >+{ >+ if (m_page) >+ m_page->needsSiteSpecificQuirksChanged(); >+} > > void SettingsBase::usesPageCacheChanged() > { >diff --git a/Source/WebCore/page/SettingsBase.h b/Source/WebCore/page/SettingsBase.h >index 3533b8f9ad6371fc171df5d58b97b53f485d306a..f4e77f9296aa4ddac1eb69beaa43daf279d83be9 100644 >--- a/Source/WebCore/page/SettingsBase.h >+++ b/Source/WebCore/page/SettingsBase.h >@@ -185,6 +185,7 @@ protected: > void imagesEnabledChanged(); > void pluginsEnabledChanged(); > void userStyleSheetLocationChanged(); >+ void needsSiteSpecificQuirksChanged(); > void usesPageCacheChanged(); > void dnsPrefetchingEnabledChanged(); > void storageBlockingPolicyChanged(); >diff --git a/Source/WebCore/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h >index 519b6cd77e8970a7e17918deb2c7769c278b7801..9f3b74702859c7b284950dc3b0a62403b0dc9829 100644 >--- a/Source/WebCore/platform/PlatformKeyboardEvent.h >+++ b/Source/WebCore/platform/PlatformKeyboardEvent.h >@@ -59,6 +59,7 @@ namespace WebCore { > , m_autoRepeat(false) > , m_isKeypad(false) > , m_isSystemKey(false) >+ , m_isSyntheticEvent(false) > #if PLATFORM(GTK) > , m_gdkEventKey(0) > #endif >@@ -134,6 +135,9 @@ namespace WebCore { > bool isAutoRepeat() const { return m_autoRepeat; } > bool isKeypad() const { return m_isKeypad; } > bool isSystemKey() const { return m_isSystemKey; } >+ >+ bool isSyntheticEvent() { return m_isSyntheticEvent; } >+ void setSyntheticEvent() { m_isSyntheticEvent = true; } > > WEBCORE_EXPORT static bool currentCapsLockState(); > WEBCORE_EXPORT static void getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey); >@@ -196,6 +200,8 @@ namespace WebCore { > bool m_autoRepeat; > bool m_isKeypad; > bool m_isSystemKey; >+ >+ bool m_isSyntheticEvent; > > #if PLATFORM(COCOA) > #if !PLATFORM(IOS_FAMILY) >diff --git a/Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm b/Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm >index a171b9db1fd4f503454d46b4e87fc1f2fb046029..6c3bd70e05b1601c845d304d7cd37c6780540e4a 100644 >--- a/Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm >+++ b/Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm >@@ -493,6 +493,7 @@ public: > m_type = (event.type == WebEventKeyUp ? PlatformEvent::KeyUp : PlatformEvent::KeyDown); > m_modifiers = modifiersForEvent(event); > m_timestamp = WallTime::now(); >+ m_isSyntheticEvent = false; > > if (event.keyboardFlags & WebEventKeyboardInputModifierFlagsChanged) { > m_text = emptyString(); >diff --git a/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm b/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm >index 2328baff896bf0b4c199335e8418e703d9961302..3d9330cfda5185c58bd8c4483ecebc4d2225ba56 100644 >--- a/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm >+++ b/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm >@@ -806,6 +806,7 @@ public: > m_type = isKeyUpEvent(event) ? PlatformEvent::KeyUp : PlatformEvent::KeyDown; > m_modifiers = modifiersForEvent(event); > m_timestamp = eventTimeStampSince1970(event); >+ m_isSyntheticEvent = false; > > // PlatformKeyboardEvent > m_text = textFromEvent(event); >diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h >index c89cbb1f237b6f149fc5519cdfe2fdbc43fb691e..1ea9134dcf35b350ee3ad9b79ee285e788b1ca2a 100644 >--- a/Source/WebKit/UIProcess/PageClient.h >+++ b/Source/WebKit/UIProcess/PageClient.h >@@ -505,6 +505,9 @@ public: > #if PLATFORM(WPE) > virtual IPC::Attachment hostFileDescriptor() = 0; > #endif >+ >+ virtual void setNeedsQuirkyNSUndoManager(bool) = 0; >+ > }; > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index c56d661685eb0cd14d2d4e073ced195ab42d95ef..73b91f2cfc5f9e28355dba165006ab0b97c921da 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -6692,6 +6692,13 @@ String WebPageProxy::currentURL() const > url = m_backForwardList->currentItem()->url(); > return url; > } >+ >+bool WebPageProxy::isCurrentURLHost(const String& base) const >+{ >+ if (URL({ }, currentURL()).host() == base) >+ return true; >+ return false; >+} > > void WebPageProxy::processDidTerminate(ProcessTerminationReason reason) > { >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 44fc8a09afe267714d8fcd0aff0cab783feb4456..4a91016bec5e8ff6528b4745c1b16c9bd6490076 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -550,6 +550,7 @@ public: > bool canShowMIMEType(const String& mimeType); > > String currentURL() const; >+ bool isCurrentURLHost(const String& base) const; > > float topContentInset() const { return m_topContentInset; } > void setTopContentInset(float); >@@ -720,6 +721,7 @@ public: > void requestEvasionRectsAboveSelection(CompletionHandler<void(const Vector<WebCore::FloatRect>&)>&&); > void updateSelectionWithDelta(int64_t locationDelta, int64_t lengthDelta, CompletionHandler<void()>&&); > void requestDocumentEditingContext(WebKit::DocumentEditingContextRequest, CompletionHandler<void(WebKit::DocumentEditingContext)>&&); >+ void generateSyntheticUndoRedo(bool isUndo); > #if ENABLE(DATA_INTERACTION) > void didHandleDragStartRequest(bool started); > void didHandleAdditionalDragItemsRequest(bool added); >@@ -727,7 +729,8 @@ public: > void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions); > void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>); > #endif >-#endif >+ void setNeedsQuirkyNSUndoManager(bool); >+#endif // PLATFORM(IOS_FAMILY) > #if ENABLE(DATA_DETECTION) > void setDataDetectionResult(const DataDetectionResult&); > #endif >diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in >index 18eeb46b40a4faadd7e3878be7b96d20c5331892..266a93ead5a49587ce610a9ed9cbff14c5df17fd 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.messages.in >+++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in >@@ -421,6 +421,8 @@ messages -> WebPageProxy { > > UpdateStringForFind(String findString) > HandleAutocorrectionContext(struct WebKit::WebAutocorrectionContext context) >+ >+ SetNeedsQuirkyNSUndoManager(bool needsQuirkyNSUndoManager) > #endif > > DidChangeInspectorFrontendCount(uint64_t count) >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.h b/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >index 3872fbd72185ad4f14d99d6af4071fb7ee37e6bb..a40de24196fea9ee7e0a60e5e0fbe0205b5371b8 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >@@ -253,6 +253,8 @@ private: > void cancelPointersForGestureRecognizer(UIGestureRecognizer*) override; > #endif > >+ void setNeedsQuirkyNSUndoManager(bool) override; >+ > WKContentView *m_contentView; > RetainPtr<WKEditorUndoTarget> m_undoTarget; > }; >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >index 9d27bc4e5bf4d8ffc4a9db953556046b673c8636..ada2299bf6fea1238fc4d5f55519b857d1834ad7 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >@@ -873,6 +873,11 @@ void PageClientImpl::handleAutocorrectionContext(const WebAutocorrectionContext& > [m_contentView _handleAutocorrectionContext:context]; > } > >+void PageClientImpl::setNeedsQuirkyNSUndoManager(bool needsQuirkyNSUndoManager) >+{ >+ [m_contentView _setNeedsQuirkyNSUndoManager:needsQuirkyNSUndoManager]; >+} >+ > } // namespace WebKit > > #endif // PLATFORM(IOS_FAMILY) >diff --git a/Source/WebKit/UIProcess/ios/WKContentView.h b/Source/WebKit/UIProcess/ios/WKContentView.h >index daa39102c7d82e1adae4b5a669d5ee76197fffc3..1a8d01a53d6cccf27a886fe5470ca744a2a9dfe3 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentView.h >+++ b/Source/WebKit/UIProcess/ios/WKContentView.h >@@ -116,4 +116,6 @@ class WebProcessPool; > - (double)_contentZoomScale; > - (double)_targetContentZoomScaleForRect:(const WebCore::FloatRect&)targetRect currentScale:(double)currentScale fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale; > >+- (void)_setNeedsQuirkyNSUndoManager:(bool)needsQuirkyNSUndoManager; >+ > @end >diff --git a/Source/WebKit/UIProcess/ios/WKContentView.mm b/Source/WebKit/UIProcess/ios/WKContentView.mm >index 6b2d9f9644f7b934d71bf17c3ae588c7c238b439..6b8c6de33502f6cad14a208f959362b809f83018 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentView.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentView.mm >@@ -59,6 +59,7 @@ > #import <WebCore/InspectorOverlay.h> > #import <WebCore/NotImplemented.h> > #import <WebCore/PlatformScreen.h> >+#import <WebCore/Quirks.h> > #import <pal/spi/cocoa/QuartzCoreSPI.h> > #import <wtf/RetainPtr.h> > #import <wtf/text/TextStream.h> >@@ -172,6 +173,41 @@ - (instancetype)initWithFrame:(CGRect)frame > > @end > >+@interface WKQuirkyNSUndoManager : NSUndoManager >+@property (readonly, weak) WKContentView* contentView; >+@end >+ >+@implementation WKQuirkyNSUndoManager >+- (instancetype)initWithContentView:(WKContentView*)contentView >+{ >+ if (!(self = [super init])) >+ return nil; >+ _contentView = contentView; >+ return self; >+} >+ >+- (BOOL)canUndo >+{ >+ return YES; >+} >+ >+- (BOOL)canRedo >+{ >+ return YES; >+} >+ >+- (void)undo >+{ >+ [self.contentView generateSyntheticUndoRedo:YES]; >+} >+ >+- (void)redo >+{ >+ [self.contentView generateSyntheticUndoRedo:NO]; >+} >+ >+@end >+ > @implementation WKContentView { > std::unique_ptr<WebKit::PageClientImpl> _pageClient; > ALLOW_DEPRECATED_DECLARATIONS_BEGIN >@@ -189,7 +225,9 @@ @implementation WKContentView { > > WebKit::HistoricalVelocityData _historicalKinematicData; > >+ BOOL _isUsingQuirkyNSUndoManager; > RetainPtr<NSUndoManager> _undoManager; >+ RetainPtr<WKQuirkyNSUndoManager> _quirkyUndoManager; > > BOOL _isPrintingToPDF; > RetainPtr<CGPDFDocumentRef> _printedDocument; >@@ -496,11 +534,24 @@ - (void)didZoomToScale:(CGFloat)scale > [self _didEndScrollingOrZooming]; > } > >+- (void)_setNeedsQuirkyNSUndoManager:(BOOL)needsQuirkyNSUndoManager >+{ >+ _isUsingQuirkyNSUndoManager = needsQuirkyNSUndoManager; >+} >+ > - (NSUndoManager *)undoManager > { >+ if (_isUsingQuirkyNSUndoManager && WebCore::Quirks::shouldEmulateUndoRedoInHiddenEditableAreasForHost(URL({ }, _page->currentURL()).host())) { >+ if (self.hasHiddenContentEditable) { >+ if (!_quirkyUndoManager) >+ _quirkyUndoManager = adoptNS([[WKQuirkyNSUndoManager alloc] initWithContentView:self]); >+ return _quirkyUndoManager.get(); >+ } >+ } else >+ _isUsingQuirkyNSUndoManager = NO; >+ > if (!_undoManager) > _undoManager = adoptNS([[NSUndoManager alloc] init]); >- > return _undoManager.get(); > } > >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >index 107a27976d9df7286b3659eacc070c8dd95825dd..2dbc3e870c345ddacc4d02d95baf325ef27803f0 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >@@ -465,6 +465,9 @@ FOR_EACH_PRIVATE_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW) > > - (void)willFinishIgnoringCalloutBarFadeAfterPerformingAction; > >+- (BOOL)hasHiddenContentEditable; >+- (void)generateSyntheticUndoRedo:(BOOL)isUndo; >+ > // UIWebFormAccessoryDelegate protocol > - (void)accessoryDone; > >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index 0cfad5f7b3a705d8c2d6e21c0ed14a89a25e9925..172e6758e712037e7db9c0129d633b94dfde3af7 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -4449,6 +4449,11 @@ - (void)_handleKeyUIEvent:(::UIEvent *)event > [super _handleKeyUIEvent:event]; > } > >+- (void)generateSyntheticUndoRedo:(BOOL)isUndo >+{ >+ _page->generateSyntheticUndoRedo(isUndo); >+} >+ > #if !USE(UIKIT_KEYBOARD_ADDITIONS) > - (void)handleKeyEvent:(::UIEvent *)event > { >@@ -5683,6 +5688,11 @@ - (BOOL)shouldAllowHidingSelectionCommands > return !_ignoreSelectionCommandFadeCount; > } > >+- (BOOL)hasHiddenContentEditable >+{ >+ return _suppressSelectionAssistantReasons.contains(WebKit::EditableRootIsTransparentOrFullyClipped); >+} >+ > - (BOOL)_shouldSuppressSelectionCommands > { > return !!_suppressSelectionAssistantReasons; >diff --git a/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm b/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm >index c682fda34246ff9d721f84063b27a20eb221d45b..2cc526e939ae9541e49ac5048a5f6cca51a54b23 100644 >--- a/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm >+++ b/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm >@@ -1097,6 +1097,14 @@ void WebPageProxy::contentSizeCategoryDidChange(const String& contentSizeCategor > process().send(Messages::WebPage::ContentSizeCategoryDidChange(contentSizeCategory), m_pageID); > } > >+void WebPageProxy::generateSyntheticUndoRedo(bool isUndo) >+{ >+ if (!hasRunningProcess()) >+ return; >+ >+ process().send(Messages::WebPage::GenerateSyntheticUndoRedo(isUndo), m_pageID); >+} >+ > void WebPageProxy::editorStateChanged(const EditorState& editorState) > { > bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone; >@@ -1257,6 +1265,12 @@ const String& WebPageProxy::paymentCoordinatorCTDataConnectionServiceType(const > > #endif > >+void WebPageProxy::setNeedsQuirkyNSUndoManager(bool needsQuirkyNSUndoManager) >+{ >+ pageClient().setNeedsQuirkyNSUndoManager(needsQuirkyNSUndoManager); >+} >+ >+ > #if USE(APPLE_INTERNAL_SDK) > #import <WebKitAdditions/WebPageProxyIOSAdditions.mm> > #endif >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h >index 911f76a1acf0da69317836d48eece6d47b07ecc5..fe8767b91c28e63bd4979d3739c51b0b6180eea2 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h >@@ -179,6 +179,8 @@ private: > void associateEditableImageWithAttachment(WebCore::GraphicsLayer::EmbeddedViewID, const String& attachmentID) final; > void didCreateEditableImage(WebCore::GraphicsLayer::EmbeddedViewID) final; > void didDestroyEditableImage(WebCore::GraphicsLayer::EmbeddedViewID) final; >+ >+ void setNeedsQuirkyNSUndoManager(bool) final; > #endif > > #if ENABLE(ORIENTATION_EVENTS) >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm b/Source/WebKit/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm >index 2944091e3aa13d4ea9e3c5290f2211b2e2fc8b7e..0633c76ff21ac0a5abc15919f5585d69830c01f6 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm >+++ b/Source/WebKit/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm >@@ -181,6 +181,11 @@ void WebChromeClient::didDestroyEditableImage(GraphicsLayer::EmbeddedViewID embe > #endif > } > >+void WebChromeClient::setNeedsQuirkyNSUndoManager(bool needsQuirkyNSUndoManager) >+{ >+ m_page.send(Messages::WebPageProxy::SetNeedsQuirkyNSUndoManager(needsQuirkyNSUndoManager)); >+} >+ > } // namespace WebKit > > #endif // PLATFORM(IOS_FAMILY) >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index 5e4697dea23ec3dc51a7e5c51306c19de348b584..1abdc8fba1ab9b2af903915966af68827c40325f 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -1214,6 +1214,7 @@ private: > RefPtr<WebCore::Range> rangeForWebSelectionAtPosition(const WebCore::IntPoint&, const WebCore::VisiblePosition&, SelectionFlags&); > void getFocusedElementInformation(FocusedElementInformation&); > void platformInitializeAccessibility(); >+ void generateSyntheticUndoRedo(bool); > void handleSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>); > void completeSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::SyntheticClickType); > void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*); >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >index 3ff4e408712a47d62127d01455ec657ef2238061..32a8a48ba58dd46ca04a326e4f5443d3606a364b 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >@@ -112,6 +112,7 @@ messages -> WebPage LegacyReceiver { > SetIsShowingInputViewForFocusedElement(bool showingInputView) > UpdateSelectionWithDelta(int64_t locationDelta, int64_t lengthDelta) -> () Async > RequestDocumentEditingContext(struct WebKit::DocumentEditingContextRequest request) -> (struct WebKit::DocumentEditingContext response) Async >+ GenerateSyntheticUndoRedo(bool isUndo) > #endif > > SetControlledByAutomation(bool controlled) >diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >index d4621ea988ae83087767680990830099b64766dc..53cc3f303ecc68d3f4dc5bb2940141f7ffcb51d5 100644 >--- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >+++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >@@ -419,6 +419,11 @@ bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event) > auto* platformEvent = event->underlyingPlatformEvent(); > if (!platformEvent) > return false; >+ >+ // Don't send synthetic events to the UIProcess. They are only >+ // used for interacting with JavaScript. >+ if (platformEvent->isSyntheticEvent()) >+ return false; > > // FIXME: Interpret the event immediately upon receiving it in UI process, without sending to WebProcess first. > bool eventWasHandled = false; >@@ -580,6 +585,39 @@ static bool nodeAlwaysTriggersClick(const Node& targetNode) > return AccessibilityObject::isARIAControl(ariaRole) || AccessibilityObject::isARIAInput(ariaRole); > } > >+void WebPage::generateSyntheticUndoRedo(bool isUndo) >+{ >+ PlatformKeyboardEvent keyEvent; >+ auto& frame = m_page->focusController().focusedOrMainFrame(); >+ >+ OptionSet<PlatformEvent::Modifier> modifiers; >+ modifiers.add(PlatformEvent::Modifier::MetaKey); >+ >+ if (isUndo) { >+ keyEvent = PlatformKeyboardEvent(PlatformEvent::KeyDown, "z", "z", >+#if ENABLE(KEYBOARD_KEY_ATTRIBUTE) >+ "z", >+#endif >+#if ENABLE(KEYBOARD_CODE_ATTRIBUTE) >+ "KeyZ"_s, >+#endif >+ @"U+005A", 90, false, false, false, modifiers, WallTime::now()); >+ } else { >+ keyEvent = PlatformKeyboardEvent(PlatformEvent::KeyDown, "y", "y", >+#if ENABLE(KEYBOARD_KEY_ATTRIBUTE) >+ "y", >+#endif >+#if ENABLE(KEYBOARD_CODE_ATTRIBUTE) >+ "KeyY"_s, >+#endif >+ @"U+0059", 89, false, false, false, modifiers, WallTime::now()); >+ } >+ >+ PlatformKeyboardEvent::setCurrentModifierState(modifiers); >+ >+ frame.eventHandler().keyEvent(keyEvent); >+} >+ > void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers) > { > if (!nodeRespondingToClick.document().settings().contentChangeObserverEnabled()) { >diff --git a/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.h b/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.h >index 127633e6bce382a0af914868acd7182fc3835fc9..f9ef4159f6a24914742ff214e99db2d64051f959 100644 >--- a/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.h >+++ b/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.h >@@ -93,6 +93,8 @@ private: > void showPlaybackTargetPicker(bool hasVideo, WebCore::RouteSharingPolicy, const String&) final; > RefPtr<WebCore::Icon> createIconForFiles(const Vector<String>& filenames) final; > >+ void setNeedsQuirkyNSUndoManager(bool) final; >+ > #if ENABLE(ORIENTATION_EVENTS) > int deviceOrientation() const final; > #endif >diff --git a/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.mm b/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.mm >index 786431f722076ce4c83dcca7c2d5ce91cbc08f50..a194b554dd8de98bd46d88c55bd924a62740b833 100644 >--- a/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.mm >+++ b/Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.mm >@@ -389,4 +389,8 @@ int WebChromeClientIOS::deviceOrientation() const > } > #endif > >+void WebChromeClientIOS::setNeedsQuirkyNSUndoManager(bool needsQuirkyNSUndoManager) >+{ >+} >+ > #endif // PLATFORM(IOS_FAMILY)
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 197452
:
368878
|
368882
|
368987
|
368989
|
369001
|
369040
|
369172
|
369209
|
369214
|
369221
|
369254
|
369322
|
369342
|
369346
|
369356
|
369362
|
369396
|
369400
|
369413
|
369416
|
369440