Title: [285725] trunk/Source/WebCore
Revision
285725
Author
[email protected]
Date
2021-11-12 08:52:20 -0800 (Fri, 12 Nov 2021)

Log Message

Move subtree update logic in ImageOverlay::updateWithTextRecognitionResult() into a separate helper
https://bugs.webkit.org/show_bug.cgi?id=233010

Reviewed by Aditya Keerthi.

Split `updateWithTextRecognitionResult()` into two phases: the first of which updates the UA shadow DOM to
reflect the given text recognition results, and a second phase that updates inline styles for each of the image
overlay elements by mapping normalized OCR quads onto rotated bounding rects in client coordinates. This will
make it easier to add support for representing `TextRecognitionBlockData` as image overlay content in the next
patch.

* dom/ImageOverlay.cpp:
(WebCore::ImageOverlay::imageOverlayLineClass):
(WebCore::ImageOverlay::imageOverlayTextClass):
(WebCore::ImageOverlay::updateSubtree):

Now that this is all namespaced inside `ImageOverlay`, we can also simplify some of these names. Instead of
TextRecognitionLineElements and TextRecognitionElements, we can just call them LineElements and Elements.

(WebCore::ImageOverlay::updateWithTextRecognitionResult):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (285724 => 285725)


--- trunk/Source/WebCore/ChangeLog	2021-11-12 16:39:49 UTC (rev 285724)
+++ trunk/Source/WebCore/ChangeLog	2021-11-12 16:52:20 UTC (rev 285725)
@@ -1,3 +1,26 @@
+2021-11-12  Wenson Hsieh  <[email protected]>
+
+        Move subtree update logic in ImageOverlay::updateWithTextRecognitionResult() into a separate helper
+        https://bugs.webkit.org/show_bug.cgi?id=233010
+
+        Reviewed by Aditya Keerthi.
+
+        Split `updateWithTextRecognitionResult()` into two phases: the first of which updates the UA shadow DOM to
+        reflect the given text recognition results, and a second phase that updates inline styles for each of the image
+        overlay elements by mapping normalized OCR quads onto rotated bounding rects in client coordinates. This will
+        make it easier to add support for representing `TextRecognitionBlockData` as image overlay content in the next
+        patch.
+
+        * dom/ImageOverlay.cpp:
+        (WebCore::ImageOverlay::imageOverlayLineClass):
+        (WebCore::ImageOverlay::imageOverlayTextClass):
+        (WebCore::ImageOverlay::updateSubtree):
+
+        Now that this is all namespaced inside `ImageOverlay`, we can also simplify some of these names. Instead of
+        TextRecognitionLineElements and TextRecognitionElements, we can just call them LineElements and Elements.
+
+        (WebCore::ImageOverlay::updateWithTextRecognitionResult):
+
 2021-11-12  Adrian Perez de Castro  <[email protected]>
 
         Some C++ source files use #pragma once

Modified: trunk/Source/WebCore/dom/ImageOverlay.cpp (285724 => 285725)


--- trunk/Source/WebCore/dom/ImageOverlay.cpp	2021-11-12 16:39:49 UTC (rev 285724)
+++ trunk/Source/WebCore/dom/ImageOverlay.cpp	2021-11-12 16:52:20 UTC (rev 285725)
@@ -69,6 +69,22 @@
     return className;
 }
 
+#if ENABLE(IMAGE_ANALYSIS)
+
+static const AtomString& imageOverlayLineClass()
+{
+    static MainThreadNeverDestroyed<const AtomString> className("image-overlay-line", AtomString::ConstructFromLiteral);
+    return className;
+}
+
+static const AtomString& imageOverlayTextClass()
+{
+    static MainThreadNeverDestroyed<const AtomString> className("image-overlay-text", AtomString::ConstructFromLiteral);
+    return className;
+}
+
+#endif // ENABLE(IMAGE_ANALYSIS)
+
 bool hasOverlay(const HTMLElement& element)
 {
     auto shadowRoot = element.shadowRoot();
@@ -166,24 +182,21 @@
     return enclosingIntRect(downcast<RenderImage>(*renderer).replacedContentRect());
 }
 
-void updateWithTextRecognitionResult(HTMLElement& element, const TextRecognitionResult& result, CacheTextRecognitionResults cacheTextRecognitionResults)
-{
-    static MainThreadNeverDestroyed<const AtomString> imageOverlayLineClass("image-overlay-line", AtomString::ConstructFromLiteral);
-    static MainThreadNeverDestroyed<const AtomString> imageOverlayTextClass("image-overlay-text", AtomString::ConstructFromLiteral);
+struct LineElements {
+    Ref<HTMLDivElement> line;
+    Vector<Ref<HTMLElement>> children;
+};
 
-    struct TextRecognitionLineElements {
-        Ref<HTMLDivElement> line;
-        Vector<Ref<HTMLElement>> children;
-    };
+struct Elements {
+    RefPtr<HTMLDivElement> root;
+    Vector<LineElements> lines;
+    Vector<Ref<HTMLDivElement>> dataDetectors;
+};
 
-    struct TextRecognitionElements {
-        RefPtr<HTMLDivElement> root;
-        Vector<TextRecognitionLineElements> lines;
-        Vector<Ref<HTMLDivElement>> dataDetectors;
-    };
-
-    bool hadExistingTextRecognitionElements = false;
-    TextRecognitionElements textRecognitionElements;
+static Elements updateSubtree(HTMLElement& element, const TextRecognitionResult& result)
+{
+    bool hadExistingElements = false;
+    Elements elements;
     RefPtr<HTMLElement> mediaControlsContainer;
     if (RefPtr shadowRoot = element.shadowRoot()) {
 #if ENABLE(MODERN_MEDIA_CONTROLS)
@@ -207,8 +220,8 @@
                 containerForImageOverlay = shadowRoot;
             for (auto& child : childrenOfType<HTMLDivElement>(*containerForImageOverlay)) {
                 if (child.getIdAttribute() == imageOverlayElementIdentifier()) {
-                    textRecognitionElements.root = &child;
-                    hadExistingTextRecognitionElements = true;
+                    elements.root = &child;
+                    hadExistingElements = true;
                     continue;
                 }
             }
@@ -215,30 +228,30 @@
         }
     }
 
-    if (textRecognitionElements.root) {
-        for (auto& lineOrDataDetector : childrenOfType<HTMLDivElement>(*textRecognitionElements.root)) {
+    if (elements.root) {
+        for (auto& lineOrDataDetector : childrenOfType<HTMLDivElement>(*elements.root)) {
             if (!lineOrDataDetector.hasClass())
                 continue;
 
-            if (lineOrDataDetector.classList().contains(imageOverlayLineClass)) {
-                TextRecognitionLineElements lineElements { lineOrDataDetector, { } };
+            if (lineOrDataDetector.classList().contains(imageOverlayLineClass())) {
+                LineElements lineElements { lineOrDataDetector, { } };
                 for (auto& text : childrenOfType<HTMLDivElement>(lineOrDataDetector))
                     lineElements.children.append(text);
-                textRecognitionElements.lines.append(WTFMove(lineElements));
+                elements.lines.append(WTFMove(lineElements));
             } else if (lineOrDataDetector.classList().contains(imageOverlayDataDetectorClassName()))
-                textRecognitionElements.dataDetectors.append(lineOrDataDetector);
+                elements.dataDetectors.append(lineOrDataDetector);
         }
 
-        bool canUseExistingTextRecognitionElements = ([&] {
-            if (result.dataDetectors.size() != textRecognitionElements.dataDetectors.size())
+        bool canUseExistingElements = ([&] {
+            if (result.dataDetectors.size() != elements.dataDetectors.size())
                 return false;
 
-            if (result.lines.size() != textRecognitionElements.lines.size())
+            if (result.lines.size() != elements.lines.size())
                 return false;
 
             for (size_t lineIndex = 0; lineIndex < result.lines.size(); ++lineIndex) {
                 auto& childResults = result.lines[lineIndex].children;
-                auto& childTextElements = textRecognitionElements.lines[lineIndex].children;
+                auto& childTextElements = elements.lines[lineIndex].children;
                 if (childResults.size() != childTextElements.size())
                     return false;
 
@@ -251,18 +264,18 @@
             return true;
         })();
 
-        if (!canUseExistingTextRecognitionElements) {
-            textRecognitionElements.root->remove();
-            textRecognitionElements = { };
+        if (!canUseExistingElements) {
+            elements.root->remove();
+            elements = { };
         }
     }
 
     if (result.isEmpty())
-        return;
+        return { };
 
     Ref document = element.document();
     Ref shadowRoot = element.ensureUserAgentShadowRoot();
-    if (!textRecognitionElements.root) {
+    if (!elements.root) {
         auto rootContainer = HTMLDivElement::create(document.get());
         rootContainer->setIdAttribute(imageOverlayElementIdentifier());
         if (document->isImageDocument())
@@ -272,18 +285,18 @@
             mediaControlsContainer->appendChild(rootContainer);
         else
             shadowRoot->appendChild(rootContainer);
-        textRecognitionElements.root = rootContainer.copyRef();
-        textRecognitionElements.lines.reserveInitialCapacity(result.lines.size());
+        elements.root = rootContainer.copyRef();
+        elements.lines.reserveInitialCapacity(result.lines.size());
         for (auto& line : result.lines) {
             auto lineContainer = HTMLDivElement::create(document.get());
-            lineContainer->classList().add(imageOverlayLineClass);
+            lineContainer->classList().add(imageOverlayLineClass());
             rootContainer->appendChild(lineContainer);
-            TextRecognitionLineElements lineElements { lineContainer, { } };
+            LineElements lineElements { lineContainer, { } };
             lineElements.children.reserveInitialCapacity(line.children.size());
             for (size_t childIndex = 0; childIndex < line.children.size(); ++childIndex) {
                 auto& child = line.children[childIndex];
                 auto textContainer = HTMLDivElement::create(document.get());
-                textContainer->classList().add(imageOverlayTextClass);
+                textContainer->classList().add(imageOverlayTextClass());
                 lineContainer->appendChild(textContainer);
                 textContainer->appendChild(Text::create(document.get(), child.hasLeadingWhitespace ? makeString('\n', child.text) : child.text));
                 lineElements.children.uncheckedAppend(WTFMove(textContainer));
@@ -290,16 +303,16 @@
             }
 
             lineContainer->appendChild(HTMLBRElement::create(document.get()));
-            textRecognitionElements.lines.uncheckedAppend(WTFMove(lineElements));
+            elements.lines.uncheckedAppend(WTFMove(lineElements));
         }
 
 #if ENABLE(DATA_DETECTION)
-        textRecognitionElements.dataDetectors.reserveInitialCapacity(result.dataDetectors.size());
+        elements.dataDetectors.reserveInitialCapacity(result.dataDetectors.size());
         for (auto& dataDetector : result.dataDetectors) {
             auto dataDetectorContainer = DataDetection::createElementForImageOverlay(document.get(), dataDetector);
             dataDetectorContainer->classList().add(imageOverlayDataDetectorClassName());
             rootContainer->appendChild(dataDetectorContainer);
-            textRecognitionElements.dataDetectors.uncheckedAppend(WTFMove(dataDetectorContainer));
+            elements.dataDetectors.uncheckedAppend(WTFMove(dataDetectorContainer));
         }
 #endif // ENABLE(DATA_DETECTION)
 
@@ -307,7 +320,7 @@
             element.setInlineStyleProperty(CSSPropertyWebkitUserSelect, CSSValueText);
     }
 
-    if (!hadExistingTextRecognitionElements) {
+    if (!hadExistingElements) {
         static MainThreadNeverDestroyed<const String> shadowStyle(StringImpl::createWithoutCopying(imageOverlayUserAgentStyleSheet, sizeof(imageOverlayUserAgentStyleSheet)));
         auto style = HTMLStyleElement::create(HTMLNames::styleTag, document.get(), false);
         style->setTextContent(shadowStyle);
@@ -314,6 +327,16 @@
         shadowRoot->appendChild(WTFMove(style));
     }
 
+    return elements;
+}
+
+void updateWithTextRecognitionResult(HTMLElement& element, const TextRecognitionResult& result, CacheTextRecognitionResults cacheTextRecognitionResults)
+{
+    auto elements = updateSubtree(element, result);
+    if (!elements.root)
+        return;
+
+    Ref document = element.document();
     document->updateLayoutIgnorePendingStylesheets();
 
     auto* renderer = element.renderer();
@@ -332,7 +355,7 @@
 
     bool applyUserSelectAll = document->isImageDocument() || renderer->style().userSelect() != UserSelect::None;
     for (size_t lineIndex = 0; lineIndex < result.lines.size(); ++lineIndex) {
-        auto& lineElements = textRecognitionElements.lines[lineIndex];
+        auto& lineElements = elements.lines[lineIndex];
         auto& lineContainer = lineElements.line;
         auto& line = result.lines[lineIndex];
         auto lineQuad = convertToContainerCoordinates(line.normalizedQuad);
@@ -423,7 +446,7 @@
 
 #if ENABLE(DATA_DETECTION)
     for (size_t index = 0; index < result.dataDetectors.size(); ++index) {
-        auto dataDetectorContainer = textRecognitionElements.dataDetectors[index];
+        auto dataDetectorContainer = elements.dataDetectors[index];
         auto& dataDetector = result.dataDetectors[index];
         if (dataDetector.normalizedQuads.isEmpty())
             continue;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to