Autocorrection makes it hard to type "doesn't" and to type @ in email addresses
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 May 2016 19:18:48 +0000 (19:18 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 May 2016 19:18:48 +0000 (19:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=158177
.:

Reviewed by Darin Adler.

Fixed manual tests for autocorrection panels and added a manual test for . Most of changes are fixing up the path to LayoutTests/editing/editing.js.

Also wrap many steps to type in a space or delete a character inside setTimeout since autocorrection happens on a timer
and the fact WebKit2 communicates with NSSpellChecker via IPC makes the behavior even more indeterministic.

* ManualTests/autocorrection/autocorrection-at-mark.html: Added.
* ManualTests/autocorrection/autocorrection-cancelled-by-ESC.html:
* ManualTests/autocorrection/autocorrection-cancelled-by-typing-1.html:
* ManualTests/autocorrection/autocorrection-contraction-2.html: Added.
* ManualTests/autocorrection/autocorrection-contraction.html:
* ManualTests/autocorrection/autocorrection-in-iframe.html:
* ManualTests/autocorrection/close-window-when-correction-is-shown.html:
* ManualTests/autocorrection/continue-typing-to-dismiss-reversion.html:
* ManualTests/autocorrection/delete-to-dismiss-reversion.html:
* ManualTests/autocorrection/delete-to-end-of-word-to-show-reversion.html:
* ManualTests/autocorrection/dismiss-multiple-guesses.html:
* ManualTests/autocorrection/document-for-iframe-test.html: Removed.
* ManualTests/autocorrection/move-to-end-of-word-to-show-reversion.html: Type a space and move care in setTimeout as
the reversion panel wouldn't show up otherwise.
* ManualTests/autocorrection/remove-misspelling-marker-after-appending-letter.html: Delay the typing of a space as well as
deleting letters since autocorrection panel wouldn't show up in time otherwise, and deleting character immediately would
reject the autocorrection instead of accepting it. Also removed the steps to add back the spellchecking marker and extracted
it as a separate test.
* ManualTests/autocorrection/removing-misspelling-marker-after-appending-letter-2.html: Copied. This test continues the full
scenario in the previous test by typing a space and deleting the character, thereby bringing up spellchecking marker.
* ManualTests/autocorrection/resources: Added.
* ManualTests/autocorrection/resources/document-for-iframe-test.html: Moved from ManualTests/autocorrection/.
* ManualTests/autocorrection/select-from-multiple-guesses.html: Added a missing instruction.
* ManualTests/autocorrection/spell-checking-after-reversion.html:
* ManualTests/autocorrection/type-whitespace-to-dismiss-reversion.html: Delay the typing of a space and moving the selection
since the reversion panel wouldn't show up otherwise.
* ManualTests/autocorrection/undo-autocorrection-2.html: Copied. Automated most of steps in the second test case.
* ManualTests/autocorrection/undo-autocorrection.html:

Source/WebCore:

<rdar://problem/20490862>
<rdar://problem/24707954>

Reviewed by Darin Adler.

When the user had typed "doesn'", some unified spellchecker may try to autocorrect it to "doesn't" or "does"
but we should ignore this for a moment until the next character is typed by the user. The code to deal with
this situation which checks the existence of an "ambiguous boundary character" was not robust when the
replacement text was longer than the corrected text.

Fixed this bug by fixing the logic to detect this case. Also added '@' as an ambiguous boundary character
since autocorrecting letters that appear right before '@' would not be useful in many cases.

Tests: ManualTests/autocorrection/autocorrection-at-mark.html
       ManualTests/autocorrection/autocorrection-contraction-2.html

* editing/AlternativeTextController.cpp:
(WebCore::AlternativeTextController::timerFired): Fixed a bug that we can show an empty reversion panel.
* editing/Editor.cpp:
(WebCore::Editor::markAndReplaceFor): When the user had typed "doesn'" and our autocorrection result is
"doesn't", resultEndLocation (the end of "doesn't") is larger than selectionOffset (the end of "doesn'").
When the correction is "does", resultEndLocation (the end of "does") is one less than selectionOffset.
Updated the condition to deal with both of these conditions as well as cases where the correction result
contains more than one letter after '.
* editing/htmlediting.cpp:
(WebCore::isAmbiguousBoundaryCharacter): Moved from the header file since this is not a hot function and
doesn't need to be inlined everywhere. Added '@' as an ambiguous boundary character.
* editing/htmlediting.h:
(WebCore::isAmbiguousBoundaryCharacter): Moved to the cpp file.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@201490 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
ChangeLog
ManualTests/autocorrection/autocorrection-at-mark.html [new file with mode: 0644]
ManualTests/autocorrection/autocorrection-cancelled-by-ESC.html
ManualTests/autocorrection/autocorrection-cancelled-by-typing-1.html
ManualTests/autocorrection/autocorrection-contraction.html
ManualTests/autocorrection/autocorrection-in-iframe.html
ManualTests/autocorrection/close-window-when-correction-is-shown.html
ManualTests/autocorrection/continue-typing-to-dismiss-reversion.html
ManualTests/autocorrection/delete-to-dismiss-reversion.html
ManualTests/autocorrection/delete-to-end-of-word-to-show-reversion.html
ManualTests/autocorrection/dismiss-multiple-guesses.html
ManualTests/autocorrection/move-to-end-of-word-to-show-reversion.html
ManualTests/autocorrection/remove-misspelling-marker-after-appending-letter.html
ManualTests/autocorrection/removing-misspelling-marker-after-appending-letter-2.html [new file with mode: 0644]
ManualTests/autocorrection/resources/document-for-iframe-test.html [moved from ManualTests/autocorrection/document-for-iframe-test.html with 83% similarity]
ManualTests/autocorrection/select-from-multiple-guesses.html
ManualTests/autocorrection/spell-checking-after-reversion.html
ManualTests/autocorrection/type-whitespace-to-dismiss-reversion.html
ManualTests/autocorrection/undo-autocorrection-2.html [new file with mode: 0644]
ManualTests/autocorrection/undo-autocorrection.html
Source/WebCore/ChangeLog
Source/WebCore/editing/AlternativeTextController.cpp
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/htmlediting.cpp
Source/WebCore/editing/htmlediting.h

index aff266e..7877a4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+2016-05-28  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Autocorrection makes it hard to type "doesn't" and to type @ in email addresses
+        https://bugs.webkit.org/show_bug.cgi?id=158177
+
+        Reviewed by Darin Adler.
+
+        Fixed manual tests for autocorrection panels and added a manual test for . Most of changes are fixing up the path to LayoutTests/editing/editing.js.
+
+        Also wrap many steps to type in a space or delete a character inside setTimeout since autocorrection happens on a timer
+        and the fact WebKit2 communicates with NSSpellChecker via IPC makes the behavior even more indeterministic.
+
+        * ManualTests/autocorrection/autocorrection-at-mark.html: Added.
+        * ManualTests/autocorrection/autocorrection-cancelled-by-ESC.html:
+        * ManualTests/autocorrection/autocorrection-cancelled-by-typing-1.html:
+        * ManualTests/autocorrection/autocorrection-contraction-2.html: Added.
+        * ManualTests/autocorrection/autocorrection-contraction.html:
+        * ManualTests/autocorrection/autocorrection-in-iframe.html:
+        * ManualTests/autocorrection/close-window-when-correction-is-shown.html:
+        * ManualTests/autocorrection/continue-typing-to-dismiss-reversion.html:
+        * ManualTests/autocorrection/delete-to-dismiss-reversion.html:
+        * ManualTests/autocorrection/delete-to-end-of-word-to-show-reversion.html:
+        * ManualTests/autocorrection/dismiss-multiple-guesses.html:
+        * ManualTests/autocorrection/document-for-iframe-test.html: Removed.
+        * ManualTests/autocorrection/move-to-end-of-word-to-show-reversion.html: Type a space and move care in setTimeout as
+        the reversion panel wouldn't show up otherwise.
+        * ManualTests/autocorrection/remove-misspelling-marker-after-appending-letter.html: Delay the typing of a space as well as
+        deleting letters since autocorrection panel wouldn't show up in time otherwise, and deleting character immediately would
+        reject the autocorrection instead of accepting it. Also removed the steps to add back the spellchecking marker and extracted
+        it as a separate test.
+        * ManualTests/autocorrection/removing-misspelling-marker-after-appending-letter-2.html: Copied. This test continues the full
+        scenario in the previous test by typing a space and deleting the character, thereby bringing up spellchecking marker.
+        * ManualTests/autocorrection/resources: Added.
+        * ManualTests/autocorrection/resources/document-for-iframe-test.html: Moved from ManualTests/autocorrection/.
+        * ManualTests/autocorrection/select-from-multiple-guesses.html: Added a missing instruction.
+        * ManualTests/autocorrection/spell-checking-after-reversion.html:
+        * ManualTests/autocorrection/type-whitespace-to-dismiss-reversion.html: Delay the typing of a space and moving the selection
+        since the reversion panel wouldn't show up otherwise.
+        * ManualTests/autocorrection/undo-autocorrection-2.html: Copied. Automated most of steps in the second test case.
+        * ManualTests/autocorrection/undo-autocorrection.html:
+
 2016-05-25  Konstantin Tokarev  <annulen@yandex.ru>
 
         [cmake] Deduplicate make-js-file-arrays usage and make it work on Windows.
diff --git a/ManualTests/autocorrection/autocorrection-at-mark.html b/ManualTests/autocorrection/autocorrection-at-mark.html
new file mode 100644 (file)
index 0000000..57d20ef
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests words won't be corrected immediately when "@" is typed.<br>
+To test, "jcomet@". "jcomet" should not be autocorrected to "commet@".</p>
+<div contenteditable><br></div>
+<script>
+document.querySelector('div').focus();
+document.execCommand('insertText', false, 'Hello, ');
+</script>
+</body>
+</html>
index e6af6ec..61f40e6 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index 3e78bb1..65ef99a 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index ca40d62..fe67469 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index c4ebbcf..091f71a 100644 (file)
@@ -10,7 +10,7 @@
 <br>
 <br>
 <div style="-webkit-transform: translate(100px, 100px) rotate(20deg)">
-  <iframe src="document-for-iframe-test.html"></iframe>
+  <iframe src="resources/document-for-iframe-test.html"></iframe>
 </div>
 </body>
 </html>
index 5c82a20..e186df2 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index a1011fa..c364bec 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index bbaa77d..1eebfe8 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index aad1376..e177be9 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
@@ -22,8 +22,12 @@ function editingTest() {
     typeCharacterCommand('a');
     typeCharacterCommand('g');
     typeCharacterCommand('e');
-    typeCharacterCommand(' ');
-    execDeleteCommand();
+    setTimeout(function () {
+        typeCharacterCommand(' ');
+        setTimeout(function () {
+            execDeleteCommand();
+        }, 100);
+    }, 100);
 }
 
 </script>
index 67171b7..1184d9e 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index ce0170a..5310fc2 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
@@ -22,8 +22,12 @@ function editingTest() {
     typeCharacterCommand('a');
     typeCharacterCommand('g');
     typeCharacterCommand('e');
-    typeCharacterCommand(' ');
-    execMoveSelectionBackwardByCharacterCommand();
+    setTimeout(function () {
+        typeCharacterCommand(' ');
+            setTimeout(function () {
+                execMoveSelectionBackwardByCharacterCommand();
+            }, 100);
+    }, 100);
 }
 
 </script>
index f1c5350..e036b32 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px; 
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 
@@ -16,14 +16,13 @@ function editingTest() {
     textarea = document.getElementById('test');
     textarea.focus();
     document.execCommand("InsertText", false, "this brougt");
-    typeCharacterCommand(' ');
-    document.execCommand("Delete");
-    document.execCommand("Delete");
-    typeCharacterCommand(' ');
-    
-    // Now the word "brough" should carry misspelling marker.
-    
-    document.execCommand("Delete");
+    setTimeout(function () {
+        typeCharacterCommand(' ');
+        setTimeout(function () {
+            document.execCommand("Delete");
+            document.execCommand("Delete");
+        }, 100);
+    }, 100);
 }
 
 </script>
@@ -31,8 +30,8 @@ function editingTest() {
 <title>Removing misspelling marker after appending letter test.</title> 
 </head> 
 <body>
-<div>The test verified that misspelling marker is removed after appending new letter to misspelled word. You should see the phrase "this brought" without red underline.</div>
-<p  style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously dismissed 'brought' as the correct spelling of 'brougth' several times, the spell checker will not provide 'notational' as a suggestion anymore. To fix this, remove all files in ~/Library/Spelling.</p>
+<div>The test verified that misspelling marker is removed after accepting a correction. You should see the phrase "this brough" without red underline.</div>
+<p  style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously dismissed 'brought' as the correct spelling of 'brougt' several times, the spell checker will not provide 'notational' as a suggestion anymore. To fix this, remove all files in ~/Library/Spelling.</p>
 <textarea id="test" cols="80" rows="10"></textarea>
 </div>
 
diff --git a/ManualTests/autocorrection/removing-misspelling-marker-after-appending-letter-2.html b/ManualTests/autocorrection/removing-misspelling-marker-after-appending-letter-2.html
new file mode 100644 (file)
index 0000000..5a1ddf1
--- /dev/null
@@ -0,0 +1,49 @@
+<html> 
+<head>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    padding: 12px; 
+    font-size: 24px; 
+}
+</style>
+<script src="../../LayoutTests/editing/editing.js"></script>
+
+<script>
+
+function editingTest() {
+    textarea = document.getElementById('test');
+    textarea.focus();
+
+    document.execCommand("InsertText", false, "this brougt");
+    setTimeout(function () {
+        typeCharacterCommand(' ');
+        setTimeout(function () {
+            document.execCommand("Delete");
+            document.execCommand("Delete");
+            setTimeout(function () {
+                typeCharacterCommand(" ");
+                document.execCommand("Delete");
+            }, 100);
+        }, 100);
+    }, 100);
+}
+
+</script>
+
+<title>Removing misspelling marker after appending letter test.</title> 
+</head> 
+<body>
+<div>The test verified that misspelling marker is removed after appending new letter to misspelled word. You should see the phrase "this brought" without red underline.</div>
+<p  style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously dismissed 'brought' as the correct spelling of 'brougth' several times, the spell checker will not provide 'notational' as a suggestion anymore. To fix this, remove all files in ~/Library/Spelling.</p>
+<textarea id="test" cols="80" rows="10"></textarea>
+</div>
+
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
@@ -8,7 +8,7 @@
 }
 </style>
 
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index cbd1dcd..8952c22 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
@@ -34,7 +34,7 @@ function editingTest() {
 </head>
 <body>
 <div><p>This test verifies that multiple guesses on mispelled word is working correctly</p>
-<p>After seeing the panel with multiple candidates, use left and/or right arrow key to select the desired candidate, and then use return key to confirm. You can also use this test to test that pressing ESC key will dismiss the panel.</p>
+<p>After seeing the panel with multiple candidates, use down arrow key to select the first candidate, and then use left and/or right arrow key to select the desired candidate, and then use return key to confirm. You can also use this test to test that pressing ESC key will dismiss the panel.</p>
 <p  style="color:green">Note, this test can fail due to user specific spell checking data. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p>
 <div contenteditable id="root" class="editing">
 <span id="test"></span>
index b125f8a..a80e315 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
index 8eb346a..9efffc1 100644 (file)
@@ -8,7 +8,7 @@
     font-size: 24px;
 }
 </style>
-<script src=../../../../LayoutTests/editing/editing.js language="JavaScript" type="text/JavaScript" ></script>
+<script src="../../LayoutTests/editing/editing.js"></script>
 
 <script>
 function editingTest() {
@@ -22,8 +22,12 @@ function editingTest() {
     typeCharacterCommand('a');
     typeCharacterCommand('g');
     typeCharacterCommand('e');
-    typeCharacterCommand(' ');
-    execMoveSelectionBackwardByCharacterCommand();
+    setTimeout(function () {
+        typeCharacterCommand(' ');
+        setTimeout(function () {
+            execMoveSelectionBackwardByCharacterCommand();
+        }, 100);
+    }, 100);
 }
 
 </script>
diff --git a/ManualTests/autocorrection/undo-autocorrection-2.html b/ManualTests/autocorrection/undo-autocorrection-2.html
new file mode 100644 (file)
index 0000000..1826793
--- /dev/null
@@ -0,0 +1,37 @@
+<html>
+<head>
+
+<style>
+.editing {
+    border: 2px solid red;
+    padding: 12px;
+    font-size: 24px;
+}
+</style>
+
+<title>Undo Autocorrection Test</title>
+</head>
+<body>
+<div><p>This test verifies the behavior of undoing autocorrection.</p>
+
+<p>Type "the ". Set font to bold, then type "me". Set font to regular, then type "sage". After seeing the correction panel, type whitespace to accept the correction (automated). Undo the autocorrection. You should see the second word being reverted to "message" with "me" in bold font.</p>
+<p  style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p>
+<div contenteditable id="root2" class="editing">
+<span id="test"></span>
+</div>
+<script>
+
+document.getElementById('root2').focus();
+document.execCommand('insertText', false, 'the ');
+document.execCommand('bold', false, null);
+document.execCommand('insertText', false, 'me');
+document.execCommand('bold', false, null);
+document.execCommand('insertText', false, 'sage');
+setTimeout(function () {
+    document.execCommand('insertText', false, ' ');
+}, 500);
+
+</script>
+
+</body>
+</html>
index 972c88b..dce7bd5 100644 (file)
 </head>
 <body>
 <div><p>This test verifies the behavior of undoing autocorrection.</p>
-<p><b>Test 1:</b> Type "the mesage". After seeing the correction panel, type whitespace to accept the correction, then select undo. You should see the second word being reverted to "message".</p>
-<p><b>Test 2:</b> Type "the ". Set font to bold, then type "me". Set font to regular, then type "sage". After seeing the correction panel, type whitespace to accept the correction, then select undo. You should see the second word being reverted to "message" with "me" in bold font.</p>
-<p  style="color:green">Note, this test can fail due to user specific spell checking data. If the user has previously frequently revert 'message' to 'mesage'. To fix this, remove all files in ~/Library/Spelling, then kill AppleSpell.service process.</p>
-<div contenteditable id="root" class="editing">
+<p>Type "the mesage". After seeing the correction panel, type whitespace to accept the correction, then select undo. You should see the second word being reverted to "message".</p>
+<div contenteditable id="root1" class="editing">
 <span id="test"></span>
 </div>
-
 </body>
 </html>
index 9ee7d71..429e4b8 100644 (file)
@@ -1,3 +1,37 @@
+2016-05-28  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Autocorrection makes it hard to type "doesn't" and to type @ in email addresses
+        https://bugs.webkit.org/show_bug.cgi?id=158177
+        <rdar://problem/20490862>
+        <rdar://problem/24707954>
+
+        Reviewed by Darin Adler.
+
+        When the user had typed "doesn'", some unified spellchecker may try to autocorrect it to "doesn't" or "does"
+        but we should ignore this for a moment until the next character is typed by the user. The code to deal with
+        this situation which checks the existence of an "ambiguous boundary character" was not robust when the
+        replacement text was longer than the corrected text.
+
+        Fixed this bug by fixing the logic to detect this case. Also added '@' as an ambiguous boundary character
+        since autocorrecting letters that appear right before '@' would not be useful in many cases.
+
+        Tests: ManualTests/autocorrection/autocorrection-at-mark.html
+               ManualTests/autocorrection/autocorrection-contraction-2.html
+
+        * editing/AlternativeTextController.cpp:
+        (WebCore::AlternativeTextController::timerFired): Fixed a bug that we can show an empty reversion panel.
+        * editing/Editor.cpp:
+        (WebCore::Editor::markAndReplaceFor): When the user had typed "doesn'" and our autocorrection result is
+        "doesn't", resultEndLocation (the end of "doesn't") is larger than selectionOffset (the end of "doesn'").
+        When the correction is "does", resultEndLocation (the end of "does") is one less than selectionOffset.
+        Updated the condition to deal with both of these conditions as well as cases where the correction result
+        contains more than one letter after '.
+        * editing/htmlediting.cpp:
+        (WebCore::isAmbiguousBoundaryCharacter): Moved from the header file since this is not a hot function and
+        doesn't need to be inlined everywhere. Added '@' as an ambiguous boundary character.
+        * editing/htmlediting.h:
+        (WebCore::isAmbiguousBoundaryCharacter): Moved to the cpp file.
+
 2016-05-28  Konstantin Tokarev  <annulen@yandex.ru>
 
         FileSystem: use OS(WINDOWS) instead of PLATFORM(WIN).
index 66e217e..f9d557c 100644 (file)
@@ -340,13 +340,13 @@ void AlternativeTextController::timerFired()
     }
         break;
     case AlternativeTextTypeReversion: {
-        if (!m_alternativeTextInfo.rangeWithAlternative)
+        auto* details = static_cast<const AutocorrectionAlternativeDetails*>(m_alternativeTextInfo.details.get());
+        if (!m_alternativeTextInfo.rangeWithAlternative || !details || details->replacementString().isEmpty())
             break;
         m_alternativeTextInfo.isActive = true;
         m_alternativeTextInfo.originalText = plainText(m_alternativeTextInfo.rangeWithAlternative.get());
         FloatRect boundingBox = rootViewRectForRange(m_alternativeTextInfo.rangeWithAlternative.get());
         if (!boundingBox.isEmpty()) {
-            const AutocorrectionAlternativeDetails* details = static_cast<const AutocorrectionAlternativeDetails*>(m_alternativeTextInfo.details.get());
             if (AlternativeTextClient* client = alternativeTextClient())
                 client->showCorrectionAlternative(m_alternativeTextInfo.type, boundingBox, m_alternativeTextInfo.originalText, details->replacementString(), Vector<String>());
         }
index 61a0c3b..813e3c6 100644 (file)
@@ -2524,7 +2524,7 @@ void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vect
         const int resultLength = results[i].length;
         const int resultEndLocation = resultLocation + resultLength;
         const String& replacement = results[i].replacement;
-        const bool resultEndsAtAmbiguousBoundary = useAmbiguousBoundaryOffset && resultEndLocation == selectionOffset - 1;
+        const bool resultEndsAtAmbiguousBoundary = useAmbiguousBoundaryOffset && selectionOffset - 1 <= resultEndLocation;
 
         // Only mark misspelling if:
         // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false.
index 1b7e064..b407908 100644 (file)
@@ -389,6 +389,14 @@ int lastOffsetForEditing(const Node& node)
     return 0;
 }
 
+bool isAmbiguousBoundaryCharacter(UChar character)
+{
+    // These are characters that can behave as word boundaries, but can appear within words.
+    // If they are just typed, i.e. if they are immediately followed by a caret, we want to delay text checking until the next character has been typed.
+    // FIXME: this is required until <rdar://problem/6853027> is fixed and text checking can do this for us.
+    return character == '\'' || character == '@' || character == rightSingleQuotationMark || character == hebrewPunctuationGershayim;
+}
+
 String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
 {
     StringBuilder rebalancedString;
index 07b0f10..e32928a 100644 (file)
@@ -215,13 +215,7 @@ inline bool deprecatedIsCollapsibleWhitespace(UChar c)
     return c == ' ' || c == '\n';
 }
 
-inline bool isAmbiguousBoundaryCharacter(UChar character)
-{
-    // These are characters that can behave as word boundaries, but can appear within words.
-    // If they are just typed, i.e. if they are immediately followed by a caret, we want to delay text checking until the next character has been typed.
-    // FIXME: this is required until 6853027 is fixed and text checking can do this for us.
-    return character == '\'' || character == rightSingleQuotationMark || character == hebrewPunctuationGershayim;
-}
+bool isAmbiguousBoundaryCharacter(UChar);
 
 inline bool editingIgnoresContent(const Node& node)
 {