Skip to content

Commit

Permalink
Apply patch. rdar://problem/104872702
Browse files Browse the repository at this point in the history
Identifier: 259548.722@safari-7615-branch
  • Loading branch information
rjepstein committed May 1, 2023
1 parent bd32211 commit 56d6eb6
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
<style type="text/css"><![CDATA[
div
{
background-color: green;
height: 100px;
width: 100px;
}
]]></style>
</head>
<body>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
<style type="text/css"><![CDATA[
div
{
background-color: green;
height: 100px;
width: 100px;
}
]]></style>
</head>
<body>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>currentColor in color-mix() used in border repaints properly when parent color changes</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/css-color/#currentcolor-color">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
#container {
color: red;
}

#container.green {
color: green;
}

#target {
border: 50px solid color-mix(in hsl, transparent 0%, currentColor 100%);
width: 0;
}
</style>

<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>

<div id="container">
<div id="target"></div>
</div>

<script>
addEventListener("load", () => {
setTimeout(() => {
requestAnimationFrame(() => {
container.classList.add("green");
document.documentElement.classList.remove("reftest-wait");
});
}, 0);
});
</script>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>currentColor in color-mix() used in border repaints properly when color changes</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/css-color/#currentcolor-color">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
#target {
color: red;
border: 50px solid color-mix(in hsl, transparent 0%, currentColor 100%);
width: 0;
}

#target.green {
color: green;
}
</style>

<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>

<div id="target"></div>

<script>
addEventListener("load", () => {
setTimeout(() => {
requestAnimationFrame(() => {
target.classList.add("green");
document.documentElement.classList.remove("reftest-wait");
});
}, 0);
});
</script>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
<style type="text/css"><![CDATA[
div
{
background-color: green;
height: 100px;
width: 100px;
}
]]></style>
</head>
<body>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html class="reftest-wait">
<title>currentColor used in border repaints properly when parent color changes</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/css-color/#currentcolor-color">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
#container {
color: red;
}

#container.green {
color: green;
}

#target {
border: 50px solid currentColor;
width: 0;
}
</style>

<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>

<div id="container">
<div id="target"></div>
</div>

<script>
addEventListener("load", () => {
setTimeout(() => {
requestAnimationFrame(() => {
container.classList.add("green");
document.documentElement.classList.remove("reftest-wait");
});
}, 0);
});
</script>
</html>
4 changes: 2 additions & 2 deletions Source/WebCore/animation/CSSPropertyAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2353,7 +2353,7 @@ class PropertyWrapperSVGPaint final : public AnimationPropertyWrapperBase {
auto toStyleColor = (to.*m_getter)();

// We don't animate when both are currentcolor
if (RenderStyle::isCurrentColor(fromStyleColor) && RenderStyle::isCurrentColor(toStyleColor))
if (fromStyleColor.isCurrentColor() && toStyleColor.isCurrentColor())
return;

auto fromColor = from.colorResolvingCurrentColor(fromStyleColor);
Expand Down Expand Up @@ -3880,7 +3880,7 @@ static std::optional<CSSCustomPropertyValue::SyntaxValue> blendSyntaxValues(cons
if (std::holds_alternative<StyleColor>(from) && std::holds_alternative<StyleColor>(to)) {
auto& fromStyleColor = std::get<StyleColor>(from);
auto& toStyleColor = std::get<StyleColor>(to);
if (!RenderStyle::isCurrentColor(fromStyleColor) || !RenderStyle::isCurrentColor(toStyleColor))
if (!fromStyleColor.isCurrentColor() || !toStyleColor.isCurrentColor())
return blendFunc(fromStyle.colorResolvingCurrentColor(fromStyleColor), toStyle.colorResolvingCurrentColor(toStyleColor), blendingContext);
}

Expand Down
27 changes: 27 additions & 0 deletions Source/WebCore/css/StyleColor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "StyleColor.h"

#include "CSSResolvedColorMix.h"
#include "CSSUnresolvedColor.h"
#include "ColorNormalization.h"
#include "ColorSerialization.h"
#include "HashTools.h"
Expand Down Expand Up @@ -119,6 +120,17 @@ bool StyleColor::isColorKeyword(CSSValueID id, OptionSet<CSSColorType> allowedCo
|| (allowedColorTypes.contains(CSSColorType::System) && isSystemColorKeyword(id));
}

bool StyleColor::containsCurrentColor(const CSSPrimitiveValue& value)
{
if (StyleColor::isCurrentColor(value))
return true;

if (value.isUnresolvedColor())
return value.unresolvedColor().containsCurrentColor();

return false;
}

String StyleColor::debugDescription() const
{
TextStream ts;
Expand All @@ -141,6 +153,21 @@ Color StyleColor::resolveColor(const Color& currentColor) const
);
}

bool StyleColor::containsCurrentColor() const
{
return WTF::switchOn(m_color,
[&] (const Color&) -> bool {
return false;
},
[&] (const StyleCurrentColor&) -> bool {
return true;
},
[&] (const UniqueRef<StyleColorMix>& colorMix) -> bool {
return colorMix->mixComponents1.color.containsCurrentColor() || colorMix->mixComponents2.color.containsCurrentColor();
}
);
}

bool StyleColor::isCurrentColor() const
{
return std::holds_alternative<StyleCurrentColor>(m_color);
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/css/StyleColor.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class StyleColor {
static Color colorFromKeyword(CSSValueID, OptionSet<StyleColorOptions>);
static Color colorFromAbsoluteKeyword(CSSValueID);

static bool containsCurrentColor(const CSSPrimitiveValue&);
static bool isAbsoluteColorKeyword(CSSValueID);
static bool isCurrentColorKeyword(CSSValueID id) { return id == CSSValueCurrentcolor; }
static bool isCurrentColor(const CSSPrimitiveValue& value) { return isCurrentColorKeyword(value.valueID()); }
Expand All @@ -111,6 +112,7 @@ class StyleColor {
// https://drafts.csswg.org/css-color-4/#typedef-color
static bool isColorKeyword(CSSValueID, OptionSet<CSSColorType> = { CSSColorType::Absolute, CSSColorType::Current, CSSColorType::System });

bool containsCurrentColor() const;
bool isCurrentColor() const;
bool isColorMix() const;
bool isAbsoluteColor() const;
Expand Down
10 changes: 10 additions & 0 deletions Source/WebCore/css/color/CSSUnresolvedColor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,23 @@

#include "config.h"
#include "CSSUnresolvedColor.h"
#include "StyleColor.h"

#include "StyleBuilderState.h"

namespace WebCore {

CSSUnresolvedColor::~CSSUnresolvedColor() = default;

bool CSSUnresolvedColor::containsCurrentColor() const
{
return WTF::switchOn(m_value,
[&] (const CSSUnresolvedColorMix& unresolved) {
return StyleColor::containsCurrentColor(unresolved.mixComponents1.color) || StyleColor::containsCurrentColor(unresolved.mixComponents2.color);
}
);
}

void CSSUnresolvedColor::serializationForCSS(StringBuilder& builder) const
{
return WTF::switchOn(m_value, [&] (auto& unresolved) { WebCore::serializationForCSS(builder, unresolved); });
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/css/color/CSSUnresolvedColor.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class CSSUnresolvedColor final : public RefCounted<CSSUnresolvedColor> {

~CSSUnresolvedColor();

bool containsCurrentColor() const;

void serializationForCSS(StringBuilder&) const;
String serializationForCSS() const;

Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/editing/EditingStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,9 @@ void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude)

void EditingStyle::removeTextFillAndStrokeColorsIfNeeded(const RenderStyle* renderStyle)
{
if (RenderStyle::isCurrentColor(renderStyle->textFillColor()))
if (renderStyle->textFillColor().isCurrentColor())
m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor);
if (RenderStyle::isCurrentColor(renderStyle->textStrokeColor()))
if (renderStyle->textStrokeColor().isCurrentColor())
m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor);
}

Expand Down
8 changes: 4 additions & 4 deletions Source/WebCore/rendering/style/BorderData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ bool BorderData::isEquivalentForPainting(const BorderData& other, bool currentCo
if (!currentColorDiffers)
return true;

auto visibleBorderHasCurrentColor = (m_top.isVisible() && RenderStyle::isCurrentColor(m_top.color()))
|| (m_right.isVisible() && RenderStyle::isCurrentColor(m_right.color()))
|| (m_bottom.isVisible() && RenderStyle::isCurrentColor(m_bottom.color()))
|| (m_left.isVisible() && RenderStyle::isCurrentColor(m_left.color()));
auto visibleBorderHasCurrentColor = (m_top.isVisible() && m_top.color().containsCurrentColor())
|| (m_right.isVisible() && m_right.color().containsCurrentColor())
|| (m_bottom.isVisible() && m_bottom.color().containsCurrentColor())
|| (m_left.isVisible() && m_left.color().containsCurrentColor());
return !visibleBorderHasCurrentColor;
}

Expand Down
10 changes: 6 additions & 4 deletions Source/WebCore/rendering/style/RenderStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,17 +1249,19 @@ bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, OptionSet<Styl
return true;


if (m_nonInheritedData.ptr() != other.m_nonInheritedData.ptr()) {
if (m_nonInheritedData->backgroundData.ptr() != other.m_nonInheritedData->backgroundData.ptr()) {
if (currentColorDiffers || m_nonInheritedData.ptr() != other.m_nonInheritedData.ptr()) {
if (currentColorDiffers || m_nonInheritedData->backgroundData.ptr() != other.m_nonInheritedData->backgroundData.ptr()) {
if (!m_nonInheritedData->backgroundData->isEquivalentForPainting(*other.m_nonInheritedData->backgroundData, currentColorDiffers))
return true;
}

if (m_nonInheritedData->surroundData.ptr() != other.m_nonInheritedData->surroundData.ptr()) {
if (currentColorDiffers || m_nonInheritedData->surroundData.ptr() != other.m_nonInheritedData->surroundData.ptr()) {
if (!m_nonInheritedData->surroundData->border.isEquivalentForPainting(other.m_nonInheritedData->surroundData->border, currentColorDiffers))
return true;
}
}

if (m_nonInheritedData.ptr() != other.m_nonInheritedData.ptr()) {
if (m_nonInheritedData->miscData.ptr() != other.m_nonInheritedData->miscData.ptr()
&& miscDataChangeRequiresRepaint(*m_nonInheritedData->miscData, *other.m_nonInheritedData->miscData, changedContextSensitiveProperties))
return true;
Expand Down Expand Up @@ -2314,7 +2316,7 @@ Color RenderStyle::colorResolvingCurrentColor(CSSPropertyID colorProperty, bool
{
auto result = unresolvedColorForProperty(colorProperty, visitedLink);

if (isCurrentColor(result)) {
if (result.isCurrentColor()) {
if (colorProperty == CSSPropertyTextDecorationColor) {
if (hasPositiveStrokeWidth()) {
// Prefer stroke color if possible but not if it's fully transparent.
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/rendering/style/SVGRenderStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ static bool colorChangeRequiresRepaint(const StyleColor& a, const StyleColor& b,
if (a != b)
return true;

if (a.isCurrentColor()) {
ASSERT(b.isCurrentColor());
if (a.containsCurrentColor()) {
ASSERT(b.containsCurrentColor());
return currentColorDiffers;
}

Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/rendering/style/StyleGradientImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ static inline bool operator==(const StyleGradientImage::ConicData& a, const Styl
static bool stopsAreCacheable(const Vector<StyleGradientImage::Stop>& stops)
{
for (auto& stop : stops) {
// FIXME: Do we need handle calc() here?
if (stop.position && stop.position->isFontRelativeLength())
return false;
if (stop.color && stop.color->isCurrentColor())
if (stop.color && stop.color->containsCurrentColor())
return false;
}
return true;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/style/ElementRuleCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ void ElementRuleCollector::addMatchedProperties(MatchedProperties&& matchedPrope

// The value currentColor has implicitely the same side effect. It depends on the value of color,
// which is an inherited value, making the non-inherited property implicitly inherited.
if (is<CSSPrimitiveValue>(value) && StyleColor::isCurrentColor(downcast<CSSPrimitiveValue>(value)))
if (is<CSSPrimitiveValue>(value) && StyleColor::containsCurrentColor(downcast<CSSPrimitiveValue>(value)))
return false;

if (value.hasVariableReferences())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ Color SVGAnimationColorFunction::colorFromString(SVGElement& targetElement, cons
std::optional<float> SVGAnimationColorFunction::calculateDistance(SVGElement&, const String& from, const String& to) const
{
Color fromColor = CSSParser::parseColorWithoutContext(from.stripWhiteSpace());
if (RenderStyle::isCurrentColor(fromColor))
if (!fromColor.isValid())
return { };

Color toColor = CSSParser::parseColorWithoutContext(to.stripWhiteSpace());
if (RenderStyle::isCurrentColor(toColor))
if (!toColor.isValid())
return { };

auto simpleFrom = fromColor.toColorTypeLossy<SRGBA<uint8_t>>().resolved();
Expand Down

0 comments on commit 56d6eb6

Please sign in to comment.