Commit 997868f7 authored by Stephen McGruer's avatar Stephen McGruer Committed by Commit Bot

Implement logical equality on CrossThreadStyleValues

This CL adds support for comparing two CrossThreadStyleValues, handling
different subclasses via a type enum plus WTF::DowncastTraits. Comparing
CrossThreadStyleValues is required for deduplicating PaintWorkletInputs,
as we have to be able to compare PaintWorkletStylePropertyMaps for equality.

Bug: 933805
Change-Id: I40148516b060e323fa812a611fb8cd687284dc75
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1504229
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638137}
parent 19692dca
......@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadKeywordValue::ToCSSStyleValue() {
return CSSKeywordValue::Create(keyword_value_);
}
bool CrossThreadKeywordValue::operator==(
const CrossThreadStyleValue& other) const {
if (auto* o = DynamicTo<CrossThreadKeywordValue>(other))
return keyword_value_ == o->keyword_value_;
return false;
}
} // namespace blink
......@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
......@@ -20,8 +21,13 @@ class CORE_EXPORT CrossThreadKeywordValue final : public CrossThreadStyleValue {
: keyword_value_(keyword) {}
~CrossThreadKeywordValue() override = default;
StyleValueType GetType() const override {
return StyleValueType::kKeywordType;
}
CSSStyleValue* ToCSSStyleValue() override;
bool operator==(const CrossThreadStyleValue&) const override;
private:
friend class CrossThreadStyleValueTest;
......@@ -29,6 +35,14 @@ class CORE_EXPORT CrossThreadKeywordValue final : public CrossThreadStyleValue {
DISALLOW_COPY_AND_ASSIGN(CrossThreadKeywordValue);
};
template <>
struct DowncastTraits<CrossThreadKeywordValue> {
static bool AllowFrom(const CrossThreadStyleValue& keyword_value) {
return keyword_value.GetType() ==
CrossThreadStyleValue::StyleValueType::kKeywordType;
}
};
} // namespace blink
#endif
......@@ -16,10 +16,19 @@ class CSSStyleValue;
// passed cross threads.
class CORE_EXPORT CrossThreadStyleValue {
public:
enum class StyleValueType {
kUnknownType,
kKeywordType,
kUnitType,
};
virtual ~CrossThreadStyleValue() = default;
virtual StyleValueType GetType() const = 0;
virtual CSSStyleValue* ToCSSStyleValue() = 0;
virtual bool operator==(const CrossThreadStyleValue&) const = 0;
protected:
CrossThreadStyleValue() = default;
......
......@@ -165,4 +165,93 @@ TEST_F(CrossThreadStyleValueTest, CrossThreadUnitValueToCSSStyleValue) {
EXPECT_EQ(static_cast<CSSUnitValue*>(style_value)->unit(), "deg");
}
TEST_F(CrossThreadStyleValueTest, ComparingNullValues) {
// Two null values are equal to each other.
std::unique_ptr<CrossThreadStyleValue> null_value1(nullptr);
std::unique_ptr<CrossThreadStyleValue> null_value2(nullptr);
EXPECT_TRUE(DataEquivalent(null_value1, null_value2));
// If one argument is null and the other isn't they are never equal.
std::unique_ptr<CrossThreadStyleValue> keyword_value(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> unit_value(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
std::unique_ptr<CrossThreadStyleValue> unsupported_value(
new CrossThreadUnsupportedValue("unsupported"));
EXPECT_FALSE(DataEquivalent(null_value1, keyword_value));
EXPECT_FALSE(DataEquivalent(null_value1, unit_value));
EXPECT_FALSE(DataEquivalent(null_value1, unsupported_value));
EXPECT_FALSE(DataEquivalent(keyword_value, null_value1));
EXPECT_FALSE(DataEquivalent(unit_value, null_value1));
EXPECT_FALSE(DataEquivalent(unsupported_value, null_value1));
}
TEST_F(CrossThreadStyleValueTest, ComparingDifferentTypes) {
// Mismatching types are never equal.
std::unique_ptr<CrossThreadStyleValue> keyword_value(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> unit_value(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
std::unique_ptr<CrossThreadStyleValue> unsupported_value(
new CrossThreadUnsupportedValue("unsupported"));
EXPECT_FALSE(DataEquivalent(keyword_value, unit_value));
EXPECT_FALSE(DataEquivalent(keyword_value, unsupported_value));
EXPECT_FALSE(DataEquivalent(unit_value, unsupported_value));
EXPECT_FALSE(DataEquivalent(unit_value, keyword_value));
EXPECT_FALSE(DataEquivalent(unsupported_value, keyword_value));
EXPECT_FALSE(DataEquivalent(unsupported_value, unit_value));
}
TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadKeywordValue) {
// CrossThreadKeywordValues are compared on their keyword; if it is equal then
// so are they.
std::unique_ptr<CrossThreadStyleValue> keyword_value_1(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> keyword_value_2(
new CrossThreadKeywordValue("keyword"));
std::unique_ptr<CrossThreadStyleValue> keyword_value_3(
new CrossThreadKeywordValue("different"));
EXPECT_TRUE(DataEquivalent(keyword_value_1, keyword_value_2));
EXPECT_FALSE(DataEquivalent(keyword_value_1, keyword_value_3));
}
TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnitValue) {
// CrossThreadUnitValues are compared based on their value and unit type; both
// have to match. There are a lot of unit types; we just test a single sample.
std::unique_ptr<CrossThreadStyleValue> unit_value_1(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
// Same value, same unit.
std::unique_ptr<CrossThreadStyleValue> unit_value_2(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kDegrees));
EXPECT_TRUE(DataEquivalent(unit_value_1, unit_value_2));
// Same value, different unit.
std::unique_ptr<CrossThreadStyleValue> unit_value_3(
new CrossThreadUnitValue(1, CSSPrimitiveValue::UnitType::kPoints));
EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_3));
// Different value, same unit.
std::unique_ptr<CrossThreadStyleValue> unit_value_4(
new CrossThreadUnitValue(2, CSSPrimitiveValue::UnitType::kDegrees));
EXPECT_FALSE(DataEquivalent(unit_value_1, unit_value_4));
}
TEST_F(CrossThreadStyleValueTest, ComparingCrossThreadUnsupportedValue) {
// CrossThreadUnsupportedValues are compared on their value; if it is equal
// then so are they.
std::unique_ptr<CrossThreadStyleValue> unsupported_value_1(
new CrossThreadUnsupportedValue("value"));
std::unique_ptr<CrossThreadStyleValue> unsupported_value_2(
new CrossThreadUnsupportedValue("value"));
std::unique_ptr<CrossThreadStyleValue> unsupported_value_3(
new CrossThreadUnsupportedValue("different"));
EXPECT_TRUE(DataEquivalent(unsupported_value_1, unsupported_value_2));
EXPECT_FALSE(DataEquivalent(unsupported_value_1, unsupported_value_3));
}
} // namespace blink
......@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadUnitValue::ToCSSStyleValue() {
return CSSUnitValue::Create(value_, unit_);
}
bool CrossThreadUnitValue::operator==(
const CrossThreadStyleValue& other) const {
if (auto* o = DynamicTo<CrossThreadUnitValue>(other))
return value_ == o->value_ && unit_ == o->unit_;
return false;
}
} // namespace blink
......@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
......@@ -20,8 +21,11 @@ class CORE_EXPORT CrossThreadUnitValue final : public CrossThreadStyleValue {
: value_(value), unit_(unit) {}
~CrossThreadUnitValue() override = default;
StyleValueType GetType() const override { return StyleValueType::kUnitType; }
CSSStyleValue* ToCSSStyleValue() override;
bool operator==(const CrossThreadStyleValue&) const override;
private:
friend class CrossThreadStyleValueTest;
......@@ -30,6 +34,14 @@ class CORE_EXPORT CrossThreadUnitValue final : public CrossThreadStyleValue {
DISALLOW_COPY_AND_ASSIGN(CrossThreadUnitValue);
};
template <>
struct DowncastTraits<CrossThreadUnitValue> {
static bool AllowFrom(const CrossThreadStyleValue& unit_value) {
return unit_value.GetType() ==
CrossThreadStyleValue::StyleValueType::kUnitType;
}
};
} // namespace blink
#endif
......@@ -12,4 +12,11 @@ CSSStyleValue* CrossThreadUnsupportedValue::ToCSSStyleValue() {
return CSSUnsupportedStyleValue::Create(value_);
}
bool CrossThreadUnsupportedValue::operator==(
const CrossThreadStyleValue& other) const {
if (auto* o = DynamicTo<CrossThreadUnsupportedValue>(other))
return value_ == o->value_;
return false;
}
} // namespace blink
......@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/cssom/cross_thread_style_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
......@@ -20,8 +21,13 @@ class CORE_EXPORT CrossThreadUnsupportedValue final
explicit CrossThreadUnsupportedValue(const String& value) : value_(value) {}
~CrossThreadUnsupportedValue() override = default;
StyleValueType GetType() const override {
return StyleValueType::kUnknownType;
}
CSSStyleValue* ToCSSStyleValue() override;
bool operator==(const CrossThreadStyleValue&) const override;
private:
friend class CrossThreadStyleValueTest;
......@@ -29,6 +35,14 @@ class CORE_EXPORT CrossThreadUnsupportedValue final
DISALLOW_COPY_AND_ASSIGN(CrossThreadUnsupportedValue);
};
template <>
struct DowncastTraits<CrossThreadUnsupportedValue> {
static bool AllowFrom(const CrossThreadStyleValue& unsupported_value) {
return unsupported_value.GetType() ==
CrossThreadStyleValue::StyleValueType::kUnknownType;
}
};
} // namespace blink
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment