Title: [265361] trunk
Revision
265361
Author
sihui_...@apple.com
Date
2020-08-06 18:24:05 -0700 (Thu, 06 Aug 2020)

Log Message

Text manipulation: leading and trailing spaces should be ignored when comparing content
https://bugs.webkit.org/show_bug.cgi?id=214878
<rdar://problem/63735024>

Reviewed by Ryosuke Niwa.

Source/WebCore:

TextIterator does not emit collapsed space if there is no text emitted before or the last emitted character is
collapsed space. When TextManipulationController starts observing paragraphs, it iterates the whole document and
the range of TextIterator is the range of document. For some text node A in the document, if TextIterator emits
text for some other text node B before it, the collapsed space at the beginning of A will be emitted, and
TextManipulationController would think the emitted space is part of A's content. When TextManipulationController
replaces content for A, and the range of TextIterator is set to the range of A, the collapsed space is not
emitted. The check to ensure A's content is unchanged would fail.

To solve this issue, for first and last token in the paragraph, TextManipulationController checks content after
removing leading and trailing spaces.

API test: TextManipulation.CompleteTextManipulationParagraphsContainCollapsedSpaces

* editing/TextManipulationController.cpp:
(WebCore::areEqualIgnoringLeadingAndTrailingWhitespaces):
(WebCore::TextManipulationController::replace):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (265360 => 265361)


--- trunk/Source/WebCore/ChangeLog	2020-08-07 01:18:37 UTC (rev 265360)
+++ trunk/Source/WebCore/ChangeLog	2020-08-07 01:24:05 UTC (rev 265361)
@@ -1,3 +1,28 @@
+2020-08-06  Sihui Liu  <sihui_...@apple.com>
+
+        Text manipulation: leading and trailing spaces should be ignored when comparing content
+        https://bugs.webkit.org/show_bug.cgi?id=214878
+        <rdar://problem/63735024>
+
+        Reviewed by Ryosuke Niwa.
+
+        TextIterator does not emit collapsed space if there is no text emitted before or the last emitted character is 
+        collapsed space. When TextManipulationController starts observing paragraphs, it iterates the whole document and
+        the range of TextIterator is the range of document. For some text node A in the document, if TextIterator emits 
+        text for some other text node B before it, the collapsed space at the beginning of A will be emitted, and 
+        TextManipulationController would think the emitted space is part of A's content. When TextManipulationController
+        replaces content for A, and the range of TextIterator is set to the range of A, the collapsed space is not 
+        emitted. The check to ensure A's content is unchanged would fail.
+ 
+        To solve this issue, for first and last token in the paragraph, TextManipulationController checks content after 
+        removing leading and trailing spaces.
+ 
+        API test: TextManipulation.CompleteTextManipulationParagraphsContainCollapsedSpaces
+
+        * editing/TextManipulationController.cpp:
+        (WebCore::areEqualIgnoringLeadingAndTrailingWhitespaces):
+        (WebCore::TextManipulationController::replace):
+
 2020-08-06  Kenneth Russell  <k...@chromium.org>
 
         Implement createImageBitmap(ImageData)

Modified: trunk/Source/WebCore/editing/TextManipulationController.cpp (265360 => 265361)


--- trunk/Source/WebCore/editing/TextManipulationController.cpp	2020-08-07 01:18:37 UTC (rev 265360)
+++ trunk/Source/WebCore/editing/TextManipulationController.cpp	2020-08-07 01:24:05 UTC (rev 265361)
@@ -281,6 +281,11 @@
     return element.hasTagName(HTMLNames::titleTag) || element.hasTagName(HTMLNames::optionTag);
 }
 
+static bool areEqualIgnoringLeadingAndTrailingWhitespaces(const String& content, const String& originalContent)
+{
+    return content.stripWhiteSpace() == originalContent.stripWhiteSpace();
+}
+
 static Optional<TextManipulationController::ManipulationTokenInfo> tokenInfo(Node* node)
 {
     if (!node)
@@ -793,7 +798,13 @@
                 return ManipulationFailureType::ContentChanged;
 
             auto& currentToken = item.tokens[currentTokenIndex++];
-            if (!content.isReplacedContent && currentToken.content != token.content)
+            bool isContentUnchanged = currentToken.content == token.content;
+            if (!UNLIKELY(isContentUnchanged)) {
+                bool isFirstOrLastToken = currentTokenIndex == 1 || currentTokenIndex == item.tokens.size();
+                isContentUnchanged = isFirstOrLastToken && areEqualIgnoringLeadingAndTrailingWhitespaces(currentToken.content, token.content);
+            }
+
+            if (!content.isReplacedContent && !isContentUnchanged)
                 return ManipulationFailureType::ContentChanged;
 
             tokenExchangeMap.set(currentToken.identifier, TokenExchangeData { content.node.copyRef(), currentToken.content, !isNodeIncluded });

Modified: trunk/Tools/ChangeLog (265360 => 265361)


--- trunk/Tools/ChangeLog	2020-08-07 01:18:37 UTC (rev 265360)
+++ trunk/Tools/ChangeLog	2020-08-07 01:24:05 UTC (rev 265361)
@@ -1,3 +1,14 @@
+2020-08-06  Sihui Liu  <sihui_...@apple.com>
+
+        Text manipulation: leading and trailing spaces should be ignored when comparing content
+        https://bugs.webkit.org/show_bug.cgi?id=214878
+        <rdar://problem/63735024>
+
+        Reviewed by Ryosuke Niwa.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
+        (TestWebKitAPI::TEST):
+
 2020-08-06  Jonathan Bedard  <jbed...@apple.com>
 
         [webkitcorepy] Standardize setuptools version

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm (265360 => 265361)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm	2020-08-07 01:18:37 UTC (rev 265360)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm	2020-08-07 01:24:05 UTC (rev 265361)
@@ -3040,6 +3040,48 @@
     EXPECT_WK_STREQ("auto", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.querySelector('span')).overflowY"]);
 }
 
+TEST(TextManipulation, CompleteTextManipulationParagraphsContainCollapsedSpaces)
+{
+    auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+    [webView _setTextManipulationDelegate:delegate.get()];
+    [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html>"
+        "<head>"
+        "<style>"
+        "span { display: inline-block; }"
+        "</style>"
+        "</head>"
+        "<body>"
+        "<span>  hello</span>"
+        "<span>  world</span>"
+        "</body>"];
+
+    done = false;
+    [webView _startTextManipulationsWithConfiguration:nil completion:^{
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    auto items = [delegate items];
+    EXPECT_EQ(items.count, 2UL);
+    EXPECT_EQ(items[0].tokens.count, 1UL);
+    EXPECT_WK_STREQ("hello", items[0].tokens[0].content);
+    EXPECT_EQ(items[1].tokens.count, 1UL);
+    EXPECT_WK_STREQ(" world", items[1].tokens[0].content);
+
+    done = false;
+    [webView _completeTextManipulationForItems:@[
+        createItem(items[0].identifier, {{ items[0].tokens[0].identifier, @"Hello" }}).get(),
+        createItem(items[1].identifier, {{ items[1].tokens[0].identifier, @"World" }}).get(),
+    ] completion:^(NSArray<NSError *> *errors) {
+        EXPECT_EQ(errors, nil);
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+
+    EXPECT_WK_STREQ("<span>Hello</span><span>World</span>", [webView stringByEvaluatingJavaScript:@"document.body.innerHTML"]);
+}
+
 TEST(TextManipulation, TextManipulationTokenDebugDescription)
 {
     auto token = adoptNS([[_WKTextManipulationToken alloc] init]);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to