Preview of <picture> element doesn't match element bounds
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Jun 2019 20:52:44 +0000 (20:52 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Jun 2019 20:52:44 +0000 (20:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199049
<rdar://problem/51474402>

Reviewed by Simon Fraser.

Source/WebCore:

Test: fast/text-indicator/text-indicator-uses-img-size-inside-picture.html

* dom/DOMRectReadOnly.idl:
* dom/Range.cpp:
(WebCore::Range::absoluteRectsForRangeInText const):
(WebCore::Range::absoluteTextRects const):
(WebCore::Range::borderAndTextRects const):
(WebCore::Range::boundingRect const):
(WebCore::Range::absoluteBoundingRect const):
* dom/Range.h:
(WebCore::Range::absoluteTextRects):
(WebCore::Range::absoluteBoundingRect):
(WebCore::Range::borderAndTextRects):
(WebCore::Range::boundingRect):
* page/TextIndicator.cpp:
(WebCore::absoluteBoundingRectForRange):
(WebCore::estimatedBackgroundColorForRange):
(WebCore::initializeIndicator):
* rendering/RenderBlock.h:
* testing/Internals.cpp:
(WebCore::Internals::TextIndicatorData::TextIndicatorData):
(WebCore::Internals::TextIndicatorData::~TextIndicatorData):
(WebCore::Internals::textIndicatorForRange):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* fast/text-indicator/text-indicator-uses-img-size-inside-picture-expected.txt: Added.
* fast/text-indicator/text-indicator-uses-img-size-inside-picture.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246695 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/text-indicator/text-indicator-uses-img-size-inside-picture-expected.txt [new file with mode: 0644]
LayoutTests/fast/text-indicator/text-indicator-uses-img-size-inside-picture.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/DOMRectReadOnly.idl
Source/WebCore/dom/Range.cpp
Source/WebCore/dom/Range.h
Source/WebCore/page/TextIndicator.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index 8e46891..8a88232 100644 (file)
@@ -1,3 +1,14 @@
+2019-06-21  Tim Horton  <timothy_horton@apple.com>
+
+        Preview of <picture> element doesn't match element bounds
+        https://bugs.webkit.org/show_bug.cgi?id=199049
+        <rdar://problem/51474402>
+
+        Reviewed by Simon Fraser.
+
+        * fast/text-indicator/text-indicator-uses-img-size-inside-picture-expected.txt: Added.
+        * fast/text-indicator/text-indicator-uses-img-size-inside-picture.html: Added.
+
 2019-06-21  Antoine Quint  <graouts@apple.com>
 
         [iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
diff --git a/LayoutTests/fast/text-indicator/text-indicator-uses-img-size-inside-picture-expected.txt b/LayoutTests/fast/text-indicator/text-indicator-uses-img-size-inside-picture-expected.txt
new file mode 100644 (file)
index 0000000..8257634
--- /dev/null
@@ -0,0 +1,6 @@
+
+imageOnly: -2 -1 260 258
+picture: -2 -1 260 258
+clippedPicture: -2 -1 260 22
+deeperClippedPicture: -2 -1 260 22
+
diff --git a/LayoutTests/fast/text-indicator/text-indicator-uses-img-size-inside-picture.html b/LayoutTests/fast/text-indicator/text-indicator-uses-img-size-inside-picture.html
new file mode 100644 (file)
index 0000000..0fdfdfd
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+* { box-sizing: border-box; }
+body { margin: 0; }
+span { position: absolute; top: 0; left: 0; }
+</style>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function output(s)
+{
+    window.log.innerText += s + "\n";
+}
+
+function runTest()
+{
+    if (!window.internals) {
+        output("This test cannot be run outside of WebKitTestRunner.");
+        return;
+    }
+
+    function dumpIndicatorBoundsForElement(el)
+    {
+        var indicatorOptions = {"useBoundingRectAndPaintAllContentForComplexRanges": true};
+        var range = internals.rangeFromLocationAndLength(el, 0, 1);
+        var indicator = window.internals.textIndicatorForRange(range, indicatorOptions);
+        var rect = indicator.textBoundingRectInRootViewCoordinates;
+        output(`${el.id}: ${rect.x} ${rect.y} ${rect.width} ${rect.height}`);
+    }
+
+    dumpIndicatorBoundsForElement(document.getElementById("imageOnly"));
+    dumpIndicatorBoundsForElement(document.getElementById("picture"));
+    dumpIndicatorBoundsForElement(document.getElementById("clippedPicture"));
+    dumpIndicatorBoundsForElement(document.getElementById("deeperClippedPicture"));
+}
+</script>
+</head>
+<body onload="runTest()">
+<span id="imageOnly"><img src="../images/resources/green-256x256.jpg"></span>
+<span id="picture"><picture><img src="../images/resources/green-256x256.jpg"></picture></span>
+<span id="clippedPicture"><picture style="display: inline-block; height: 20px; overflow: hidden;"><img src="../images/resources/green-256x256.jpg"></picture></span>
+<span id="deeperClippedPicture"><div style="display: inline-block; height: 20px; overflow: hidden;"><picture style="position: relative; height: 50px; overflow: hidden;"><img src="../images/resources/green-256x256.jpg"></picture></div></span>
+<pre id="log"></pre>
+</body>
+</html>
\ No newline at end of file
index a53416b..dfcc469 100644 (file)
@@ -1,3 +1,37 @@
+2019-06-21  Tim Horton  <timothy_horton@apple.com>
+
+        Preview of <picture> element doesn't match element bounds
+        https://bugs.webkit.org/show_bug.cgi?id=199049
+        <rdar://problem/51474402>
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/text-indicator/text-indicator-uses-img-size-inside-picture.html
+
+        * dom/DOMRectReadOnly.idl:
+        * dom/Range.cpp:
+        (WebCore::Range::absoluteRectsForRangeInText const):
+        (WebCore::Range::absoluteTextRects const):
+        (WebCore::Range::borderAndTextRects const):
+        (WebCore::Range::boundingRect const):
+        (WebCore::Range::absoluteBoundingRect const):
+        * dom/Range.h:
+        (WebCore::Range::absoluteTextRects):
+        (WebCore::Range::absoluteBoundingRect):
+        (WebCore::Range::borderAndTextRects):
+        (WebCore::Range::boundingRect):
+        * page/TextIndicator.cpp:
+        (WebCore::absoluteBoundingRectForRange):
+        (WebCore::estimatedBackgroundColorForRange):
+        (WebCore::initializeIndicator):
+        * rendering/RenderBlock.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::TextIndicatorData::TextIndicatorData):
+        (WebCore::Internals::TextIndicatorData::~TextIndicatorData):
+        (WebCore::Internals::textIndicatorForRange):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-06-21  Youenn Fablet  <youenn@apple.com>
 
         Safari crashes after ~2028 OfflineAudioContext objects are created (they never get garbage collected, consuming a thread each)
index 9975a63..58721fd 100644 (file)
@@ -28,6 +28,7 @@
 [
     Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
         optional unrestricted double width = 0, optional unrestricted double height = 0),
+    ExportMacro=WEBCORE_EXPORT,
     Exposed=(Window,Worker),
     GenerateIsReachable=Impl,
     ImplementationLacksVTable
index 73db669..bf8fdbd 100644 (file)
 #include "NodeTraversal.h"
 #include "NodeWithIndex.h"
 #include "ProcessingInstruction.h"
+#include "RenderBlock.h"
 #include "RenderBoxModelObject.h"
 #include "RenderText.h"
+#include "RenderView.h"
 #include "ScopedEventQueue.h"
 #include "TextIterator.h"
 #include "VisiblePosition.h"
@@ -1159,14 +1161,14 @@ IntRect Range::absoluteBoundingBox() const
     return result;
 }
 
-Vector<FloatRect> Range::absoluteRectsForRangeInText(Node* node, RenderText& renderText, bool useSelectionHeight, bool& isFixed, RespectClippingForTextRects respectClippingForTextRects) const
+Vector<FloatRect> Range::absoluteRectsForRangeInText(Node* node, RenderText& renderText, bool useSelectionHeight, bool& isFixed, OptionSet<BoundingRectBehavior> rectOptions) const
 {
     unsigned startOffset = node == &startContainer() ? m_start.offset() : 0;
     unsigned endOffset = node == &endContainer() ? m_end.offset() : std::numeric_limits<unsigned>::max();
 
     auto textQuads = renderText.absoluteQuadsForRange(startOffset, endOffset, useSelectionHeight, &isFixed);
 
-    if (respectClippingForTextRects == RespectClippingForTextRects::Yes) {
+    if (rectOptions.contains(BoundingRectBehavior::RespectClipping)) {
         Vector<FloatRect> clippedRects;
         clippedRects.reserveInitialCapacity(textQuads.size());
 
@@ -1188,7 +1190,7 @@ Vector<FloatRect> Range::absoluteRectsForRangeInText(Node* node, RenderText& ren
     return floatRects;
 }
 
-void Range::absoluteTextRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed, RespectClippingForTextRects respectClippingForTextRects) const
+void Range::absoluteTextRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed, OptionSet<BoundingRectBehavior> rectOptions) const
 {
     // FIXME: This function should probably return FloatRects.
 
@@ -1204,7 +1206,7 @@ void Range::absoluteTextRects(Vector<IntRect>& rects, bool useSelectionHeight, R
         if (renderer->isBR())
             renderer->absoluteRects(rects, flooredLayoutPoint(renderer->localToAbsolute()));
         else if (is<RenderText>(*renderer)) {
-            auto rectsForRenderer = absoluteRectsForRangeInText(node, downcast<RenderText>(*renderer), useSelectionHeight, isFixed, respectClippingForTextRects);
+            auto rectsForRenderer = absoluteRectsForRangeInText(node, downcast<RenderText>(*renderer), useSelectionHeight, isFixed, rectOptions);
             for (auto& rect : rectsForRenderer)
                 rects.append(enclosingIntRect(rect));
         } else
@@ -1793,13 +1795,14 @@ Ref<DOMRect> Range::getBoundingClientRect() const
     return DOMRect::create(boundingRect(CoordinateSpace::Client));
 }
 
-Vector<FloatRect> Range::borderAndTextRects(CoordinateSpace space, RespectClippingForTextRects respectClippingForTextRects) const
+Vector<FloatRect> Range::borderAndTextRects(CoordinateSpace space, OptionSet<BoundingRectBehavior> rectOptions) const
 {
     Vector<FloatRect> rects;
 
     ownerDocument().updateLayoutIgnorePendingStylesheets();
 
     Node* stopNode = pastLastNode();
+    bool useVisibleBounds = rectOptions.contains(BoundingRectBehavior::UseVisibleBounds);
 
     HashSet<Node*> selectedElementsSet;
     for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
@@ -1811,22 +1814,37 @@ Vector<FloatRect> Range::borderAndTextRects(CoordinateSpace space, RespectClippi
     Node* lastNode = m_end.childBefore() ? m_end.childBefore() : &endContainer();
     for (Node* parent = lastNode->parentNode(); parent; parent = parent->parentNode())
         selectedElementsSet.remove(parent);
+    
+    OptionSet<RenderObject::VisibleRectContextOption> visibleRectOptions = { RenderObject::VisibleRectContextOption::UseEdgeInclusiveIntersection, RenderObject::VisibleRectContextOption::ApplyCompositedClips, RenderObject::VisibleRectContextOption::ApplyCompositedContainerScrolls };
 
     for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
-        if (is<Element>(*node) && selectedElementsSet.contains(node) && (!node->parentNode() || !selectedElementsSet.contains(node->parentNode()))) {
+        if (is<Element>(*node) && selectedElementsSet.contains(node) && (useVisibleBounds || !node->parentNode() || !selectedElementsSet.contains(node->parentNode()))) {
             if (auto* renderer = downcast<Element>(*node).renderBoxModelObject()) {
+                if (useVisibleBounds) {
+                    auto localBounds = renderer->borderBoundingBox();
+                    auto rootClippedBounds = renderer->computeVisibleRectInContainer(localBounds, &renderer->view(), { false, false, visibleRectOptions });
+                    if (!rootClippedBounds)
+                        continue;
+                    auto snappedBounds = snapRectToDevicePixels(*rootClippedBounds, node->document().deviceScaleFactor());
+                    if (space == CoordinateSpace::Client)
+                        node->document().convertAbsoluteToClientRect(snappedBounds, renderer->style());
+                    rects.append(snappedBounds);
+
+                    continue;
+                }
+
                 Vector<FloatQuad> elementQuads;
                 renderer->absoluteQuads(elementQuads);
                 if (space == CoordinateSpace::Client)
                     node->document().convertAbsoluteToClientQuads(elementQuads, renderer->style());
-                
+
                 for (auto& quad : elementQuads)
                     rects.append(quad.boundingBox());
             }
         } else if (is<Text>(*node)) {
             if (auto* renderer = downcast<Text>(*node).renderer()) {
                 bool isFixed;
-                auto clippedRects = absoluteRectsForRangeInText(node, *renderer, false, isFixed, respectClippingForTextRects);
+                auto clippedRects = absoluteRectsForRangeInText(node, *renderer, false, isFixed, rectOptions);
                 if (space == CoordinateSpace::Client)
                     node->document().convertAbsoluteToClientRects(clippedRects, renderer->style());
 
@@ -1838,17 +1856,17 @@ Vector<FloatRect> Range::borderAndTextRects(CoordinateSpace space, RespectClippi
     return rects;
 }
 
-FloatRect Range::boundingRect(CoordinateSpace space, RespectClippingForTextRects respectClippingForTextRects) const
+FloatRect Range::boundingRect(CoordinateSpace space, OptionSet<BoundingRectBehavior> rectOptions) const
 {
     FloatRect result;
-    for (auto& rect : borderAndTextRects(space, respectClippingForTextRects))
+    for (auto& rect : borderAndTextRects(space, rectOptions))
         result.uniteIfNonZero(rect);
     return result;
 }
 
-FloatRect Range::absoluteBoundingRect(RespectClippingForTextRects respectClippingForTextRects) const
+FloatRect Range::absoluteBoundingRect(OptionSet<BoundingRectBehavior> rectOptions) const
 {
-    return boundingRect(CoordinateSpace::Absolute, respectClippingForTextRects);
+    return boundingRect(CoordinateSpace::Absolute, rectOptions);
 }
 
 WTF::TextStream& operator<<(WTF::TextStream& ts, const RangeBoundaryPoint& r)
index b99b314..003533d 100644 (file)
@@ -28,6 +28,7 @@
 #include "IntRect.h"
 #include "RangeBoundaryPoint.h"
 #include <wtf/Forward.h>
+#include <wtf/OptionSet.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
@@ -114,15 +115,19 @@ public:
         PartiallyFixedPosition,
         EntirelyFixedPosition
     };
+    
+    enum class BoundingRectBehavior : uint8_t {
+        RespectClipping = 1 << 0,
+        UseVisibleBounds = 1 << 1,
+    };
 
     // Not transform-friendly
-    enum class RespectClippingForTextRects { No, Yes };
-    WEBCORE_EXPORT void absoluteTextRects(Vector<IntRect>&, bool useSelectionHeight = false, RangeInFixedPosition* = nullptr, RespectClippingForTextRects = RespectClippingForTextRects::No) const;
+    WEBCORE_EXPORT void absoluteTextRects(Vector<IntRect>&, bool useSelectionHeight = false, RangeInFixedPosition* = nullptr, OptionSet<BoundingRectBehavior> = { }) const;
     WEBCORE_EXPORT IntRect absoluteBoundingBox() const;
 
     // Transform-friendly
     WEBCORE_EXPORT void absoluteTextQuads(Vector<FloatQuad>&, bool useSelectionHeight = false, RangeInFixedPosition* = nullptr) const;
-    WEBCORE_EXPORT FloatRect absoluteBoundingRect(RespectClippingForTextRects = RespectClippingForTextRects::No) const;
+    WEBCORE_EXPORT FloatRect absoluteBoundingRect(OptionSet<BoundingRectBehavior> = { }) const;
 #if PLATFORM(IOS_FAMILY)
     WEBCORE_EXPORT void collectSelectionRects(Vector<SelectionRect>&) const;
     WEBCORE_EXPORT int collectSelectionRectsWithoutUnionInteriorLines(Vector<SelectionRect>&) const;
@@ -163,10 +168,10 @@ private:
     ExceptionOr<RefPtr<DocumentFragment>> processContents(ActionType);
 
     enum class CoordinateSpace { Absolute, Client };
-    Vector<FloatRect> borderAndTextRects(CoordinateSpace, RespectClippingForTextRects = RespectClippingForTextRects::No) const;
-    FloatRect boundingRect(CoordinateSpace, RespectClippingForTextRects = RespectClippingForTextRects::No) const;
+    Vector<FloatRect> borderAndTextRects(CoordinateSpace, OptionSet<BoundingRectBehavior> = { }) const;
+    FloatRect boundingRect(CoordinateSpace, OptionSet<BoundingRectBehavior> = { }) const;
 
-    Vector<FloatRect> absoluteRectsForRangeInText(Node*, RenderText&, bool useSelectionHeight, bool& isFixed, RespectClippingForTextRects) const;
+    Vector<FloatRect> absoluteRectsForRangeInText(Node*, RenderText&, bool useSelectionHeight, bool& isFixed, OptionSet<BoundingRectBehavior>) const;
 
     Ref<Document> m_ownerDocument;
     RangeBoundaryPoint m_start;
index 7900812..a05d2eb 100644 (file)
@@ -221,6 +221,14 @@ static HashSet<Color> estimatedTextColorsForRange(const Range& range)
     }
     return colors;
 }
+    
+static FloatRect absoluteBoundingRectForRange(const Range& range)
+{
+    return range.absoluteBoundingRect({
+        Range::BoundingRectBehavior::RespectClipping,
+        Range::BoundingRectBehavior::UseVisibleBounds
+    });
+}
 
 static Color estimatedBackgroundColorForRange(const Range& range, const Frame& frame)
 {
@@ -236,7 +244,7 @@ static Color estimatedBackgroundColorForRange(const Range& range, const Frame& f
         commonAncestor = commonAncestor->parentOrShadowHostElement();
     }
 
-    auto boundingRectForRange = enclosingIntRect(range.absoluteBoundingRect(Range::RespectClippingForTextRects::Yes));
+    auto boundingRectForRange = enclosingIntRect(absoluteBoundingRectForRange(range));
     Vector<Color> parentRendererBackgroundColors;
     for (; !!renderer; renderer = renderer->parent()) {
         auto absoluteBoundingBox = renderer->absoluteBoundingBoxRect();
@@ -311,7 +319,7 @@ static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const Ran
 #endif
     else {
         Vector<IntRect> absoluteTextRects;
-        range.absoluteTextRects(absoluteTextRects, textRectHeight == FrameSelection::TextRectangleHeight::SelectionHeight, nullptr, Range::RespectClippingForTextRects::Yes);
+        range.absoluteTextRects(absoluteTextRects, textRectHeight == FrameSelection::TextRectangleHeight::SelectionHeight, nullptr, Range::BoundingRectBehavior::RespectClipping);
 
         textRects.reserveInitialCapacity(absoluteTextRects.size());
         for (auto& rect : absoluteTextRects)
@@ -319,7 +327,7 @@ static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const Ran
     }
 
     if (textRects.isEmpty())
-        textRects.append(range.absoluteBoundingRect(Range::RespectClippingForTextRects::Yes));
+        textRects.append(absoluteBoundingRectForRange(range));
 
     auto frameView = frame.view();
 
index 01ffc8d..128b5f1 100644 (file)
@@ -393,6 +393,9 @@ public:
     void adjustBorderBoxRectForPainting(LayoutRect&) override;
     LayoutRect paintRectToClipOutFromBorder(const LayoutRect&) override;
     bool isInlineBlockOrInlineTable() const final { return isInline() && isReplaced(); }
+    
+    void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
+    void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
 
 protected:
     virtual void addOverflowFromChildren();
@@ -477,9 +480,6 @@ private:
     virtual void clipOutFloatingObjects(RenderBlock&, const PaintInfo*, const LayoutPoint&, const LayoutSize&) { };
     friend class LogicalSelectionOffsetCaches;
 
-    void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
-    void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
-
     void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
 
     LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) final;
index d25745a..acde12f 100644 (file)
@@ -5097,5 +5097,22 @@ void Internals::setIsPlayingToAutomotiveHeadUnit(bool isPlaying)
 {
     PlatformMediaSessionManager::sharedManager().setIsPlayingToAutomotiveHeadUnit(isPlaying);
 }
+    
+Internals::TextIndicatorInfo::TextIndicatorInfo()
+{
+}
+
+Internals::TextIndicatorInfo::TextIndicatorInfo(const WebCore::TextIndicatorData& data)
+    : textBoundingRectInRootViewCoordinates(DOMRect::create(data.textBoundingRectInRootViewCoordinates))
+{
+}
+    
+Internals::TextIndicatorInfo::~TextIndicatorInfo() = default;
+
+Internals::TextIndicatorInfo Internals::textIndicatorForRange(const Range& range, TextIndicatorOptions options)
+{
+    auto indicator = TextIndicator::createWithRange(range, options.core(), TextIndicatorPresentationTransition::None);
+    return indicator->data();
+}
 
 } // namespace WebCore
index 7e41758..bbf1e91 100644 (file)
@@ -35,6 +35,7 @@
 #include "OrientationNotifier.h"
 #include "PageConsoleClient.h"
 #include "RealtimeMediaSource.h"
+#include "TextIndicator.h"
 #include <JavaScriptCore/Float32Array.h>
 #include <wtf/Optional.h>
 
@@ -53,6 +54,7 @@ class AudioContext;
 class CacheStorageConnection;
 class DOMRect;
 class DOMRectList;
+class DOMRectReadOnly;
 class DOMURL;
 class DOMWindow;
 class Document;
@@ -828,6 +830,28 @@ public:
     void setXHRMaximumIntervalForUserGestureForwarding(XMLHttpRequest&, double);
 
     void setIsPlayingToAutomotiveHeadUnit(bool);
+    
+    struct TextIndicatorInfo {
+        RefPtr<DOMRectReadOnly> textBoundingRectInRootViewCoordinates;
+        
+        TextIndicatorInfo();
+        TextIndicatorInfo(const WebCore::TextIndicatorData&);
+        ~TextIndicatorInfo();
+    };
+        
+    struct TextIndicatorOptions {
+        bool useBoundingRectAndPaintAllContentForComplexRanges { false };
+        
+        WebCore::TextIndicatorOptions core()
+        {
+            WebCore::TextIndicatorOptions options = 0;
+            if (useBoundingRectAndPaintAllContentForComplexRanges)
+                options = options | TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges;
+            return options;
+        }
+    };
+
+    TextIndicatorInfo textIndicatorForRange(const Range&, TextIndicatorOptions);
 
 private:
     explicit Internals(Document&);
index 0822dbc..1525609 100644 (file)
@@ -161,6 +161,20 @@ enum CompositingPolicy {
 
 [
     ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
+    JSGenerateToJSObject,
+] dictionary TextIndicatorInfo {
+    DOMRectReadOnly textBoundingRectInRootViewCoordinates;
+};
+
+[
+    ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
+    JSGenerateToJSObject,
+] dictionary TextIndicatorOptions {
+    boolean useBoundingRectAndPaintAllContentForComplexRanges = false;
+};
+
+[
+    ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
     NoInterfaceObject,
 ] interface Internals {
     DOMString address(Node node);
@@ -758,4 +772,6 @@ enum CompositingPolicy {
     void setXHRMaximumIntervalForUserGestureForwarding(XMLHttpRequest xhr, double interval);
 
     void setIsPlayingToAutomotiveHeadUnit(boolean value);
+
+    TextIndicatorInfo textIndicatorForRange(Range range, TextIndicatorOptions options);
 };