Title: [205870] trunk
Revision
205870
Author
[email protected]
Date
2016-09-13 12:44:42 -0700 (Tue, 13 Sep 2016)

Log Message

Undoing a candidate insertion results in the replaced text being selected
https://bugs.webkit.org/show_bug.cgi?id=161894
<rdar://problem/28225774>

Reviewed by Simon Fraser.

Test: editing/mac/spelling/accept-candidate-undo-does-not-select.html

* WebCore.xcodeproj/project.pbxproj:
* editing/ReplaceRangeWithTextCommand.cpp: Added.
(WebCore::ReplaceRangeWithTextCommand::ReplaceRangeWithTextCommand):
(WebCore::ReplaceRangeWithTextCommand::doApply):
* editing/ReplaceRangeWithTextCommand.h: Added.
(WebCore::ReplaceRangeWithTextCommand::create):
Add a editor command that replaces a range with the given text.

* editing/Editor.cpp:
(WebCore::Editor::rangeForTextCheckingResult):
(WebCore::Editor::handleAcceptedCandidate):
(WebCore::Editor::selectTextCheckingResult): Deleted.
* editing/Editor.h:
Make use of the new editor command to do candidate insertion as a single
composite operation, so that it is undone as a unit. Otherwise, undo ends up
undoing the insertion, but not the selection, and we are left with the old
text, selected, which is undesirable.

* editing/mac/spelling/accept-candidate-allows-autocorrect-on-next-word-expected.txt:
* editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt:
* editing/mac/spelling/accept-candidate-undo-does-not-select-expected.txt: Copied from LayoutTests/editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt.
* editing/mac/spelling/accept-candidate-undo-does-not-select.html: Added.
* editing/mac/spelling/accept-candidate-without-adding-space-expected.txt:
* editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt:
Adjust some test results, and add a new test that ensures that undoing
a candidate insertion does not select the replaced text.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (205869 => 205870)


--- trunk/LayoutTests/ChangeLog	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/LayoutTests/ChangeLog	2016-09-13 19:44:42 UTC (rev 205870)
@@ -1,3 +1,20 @@
+2016-09-13  Tim Horton  <[email protected]>
+
+        Undoing a candidate insertion results in the replaced text being selected
+        https://bugs.webkit.org/show_bug.cgi?id=161894
+        <rdar://problem/28225774>
+
+        Reviewed by Simon Fraser.
+
+        * editing/mac/spelling/accept-candidate-allows-autocorrect-on-next-word-expected.txt:
+        * editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt:
+        * editing/mac/spelling/accept-candidate-undo-does-not-select-expected.txt: Copied from LayoutTests/editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt.
+        * editing/mac/spelling/accept-candidate-undo-does-not-select.html: Added.
+        * editing/mac/spelling/accept-candidate-without-adding-space-expected.txt:
+        * editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt:
+        Adjust some test results, and add a new test that ensures that undoing
+        a candidate insertion does not select the replaced text.
+
 2016-09-13  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Should be able to pretty print module code (import / export statements)

Modified: trunk/LayoutTests/editing/mac/spelling/accept-candidate-allows-autocorrect-on-next-word-expected.txt (205869 => 205870)


--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-allows-autocorrect-on-next-word-expected.txt	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-allows-autocorrect-on-next-word-expected.txt	2016-09-13 19:44:42 UTC (rev 205870)
@@ -70,9 +70,11 @@
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 21 of #text > DIV > BODY > HTML > #document to 21 of #text > DIV > BODY > HTML > #document toDOMRange:range from 22 of #text > DIV > BODY > HTML > #document to 22 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldInsertText:extremely long replacingDOMRange:range from 2 of #text > DIV > BODY > HTML > #document to 15 of #text > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 22 of #text > DIV > BODY > HTML > #document to 22 of #text > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > DIV > BODY > HTML > #document to 15 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 22 of #text > DIV > BODY > HTML > #document to 22 of #text > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > DIV > BODY > HTML > #document to 15 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of #text > DIV > BODY > HTML > #document to 2 of #text > DIV > BODY > HTML > #document toDOMRange:range from 16 of #text > DIV > BODY > HTML > #document to 16 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification

Modified: trunk/LayoutTests/editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt (205869 => 205870)


--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-replacing-multiple-words-expected.txt	2016-09-13 19:44:42 UTC (rev 205870)
@@ -30,9 +30,11 @@
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldInsertText:good idea  replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification

Added: trunk/LayoutTests/editing/mac/spelling/accept-candidate-undo-does-not-select-expected.txt (0 => 205870)


--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-undo-does-not-select-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-undo-does-not-select-expected.txt	2016-09-13 19:44:42 UTC (rev 205870)
@@ -0,0 +1,54 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > DIV > DIV > BODY > HTML > #document to 1 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > DIV > DIV > BODY > HTML > #document to 1 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 4 of #text > DIV > DIV > BODY > HTML > #document to 4 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 5 of #text > DIV > DIV > BODY > HTML > #document to 5 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 5 of #text > DIV > DIV > BODY > HTML > #document to 5 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 6 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 6 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldInsertText:good idea  replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This test verifies that undoing an accepted candidate replacement doesn't select the original text.
+
+goo didea.

Added: trunk/LayoutTests/editing/mac/spelling/accept-candidate-undo-does-not-select.html (0 => 205870)


--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-undo-does-not-select.html	                        (rev 0)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-undo-does-not-select.html	2016-09-13 19:44:42 UTC (rev 205870)
@@ -0,0 +1,52 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+
+function editingTest() {
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.dumpAsText(true);
+    }
+
+    edit = document.getElementById('edit');
+    edit.focus();
+    typeCharacterCommand('g');
+    typeCharacterCommand('o');
+    typeCharacterCommand('o');
+    typeCharacterCommand(' ');
+    typeCharacterCommand('d');
+    typeCharacterCommand('i');
+    typeCharacterCommand('d');
+    typeCharacterCommand('e');
+    typeCharacterCommand('a');    
+
+    // Wait a bit before swapping in the candidate, because otherwise 
+    // AppKit can combine the undo of the candidate insertion with the other text.
+    setTimeout(function () {
+        if (window.internals)
+            internals.handleAcceptedCandidate("good idea ", 0, 9);
+
+        undoCommand();
+
+        // If the undo wrongly left "goo didea" selected, this will replace it.
+        typeCharacterCommand('.');
+
+        testRunner.notifyDone();
+    }, 100);
+}
+
+</script>
+</head>
+<body>
+<p>This test verifies that undoing an accepted candidate replacement doesn't select the original text.</p>
+<div style="border:1px solid black;">
+    <div contenteditable="true" id="edit"></div>
+</div>
+<script>
+runEditingTest();
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-adding-space-expected.txt (205869 => 205870)


--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-adding-space-expected.txt	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-adding-space-expected.txt	2016-09-13 19:44:42 UTC (rev 205870)
@@ -8,9 +8,11 @@
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > DIV > DIV > BODY > HTML > #document to 1 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldInsertText:is replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification

Modified: trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt (205869 => 205870)


--- trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/LayoutTests/editing/mac/spelling/accept-candidate-without-crossing-editing-boundary-expected.txt	2016-09-13 19:44:42 UTC (rev 205870)
@@ -8,9 +8,11 @@
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > DIV > DIV > BODY > HTML > #document to 1 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldInsertText:happy  replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 2 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 2 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 6 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification

Modified: trunk/Source/WebCore/CMakeLists.txt (205869 => 205870)


--- trunk/Source/WebCore/CMakeLists.txt	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/Source/WebCore/CMakeLists.txt	2016-09-13 19:44:42 UTC (rev 205870)
@@ -1559,6 +1559,7 @@
     editing/RemoveNodePreservingChildrenCommand.cpp
     editing/RenderedPosition.cpp
     editing/ReplaceNodeWithSpanCommand.cpp
+    editing/ReplaceRangeWithTextCommand.cpp
     editing/ReplaceSelectionCommand.cpp
     editing/SetNodeAttributeCommand.cpp
     editing/SetSelectionCommand.cpp

Modified: trunk/Source/WebCore/ChangeLog (205869 => 205870)


--- trunk/Source/WebCore/ChangeLog	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/Source/WebCore/ChangeLog	2016-09-13 19:44:42 UTC (rev 205870)
@@ -1,3 +1,31 @@
+2016-09-13  Tim Horton  <[email protected]>
+
+        Undoing a candidate insertion results in the replaced text being selected
+        https://bugs.webkit.org/show_bug.cgi?id=161894
+        <rdar://problem/28225774>
+
+        Reviewed by Simon Fraser.
+
+        Test: editing/mac/spelling/accept-candidate-undo-does-not-select.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * editing/ReplaceRangeWithTextCommand.cpp: Added.
+        (WebCore::ReplaceRangeWithTextCommand::ReplaceRangeWithTextCommand):
+        (WebCore::ReplaceRangeWithTextCommand::doApply):
+        * editing/ReplaceRangeWithTextCommand.h: Added.
+        (WebCore::ReplaceRangeWithTextCommand::create):
+        Add a editor command that replaces a range with the given text.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::rangeForTextCheckingResult):
+        (WebCore::Editor::handleAcceptedCandidate):
+        (WebCore::Editor::selectTextCheckingResult): Deleted.
+        * editing/Editor.h:
+        Make use of the new editor command to do candidate insertion as a single
+        composite operation, so that it is undone as a unit. Otherwise, undo ends up
+        undoing the insertion, but not the selection, and we are left with the old
+        text, selected, which is undesirable.
+
 2016-09-13  Dave Hyatt  <[email protected]>
 
         [CSS Parser] Add CSS Variable Parsing support

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205869 => 205870)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-09-13 19:44:42 UTC (rev 205870)
@@ -1231,6 +1231,8 @@
 		2DCB837A19F99BBA00A7FBE4 /* NSSharingServiceSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DCB837819F99BBA00A7FBE4 /* NSSharingServiceSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2DDB97F419F9AECA002025D8 /* NSExtensionSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDB97F319F9AECA002025D8 /* NSExtensionSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2DE70023192FE82A00B0975C /* DisplayRefreshMonitorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE70022192FE82A00B0975C /* DisplayRefreshMonitorMac.h */; };
+		2DF512CD1D873E47001D6780 /* ReplaceRangeWithTextCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DF512CB1D873E47001D6780 /* ReplaceRangeWithTextCommand.cpp */; };
+		2DF512CE1D873E47001D6780 /* ReplaceRangeWithTextCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DF512CC1D873E47001D6780 /* ReplaceRangeWithTextCommand.h */; };
 		2E0888D41148848A00AF4265 /* JSDOMFormData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E0888D21148848A00AF4265 /* JSDOMFormData.cpp */; };
 		2E0888D51148848A00AF4265 /* JSDOMFormData.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E0888D31148848A00AF4265 /* JSDOMFormData.h */; };
 		2E19516B1B6598D200DF6EEF /* WheelEventDeltaFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E19516A1B6598D200DF6EEF /* WheelEventDeltaFilter.cpp */; };
@@ -8159,6 +8161,8 @@
 		2DCB837819F99BBA00A7FBE4 /* NSSharingServiceSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSSharingServiceSPI.h; sourceTree = "<group>"; };
 		2DDB97F319F9AECA002025D8 /* NSExtensionSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSExtensionSPI.h; sourceTree = "<group>"; };
 		2DE70022192FE82A00B0975C /* DisplayRefreshMonitorMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayRefreshMonitorMac.h; sourceTree = "<group>"; };
+		2DF512CB1D873E47001D6780 /* ReplaceRangeWithTextCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplaceRangeWithTextCommand.cpp; sourceTree = "<group>"; };
+		2DF512CC1D873E47001D6780 /* ReplaceRangeWithTextCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplaceRangeWithTextCommand.h; sourceTree = "<group>"; };
 		2E0888C3114883A900AF4265 /* DOMFormData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMFormData.idl; sourceTree = "<group>"; };
 		2E0888D21148848A00AF4265 /* JSDOMFormData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMFormData.cpp; sourceTree = "<group>"; };
 		2E0888D31148848A00AF4265 /* JSDOMFormData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMFormData.h; sourceTree = "<group>"; };
@@ -17618,6 +17622,8 @@
 				93309DB6099E64910056E581 /* RemoveNodeCommand.h */,
 				93309DB7099E64910056E581 /* RemoveNodePreservingChildrenCommand.cpp */,
 				93309DB8099E64910056E581 /* RemoveNodePreservingChildrenCommand.h */,
+				2DF512CB1D873E47001D6780 /* ReplaceRangeWithTextCommand.cpp */,
+				2DF512CC1D873E47001D6780 /* ReplaceRangeWithTextCommand.h */,
 				9B32CDA813DF7FA900F34D13 /* RenderedPosition.cpp */,
 				9B32CDA713DF7FA900F34D13 /* RenderedPosition.h */,
 				A89CCC500F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.cpp */,
@@ -26791,6 +26797,7 @@
 				26FAE4CF1852E3A5004C8C46 /* SynchronousResourceHandleCFURLConnectionDelegate.h in Headers */,
 				0F03C0741884695E00A5F8CA /* SystemMemory.h in Headers */,
 				CDA07FBE18E0A16A004699FA /* SystemSleepListener.h in Headers */,
+				2DF512CE1D873E47001D6780 /* ReplaceRangeWithTextCommand.h in Headers */,
 				CDA07FC218E0A22B004699FA /* SystemSleepListenerMac.h in Headers */,
 				5D5975B319635F1100D00878 /* SystemVersion.h in Headers */,
 				51E399021D6E4750009C8831 /* GameControllerGamepadProvider.h in Headers */,
@@ -29599,6 +29606,7 @@
 				CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */,
 				CDAA8D0A14D71B2E0061EA60 /* PlatformClockCM.mm in Sources */,
 				26601EC014B3B9AD0012C0FE /* PlatformEventFactoryIOS.mm in Sources */,
+				2DF512CD1D873E47001D6780 /* ReplaceRangeWithTextCommand.cpp in Sources */,
 				BCAA486F14A052530088FAC4 /* PlatformEventFactoryMac.mm in Sources */,
 				F544F78815CFB2A800AF33A8 /* PlatformLocale.cpp in Sources */,
 				070E091B1875EF71003A1D3C /* PlatformMediaSession.cpp in Sources */,

Modified: trunk/Source/WebCore/editing/EditingAllInOne.cpp (205869 => 205870)


--- trunk/Source/WebCore/editing/EditingAllInOne.cpp	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/Source/WebCore/editing/EditingAllInOne.cpp	2016-09-13 19:44:42 UTC (rev 205870)
@@ -60,6 +60,7 @@
 #include <RemoveNodePreservingChildrenCommand.cpp>
 #include <RenderedPosition.cpp>
 #include <ReplaceNodeWithSpanCommand.cpp>
+#include <ReplaceRangeWithTextCommand.cpp>
 #include <ReplaceSelectionCommand.cpp>
 #include <SetNodeAttributeCommand.cpp>
 #include <SetSelectionCommand.cpp>

Modified: trunk/Source/WebCore/editing/Editor.cpp (205869 => 205870)


--- trunk/Source/WebCore/editing/Editor.cpp	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/Source/WebCore/editing/Editor.cpp	2016-09-13 19:44:42 UTC (rev 205870)
@@ -75,6 +75,7 @@
 #include "RenderTextControl.h"
 #include "RenderedDocumentMarker.h"
 #include "RenderedPosition.h"
+#include "ReplaceRangeWithTextCommand.h"
 #include "ReplaceSelectionCommand.h"
 #include "Settings.h"
 #include "ShadowRoot.h"
@@ -3616,21 +3617,17 @@
     const VisibleSelection& selection = m_frame.selection().selection();
     return makeRange(startOfParagraph(selection.visibleStart()), endOfParagraph(selection.visibleEnd()));
 }
-    
-void Editor::selectTextCheckingResult(const TextCheckingResult& result)
+
+RefPtr<Range> Editor::rangeForTextCheckingResult(const TextCheckingResult& result) const
 {
     if (!result.length)
-        return;
-    
+        return nullptr;
+
     RefPtr<Range> contextRange = contextRangeForCandidateRequest();
     if (!contextRange)
-        return;
-    
-    RefPtr<Range> replacementRange = TextIterator::subrange(contextRange.get(), result.location, result.length);
-    if (!replacementRange)
-        return;
-    
-    m_frame.selection().setSelectedRange(replacementRange.get(), UPSTREAM, true);
+        return nullptr;
+
+    return TextIterator::subrange(contextRange.get(), result.location, result.length);
 }
 
 void Editor::handleAcceptedCandidate(TextCheckingResult acceptedCandidate)
@@ -3639,8 +3636,13 @@
 
     m_isHandlingAcceptedCandidate = true;
 
-    selectTextCheckingResult(acceptedCandidate);
-    insertText(acceptedCandidate.replacement, 0);
+    if (auto range = rangeForTextCheckingResult(acceptedCandidate)) {
+        if (shouldInsertText(acceptedCandidate.replacement, range.get(), EditorInsertActionTyped)) {
+            Ref<ReplaceRangeWithTextCommand> replaceCommand = ReplaceRangeWithTextCommand::create(range.get(), acceptedCandidate.replacement);
+            applyCommand(replaceCommand.ptr());
+        }
+    } else
+        insertText(acceptedCandidate.replacement, nullptr);
 
     RefPtr<Range> insertedCandidateRange = rangeExpandedByCharactersInDirectionAtWordBoundary(selection.visibleStart(), acceptedCandidate.replacement.length(), DirectionBackward);
     if (insertedCandidateRange)

Modified: trunk/Source/WebCore/editing/Editor.h (205869 => 205870)


--- trunk/Source/WebCore/editing/Editor.h	2016-09-13 19:08:30 UTC (rev 205869)
+++ trunk/Source/WebCore/editing/Editor.h	2016-09-13 19:44:42 UTC (rev 205870)
@@ -467,7 +467,7 @@
     WEBCORE_EXPORT String stringForCandidateRequest() const;
     WEBCORE_EXPORT void handleAcceptedCandidate(TextCheckingResult);
     WEBCORE_EXPORT RefPtr<Range> contextRangeForCandidateRequest() const;
-    void selectTextCheckingResult(const TextCheckingResult&);
+    RefPtr<Range> rangeForTextCheckingResult(const TextCheckingResult&) const;
     bool isHandlingAcceptedCandidate() const { return m_isHandlingAcceptedCandidate; }
 
 private:

Added: trunk/Source/WebCore/editing/ReplaceRangeWithTextCommand.cpp (0 => 205870)


--- trunk/Source/WebCore/editing/ReplaceRangeWithTextCommand.cpp	                        (rev 0)
+++ trunk/Source/WebCore/editing/ReplaceRangeWithTextCommand.cpp	2016-09-13 19:44:42 UTC (rev 205870)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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. ``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
+ * 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.
+ */
+
+#include "config.h"
+#include "ReplaceRangeWithTextCommand.h"
+
+#include "AlternativeTextController.h"
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Editor.h"
+#include "Frame.h"
+#include "ReplaceSelectionCommand.h"
+#include "SetSelectionCommand.h"
+#include "TextIterator.h"
+#include "markup.h"
+
+namespace WebCore {
+
+ReplaceRangeWithTextCommand::ReplaceRangeWithTextCommand(RefPtr<Range> rangeToBeReplaced, const String& text)
+    : CompositeEditCommand(rangeToBeReplaced->startContainer().document())
+    , m_rangeToBeReplaced(rangeToBeReplaced)
+    , m_text(text)
+{
+}
+
+void ReplaceRangeWithTextCommand::doApply()
+{
+    VisibleSelection selection = *m_rangeToBeReplaced;
+
+    if (!m_rangeToBeReplaced)
+        return;
+
+    if (!frame().selection().shouldChangeSelection(selection))
+        return;
+
+    String previousText = plainText(m_rangeToBeReplaced.get());
+    if (!previousText.length())
+        return;
+
+    applyCommandToComposite(SetSelectionCommand::create(selection, FrameSelection::defaultSetSelectionOptions()));
+
+    auto fragment = createFragmentFromText(*m_rangeToBeReplaced, m_text);
+    applyCommandToComposite(ReplaceSelectionCommand::create(document(), WTFMove(fragment), ReplaceSelectionCommand::MatchStyle, EditActionPaste));
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/editing/ReplaceRangeWithTextCommand.h (0 => 205870)


--- trunk/Source/WebCore/editing/ReplaceRangeWithTextCommand.h	                        (rev 0)
+++ trunk/Source/WebCore/editing/ReplaceRangeWithTextCommand.h	2016-09-13 19:44:42 UTC (rev 205870)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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. ``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
+ * 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
+
+#include "CompositeEditCommand.h"
+#include "Range.h"
+
+namespace WebCore {
+
+class ReplaceRangeWithTextCommand : public CompositeEditCommand {
+public:
+    static Ref<ReplaceRangeWithTextCommand> create(RefPtr<Range> rangeToBeReplaced, const String& text)
+    {
+        return adoptRef(*new ReplaceRangeWithTextCommand(rangeToBeReplaced, text));
+    }
+
+private:
+    ReplaceRangeWithTextCommand(RefPtr<Range> rangeToBeReplaced, const String& text);
+    void doApply() override;
+
+    RefPtr<Range> m_rangeToBeReplaced;
+    String m_text;
+};
+
+} // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to