- Revision
- 265286
- Author
- commit-qu...@webkit.org
- Date
- 2020-08-05 08:46:59 -0700 (Wed, 05 Aug 2020)
Log Message
TextManipulationController should observe newly inserted or displayed text
https://bugs.webkit.org/show_bug.cgi?id=215157
Patch by Sihui Liu <sihui_...@appe.com> on 2020-08-05
Reviewed by Wenson Hsieh.
Source/WebCore:
TextManipulationController already tracks renderer state of Element, but the case where Text children of an
Element is newly inserted and displayed is not covered. Therefore, TextManipulationController also needs to
know when render of Text is created.
API test: TextManipulation.CompleteTextManipulationForNewlyDisplayedText
* editing/TextManipulationController.cpp:
(WebCore::TextManipulationController::didCreateRendererForTextNode):
(WebCore::TextManipulationController::scheduleObservationUpdate):
(WebCore::TextManipulationController::removeNode):
* editing/TextManipulationController.h:
* rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::createTextRenderer):
Tools:
* TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
(TestWebKitAPI::TEST):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (265285 => 265286)
--- trunk/Source/WebCore/ChangeLog 2020-08-05 15:19:07 UTC (rev 265285)
+++ trunk/Source/WebCore/ChangeLog 2020-08-05 15:46:59 UTC (rev 265286)
@@ -1,3 +1,24 @@
+2020-08-05 Sihui Liu <sihui_...@appe.com>
+
+ TextManipulationController should observe newly inserted or displayed text
+ https://bugs.webkit.org/show_bug.cgi?id=215157
+
+ Reviewed by Wenson Hsieh.
+
+ TextManipulationController already tracks renderer state of Element, but the case where Text children of an
+ Element is newly inserted and displayed is not covered. Therefore, TextManipulationController also needs to
+ know when render of Text is created.
+
+ API test: TextManipulation.CompleteTextManipulationForNewlyDisplayedText
+
+ * editing/TextManipulationController.cpp:
+ (WebCore::TextManipulationController::didCreateRendererForTextNode):
+ (WebCore::TextManipulationController::scheduleObservationUpdate):
+ (WebCore::TextManipulationController::removeNode):
+ * editing/TextManipulationController.h:
+ * rendering/updating/RenderTreeUpdater.cpp:
+ (WebCore::RenderTreeUpdater::createTextRenderer):
+
2020-08-05 Youenn Fablet <you...@apple.com>
RegistrationDatabase::openSQLiteDatabase can spin
Modified: trunk/Source/WebCore/editing/TextManipulationController.cpp (265285 => 265286)
--- trunk/Source/WebCore/editing/TextManipulationController.cpp 2020-08-05 15:19:07 UTC (rev 265285)
+++ trunk/Source/WebCore/editing/TextManipulationController.cpp 2020-08-05 15:46:59 UTC (rev 265286)
@@ -541,10 +541,20 @@
m_manipulatedTextsWithNewContent.add(&text);
}
+void TextManipulationController::didCreateRendererForTextNode(Text& text)
+{
+ if (m_manipulatedNodes.contains(&text))
+ return;
+
+ scheduleObservationUpdate();
+
+ m_textNodesWithNewRenderer.add(&text);
+}
+
void TextManipulationController::scheduleObservationUpdate()
{
// An update is already scheduled.
- if (!m_manipulatedTextsWithNewContent.isEmpty() || !m_elementsWithNewRenderer.computesEmpty())
+ if (!m_textNodesWithNewRenderer.isEmpty() || !m_manipulatedTextsWithNewContent.isEmpty() || !m_elementsWithNewRenderer.computesEmpty())
return;
if (!m_document)
@@ -568,6 +578,10 @@
}
controller->m_manipulatedTextsWithNewContent.clear();
+ for (auto* text : controller->m_textNodesWithNewRenderer)
+ nodesToObserve.add(*text);
+ controller->m_textNodesWithNewRenderer.clear();
+
if (nodesToObserve.isEmpty())
return;
@@ -884,6 +898,7 @@
void TextManipulationController::removeNode(Node* node)
{
m_manipulatedNodes.remove(node);
+ m_textNodesWithNewRenderer.remove(node);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/TextManipulationController.h (265285 => 265286)
--- trunk/Source/WebCore/editing/TextManipulationController.h 2020-08-05 15:19:07 UTC (rev 265285)
+++ trunk/Source/WebCore/editing/TextManipulationController.h 2020-08-05 15:46:59 UTC (rev 265286)
@@ -116,6 +116,7 @@
WEBCORE_EXPORT void startObservingParagraphs(ManipulationItemCallback&&, Vector<ExclusionRule>&& = { });
void didCreateRendererForElement(Element&);
+ void didCreateRendererForTextNode(Text&);
void didUpdateContentForText(Text&);
void removeNode(Node*);
@@ -181,6 +182,7 @@
WeakPtr<Document> m_document;
WeakHashSet<Element> m_elementsWithNewRenderer;
HashSet<Text*> m_manipulatedTextsWithNewContent;
+ HashSet<Node*> m_textNodesWithNewRenderer;
HashSet<Node*> m_manipulatedNodes;
HashMap<String, bool> m_cachedFontFamilyExclusionResults;
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp (265285 => 265286)
--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp 2020-08-05 15:19:07 UTC (rev 265285)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp 2020-08-05 15:46:59 UTC (rev 265286)
@@ -482,6 +482,10 @@
}
m_builder.attach(renderTreePosition.parent(), WTFMove(textRenderer), renderTreePosition.nextSibling());
+
+ auto* textManipulationController = m_document.textManipulationControllerIfExists();
+ if (UNLIKELY(textManipulationController))
+ textManipulationController->didCreateRendererForTextNode(textNode);
}
void RenderTreeUpdater::updateTextRenderer(Text& text, const Style::TextUpdate* textUpdate)
Modified: trunk/Tools/ChangeLog (265285 => 265286)
--- trunk/Tools/ChangeLog 2020-08-05 15:19:07 UTC (rev 265285)
+++ trunk/Tools/ChangeLog 2020-08-05 15:46:59 UTC (rev 265286)
@@ -1,3 +1,13 @@
+2020-08-05 Sihui Liu <sihui_...@appe.com>
+
+ TextManipulationController should observe newly inserted or displayed text
+ https://bugs.webkit.org/show_bug.cgi?id=215157
+
+ Reviewed by Wenson Hsieh.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
+ (TestWebKitAPI::TEST):
+
2020-08-05 Wenson Hsieh <wenson_hs...@apple.com>
[iOS] Keyboard shortcuts and arrow key scrolling stop working after navigating via swipe gesture
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm (265285 => 265286)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm 2020-08-05 15:19:07 UTC (rev 265285)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm 2020-08-05 15:46:59 UTC (rev 265286)
@@ -2184,7 +2184,7 @@
done = false;
delegate.get().itemCallback = ^(_WKTextManipulationItem *item) {
- if (items.count == 2)
+ if (items.count == 3)
done = true;
};
[webView stringByEvaluatingJavaScript:@"document.querySelector('p').innerHTML = 'hello, world bye';"
@@ -2808,6 +2808,61 @@
EXPECT_WK_STREQ("<b>WebKit!</b><span>Hello World<i>Bye</i></span>", [webView stringByEvaluatingJavaScript:@"document.querySelector('div').innerHTML"]);
}
+TEST(TextManipulation, CompleteTextManipulationForNewlyDisplayedText)
+{
+ 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>"
+ "<html>"
+ "<body>"
+ "<a>hello world</a>"
+ "</body>"
+ "</html>"];
+
+ done = false;
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ auto *items = [delegate items];
+ EXPECT_EQ(items.count, 1UL);
+ EXPECT_EQ(items[0].tokens.count, 1UL);
+ EXPECT_WK_STREQ("hello world", items[0].tokens[0].content);
+
+ done = false;
+ [webView _completeTextManipulationForItems:@[
+ createItem(items[0].identifier, {{ items[0].tokens[0].identifier, @"Hello World" }}).get()
+ ] completion:^(NSArray<NSError *> *errors) {
+ EXPECT_EQ(errors, nil);
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+ EXPECT_WK_STREQ("<a>Hello World</a>", [webView stringByEvaluatingJavaScript:@"document.body.innerHTML"]);
+
+ done = false;
+ delegate.get().itemCallback = ^(_WKTextManipulationItem *item) {
+ if (items.count == 2)
+ done = true;
+ };
+ NSString *scriptString = @"document.querySelector('a').innerHTML=''; document.querySelector('a').innerHTML='hello world again';";
+ [webView evaluateJavaScript:scriptString completionHandler:nil];
+ TestWebKitAPI::Util::run(&done);
+ EXPECT_EQ(items[1].tokens.count, 1UL);
+ EXPECT_WK_STREQ("hello world again", items[1].tokens[0].content);
+
+ done = false;
+ [webView _completeTextManipulationForItems:@[
+ createItem(items[1].identifier, {{ items[1].tokens[0].identifier, @"Hello World Again" }}).get()
+ ] completion:^(NSArray<NSError *> *errors) {
+ EXPECT_EQ(errors, nil);
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+ EXPECT_WK_STREQ("<a>Hello World Again</a>", [webView stringByEvaluatingJavaScript:@"document.body.innerHTML"]);
+}
+
TEST(TextManipulation, CompleteTextManipulationForManipulatedTextWithNewContent)
{
auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);