Title: [287849] trunk
- Revision
- 287849
- Author
- [email protected]
- Date
- 2022-01-10 11:19:54 -0800 (Mon, 10 Jan 2022)
Log 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 `bool`s: 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):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (287848 => 287849)
--- trunk/Source/WebCore/ChangeLog 2022-01-10 19:16:17 UTC (rev 287848)
+++ trunk/Source/WebCore/ChangeLog 2022-01-10 19:19:54 UTC (rev 287849)
@@ -1,3 +1,27 @@
+2022-01-10 Wenson Hsieh <[email protected]>
+
+ 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.
+
+ 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 `bool`s: 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.
+
2022-01-10 Alex Christensen <[email protected]>
Start using C++20
Modified: trunk/Source/WebCore/page/ModalContainerObserver.cpp (287848 => 287849)
--- trunk/Source/WebCore/page/ModalContainerObserver.cpp 2022-01-10 19:16:17 UTC (rev 287848)
+++ trunk/Source/WebCore/page/ModalContainerObserver.cpp 2022-01-10 19:19:54 UTC (rev 287849)
@@ -147,13 +147,22 @@
return false;
}
-static bool containsMatchingText(RenderLayerModelObject& renderer, const AtomString& searchTerm)
+struct TextSearchResult {
+ bool foundMatch { false };
+ bool containsAnyText { false };
+};
+
+static TextSearchResult searchForMatch(RenderLayerModelObject& renderer, const AtomString& searchTerm)
{
+ TextSearchResult result;
for (auto& textRenderer : descendantsOfType<RenderText>(renderer)) {
- if (RefPtr textNode = textRenderer.textNode(); textNode && matchesSearchTerm(*textNode, searchTerm))
- return !isInsideNavigationElement(*textNode);
+ result.containsAnyText = true;
+ if (RefPtr textNode = textRenderer.textNode(); textNode && matchesSearchTerm(*textNode, searchTerm)) {
+ result.foundMatch = !isInsideNavigationElement(*textNode);
+ return result;
+ }
}
- return false;
+ return result;
}
void ModalContainerObserver::searchForModalContainerOnBehalfOfFrameOwnerIfNeeded(HTMLFrameOwnerElement& owner)
@@ -213,10 +222,15 @@
if (!element || is<HTMLBodyElement>(*element) || element->isDocumentNode())
continue;
- if (!m_elementsToIgnoreWhenSearching.add(*element).isNewEntry)
+ if (m_elementsToIgnoreWhenSearching.contains(*element))
continue;
- if (containsMatchingText(renderer, searchTerm)) {
+ auto [foundMatch, containsAnyText] = searchForMatch(renderer, searchTerm);
+
+ if (containsAnyText)
+ m_elementsToIgnoreWhenSearching.add(*element);
+
+ if (foundMatch) {
setContainer(*element);
return;
}
@@ -230,7 +244,7 @@
if (!renderView)
continue;
- if (containsMatchingText(*renderView, searchTerm)) {
+ if (searchForMatch(*renderView, searchTerm).foundMatch) {
setContainer(*element, &frameOwner);
return;
}
Modified: trunk/Tools/ChangeLog (287848 => 287849)
--- trunk/Tools/ChangeLog 2022-01-10 19:16:17 UTC (rev 287848)
+++ trunk/Tools/ChangeLog 2022-01-10 19:19:54 UTC (rev 287849)
@@ -1,3 +1,16 @@
+2022-01-10 Wenson Hsieh <[email protected]>
+
+ 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.
+
+ Add a new API test to exercise the change.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm:
+ (TestWebKitAPI::TEST):
+
2022-01-10 Alex Christensen <[email protected]>
Start using C++20
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm (287848 => 287849)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm 2022-01-10 19:16:17 UTC (rev 287848)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ModalContainerObservation.mm 2022-01-10 19:19:54 UTC (rev 287849)
@@ -317,4 +317,15 @@
EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypePositive);
}
+TEST(ModalContainerObservation, DetectModalContainerAfterSettingText)
+{
+ auto webView = createModalContainerWebView();
+ [webView loadBundlePage:@"modal-container-custom"];
+ [webView objectByEvaluatingJavaScript:@"show(`<div id='content'></div>`)"];
+ [webView waitForNextPresentationUpdate];
+ [webView evaluate:@"document.getElementById('content').innerHTML = `hello world <a href=''>no</a>`" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];
+ EXPECT_FALSE([[webView contentsAsString] containsString:@"hello world"]);
+ EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypeNegative);
+}
+
} // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes