Changeset 260678 in webkit


Ignore:
Timestamp:
Apr 24, 2020 4:18:05 PM (4 years ago)
Author:
Wenson Hsieh
Message:

Make some more adjustments to TextManipulationController's paragraph boundary heuristic
https://bugs.webkit.org/show_bug.cgi?id=210993
<rdar://problem/61571299>

Reviewed by Tim Horton.

Source/WebCore:

Adjust the heuristic added in r260583 to account for a few more common scenarios where we currently consider
text as a part of the same paragraph. This can lead to many issues during text manipulation where text is moved
between these elements, when it should not be.

The new scenarios include block and inline-block links, as well as button elements.

Test: TextManipulation.StartTextManipulationTreatsInlineBlockLinksAndButtonsAsParagraphs

  • editing/TextManipulationController.cpp:

(WebCore::TextManipulationController::observeParagraphs):

Additionally rename "paragraph boundary element" to "item boundary element", to avoid colliding with the
existing notion of paragraph boundaries in editing code.

Tools:

Add a new API test with buttons and links styled with display: inline-block;. Additionally, rebaseline an
existing API test that exercises inline-block list items.

  • TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r260672 r260678  
     12020-04-24  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Make some more adjustments to TextManipulationController's paragraph boundary heuristic
     4        https://bugs.webkit.org/show_bug.cgi?id=210993
     5        <rdar://problem/61571299>
     6
     7        Reviewed by Tim Horton.
     8
     9        Adjust the heuristic added in r260583 to account for a few more common scenarios where we currently consider
     10        text as a part of the same paragraph. This can lead to many issues during text manipulation where text is moved
     11        between these elements, when it should not be.
     12
     13        The new scenarios include block and inline-block links, as well as button elements.
     14
     15        Test: TextManipulation.StartTextManipulationTreatsInlineBlockLinksAndButtonsAsParagraphs
     16
     17        * editing/TextManipulationController.cpp:
     18        (WebCore::TextManipulationController::observeParagraphs):
     19
     20        Additionally rename "paragraph boundary element" to "item boundary element", to avoid colliding with the
     21        existing notion of paragraph boundaries in editing code.
     22
    1232020-04-24  Christopher Reid  <chris.reid@sony.com>
    224
  • trunk/Source/WebCore/editing/TextManipulationController.cpp

    r260625 r260678  
    275275    Position startOfCurrentParagraph;
    276276    Position endOfCurrentParagraph;
    277     RefPtr<Element> enclosingParagraphElement;
    278 
    279     auto isEnclosingParagraphElement = [](const Element& element) {
    280         if (element.hasTagName(HTMLNames::liTag)) {
    281             auto* renderer = element.renderer();
    282             return renderer && renderer->style().display() == DisplayType::Block;
    283         }
     277    RefPtr<Element> enclosingItemBoundaryElement;
     278
     279    auto isEnclosingItemBoundaryElement = [](const Element& element) {
     280        auto* renderer = element.renderer();
     281        if (!renderer)
     282            return false;
     283
     284        if (element.hasTagName(HTMLNames::buttonTag))
     285            return true;
     286
     287        if (element.hasTagName(HTMLNames::liTag) || element.hasTagName(HTMLNames::aTag)) {
     288            auto displayType = renderer->style().display();
     289            return displayType == DisplayType::Block || displayType == DisplayType::InlineBlock;
     290        }
     291
    284292        return false;
    285293    };
     
    288296        auto content = iterator.currentContent();
    289297        if (content.node) {
    290             if (enclosingParagraphElement && !enclosingParagraphElement->contains(content.node.get())) {
     298            if (enclosingItemBoundaryElement && !enclosingItemBoundaryElement->contains(content.node.get())) {
    291299                if (!tokensInCurrentParagraph.isEmpty())
    292300                    addItem(ManipulationItemData { startOfCurrentParagraph, endOfCurrentParagraph, nullptr, nullQName(), std::exchange(tokensInCurrentParagraph, { }) });
    293                 enclosingParagraphElement = nullptr;
    294             }
     301                enclosingItemBoundaryElement = nullptr;
     302            }
     303
    295304            if (RefPtr<Element> currentElementAncestor = is<Element>(*content.node) ? downcast<Element>(content.node.get()) : content.node->parentOrShadowHostElement()) {
    296305                if (isInManipulatedElement(*currentElementAncestor))
     
    312321                    }
    313322                }
    314                 if (isEnclosingParagraphElement(currentElement))
    315                     enclosingParagraphElement = &currentElement;
     323                if (!enclosingItemBoundaryElement && isEnclosingItemBoundaryElement(currentElement))
     324                    enclosingItemBoundaryElement = &currentElement;
    316325            }
    317326        }
  • trunk/Tools/ChangeLog

    r260675 r260678  
     12020-04-24  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Make some more adjustments to TextManipulationController's paragraph boundary heuristic
     4        https://bugs.webkit.org/show_bug.cgi?id=210993
     5        <rdar://problem/61571299>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a new API test with buttons and links styled with `display: inline-block;`. Additionally, rebaseline an
     10        existing API test that exercises inline-block list items.
     11
     12        * TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
     13
    1142020-04-24  Chris Dumez  <cdumez@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm

    r260609 r260678  
    617617}
    618618
     619TEST(TextManipulation, StartTextManipulationTreatsInlineBlockLinksAndButtonsAsParagraphs)
     620{
     621    auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
     622    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
     623    [webView _setTextManipulationDelegate:delegate.get()];
     624
     625    [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html>"
     626        "<head>"
     627        "    <style>"
     628        "        a {"
     629        "            display: inline-block;"
     630        "            border: 1px blue solid;"
     631        "            margin-left: 1em;"
     632        "        }"
     633        "    </style>"
     634        "</head>"
     635        "<body>"
     636        "    <button>One</button><button>Two</button>"
     637        "    <div><br></div>"
     638        "    <a href='#'>Three</a><a href='#'>Four</a>"
     639        "</body>"];
     640
     641    done = false;
     642    [webView _startTextManipulationsWithConfiguration:nil completion:^{
     643        done = true;
     644    }];
     645    TestWebKitAPI::Util::run(&done);
     646
     647    NSArray<_WKTextManipulationItem *> *items = [delegate items];
     648    EXPECT_EQ(items.count, 4UL);
     649    EXPECT_EQ(items[0].tokens.count, 1UL);
     650    EXPECT_EQ(items[1].tokens.count, 1UL);
     651    EXPECT_EQ(items[2].tokens.count, 1UL);
     652    EXPECT_EQ(items[3].tokens.count, 1UL);
     653    EXPECT_WK_STREQ("One", items[0].tokens[0].content);
     654    EXPECT_WK_STREQ("Two", items[1].tokens[0].content);
     655    EXPECT_WK_STREQ("Three", items[2].tokens[0].content);
     656    EXPECT_WK_STREQ("Four", items[3].tokens[0].content);
     657}
     658
    619659struct Token {
    620660    NSString *identifier;
     
    17791819
    17801820    auto *items = [delegate items];
    1781     EXPECT_EQ(items.count, 1UL);
    1782     EXPECT_EQ(items[0].tokens.count, 2UL);
    1783     EXPECT_STREQ("holle", items[0].tokens[0].content.UTF8String);
    1784     EXPECT_STREQ("wdrlo", items[0].tokens[1].content.UTF8String);
    1785 
    1786     done = false;
    1787     [webView _completeTextManipulationForItems:@[(_WKTextManipulationItem *)createItem(items[0].identifier, {
    1788         { items[0].tokens[0].identifier, @"hello" },
    1789         { items[0].tokens[1].identifier, @"world" },
    1790     })] completion:^(NSArray<NSError *> *errors) {
     1821    EXPECT_EQ(items.count, 2UL);
     1822    EXPECT_EQ(items[0].tokens.count, 1UL);
     1823    EXPECT_EQ(items[1].tokens.count, 1UL);
     1824    EXPECT_WK_STREQ("holle", items[0].tokens[0].content);
     1825    EXPECT_WK_STREQ("wdrlo", items[1].tokens[0].content);
     1826
     1827    done = false;
     1828    [webView _completeTextManipulationForItems:@[
     1829        createItem(items[0].identifier, {{ items[0].tokens[0].identifier, @"hello" }}).autorelease(),
     1830        createItem(items[1].identifier, {{ items[1].tokens[0].identifier, @"world" }}).autorelease()
     1831    ] completion:^(NSArray<NSError *> *errors) {
    17911832        EXPECT_EQ(errors, nil);
    17921833        done = true;
Note: See TracChangeset for help on using the changeset viewer.