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

Changeset 285725 in webkit


Ignore:
Timestamp:
Nov 12, 2021, 8:52:20 AM (5 years ago)
Author:
Wenson Hsieh
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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r285724 r285725  
     12021-11-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Move subtree update logic in ImageOverlay::updateWithTextRecognitionResult() into a separate helper
     4        https://bugs.webkit.org/show_bug.cgi?id=233010
     5
     6        Reviewed by Aditya Keerthi.
     7
     8        Split `updateWithTextRecognitionResult()` into two phases: the first of which updates the UA shadow DOM to
     9        reflect the given text recognition results, and a second phase that updates inline styles for each of the image
     10        overlay elements by mapping normalized OCR quads onto rotated bounding rects in client coordinates. This will
     11        make it easier to add support for representing `TextRecognitionBlockData` as image overlay content in the next
     12        patch.
     13
     14        * dom/ImageOverlay.cpp:
     15        (WebCore::ImageOverlay::imageOverlayLineClass):
     16        (WebCore::ImageOverlay::imageOverlayTextClass):
     17        (WebCore::ImageOverlay::updateSubtree):
     18
     19        Now that this is all namespaced inside `ImageOverlay`, we can also simplify some of these names. Instead of
     20        TextRecognitionLineElements and TextRecognitionElements, we can just call them LineElements and Elements.
     21
     22        (WebCore::ImageOverlay::updateWithTextRecognitionResult):
     23
    1242021-11-12  Adrian Perez de Castro  <aperez@igalia.com>
    225
  • trunk/Source/WebCore/dom/ImageOverlay.cpp

    r285655 r285725  
    7070}
    7171
     72#if ENABLE(IMAGE_ANALYSIS)
     73
     74static const AtomString& imageOverlayLineClass()
     75{
     76    static MainThreadNeverDestroyed<const AtomString> className("image-overlay-line", AtomString::ConstructFromLiteral);
     77    return className;
     78}
     79
     80static const AtomString& imageOverlayTextClass()
     81{
     82    static MainThreadNeverDestroyed<const AtomString> className("image-overlay-text", AtomString::ConstructFromLiteral);
     83    return className;
     84}
     85
     86#endif // ENABLE(IMAGE_ANALYSIS)
     87
    7288bool hasOverlay(const HTMLElement& element)
    7389{
     
    167183}
    168184
    169 void updateWithTextRecognitionResult(HTMLElement& element, const TextRecognitionResult& result, CacheTextRecognitionResults cacheTextRecognitionResults)
    170 {
    171     static MainThreadNeverDestroyed<const AtomString> imageOverlayLineClass("image-overlay-line", AtomString::ConstructFromLiteral);
    172     static MainThreadNeverDestroyed<const AtomString> imageOverlayTextClass("image-overlay-text", AtomString::ConstructFromLiteral);
    173 
    174     struct TextRecognitionLineElements {
    175         Ref<HTMLDivElement> line;
    176         Vector<Ref<HTMLElement>> children;
    177     };
    178 
    179     struct TextRecognitionElements {
    180         RefPtr<HTMLDivElement> root;
    181         Vector<TextRecognitionLineElements> lines;
    182         Vector<Ref<HTMLDivElement>> dataDetectors;
    183     };
    184 
    185     bool hadExistingTextRecognitionElements = false;
    186     TextRecognitionElements textRecognitionElements;
     185struct LineElements {
     186    Ref<HTMLDivElement> line;
     187    Vector<Ref<HTMLElement>> children;
     188};
     189
     190struct Elements {
     191    RefPtr<HTMLDivElement> root;
     192    Vector<LineElements> lines;
     193    Vector<Ref<HTMLDivElement>> dataDetectors;
     194};
     195
     196static Elements updateSubtree(HTMLElement& element, const TextRecognitionResult& result)
     197{
     198    bool hadExistingElements = false;
     199    Elements elements;
    187200    RefPtr<HTMLElement> mediaControlsContainer;
    188201    if (RefPtr shadowRoot = element.shadowRoot()) {
     
    208221            for (auto& child : childrenOfType<HTMLDivElement>(*containerForImageOverlay)) {
    209222                if (child.getIdAttribute() == imageOverlayElementIdentifier()) {
    210                     textRecognitionElements.root = &child;
    211                     hadExistingTextRecognitionElements = true;
     223                    elements.root = &child;
     224                    hadExistingElements = true;
    212225                    continue;
    213226                }
     
    216229    }
    217230
    218     if (textRecognitionElements.root) {
    219         for (auto& lineOrDataDetector : childrenOfType<HTMLDivElement>(*textRecognitionElements.root)) {
     231    if (elements.root) {
     232        for (auto& lineOrDataDetector : childrenOfType<HTMLDivElement>(*elements.root)) {
    220233            if (!lineOrDataDetector.hasClass())
    221234                continue;
    222235
    223             if (lineOrDataDetector.classList().contains(imageOverlayLineClass)) {
    224                 TextRecognitionLineElements lineElements { lineOrDataDetector, { } };
     236            if (lineOrDataDetector.classList().contains(imageOverlayLineClass())) {
     237                LineElements lineElements { lineOrDataDetector, { } };
    225238                for (auto& text : childrenOfType<HTMLDivElement>(lineOrDataDetector))
    226239                    lineElements.children.append(text);
    227                 textRecognitionElements.lines.append(WTFMove(lineElements));
     240                elements.lines.append(WTFMove(lineElements));
    228241            } else if (lineOrDataDetector.classList().contains(imageOverlayDataDetectorClassName()))
    229                 textRecognitionElements.dataDetectors.append(lineOrDataDetector);
    230         }
    231 
    232         bool canUseExistingTextRecognitionElements = ([&] {
    233             if (result.dataDetectors.size() != textRecognitionElements.dataDetectors.size())
     242                elements.dataDetectors.append(lineOrDataDetector);
     243        }
     244
     245        bool canUseExistingElements = ([&] {
     246            if (result.dataDetectors.size() != elements.dataDetectors.size())
    234247                return false;
    235248
    236             if (result.lines.size() != textRecognitionElements.lines.size())
     249            if (result.lines.size() != elements.lines.size())
    237250                return false;
    238251
    239252            for (size_t lineIndex = 0; lineIndex < result.lines.size(); ++lineIndex) {
    240253                auto& childResults = result.lines[lineIndex].children;
    241                 auto& childTextElements = textRecognitionElements.lines[lineIndex].children;
     254                auto& childTextElements = elements.lines[lineIndex].children;
    242255                if (childResults.size() != childTextElements.size())
    243256                    return false;
     
    252265        })();
    253266
    254         if (!canUseExistingTextRecognitionElements) {
    255             textRecognitionElements.root->remove();
    256             textRecognitionElements = { };
     267        if (!canUseExistingElements) {
     268            elements.root->remove();
     269            elements = { };
    257270        }
    258271    }
    259272
    260273    if (result.isEmpty())
    261         return;
     274        return { };
    262275
    263276    Ref document = element.document();
    264277    Ref shadowRoot = element.ensureUserAgentShadowRoot();
    265     if (!textRecognitionElements.root) {
     278    if (!elements.root) {
    266279        auto rootContainer = HTMLDivElement::create(document.get());
    267280        rootContainer->setIdAttribute(imageOverlayElementIdentifier());
     
    273286        else
    274287            shadowRoot->appendChild(rootContainer);
    275         textRecognitionElements.root = rootContainer.copyRef();
    276         textRecognitionElements.lines.reserveInitialCapacity(result.lines.size());
     288        elements.root = rootContainer.copyRef();
     289        elements.lines.reserveInitialCapacity(result.lines.size());
    277290        for (auto& line : result.lines) {
    278291            auto lineContainer = HTMLDivElement::create(document.get());
    279             lineContainer->classList().add(imageOverlayLineClass);
     292            lineContainer->classList().add(imageOverlayLineClass());
    280293            rootContainer->appendChild(lineContainer);
    281             TextRecognitionLineElements lineElements { lineContainer, { } };
     294            LineElements lineElements { lineContainer, { } };
    282295            lineElements.children.reserveInitialCapacity(line.children.size());
    283296            for (size_t childIndex = 0; childIndex < line.children.size(); ++childIndex) {
    284297                auto& child = line.children[childIndex];
    285298                auto textContainer = HTMLDivElement::create(document.get());
    286                 textContainer->classList().add(imageOverlayTextClass);
     299                textContainer->classList().add(imageOverlayTextClass());
    287300                lineContainer->appendChild(textContainer);
    288301                textContainer->appendChild(Text::create(document.get(), child.hasLeadingWhitespace ? makeString('\n', child.text) : child.text));
     
    291304
    292305            lineContainer->appendChild(HTMLBRElement::create(document.get()));
    293             textRecognitionElements.lines.uncheckedAppend(WTFMove(lineElements));
     306            elements.lines.uncheckedAppend(WTFMove(lineElements));
    294307        }
    295308
    296309#if ENABLE(DATA_DETECTION)
    297         textRecognitionElements.dataDetectors.reserveInitialCapacity(result.dataDetectors.size());
     310        elements.dataDetectors.reserveInitialCapacity(result.dataDetectors.size());
    298311        for (auto& dataDetector : result.dataDetectors) {
    299312            auto dataDetectorContainer = DataDetection::createElementForImageOverlay(document.get(), dataDetector);
    300313            dataDetectorContainer->classList().add(imageOverlayDataDetectorClassName());
    301314            rootContainer->appendChild(dataDetectorContainer);
    302             textRecognitionElements.dataDetectors.uncheckedAppend(WTFMove(dataDetectorContainer));
     315            elements.dataDetectors.uncheckedAppend(WTFMove(dataDetectorContainer));
    303316        }
    304317#endif // ENABLE(DATA_DETECTION)
     
    308321    }
    309322
    310     if (!hadExistingTextRecognitionElements) {
     323    if (!hadExistingElements) {
    311324        static MainThreadNeverDestroyed<const String> shadowStyle(StringImpl::createWithoutCopying(imageOverlayUserAgentStyleSheet, sizeof(imageOverlayUserAgentStyleSheet)));
    312325        auto style = HTMLStyleElement::create(HTMLNames::styleTag, document.get(), false);
     
    315328    }
    316329
     330    return elements;
     331}
     332
     333void updateWithTextRecognitionResult(HTMLElement& element, const TextRecognitionResult& result, CacheTextRecognitionResults cacheTextRecognitionResults)
     334{
     335    auto elements = updateSubtree(element, result);
     336    if (!elements.root)
     337        return;
     338
     339    Ref document = element.document();
    317340    document->updateLayoutIgnorePendingStylesheets();
    318341
     
    333356    bool applyUserSelectAll = document->isImageDocument() || renderer->style().userSelect() != UserSelect::None;
    334357    for (size_t lineIndex = 0; lineIndex < result.lines.size(); ++lineIndex) {
    335         auto& lineElements = textRecognitionElements.lines[lineIndex];
     358        auto& lineElements = elements.lines[lineIndex];
    336359        auto& lineContainer = lineElements.line;
    337360        auto& line = result.lines[lineIndex];
     
    424447#if ENABLE(DATA_DETECTION)
    425448    for (size_t index = 0; index < result.dataDetectors.size(); ++index) {
    426         auto dataDetectorContainer = textRecognitionElements.dataDetectors[index];
     449        auto dataDetectorContainer = elements.dataDetectors[index];
    427450        auto& dataDetector = result.dataDetectors[index];
    428451        if (dataDetector.normalizedQuads.isEmpty())
Note: See TracChangeset for help on using the changeset viewer.