Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 90ab262c20a7ad6601d72961b4fd7a2d745b8f41
      
https://github.com/WebKit/WebKit/commit/90ab262c20a7ad6601d72961b4fd7a2d745b8f41
  Author: Wenson Hsieh <wenson_hs...@apple.com>
  Date:   2024-07-08 (Mon, 08 Jul 2024)

  Changed paths:
    M Source/WebCore/editing/Editor.cpp
    M Source/WebCore/editing/Editor.h
    M Source/WebKit/UIProcess/WebPageProxy.cpp
    M Source/WebKit/UIProcess/WebPageProxy.h
    M Source/WebKit/UIProcess/ios/WKContentView.mm
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
    M Source/WebKit/WebProcess/WebPage/WebPage.cpp
    M Source/WebKit/WebProcess/WebPage/WebPage.h
    M Source/WebKit/WebProcess/WebPage/WebPage.messages.in
    M Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm

  Log Message:
  -----------
  [iOS 18] Undo voice command in Mail compose view does not fully undo dictated 
text
https://bugs.webkit.org/show_bug.cgi?id=276300
rdar://126653644

Reviewed by Abrar Rahman Protyasha.

In iOS 18, dictation recognizes the phrase "Undo" while dictating text, and 
reverts the most
recently inserted dictation phrase. However, in the following scenario:

1. Type "Hello"
2. Begin dictation and say "world"
3. Say "Undo"

...the resulting text will sometimes end up being `"Hello wo"` or `"Hello 
wor"`. To understand why,
we first need to understand how dictation-triggered undo works — when phrases 
are dictated,
`UIDictationController` begins a new undo group by calling `-[NSUndoManager 
beginUndoGrouping]` on
the editing responder (`WKContentView`). As the user continues speaking, the 
"hypothesis text" is
updated, which repeatedly uses `-insertText:` and 
`-adjustSelectionByRange:completionHandler:` to
replace the dictated text. When the user says "Undo", the dictation controller 
then undoes this
entire group.

The issue is that when the dictation controller first calls `-insertText:` 
after beginning the undo
group, this inserted text is added to the last open typing command (after the 
user types `"Hello"`)
instead of being a part of the newly established group that encapsulates all of 
the edit commands
triggered by dictation. As such, when the undo group is undone, we end up with 
`"Hello"` along with
the first piece of text, with which the dictation controller called 
`-insertText:`.

To fix this, we detect when any WebKit client (or the system, in this case 
dictation code) tells the
`WKContentView`'s undo manager to `-beginUndoGrouping`, and close the current 
typing command to
ensure that edit commands triggered in the new undo group aren't merged into 
the previous typing
command before the undo group.

Test: KeyboardInputTests.NewUndoGroupClosesPreviousTypingCommand

* Source/WebCore/editing/Editor.cpp:
(WebCore::Editor::closeTyping):
* Source/WebCore/editing/Editor.h:

Add a helper command to close the typing command if needed.

* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::closeCurrentTypingCommand):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/ios/WKContentView.mm:
(-[WKNSUndoManager initWithContentView:]):
(-[WKNSUndoManager beginUndoGrouping]):
(-[WKNSUndoManager registerUndoWithTarget:selector:object:]):
(-[WKNSUndoManager registerUndoWithTarget:handler:]):

Add a helper class that overrides `-beginUndoGrouping` and tells the webpage to 
close the current
typing command when a new undo group starts. Note that we avoid this codepath 
when a new command is
being registered, so that we don't prematurely close typing commands while 
typing.

(-[WKContentView undoManagerForWebView]):
(-[WKQuirkyNSUndoManager initWithContentView:]): Deleted.
(-[WKQuirkyNSUndoManager canUndo]): Deleted.
(-[WKQuirkyNSUndoManager canRedo]): Deleted.
(-[WKQuirkyNSUndoManager undo]): Deleted.
(-[WKQuirkyNSUndoManager redo]): Deleted.

Rename this helper class to `WKNSKeyEventSimulatorUndoManager` to better 
reflect its purpose, and
make it subclass `WKNSUndoManager`.

* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _closeCurrentTypingCommand]):
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::closeCurrentTypingCommand):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
* Tools/TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm:
(TestWebKitAPI::TEST(KeyboardInputTests, 
NewUndoGroupClosesPreviousTypingCommand)):

Add a new API test to exercise the change by inserting text within an undo 
group, bookended using
`-(begin|end)UndoGrouping`.

Canonical link: https://commits.webkit.org/280737@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to