Diff
Modified: trunk/LayoutTests/ChangeLog (294194 => 294195)
--- trunk/LayoutTests/ChangeLog 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/LayoutTests/ChangeLog 2022-05-14 15:24:29 UTC (rev 294195)
@@ -1,3 +1,15 @@
+2022-05-14 Alan Bujtas <za...@apple.com>
+
+ [Repaint] Border ignores currentColor change when hovering
+ https://bugs.webkit.org/show_bug.cgi?id=240401
+
+ Reviewed by Antti Koivisto.
+
+ * fast/repaint/repaint-current-color-border-on-hover-expected.txt: Added.
+ * fast/repaint/repaint-current-color-border-on-hover.html: Added.
+ * fast/repaint/repaint-pseudo-border-on-hover-expected.txt: Added.
+ * fast/repaint/repaint-pseudo-border-on-hover.html: Added.
+
2022-05-13 Tim Nguyen <n...@apple.com>
[css-ui] Unexpose appearance property values already handled by appearance: auto
Added: trunk/LayoutTests/fast/repaint/repaint-current-color-border-on-hover-expected.txt (0 => 294195)
--- trunk/LayoutTests/fast/repaint/repaint-current-color-border-on-hover-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/repaint/repaint-current-color-border-on-hover-expected.txt 2022-05-14 15:24:29 UTC (rev 294195)
@@ -0,0 +1,4 @@
+(repaint rects
+(rect 8 8 120 120)
+)
+
Added: trunk/LayoutTests/fast/repaint/repaint-current-color-border-on-hover.html (0 => 294195)
--- trunk/LayoutTests/fast/repaint/repaint-current-color-border-on-hover.html (rev 0)
+++ trunk/LayoutTests/fast/repaint/repaint-current-color-border-on-hover.html 2022-05-14 15:24:29 UTC (rev 294195)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ border: solid 10px currentColor;
+}
+div:hover {
+ color: green;
+}
+</style>
+<div id=hitregion></div>
+<script>
+if (window.eventSender) {
+ testRunner.dumpAsText();
+
+ window.internals.startTrackingRepaints();
+
+ eventSender.mouseMoveTo(50, 50);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+
+ document.body.offsetHeight;
+
+ let repaintRects = window.internals.repaintRectsAsText();
+ window.internals.stopTrackingRepaints();
+
+ hitregion.innerText = repaintRects;
+}
+</script>
Added: trunk/LayoutTests/fast/repaint/repaint-pseudo-border-on-hover-expected.txt (0 => 294195)
--- trunk/LayoutTests/fast/repaint/repaint-pseudo-border-on-hover-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/repaint/repaint-pseudo-border-on-hover-expected.txt 2022-05-14 15:24:29 UTC (rev 294195)
@@ -0,0 +1,4 @@
+(repaint rects
+(rect 148 8 100 100)
+)
+
Added: trunk/LayoutTests/fast/repaint/repaint-pseudo-border-on-hover.html (0 => 294195)
--- trunk/LayoutTests/fast/repaint/repaint-pseudo-border-on-hover.html (rev 0)
+++ trunk/LayoutTests/fast/repaint/repaint-pseudo-border-on-hover.html 2022-05-14 15:24:29 UTC (rev 294195)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<style>
+#hitregion {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+#hitregion:after {
+ content: "";
+ border: 50px solid;
+ position: absolute;
+ width: 0;
+ height: 0;
+ margin-left: 140px;
+}
+
+#hitregion:hover:after {
+ color: green;
+}
+</style>
+<div id="hitregion"></div>
+<script>
+if (window.eventSender) {
+ testRunner.dumpAsText();
+
+ window.internals.startTrackingRepaints();
+
+ eventSender.mouseMoveTo(50, 50);
+ eventSender.mouseDown();
+ eventSender.mouseUp();
+
+ document.body.offsetHeight;
+
+ let repaintRects = window.internals.repaintRectsAsText();
+ window.internals.stopTrackingRepaints();
+
+ hitregion.innerText = repaintRects;
+}
+</script>
Modified: trunk/Source/WebCore/ChangeLog (294194 => 294195)
--- trunk/Source/WebCore/ChangeLog 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/ChangeLog 2022-05-14 15:24:29 UTC (rev 294195)
@@ -1,5 +1,39 @@
2022-05-14 Alan Bujtas <za...@apple.com>
+ [Repaint] Border ignores currentColor change when hovering
+ https://bugs.webkit.org/show_bug.cgi?id=240401
+
+ Reviewed by Antti Koivisto.
+
+ This patch triggers repaint when currentColor is applied on border.
+
+ It most likely got broken at r150259 (9 years ago!) when StyleDifferenceRepaintIfText was introduced.
+ StyleDifferenceRepaintIfText is a "conditional repaint" diff value which only triggers repaint if the renderer has some text content.
+
+ Later, r156619 addressed some of the "content with border/outline is not painting" fallout by extending
+ StyleDifferenceRepaintIfText to RepaintIfTextOrBorderOrOutline.
+ RepaintIfTextOrBorderOrOutline turns "conditional repaints" to real repaints if, in addition to text, the content has outline/border.
+ However the fix was neither complete nor proper (it patched the repaint logic by changing hasImmediateNonWhitespaceTextChildOrBorderOrOutline
+ instead of computing the correct diff value -unconditional Repaint).
+
+ Fast-forward to 2020, r267528 ensured that content with outline is no longer a "conditional repaint".
+ It also made some of the code introduced in r156619 redundant (see hasImmediateNonWhitespaceTextChildOrBorderOrOutline).
+
+ This patch expands on r267528 by introducing isEquivalentForPainting for the border data. It ensures that we
+ compute (unconditional) Repaint diff value, if the border uses currentColor.
+
+ Tests: fast/repaint/repaint-current-color-border-on-hover.html
+ fast/repaint/repaint-pseudo-border-on-hover.html
+
+ * rendering/RenderElement.cpp:
+ (WebCore::RenderElement::hasImmediateNonWhitespaceTextChildOrBorderOrOutline const):
+ * rendering/style/BorderData.h:
+ (WebCore::BorderData::isEquivalentForPainting const):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::changeRequiresRepaint const):
+
+2022-05-14 Alan Bujtas <za...@apple.com>
+
[FFC][Integration] Add updateFormattingRootGeometryAndInvalidate/updateRenderers
https://bugs.webkit.org/show_bug.cgi?id=240413
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp (294194 => 294195)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -652,7 +652,7 @@
case StyleDifference::RecompositeLayer:
return true;
case StyleDifference::Repaint:
- case StyleDifference::RepaintIfTextOrBorderOrOutline:
+ case StyleDifference::RepaintIfText:
case StyleDifference::RepaintLayer:
// FIXME: We could do a more focused style check by matching RendererStyle::changeRequiresRepaint&co.
return canUseForStyle(blockContainer, IncludeReasons::First).isEmpty();
Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (294194 => 294195)
--- trunk/Source/WebCore/rendering/RenderElement.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -301,20 +301,17 @@
return diff;
}
-inline bool RenderElement::hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const
-{
- for (auto& child : childrenOfType<RenderObject>(*this)) {
- if (is<RenderText>(child) && !downcast<RenderText>(child).isAllCollapsibleWhitespace())
- return true;
- if (child.style().hasOutline() || child.style().hasBorder())
- return true;
- }
- return false;
-}
inline bool RenderElement::shouldRepaintForStyleDifference(StyleDifference diff) const
{
- return diff == StyleDifference::Repaint || (diff == StyleDifference::RepaintIfTextOrBorderOrOutline && hasImmediateNonWhitespaceTextChildOrBorderOrOutline());
+ auto hasImmediateNonWhitespaceTextChild = [&] {
+ for (auto& child : childrenOfType<RenderText>(*this)) {
+ if (!child.isAllCollapsibleWhitespace())
+ return true;
+ }
+ return false;
+ };
+ return diff == StyleDifference::Repaint || (diff == StyleDifference::RepaintIfText && hasImmediateNonWhitespaceTextChild());
}
void RenderElement::updateFillImages(const FillLayer* oldLayers, const FillLayer& newLayers)
Modified: trunk/Source/WebCore/rendering/RenderElement.h (294194 => 294195)
--- trunk/Source/WebCore/rendering/RenderElement.h 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/RenderElement.h 2022-05-14 15:24:29 UTC (rev 294195)
@@ -368,7 +368,6 @@
void handleDynamicFloatPositionChange();
bool shouldRepaintForStyleDifference(StyleDifference) const;
- bool hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const;
void updateFillImages(const FillLayer*, const FillLayer&);
void updateImage(StyleImage*, StyleImage*);
Modified: trunk/Source/WebCore/rendering/RenderTextControl.cpp (294194 => 294195)
--- trunk/Source/WebCore/rendering/RenderTextControl.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/RenderTextControl.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -71,7 +71,7 @@
auto oldInnerTextStyle = textFormControlElement().createInnerTextStyle(*oldStyle);
if (newInnerTextStyle != oldInnerTextStyle)
innerTextRenderer->setStyle(WTFMove(newInnerTextStyle));
- else if (diff == StyleDifference::RepaintIfTextOrBorderOrOutline || diff == StyleDifference::Repaint) {
+ else if (diff == StyleDifference::RepaintIfText || diff == StyleDifference::Repaint) {
// Repaint is expected to be propagated down to the shadow tree when non-inherited style property changes
// (e.g. text-decoration-color) since that's where the value actually takes effect.
innerTextRenderer->repaint();
Modified: trunk/Source/WebCore/rendering/style/BorderData.cpp (294194 => 294195)
--- trunk/Source/WebCore/rendering/style/BorderData.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/style/BorderData.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -27,10 +27,23 @@
#include "BorderData.h"
#include "OutlineValue.h"
+#include "RenderStyle.h"
#include <wtf/text/TextStream.h>
namespace WebCore {
+bool BorderData::isEquivalentForPainting(const BorderData& other, bool currentColorDiffers) const
+{
+ if (*this != other)
+ return false;
+
+ if (!currentColorDiffers)
+ return true;
+
+ auto borderHasCurrentColor = RenderStyle::isCurrentColor(m_top.color()) || RenderStyle::isCurrentColor(m_right.color()) || RenderStyle::isCurrentColor(m_bottom.color()) || RenderStyle::isCurrentColor(m_left.color());
+ return !borderHasCurrentColor;
+}
+
TextStream& operator<<(TextStream& ts, const BorderValue& borderValue)
{
ts << borderValue.width() << " " << borderValue.style() << " " << borderValue.color();
Modified: trunk/Source/WebCore/rendering/style/BorderData.h (294194 => 294195)
--- trunk/Source/WebCore/rendering/style/BorderData.h 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/style/BorderData.h 2022-05-14 15:24:29 UTC (rev 294195)
@@ -107,6 +107,8 @@
return FloatBoxExtent(borderTopWidth(), borderRightWidth(), borderBottomWidth(), borderLeftWidth());
}
+ bool isEquivalentForPainting(const BorderData& other, bool currentColorDiffers) const;
+
bool operator==(const BorderData& o) const
{
return m_left == o.m_left && m_right == o.m_right && m_top == o.m_top && m_bottom == o.m_bottom && m_image == o.m_image
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (294194 => 294195)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -1214,14 +1214,14 @@
return true;
+ bool currentColorDiffers = m_inheritedData->color != other.m_inheritedData->color;
if (m_backgroundData.ptr() != other.m_backgroundData.ptr()) {
- bool currentColorDiffers = m_inheritedData->color != other.m_inheritedData->color;
if (!m_backgroundData->isEquivalentForPainting(*other.m_backgroundData, currentColorDiffers))
return true;
}
if (m_surroundData.ptr() != other.m_surroundData.ptr()) {
- if (m_surroundData->border != other.m_surroundData->border)
+ if (!m_surroundData->border.isEquivalentForPainting(other.m_surroundData->border, currentColorDiffers))
return true;
}
@@ -1241,7 +1241,7 @@
return false;
}
-bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle& other, OptionSet<StyleDifferenceContextSensitiveProperty>&) const
+bool RenderStyle::changeRequiresRepaintIfText(const RenderStyle& other, OptionSet<StyleDifferenceContextSensitiveProperty>&) const
{
if (m_inheritedData->color != other.m_inheritedData->color
|| m_inheritedFlags.textDecorationLines != other.m_inheritedFlags.textDecorationLines
@@ -1309,8 +1309,8 @@
if (changeRequiresRepaint(other, changedContextSensitiveProperties))
return StyleDifference::Repaint;
- if (changeRequiresRepaintIfTextOrBorderOrOutline(other, changedContextSensitiveProperties))
- return StyleDifference::RepaintIfTextOrBorderOrOutline;
+ if (changeRequiresRepaintIfText(other, changedContextSensitiveProperties))
+ return StyleDifference::RepaintIfText;
// FIXME: RecompositeLayer should also behave as a priority bit (e.g when the style change requires layout, we know that
// the content also needs repaint and it will eventually get repainted,
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (294194 => 294195)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-05-14 15:24:29 UTC (rev 294195)
@@ -2076,7 +2076,7 @@
bool changeRequiresPositionedLayoutOnly(const RenderStyle&, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const;
bool changeRequiresLayerRepaint(const RenderStyle&, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const;
bool changeRequiresRepaint(const RenderStyle&, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const;
- bool changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle&, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const;
+ bool changeRequiresRepaintIfText(const RenderStyle&, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const;
bool changeRequiresRecompositeLayer(const RenderStyle&, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const;
// non-inherited attributes
Modified: trunk/Source/WebCore/rendering/style/RenderStyleConstants.cpp (294194 => 294195)
--- trunk/Source/WebCore/rendering/style/RenderStyleConstants.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/style/RenderStyleConstants.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -958,7 +958,7 @@
case StyleDifference::Equal: ts << "equal"; break;
case StyleDifference::RecompositeLayer: ts << "recomposite layer"; break;
case StyleDifference::Repaint: ts << "repaint"; break;
- case StyleDifference::RepaintIfTextOrBorderOrOutline: ts << "repaint if text or border or outline"; break;
+ case StyleDifference::RepaintIfText: ts << "repaint if text"; break;
case StyleDifference::RepaintLayer: ts << "repaint layer"; break;
case StyleDifference::LayoutPositionedMovementOnly: ts << "layout positioned movement only"; break;
case StyleDifference::SimplifiedLayout: ts << "simplified layout"; break;
Modified: trunk/Source/WebCore/rendering/style/RenderStyleConstants.h (294194 => 294195)
--- trunk/Source/WebCore/rendering/style/RenderStyleConstants.h 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/style/RenderStyleConstants.h 2022-05-14 15:24:29 UTC (rev 294195)
@@ -49,7 +49,7 @@
// - StyleDifference::Equal - The two styles are identical
// - StyleDifference::RecompositeLayer - The layer needs its position and transform updated, but no repaint
// - StyleDifference::Repaint - The object just needs to be repainted.
-// - StyleDifference::RepaintIfTextOrBorderOrOutline - The object needs to be repainted if it contains text or a border or outline.
+// - StyleDifference::RepaintIfText - The object needs to be repainted if it contains text.
// - StyleDifference::RepaintLayer - The layer and its descendant layers needs to be repainted.
// - StyleDifference::LayoutPositionedMovementOnly - Only the position of this positioned object has been updated
// - StyleDifference::SimplifiedLayout - Only overflow needs to be recomputed
@@ -59,7 +59,7 @@
Equal,
RecompositeLayer,
Repaint,
- RepaintIfTextOrBorderOrOutline,
+ RepaintIfText,
RepaintLayer,
LayoutPositionedMovementOnly,
SimplifiedLayout,
Modified: trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp (294194 => 294195)
--- trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp 2022-05-14 14:40:27 UTC (rev 294194)
+++ trunk/Source/WebCore/rendering/svg/SVGResourcesCache.cpp 2022-05-14 15:24:29 UTC (rev 294195)
@@ -102,7 +102,7 @@
return;
// In this case the proper SVGFE*Element will decide whether the modified CSS properties require a relayout or repaint.
- if (renderer.isSVGResourceFilterPrimitive() && (diff == StyleDifference::Repaint || diff == StyleDifference::RepaintIfTextOrBorderOrOutline))
+ if (renderer.isSVGResourceFilterPrimitive() && (diff == StyleDifference::Repaint || diff == StyleDifference::RepaintIfText))
return;
// Dynamic changes of CSS properties like 'clip-path' may require us to recompute the associated resources for a renderer.