WebKit Bugzilla
Attachment 349778 Details for
Bug 189624
: [IntersectionObserver] Handle zero-area intersections
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189624-20180914140138.patch (text/plain), 54.72 KB, created by
Ali Juma
on 2018-09-14 11:01:40 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Ali Juma
Created:
2018-09-14 11:01:40 PDT
Size:
54.72 KB
patch
obsolete
>Subversion Revision: 235943 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 2237346682a217619f49a06f75bad8db5df8ef3e..e2ca25fe9bc08d6135a9f6c357abf3e055128c33 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,67 @@ >+2018-09-14 Ali Juma <ajuma@chromium.org> >+ >+ [IntersectionObserver] Handle zero-area intersections >+ https://bugs.webkit.org/show_bug.cgi?id=189624 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Use edge-inclusive intersection when applying clips and intersecting with the >+ root, so that two rects that touch each other are considered intersecting even >+ if the area of their intersection is 0. >+ >+ Covered by rebased tests in imported/w3c/web-platform-tests/intersection-observer. >+ >+ * dom/Document.cpp: >+ (WebCore::computeIntersectionRects): >+ (WebCore::Document::updateIntersectionObservations): >+ * platform/graphics/FloatRect.cpp: >+ (WebCore::FloatRect::edgeInclusiveIntersect): >+ * platform/graphics/FloatRect.h: >+ * platform/graphics/LayoutRect.cpp: >+ (WebCore::LayoutRect::edgeInclusiveIntersect): >+ * platform/graphics/LayoutRect.h: >+ * rendering/RenderBox.cpp: >+ (WebCore::RenderBox::applyCachedClipAndScrollPositionForRepaint const): >+ (WebCore::RenderBox::computeRectForRepaint const): >+ * rendering/RenderBox.h: >+ (WebCore::RenderBox::computeRectForRepaint): >+ * rendering/RenderInline.cpp: >+ (WebCore::RenderInline::computeRectForRepaint const): >+ * rendering/RenderInline.h: >+ (WebCore::RenderInline::computeRectForRepaint): >+ * rendering/RenderObject.cpp: >+ (WebCore::RenderObject::computeRectForRepaint const): >+ (WebCore::RenderObject::computeFloatRectForRepaint const): >+ * rendering/RenderObject.h: >+ (WebCore::RenderObject::RepaintContext::RepaintContext): >+ (WebCore::RenderObject::computeRectForRepaint): >+ * rendering/RenderTableCell.cpp: >+ (WebCore::RenderTableCell::computeRectForRepaint const): >+ * rendering/RenderTableCell.h: >+ * rendering/RenderView.cpp: >+ (WebCore::RenderView::computeRectForRepaint const): >+ * rendering/RenderView.h: >+ * rendering/svg/RenderSVGForeignObject.cpp: >+ (WebCore::RenderSVGForeignObject::computeFloatRectForRepaint const): >+ (WebCore::RenderSVGForeignObject::computeRectForRepaint const): >+ * rendering/svg/RenderSVGForeignObject.h: >+ * rendering/svg/RenderSVGInline.cpp: >+ (WebCore::RenderSVGInline::computeFloatRectForRepaint const): >+ * rendering/svg/RenderSVGInline.h: >+ * rendering/svg/RenderSVGModelObject.cpp: >+ (WebCore::RenderSVGModelObject::computeFloatRectForRepaint const): >+ * rendering/svg/RenderSVGModelObject.h: >+ * rendering/svg/RenderSVGRoot.cpp: >+ (WebCore::RenderSVGRoot::computeFloatRectForRepaint const): >+ * rendering/svg/RenderSVGRoot.h: >+ * rendering/svg/RenderSVGText.cpp: >+ (WebCore::RenderSVGText::computeRectForRepaint const): >+ (WebCore::RenderSVGText::computeFloatRectForRepaint const): >+ * rendering/svg/RenderSVGText.h: >+ * rendering/svg/SVGRenderSupport.cpp: >+ (WebCore::SVGRenderSupport::computeFloatRectForRepaint): >+ * rendering/svg/SVGRenderSupport.h: >+ > 2018-09-12 Ali Juma <ajuma@chromium.org> > > [IntersectionObserver] Implement rootMargin expansion >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index 51f660e21666cb72cb9914aad9385da2d9afbc61..462295dea619c24b7e640b511052077ce43fb763 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -7497,25 +7497,25 @@ static void expandRootBoundsWithRootMargin(FloatRect& localRootBounds, const Len > localRootBounds.expand(rootMarginFloatBox); > } > >-static void computeIntersectionRects(FrameView& frameView, IntersectionObserver& observer, Element& target, FloatRect& absTargetRect, FloatRect& absIntersectionRect, FloatRect& absRootBounds) >+static bool computeIntersectionRects(FrameView& frameView, IntersectionObserver& observer, Element& target, FloatRect& absTargetRect, FloatRect& absIntersectionRect, FloatRect& absRootBounds, bool& isIntersecting) > { > // FIXME: Implement intersection computation for the cross-document case. > if (observer.trackingDocument() != &target.document()) >- return; >+ return false; > > auto* targetRenderer = target.renderer(); > if (!targetRenderer) >- return; >+ return false; > > FloatRect localRootBounds; > RenderBlock* rootRenderer; > if (observer.root()) { > if (!observer.root()->renderer() || !is<RenderBlock>(observer.root()->renderer())) >- return; >+ return false; > > rootRenderer = downcast<RenderBlock>(observer.root()->renderer()); > if (!rootRenderer->isContainingBlockAncestorFor(*targetRenderer)) >- return; >+ return false; > > if (rootRenderer->hasOverflowClip()) > localRootBounds = rootRenderer->contentBoxRect(); >@@ -7537,14 +7537,16 @@ static void computeIntersectionRects(FrameView& frameView, IntersectionObserver& > else if (is<RenderLineBreak>(targetRenderer)) > localTargetBounds = downcast<RenderLineBreak>(targetRenderer)->linesBoundingBox(); > >- FloatRect rootLocalIntersectionRect = targetRenderer->computeRectForRepaint(localTargetBounds, rootRenderer); >- rootLocalIntersectionRect.intersect(localRootBounds); >+ isIntersecting = true; >+ FloatRect rootLocalIntersectionRect = targetRenderer->computeRectForRepaint(localTargetBounds, rootRenderer, {false /* hasPositionFixedDescendant */, false /* dirtyRectIsFlipped */, true /* useEdgeInclusiveIntersection */}, &isIntersecting); >+ isIntersecting = isIntersecting && rootLocalIntersectionRect.edgeInclusiveIntersect(localRootBounds); > >- if (!rootLocalIntersectionRect.isEmpty()) >+ if (isIntersecting) > absIntersectionRect = rootRenderer->localToAbsoluteQuad(rootLocalIntersectionRect).boundingBox(); > > absTargetRect = targetRenderer->localToAbsoluteQuad(FloatRect(localTargetBounds)).boundingBox(); > absRootBounds = rootRenderer->localToAbsoluteQuad(localRootBounds).boundingBox(); >+ return true; > } > > void Document::updateIntersectionObservations() >@@ -7576,11 +7578,18 @@ void Document::updateIntersectionObservations() > FloatRect absTargetRect; > FloatRect absIntersectionRect; > FloatRect absRootBounds; >- computeIntersectionRects(*frameView, *observer, *target, absTargetRect, absIntersectionRect, absRootBounds); >+ bool isIntersecting = false; >+ bool computedIntersection = computeIntersectionRects(*frameView, *observer, *target, absTargetRect, absIntersectionRect, absRootBounds, isIntersecting); >+ >+ float intersectionRatio; >+ float absTargetArea = absTargetRect.area(); >+ if (absTargetArea) >+ intersectionRatio = absIntersectionRect.area() / absTargetArea; >+ else if (isIntersecting) >+ intersectionRatio = 1; >+ else >+ intersectionRatio = 0; > >- // FIXME: Handle zero-area intersections (e.g., intersections involving zero-area targets). >- bool isIntersecting = absIntersectionRect.area(); >- float intersectionRatio = isIntersecting ? absIntersectionRect.area() / absTargetRect.area() : 0; > size_t thresholdIndex = 0; > if (isIntersecting) { > auto& thresholds = observer->thresholds(); >@@ -7589,12 +7598,17 @@ void Document::updateIntersectionObservations() > } > > if (!registration.previousThresholdIndex || thresholdIndex != registration.previousThresholdIndex) { >- FloatRect targetBoundingClientRect = frameView->absoluteToClientRect(absTargetRect); >- FloatRect clientIntersectionRect = isIntersecting ? frameView->absoluteToClientRect(absIntersectionRect) : FloatRect(); >+ FloatRect targetBoundingClientRect; >+ FloatRect clientIntersectionRect; >+ FloatRect clientRootBounds; >+ if (computedIntersection) { >+ targetBoundingClientRect = frameView->absoluteToClientRect(absTargetRect); >+ clientIntersectionRect = isIntersecting ? frameView->absoluteToClientRect(absIntersectionRect) : FloatRect(); >+ clientRootBounds = frameView->absoluteToClientRect(absRootBounds); >+ } > > // FIXME: Once cross-document observation is implemented, only report root bounds if the target document and > // the root document are similar-origin. >- FloatRect clientRootBounds = frameView->absoluteToClientRect(absRootBounds); > std::optional<DOMRectInit> reportedRootBounds = DOMRectInit({ > clientRootBounds.x(), > clientRootBounds.y(), >diff --git a/Source/WebCore/platform/graphics/FloatRect.cpp b/Source/WebCore/platform/graphics/FloatRect.cpp >index eb165182b7bec41c90d9a82e3dd5623f81439123..4a590d21acf4622e9779b4d2e8fbe1cb5700de20 100644 >--- a/Source/WebCore/platform/graphics/FloatRect.cpp >+++ b/Source/WebCore/platform/graphics/FloatRect.cpp >@@ -93,6 +93,27 @@ void FloatRect::intersect(const FloatRect& other) > setLocationAndSizeFromEdges(l, t, r, b); > } > >+bool FloatRect::edgeInclusiveIntersect(const FloatRect& other) >+{ >+ float left = std::max(x(), other.x()); >+ float top = std::max(y(), other.y()); >+ float right = std::min(maxX(), other.maxX()); >+ float bottom = std::min(maxY(), other.maxY()); >+ bool intersects = true; >+ >+ // Return a clean empty rectangle for non-intersecting cases. >+ if (left > right || top > bottom) { >+ left = 0; >+ top = 0; >+ right = 0; >+ bottom = 0; >+ intersects = false; >+ } >+ >+ setLocationAndSizeFromEdges(left, top, right, bottom); >+ return intersects; >+} >+ > void FloatRect::unite(const FloatRect& other) > { > // Handle empty special cases first. >diff --git a/Source/WebCore/platform/graphics/FloatRect.h b/Source/WebCore/platform/graphics/FloatRect.h >index 93acad536185a6c89e0a3e88858ae69e582cd3e3..33170ebc456be846b317ac134c315045d765e3fc 100644 >--- a/Source/WebCore/platform/graphics/FloatRect.h >+++ b/Source/WebCore/platform/graphics/FloatRect.h >@@ -151,6 +151,7 @@ public: > WEBCORE_EXPORT bool contains(const FloatPoint&, ContainsMode = InsideOrOnStroke) const; > > WEBCORE_EXPORT void intersect(const FloatRect&); >+ bool edgeInclusiveIntersect(const FloatRect&); > WEBCORE_EXPORT void unite(const FloatRect&); > void uniteEvenIfEmpty(const FloatRect&); > void uniteIfNonZero(const FloatRect&); >diff --git a/Source/WebCore/platform/graphics/LayoutRect.cpp b/Source/WebCore/platform/graphics/LayoutRect.cpp >index fd0b6994c334d2569682e2340a1b51969119b341..feddab60d562c3c3ed408f734b816eec02f4774e 100644 >--- a/Source/WebCore/platform/graphics/LayoutRect.cpp >+++ b/Source/WebCore/platform/graphics/LayoutRect.cpp >@@ -71,6 +71,24 @@ void LayoutRect::intersect(const LayoutRect& other) > m_size = newMaxPoint - newLocation; > } > >+bool LayoutRect::edgeInclusiveIntersect(const LayoutRect& other) >+{ >+ LayoutPoint newLocation(std::max(x(), other.x()), std::max(y(), other.y())); >+ LayoutPoint newMaxPoint(std::min(maxX(), other.maxX()), std::min(maxY(), other.maxY())); >+ bool intersects = true; >+ >+ // Return a clean empty rectangle for non-intersecting cases. >+ if (newLocation.x() > newMaxPoint.x() || newLocation.y() > newMaxPoint.y()) { >+ newLocation = LayoutPoint(0, 0); >+ newMaxPoint = LayoutPoint(0, 0); >+ intersects = false; >+ } >+ >+ m_location = newLocation; >+ m_size = newMaxPoint - newLocation; >+ return intersects; >+} >+ > void LayoutRect::unite(const LayoutRect& other) > { > // Handle empty special cases first. >diff --git a/Source/WebCore/platform/graphics/LayoutRect.h b/Source/WebCore/platform/graphics/LayoutRect.h >index d720b5649fbec55340cbfb45e8ba2f2f99a3ce73..a2a22cb3e0dfa7e22dcc50342b464d5cb9e8a99f 100644 >--- a/Source/WebCore/platform/graphics/LayoutRect.h >+++ b/Source/WebCore/platform/graphics/LayoutRect.h >@@ -145,6 +145,7 @@ public: > bool contains(const LayoutPoint& point) const { return contains(point.x(), point.y()); } > > void intersect(const LayoutRect&); >+ bool edgeInclusiveIntersect(const LayoutRect&); > WEBCORE_EXPORT void unite(const LayoutRect&); > void uniteIfNonZero(const LayoutRect&); > bool checkedUnite(const LayoutRect&); >diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp >index 5a2ef2f375888e3c103b45270eef4df0c1fb3c3a..9b9104c23241925beb56f3cc59b5c0cee430b68f 100644 >--- a/Source/WebCore/rendering/RenderBox.cpp >+++ b/Source/WebCore/rendering/RenderBox.cpp >@@ -967,7 +967,7 @@ LayoutSize RenderBox::cachedSizeForOverflowClip() const > return layer()->size(); > } > >-void RenderBox::applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect) const >+void RenderBox::applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect, bool useEdgeInclusiveIntersection, bool* intersects) const > { > flipForWritingMode(paintRect); > paintRect.moveBy(-scrollPosition()); // For overflow:auto/scroll/hidden. >@@ -982,7 +982,14 @@ void RenderBox::applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect > // layer's size instead. Even if the layer's size is wrong, the layer itself will repaint > // anyway if its size does change. > LayoutRect clipRect(LayoutPoint(), cachedSizeForOverflowClip()); >- paintRect = intersection(paintRect, clipRect); >+ if (useEdgeInclusiveIntersection) >+ *intersects = paintRect.edgeInclusiveIntersect(clipRect); >+ else { >+ paintRect = intersection(paintRect, clipRect); >+ if (intersects) >+ *intersects = !paintRect.isEmpty(); >+ } >+ > flipForWritingMode(paintRect); > } > >@@ -2136,7 +2143,7 @@ bool RenderBox::shouldApplyClipAndScrollPositionForRepaint(const RenderLayerMode > #endif > } > >-LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool* intersects) const > { > // The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space. > // Only when we cross a writing mode boundary will we have to possibly flipForWritingMode (to convert into a more appropriate >@@ -2161,13 +2168,23 @@ LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const Render > > adjustedRect.moveBy(location()); > adjustedRect.move(layoutState->paintOffset()); >- if (layoutState->isClipped()) >- adjustedRect.intersect(layoutState->clipRect()); >+ if (layoutState->isClipped()) { >+ if (context.m_useEdgeInclusiveIntersection) >+ *intersects = adjustedRect.edgeInclusiveIntersect(layoutState->clipRect()); >+ else { >+ adjustedRect.intersect(layoutState->clipRect()); >+ if (intersects) >+ *intersects = !adjustedRect.isEmpty(); >+ } >+ } > return adjustedRect; > } > >- if (hasReflection()) >+ if (hasReflection()) { > adjustedRect.unite(reflectedRect(adjustedRect)); >+ if (intersects) >+ *intersects |= !adjustedRect.isEmpty(); >+ } > > if (repaintContainer == this) { > if (repaintContainer->style().isFlippedBlocksWritingMode()) >@@ -2207,6 +2224,8 @@ LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const Render > if (isRenderReplaced() && isWidget()) { > LayoutSize flooredLocationOffset = toIntSize(flooredIntPoint(locationOffset)); > adjustedRect.expand(locationOffset - flooredLocationOffset); >+ if (intersects) >+ *intersects |= !adjustedRect.isEmpty(); > locationOffset = flooredLocationOffset; > } > >@@ -2220,7 +2239,7 @@ LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const Render > LayoutPoint physicalPoint(flipForWritingMode(adjustedRect.location())); > if (auto* fragment = downcast<RenderMultiColumnFlow>(*this).physicalTranslationFromFlowToFragment((physicalPoint))) { > adjustedRect.setLocation(fragment->flipForWritingMode(physicalPoint)); >- return fragment->computeRectForRepaint(adjustedRect, repaintContainer, context); >+ return fragment->computeRectForRepaint(adjustedRect, repaintContainer, context, intersects); > } > } > >@@ -2253,8 +2272,11 @@ LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const Render > if (container->hasOverflowClip()) { > RenderBox& containerBox = downcast<RenderBox>(*container); > if (containerBox.shouldApplyClipAndScrollPositionForRepaint(repaintContainer)) { >- containerBox.applyCachedClipAndScrollPositionForRepaint(adjustedRect); >- if (adjustedRect.isEmpty()) >+ containerBox.applyCachedClipAndScrollPositionForRepaint(adjustedRect, context.m_useEdgeInclusiveIntersection, intersects); >+ if (context.m_useEdgeInclusiveIntersection) { >+ if (!(*intersects)) >+ return adjustedRect; >+ } else if (adjustedRect.isEmpty()) > return adjustedRect; > } > } >@@ -2265,7 +2287,7 @@ LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const Render > adjustedRect.move(-containerOffset); > return adjustedRect; > } >- return container->computeRectForRepaint(adjustedRect, repaintContainer, context); >+ return container->computeRectForRepaint(adjustedRect, repaintContainer, context, intersects); > } > > void RenderBox::repaintDuringLayoutIfMoved(const LayoutRect& oldRect) >diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h >index 81663f74d2b9add13be6d647b4325ecdac46cef5..0195800bb70767d9942b276354450707facc4a0e 100644 >--- a/Source/WebCore/rendering/RenderBox.h >+++ b/Source/WebCore/rendering/RenderBox.h >@@ -371,7 +371,7 @@ public: > void deleteLineBoxWrapper(); > > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; >- LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext context = { false, false }) const override; >+ LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext context = { false, false, false }, bool* intersects = nullptr) const override; > void repaintDuringLayoutIfMoved(const LayoutRect&); > virtual void repaintOverhangingFloats(bool paintAllDescendants); > >@@ -569,7 +569,7 @@ public: > LayoutSize cachedSizeForOverflowClip() const; > > bool shouldApplyClipAndScrollPositionForRepaint(const RenderLayerModelObject* repaintContainer) const; >- void applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect) const; >+ void applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect, bool useEdgeInclusiveIntersection = false, bool* intersects = nullptr) const; > > virtual bool hasRelativeDimensions() const; > virtual bool hasRelativeLogicalHeight() const; >diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp >index f67ab86f6a9c77222dad548138189438977f21b8..648e87c8f44280b49cb0abf7a2ef72fd3c79f6ff 100644 >--- a/Source/WebCore/rendering/RenderInline.cpp >+++ b/Source/WebCore/rendering/RenderInline.cpp >@@ -871,7 +871,7 @@ LayoutRect RenderInline::rectWithOutlineForRepaint(const RenderLayerModelObject* > return r; > } > >-LayoutRect RenderInline::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderInline::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool* intersects) const > { > // Repaint offset cache is only valid for root-relative repainting > LayoutRect adjustedRect = rect; >@@ -880,8 +880,15 @@ LayoutRect RenderInline::computeRectForRepaint(const LayoutRect& rect, const Ren > if (style().hasInFlowPosition() && layer()) > adjustedRect.move(layer()->offsetForInFlowPosition()); > adjustedRect.move(layoutState->paintOffset()); >- if (layoutState->isClipped()) >- adjustedRect.intersect(layoutState->clipRect()); >+ if (layoutState->isClipped()) { >+ if (context.m_useEdgeInclusiveIntersection) >+ *intersects = adjustedRect.edgeInclusiveIntersect(layoutState->clipRect()); >+ else { >+ adjustedRect.intersect(layoutState->clipRect()); >+ if (intersects) >+ *intersects = !adjustedRect.isEmpty(); >+ } >+ } > return adjustedRect; > } > >@@ -907,8 +914,11 @@ LayoutRect RenderInline::computeRectForRepaint(const LayoutRect& rect, const Ren > // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer. > adjustedRect.setLocation(topLeft); > if (container->hasOverflowClip()) { >- downcast<RenderBox>(*container).applyCachedClipAndScrollPositionForRepaint(adjustedRect); >- if (adjustedRect.isEmpty()) >+ downcast<RenderBox>(*container).applyCachedClipAndScrollPositionForRepaint(adjustedRect, context.m_useEdgeInclusiveIntersection, intersects); >+ if (context.m_useEdgeInclusiveIntersection) { >+ if (!(*intersects)) >+ return adjustedRect; >+ } else if (adjustedRect.isEmpty()) > return adjustedRect; > } > >@@ -918,7 +928,7 @@ LayoutRect RenderInline::computeRectForRepaint(const LayoutRect& rect, const Ren > adjustedRect.move(-containerOffset); > return adjustedRect; > } >- return container->computeRectForRepaint(adjustedRect, repaintContainer, context); >+ return container->computeRectForRepaint(adjustedRect, repaintContainer, context, intersects); > } > > LayoutSize RenderInline::offsetFromContainer(RenderElement& container, const LayoutPoint&, bool* offsetDependsOnPoint) const >diff --git a/Source/WebCore/rendering/RenderInline.h b/Source/WebCore/rendering/RenderInline.h >index 6e6bf87b53574a19e9ac42bc414bb546f49f78ab..e6bc39b4bdc1c379ce062db42a93fa264d558a12 100644 >--- a/Source/WebCore/rendering/RenderInline.h >+++ b/Source/WebCore/rendering/RenderInline.h >@@ -129,7 +129,7 @@ private: > > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; > LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const final; >- LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const final; >+ LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }, bool* intersects = nullptr) const final; > > void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; > const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override; >diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp >index fa7ab44cd32f978ce8b1a6db348d5e393745a9b6..55093e91e6ea64a30186477312659ac73de577dd 100644 >--- a/Source/WebCore/rendering/RenderObject.cpp >+++ b/Source/WebCore/rendering/RenderObject.cpp >@@ -961,7 +961,7 @@ LayoutRect RenderObject::clippedOverflowRectForRepaint(const RenderLayerModelObj > return LayoutRect(); > } > >-LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool* intersects) const > { > if (repaintContainer == this) > return rect; >@@ -972,14 +972,17 @@ LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const Ren > > LayoutRect adjustedRect = rect; > if (parent->hasOverflowClip()) { >- downcast<RenderBox>(*parent).applyCachedClipAndScrollPositionForRepaint(adjustedRect); >- if (adjustedRect.isEmpty()) >+ downcast<RenderBox>(*parent).applyCachedClipAndScrollPositionForRepaint(adjustedRect, context.m_useEdgeInclusiveIntersection, intersects); >+ if (context.m_useEdgeInclusiveIntersection) { >+ if (!(*intersects)) >+ return adjustedRect; >+ } else if (adjustedRect.isEmpty()) > return adjustedRect; > } >- return parent->computeRectForRepaint(adjustedRect, repaintContainer, context); >+ return parent->computeRectForRepaint(adjustedRect, repaintContainer, context, intersects); > } > >-FloatRect RenderObject::computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject*, bool) const >+FloatRect RenderObject::computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject*, bool, bool, bool*) const > { > ASSERT_NOT_REACHED(); > return FloatRect(); >diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h >index 7642f5846d7b9bede8b3794a711765f8445e6f4f..6d429a380a88ffa61230c66daa7766854906f928 100644 >--- a/Source/WebCore/rendering/RenderObject.h >+++ b/Source/WebCore/rendering/RenderObject.h >@@ -678,16 +678,18 @@ public: > // Given a rect in the object's coordinate space, compute a rect suitable for repainting > // that rect in the coordinate space of repaintContainer. > struct RepaintContext { >- RepaintContext(bool hasPositionFixedDescendant = false, bool dirtyRectIsFlipped = false) >+ RepaintContext(bool hasPositionFixedDescendant = false, bool dirtyRectIsFlipped = false, bool useEdgeInclusiveIntersection = false) > : m_hasPositionFixedDescendant(hasPositionFixedDescendant) > , m_dirtyRectIsFlipped(dirtyRectIsFlipped) >+ , m_useEdgeInclusiveIntersection(useEdgeInclusiveIntersection) > { > } > bool m_hasPositionFixedDescendant; > bool m_dirtyRectIsFlipped; >+ bool m_useEdgeInclusiveIntersection; > }; >- virtual LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const; >- virtual FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const; >+ virtual LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }, bool* intersects = nullptr) const; >+ virtual FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false, bool useEdgeInclusiveIntersection = false, bool* intersects = nullptr) const; > > virtual unsigned int length() const { return 1; } > >diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp >index d339c8d6e13583bef24b827bf91861682abd5567..11761c6adb4388f5caa561084a39ef8d8bb4b9b7 100644 >--- a/Source/WebCore/rendering/RenderTableCell.cpp >+++ b/Source/WebCore/rendering/RenderTableCell.cpp >@@ -395,14 +395,14 @@ LayoutRect RenderTableCell::clippedOverflowRectForRepaint(const RenderLayerModel > return computeRectForRepaint(r, repaintContainer); > } > >-LayoutRect RenderTableCell::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderTableCell::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool* intersects) const > { > if (repaintContainer == this) > return rect; > LayoutRect adjustedRect = rect; > if ((!view().frameView().layoutContext().isPaintOffsetCacheEnabled() || repaintContainer) && parent()) > adjustedRect.moveBy(-parentBox()->location()); // Rows are in the same coordinate space, so don't add their offset in. >- return RenderBlockFlow::computeRectForRepaint(adjustedRect, repaintContainer, context); >+ return RenderBlockFlow::computeRectForRepaint(adjustedRect, repaintContainer, context, intersects); > } > > LayoutUnit RenderTableCell::cellBaselinePosition() const >diff --git a/Source/WebCore/rendering/RenderTableCell.h b/Source/WebCore/rendering/RenderTableCell.h >index a249418728fc2f906be12edba0fd2e1020fde7e1..5acbf43fd1e7a29a6fa5d1700a4997048ee1efd5 100644 >--- a/Source/WebCore/rendering/RenderTableCell.h >+++ b/Source/WebCore/rendering/RenderTableCell.h >@@ -155,7 +155,7 @@ private: > bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance, InlineFlowBox*) const override; > > LayoutSize offsetFromContainer(RenderElement&, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const override; >- LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override; >+ LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }, bool* intersects = nullptr) const override; > > LayoutUnit borderHalfLeft(bool outer) const; > LayoutUnit borderHalfRight(bool outer) const; >diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp >index b6ecdcf1e2770bc62837e08c8326ac403d51907c..836eb0b9e26103973f7dc01efbc516c3231e92eb 100644 >--- a/Source/WebCore/rendering/RenderView.cpp >+++ b/Source/WebCore/rendering/RenderView.cpp >@@ -577,7 +577,7 @@ LayoutRect RenderView::visualOverflowRect() const > return RenderBlockFlow::visualOverflowRect(); > } > >-LayoutRect RenderView::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderView::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool*) const > { > // If a container was specified, and was not nullptr or the RenderView, > // then we should have found it by now. >diff --git a/Source/WebCore/rendering/RenderView.h b/Source/WebCore/rendering/RenderView.h >index 294737daad7c9c29c002459070bff7812a3aadf9..5d3e874ee24a5d9f911176b2b24e8a6d6fbb385e 100644 >--- a/Source/WebCore/rendering/RenderView.h >+++ b/Source/WebCore/rendering/RenderView.h >@@ -72,7 +72,7 @@ public: > FrameView& frameView() const { return m_frameView; } > > LayoutRect visualOverflowRect() const override; >- LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override; >+ LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }, bool* intersects = nullptr) const override; > void repaintRootContents(); > void repaintViewRectangle(const LayoutRect&) const; > void repaintViewAndCompositedLayers(); >diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp >index 8c73091b2ad679c7424189f564ef898e2f74c37e..bd82540fb6d93fe261a559ae8551f956368cd4ae 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp >@@ -98,14 +98,14 @@ LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(const RenderLay > return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer); > } > >-FloatRect RenderSVGForeignObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const >+FloatRect RenderSVGForeignObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) const > { >- return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); >+ return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed, useEdgeInclusiveIntersection, intersects); > } > >-LayoutRect RenderSVGForeignObject::computeRectForRepaint(const LayoutRect& repaintRect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderSVGForeignObject::computeRectForRepaint(const LayoutRect& repaintRect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool* intersects) const > { >- return enclosingLayoutRect(computeFloatRectForRepaint(repaintRect, repaintContainer, context.m_hasPositionFixedDescendant)); >+ return enclosingLayoutRect(computeFloatRectForRepaint(repaintRect, repaintContainer, context.m_hasPositionFixedDescendant, context.m_useEdgeInclusiveIntersection, intersects)); > } > > const AffineTransform& RenderSVGForeignObject::localToParentTransform() const >diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h >index 1d53ce02f0ff98233932ff4f7f434341634a3985..1a36872b520e39e1fca4edae43482470fe276290 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h >+++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h >@@ -40,8 +40,8 @@ public: > void paint(PaintInfo&, const LayoutPoint&) override; > > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; >- FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const override; >- LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override; >+ FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false, bool useEdgeInclusiveIntersection = false, bool* intersects = nullptr) const override; >+ LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }, bool* intersects = nullptr) const override; > > bool requiresLayer() const override { return false; } > void layout() override; >diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.cpp b/Source/WebCore/rendering/svg/RenderSVGInline.cpp >index c3a5400d2cdacdeadef4ccb930f78c43cf5b4e8b..0dbeff87be0372cf474d5dc927757ad0d977a51a 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGInline.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGInline.cpp >@@ -75,9 +75,9 @@ LayoutRect RenderSVGInline::clippedOverflowRectForRepaint(const RenderLayerModel > return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer); > } > >-FloatRect RenderSVGInline::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const >+FloatRect RenderSVGInline::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) const > { >- return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); >+ return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed, useEdgeInclusiveIntersection, intersects); > } > > void RenderSVGInline::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const >diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.h b/Source/WebCore/rendering/svg/RenderSVGInline.h >index 549bac49ba17bb60a3041902c4da7b55fbd261b5..4e57e97bc94798ad23a729e1f285e1ce9a165a48 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGInline.h >+++ b/Source/WebCore/rendering/svg/RenderSVGInline.h >@@ -51,7 +51,7 @@ private: > FloatRect repaintRectInLocalCoordinates() const final; > > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const final; >- FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const final; >+ FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false, bool useEdgeInclusiveIntersection = false, bool* intersects = nullptr) const final; > void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const final; > const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const final; > void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const final; >diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp >index 6a0b6691e7203ff675b5b1a40fde8308b98ec183..bdd273049b696ca5832e4d514931e97e7e7f6aac 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp >@@ -53,9 +53,9 @@ LayoutRect RenderSVGModelObject::clippedOverflowRectForRepaint(const RenderLayer > return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer); > } > >-FloatRect RenderSVGModelObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const >+FloatRect RenderSVGModelObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) const > { >- return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); >+ return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed, useEdgeInclusiveIntersection, intersects); > } > > void RenderSVGModelObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const >diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.h b/Source/WebCore/rendering/svg/RenderSVGModelObject.h >index 8e3a0e12f54daacb476fb34a9e99b17826cc07c8..7d8e19ff764ba81a47ab0d63d9fd4d8a0ddf2c9e 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.h >+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.h >@@ -47,7 +47,7 @@ class RenderSVGModelObject : public RenderElement { > WTF_MAKE_ISO_ALLOCATED(RenderSVGModelObject); > public: > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; >- FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const final; >+ FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false, bool useEdgeInclusiveIntersection = false, bool* intersects = nullptr) const final; > LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap*) const final; > > void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const final; >diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp >index 7170a0e5f0fab415907d61c4c24fad1895597d3f..eb20b69c3e0498e395ac8260d5abb9b20b2e36de 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp >@@ -342,7 +342,7 @@ LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(const RenderLayerModelOb > return RenderReplaced::computeRectForRepaint(enclosingIntRect(repaintRect), repaintContainer); > } > >-FloatRect RenderSVGRoot::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const >+FloatRect RenderSVGRoot::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) const > { > // Apply our local transforms (except for x/y translation), then our shadow, > // and then call RenderBox's method to handle all the normal CSS Box model bits >@@ -353,16 +353,25 @@ FloatRect RenderSVGRoot::computeFloatRectForRepaint(const FloatRect& repaintRect > shadow->adjustRectForShadow(adjustedRect); > > // Apply initial viewport clip >- if (shouldApplyViewportClip()) >- adjustedRect.intersect(snappedIntRect(borderBoxRect())); >+ if (shouldApplyViewportClip()) { >+ if (useEdgeInclusiveIntersection) >+ *intersects = adjustedRect.edgeInclusiveIntersect(snappedIntRect(borderBoxRect())); >+ else { >+ adjustedRect.intersect(snappedIntRect(borderBoxRect())); >+ if (intersects) >+ *intersects = !adjustedRect.isEmpty(); >+ } >+ } > > if (m_hasBoxDecorations || hasRenderOverflow()) { > // The selectionRect can project outside of the overflowRect, so take their union > // for repainting to avoid selection painting glitches. > LayoutRect decoratedRepaintRect = unionRect(localSelectionRect(false), visualOverflowRect()); > adjustedRect.unite(decoratedRepaintRect); >+ if (intersects) >+ *intersects |= !adjustedRect.isEmpty(); > } >- return RenderReplaced::computeRectForRepaint(enclosingIntRect(adjustedRect), repaintContainer, {fixed, false}); >+ return RenderReplaced::computeRectForRepaint(enclosingIntRect(adjustedRect), repaintContainer, {fixed, false, useEdgeInclusiveIntersection}, intersects); > } > > // This method expects local CSS box coordinates. >diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.h b/Source/WebCore/rendering/svg/RenderSVGRoot.h >index fd57cd01ba5851317bdc3140dda58c390fb0a5d3..de3ce1b4ee7e0bda066f07cfd05fe2c3be187780 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGRoot.h >+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.h >@@ -96,7 +96,7 @@ private: > bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override; > > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; >- FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed) const override; >+ FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) const override; > > void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; > const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override; >diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp >index 3a751b9cb42abd5ee43f532d9a6f291c8a287ad6..e0f6c7710469b350fbf1deedca944cbe70dd7861 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGText.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp >@@ -92,14 +92,14 @@ LayoutRect RenderSVGText::clippedOverflowRectForRepaint(const RenderLayerModelOb > return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer); > } > >-LayoutRect RenderSVGText::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const >+LayoutRect RenderSVGText::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context, bool* intersects) const > { >- return enclosingLayoutRect(computeFloatRectForRepaint(rect, repaintContainer, context.m_hasPositionFixedDescendant)); >+ return enclosingLayoutRect(computeFloatRectForRepaint(rect, repaintContainer, context.m_hasPositionFixedDescendant, context.m_useEdgeInclusiveIntersection, intersects)); > } > >-FloatRect RenderSVGText::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const >+FloatRect RenderSVGText::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) const > { >- return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); >+ return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed, useEdgeInclusiveIntersection, intersects); > } > > void RenderSVGText::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const >diff --git a/Source/WebCore/rendering/svg/RenderSVGText.h b/Source/WebCore/rendering/svg/RenderSVGText.h >index a5d1a78b98b306575503fa872dbaac7f69e0772f..08a6adf7eb04d6e2f7deca83342a7147d8b5f9e5 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGText.h >+++ b/Source/WebCore/rendering/svg/RenderSVGText.h >@@ -78,8 +78,8 @@ private: > void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override; > > LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; >- LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override; >- FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const override; >+ LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }, bool* intersects = nullptr) const override; >+ FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false, bool useEdgeInclusiveIntersection = false, bool* intersects = nullptr) const override; > > void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; > const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override; >diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp >index 971cb1a7144ccfb0dd890dd5dd8c7462a35d1f76..0f7c5fe28979e3cc34c23fe279808db1e999e175 100644 >--- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp >+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp >@@ -72,17 +72,19 @@ LayoutRect SVGRenderSupport::clippedOverflowRectForRepaint(const RenderElement& > return enclosingLayoutRect(renderer.computeFloatRectForRepaint(repaintRect, repaintContainer)); > } > >-FloatRect SVGRenderSupport::computeFloatRectForRepaint(const RenderElement& renderer, const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) >+FloatRect SVGRenderSupport::computeFloatRectForRepaint(const RenderElement& renderer, const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects) > { > FloatRect adjustedRect = repaintRect; > const SVGRenderStyle& svgStyle = renderer.style().svgStyle(); > if (const ShadowData* shadow = svgStyle.shadow()) > shadow->adjustRectForShadow(adjustedRect); > adjustedRect.inflate(renderer.style().outlineWidth()); >+ if (intersects) >+ *intersects |= !adjustedRect.isEmpty(); > > // Translate to coords in our parent renderer, and then call computeFloatRectForRepaint() on our parent. > adjustedRect = renderer.localToParentTransform().mapRect(adjustedRect); >- return renderer.parent()->computeFloatRectForRepaint(adjustedRect, repaintContainer, fixed); >+ return renderer.parent()->computeFloatRectForRepaint(adjustedRect, repaintContainer, fixed, useEdgeInclusiveIntersection, intersects); > } > > const RenderElement& SVGRenderSupport::localToParentTransform(const RenderElement& renderer, AffineTransform &transform) >diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.h b/Source/WebCore/rendering/svg/SVGRenderSupport.h >index b3533395f220466a4db4d1b3edd3343f35860a49..dd4e8a84312cce4b08aeb87b871fcf84ecdbdb55 100644 >--- a/Source/WebCore/rendering/svg/SVGRenderSupport.h >+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.h >@@ -68,7 +68,7 @@ public: > // Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations > static FloatRect repaintRectForRendererInLocalCoordinatesExcludingSVGShadow(const RenderElement&); > static LayoutRect clippedOverflowRectForRepaint(const RenderElement&, const RenderLayerModelObject* repaintContainer); >- static FloatRect computeFloatRectForRepaint(const RenderElement&, const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed); >+ static FloatRect computeFloatRectForRepaint(const RenderElement&, const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed, bool useEdgeInclusiveIntersection, bool* intersects); > static const RenderElement& localToParentTransform(const RenderElement&, AffineTransform &); > static void mapLocalToContainer(const RenderElement&, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed); > static const RenderElement* pushMappingToContainer(const RenderElement&, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&); >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index e51f78149d8998c5c85d71bf46ec60bbc71e8a31..9d8b9c089338544006dc566bf8c50911488fcf19 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,18 @@ >+2018-09-14 Ali Juma <ajuma@chromium.org> >+ >+ [IntersectionObserver] Handle zero-area intersections >+ https://bugs.webkit.org/show_bug.cgi?id=189624 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Rebaseline expectations for tests that now pass. >+ >+ * web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt: >+ * web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt: >+ * web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt: >+ * web-platform-tests/intersection-observer/text-target-expected.txt: >+ * web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt: >+ > 2018-09-12 Ali Juma <ajuma@chromium.org> > > [IntersectionObserver] Implement rootMargin expansion >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt >index 0764338166015b4a8f556ef13872ef6a3a254699..bdc59c463bd6cdbda9e33e3ffd36c3ed43ef4a26 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt >@@ -1,7 +1,7 @@ > > PASS IntersectionObserver should detect and report edge-adjacent and zero-area intersections. > PASS First rAF. >-FAIL Set transform=translateY(200px) on target. assert_equals: entries.length expected 2 but got 1 >-FAIL Set transform=translateY(201px) on target. assert_equals: entries.length expected 3 but got 1 >-FAIL Set transform=translateY(185px) on target. assert_equals: entries.length expected 4 but got 1 >+PASS Set transform=translateY(200px) on target. >+PASS Set transform=translateY(201px) on target. >+PASS Set transform=translateY(185px) on target. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt >index 998e0fa60d0b6a65e9886bd50cd89b3c472922f5..f797af317896a23033c890d081ddaac184bb6624 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt >@@ -1,4 +1,7 @@ > > PASS isIntersecting changes should trigger notifications. >-FAIL Rects in initial notifications should report initial positions. assert_equals: entries[2].target.isIntersecting equals true expected true but got false >+PASS Rects in initial notifications should report initial positions. >+PASS Set scrollTop=100 and check for no new notifications. >+PASS Add 4th target. >+PASS Set scrollTop=100 and check for one new notification. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt >index be031a0c299cf36819575e4c6b100e06f2c8753c..802e8e47fc9680fabfb14aeb38e552579d16401a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt >@@ -1,6 +1,6 @@ > > PASS Observing a zero-area target. > PASS First rAF >-FAIL document.scrollingElement.scrollTop = 300 assert_equals: entries.length expected 2 but got 1 >-FAIL document.scrollingElement.scrollTop = 100 assert_equals: entries.length expected 3 but got 1 >+PASS document.scrollingElement.scrollTop = 300 >+PASS document.scrollingElement.scrollTop = 100 > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt >index e63a4873994235949b834ffd3d703fddbf107f3a..2c088282440c744f344bc3a3bcb97fb9d2e9858c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt >@@ -2,6 +2,6 @@ > > PASS IntersectionObserver observing a br element. > PASS First rAF. >-FAIL document.scrollingElement.scrollTop = 300 assert_equals: entries.length expected 2 but got 1 >-FAIL document.scrollingElement.scrollTop = 100 assert_equals: entries.length expected 3 but got 1 >+PASS document.scrollingElement.scrollTop = 300 >+PASS document.scrollingElement.scrollTop = 100 > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt >index c118fdf66d058fe5762aa05ec0bf7250c9180de4..042b881e11cca769c6360585df57e28c838279ef 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt >@@ -1,4 +1,4 @@ > > PASS Ensure that a zero-area target intersecting root generates a notification with intersectionRatio == 1 >-FAIL First rAF should generate a notification. assert_equals: intersectionRatio == 1 expected 1 but got 0 >+PASS First rAF should generate a notification. >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189624
:
349778
|
351522
|
352736