⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 287849 in webkit


Ignore:
Timestamp:
Jan 10, 2022, 11:19:54 AM (5 years ago)
Author:
Wenson Hsieh
Message:

Modal container observer fails detection when rendered text is inserted after the container
https://bugs.webkit.org/show_bug.cgi?id=234752
rdar://87200177

Reviewed by Tim Horton.

Source/WebCore:

Teach ModalContainerObserver to detect modal containers whose text content is set by script after the container
element itself has already been inserted into the document and laid out. See below for more details.

Test: ModalContainerObservation.DetectModalContainerAfterSettingText

  • page/ModalContainerObserver.cpp:

(WebCore::searchForMatch):

Change this to return two bools: one indicating whether a match was found (i.e. the original return value),
and another indicating whether any rendered text was discovered in the process of searching. In the case where
the viewport-constrained element did not contain any rendered text at all, we avoid adding the element to the
m_elementsToIgnoreWhenSearching set, thereby allowing us to search it again in the future.

(WebCore::ModalContainerObserver::updateModalContainerIfNeeded):
(WebCore::containsMatchingText): Deleted.

Tools:

Add a new API test to exercise the change.

  • TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm:

(TestWebKitAPI::TEST):

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r287848 r287849  
     12022-01-10  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Modal container observer fails detection when rendered text is inserted after the container
     4        https://bugs.webkit.org/show_bug.cgi?id=234752
     5        rdar://87200177
     6
     7        Reviewed by Tim Horton.
     8
     9        Teach ModalContainerObserver to detect modal containers whose text content is set by script after the container
     10        element itself has already been inserted into the document and laid out. See below for more details.
     11
     12        Test: ModalContainerObservation.DetectModalContainerAfterSettingText
     13
     14        * page/ModalContainerObserver.cpp:
     15        (WebCore::searchForMatch):
     16
     17        Change this to return two `bool`s: one indicating whether a match was found (i.e. the original return value),
     18        and another indicating whether any rendered text was discovered in the process of searching. In the case where
     19        the viewport-constrained element did not contain any rendered text at all, we avoid adding the element to the
     20        `m_elementsToIgnoreWhenSearching` set, thereby allowing us to search it again in the future.
     21
     22        (WebCore::ModalContainerObserver::updateModalContainerIfNeeded):
     23        (WebCore::containsMatchingText): Deleted.
     24
    1252022-01-10  Alex Christensen  <achristensen@webkit.org>
    226
  • trunk/Source/WebCore/page/ModalContainerObserver.cpp

    r287777 r287849  
    148148}
    149149
    150 static bool containsMatchingText(RenderLayerModelObject& renderer, const AtomString& searchTerm)
    151 {
     150struct TextSearchResult {
     151    bool foundMatch { false };
     152    bool containsAnyText { false };
     153};
     154
     155static TextSearchResult searchForMatch(RenderLayerModelObject& renderer, const AtomString& searchTerm)
     156{
     157    TextSearchResult result;
    152158    for (auto& textRenderer : descendantsOfType<RenderText>(renderer)) {
    153         if (RefPtr textNode = textRenderer.textNode(); textNode && matchesSearchTerm(*textNode, searchTerm))
    154             return !isInsideNavigationElement(*textNode);
    155     }
    156     return false;
     159        result.containsAnyText = true;
     160        if (RefPtr textNode = textRenderer.textNode(); textNode && matchesSearchTerm(*textNode, searchTerm)) {
     161            result.foundMatch = !isInsideNavigationElement(*textNode);
     162            return result;
     163        }
     164    }
     165    return result;
    157166}
    158167
     
    214223            continue;
    215224
    216         if (!m_elementsToIgnoreWhenSearching.add(*element).isNewEntry)
     225        if (m_elementsToIgnoreWhenSearching.contains(*element))
    217226            continue;
    218227
    219         if (containsMatchingText(renderer, searchTerm)) {
     228        auto [foundMatch, containsAnyText] = searchForMatch(renderer, searchTerm);
     229
     230        if (containsAnyText)
     231            m_elementsToIgnoreWhenSearching.add(*element);
     232
     233        if (foundMatch) {
    220234            setContainer(*element);
    221235            return;
     
    231245                continue;
    232246
    233             if (containsMatchingText(*renderView, searchTerm)) {
     247            if (searchForMatch(*renderView, searchTerm).foundMatch) {
    234248                setContainer(*element, &frameOwner);
    235249                return;
  • trunk/Tools/ChangeLog

    r287848 r287849  
     12022-01-10  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Modal container observer fails detection when rendered text is inserted after the container
     4        https://bugs.webkit.org/show_bug.cgi?id=234752
     5        rdar://87200177
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a new API test to exercise the change.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm:
     12        (TestWebKitAPI::TEST):
     13
    1142022-01-10  Alex Christensen  <achristensen@webkit.org>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm

    r287777 r287849  
    318318}
    319319
     320TEST(ModalContainerObservation, DetectModalContainerAfterSettingText)
     321{
     322    auto webView = createModalContainerWebView();
     323    [webView loadBundlePage:@"modal-container-custom"];
     324    [webView objectByEvaluatingJavaScript:@"show(`<div id='content'></div>`)"];
     325    [webView waitForNextPresentationUpdate];
     326    [webView evaluate:@"document.getElementById('content').innerHTML = `hello world <a href='#'>no</a>`" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];
     327    EXPECT_FALSE([[webView contentsAsString] containsString:@"hello world"]);
     328    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypeNegative);
     329}
     330
    320331} // namespace TestWebKitAPI
Note: See TracChangeset for help on using the changeset viewer.