Commit 47b0b6ca authored by Darren Shen's avatar Darren Shen Committed by Commit Bot

[css-typed-om] Normalize custom property declarations.

When parsing custom properties or retrieving them from CSSOM, we need
to return a CSSUnparsedValue.

Spec: https://drafts.css-houdini.org/css-typed-om-1/#normalize-tokens

Bug: 788570, 779477
Change-Id: Ia2fa289dc076ffd6dbacf03822907663209c6284
Reviewed-on: https://chromium-review.googlesource.com/804920Reviewed-by: default avatarnainar <nainar@chromium.org>
Commit-Queue: Darren Shen <shend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521969}
parent fe2b322b
......@@ -43,7 +43,7 @@ registerPaint('geometry', class {
ctx.strokeStyle = 'green';
if (serializedStrings[0] != "--bar: [null]")
ctx.strokeStyle = 'red';
if (serializedStrings[1] != "--foo: [CSSStyleValue= bar]")
if (serializedStrings[1] != "--foo: [CSSUnparsedValue= bar]")
ctx.strokeStyle = 'blue';
if (serializedStrings[2] != "align-items: [CSSKeywordValue=normal]")
ctx.strokeStyle = 'yellow';
......
......@@ -46,7 +46,7 @@ registerPaint('geometry', class {
ctx.strokeStyle = 'green';
if (serializedStrings[0] != "--bar: [null]")
ctx.strokeStyle = 'red';
if (serializedStrings[1] != "--foo: [CSSStyleValue= bar]")
if (serializedStrings[1] != "--foo: [CSSUnparsedValue= bar]")
ctx.strokeStyle = 'blue';
if (serializedStrings[2] != "border-radius: [CSSStyleValue=2px]")
ctx.strokeStyle = 'yellow';
......
......@@ -8,6 +8,16 @@
<script>
'use strict';
function assert_string_normalizes_to(property, str, expected) {
// From string
assert_style_value_equals(CSSStyleValue.parse(property, str), expected);
// From CSSOM
assert_style_value_equals(
newDivWithStyle(property + ':' + str).attributeStyleMap.get(property),
expected
);
}
const gTestCases = [
{
value: 'var(--A)',
......@@ -40,16 +50,13 @@ const gTestCases = [
];
for (const {value, expectedResult} of gTestCases) {
// TODO(788570): Add similar tests using a custom property instead of 'color'
test(() => {
const result = CSSStyleValue.parse('color', value);
assert_style_value_equals(result, new CSSUnparsedValue(...expectedResult));
}, 'Normalizing "' + value + '" from String returns correct CSSUnparsedValue');
assert_string_normalizes_to('color', value, new CSSUnparsedValue(...expectedResult));
}, 'Normalizing "' + value + '" on a CSS property returns correct CSSUnparsedValue');
test(() => {
const result = newDivWithStyle('color:' + value).attributeStyleMap.get('color');
assert_style_value_equals(result, new CSSUnparsedValue(...expectedResult));
}, 'Normalizing "' + value + '" from CSSOM returns correct CSSUnparsedValue');
assert_string_normalizes_to('--X', value, new CSSUnparsedValue(...expectedResult));
}, 'Normalizing "' + value + '" on a custom property returns correct CSSUnparsedValue');
}
</script>
This is a testharness.js-based test.
PASS Calling CSSStyleValue.parse with an empty string throws a TypeError
PASS Calling CSSStyleValue.parse with an unsupported CSS property throws a TypeError
PASS Calling CSSStyleValue.parse with a CSS shorthand throws a TypeError
PASS Calling CSSStyleValue.parse with an invalid cssText for the given property throws a SyntaxError
PASS Calling CSSStyleValue.parseAll with an empty string throws a TypeError
PASS Calling CSSStyleValue.parseAll with an unsupported CSS property throws a TypeError
PASS Calling CSSStyleValue.parseAll with a CSS shorthand throws a TypeError
PASS Calling CSSStyleValue.parseAll with an invalid cssText for the given property throws a SyntaxError
PASS Calling CSSStyleValue.parse with a valid cssText for the given property returns a valid CSSStyleValue
PASS Calling CSSStyleValue.parse with a mixed case cssText returns a valid CSSStyleValue
FAIL Calling CSSStyleValue.parse with a custom property returns a valid CSSStyleValue Failed to execute 'parse' on 'CSSStyleValue': Invalid property name
PASS Calling CSSStyleValue.parseAll with a valid cssText for the given property returns a single-element list containing a valid CSSStyleValue
PASS Calling CSSStyleValue.parseAll with a mixed case cssText returns a single-element list containing a valid CSSStyleValue
FAIL Calling CSSStyleValue.parseAll with a custom property returns a single-element list containing a valid CSSStyleValue Failed to execute 'parseAll' on 'CSSStyleValue': Invalid property name
PASS Calling CSSStyleValue.parse with a list-value property returns first list value
PASS Calling CSSStyleValue.parseAll with a list-value property returns a sequence of values
Harness: the test ran to completion.
......@@ -30,7 +30,7 @@ for (const parseMethod of ['parse', 'parseAll']) {
const gValidNonListTests = [
{ property: 'width', value: '10px', expected: CSS.px(10), desc: 'a valid cssText for the given property' },
{ property: 'wIdTh', value: '10px', expected: CSS.px(10), desc: 'a mixed case cssText' },
{ property: '--foo', value: '10%', expected: CSS.percent(10), desc: 'a custom property' },
{ property: '--foo', value: '10%', expected: new CSSUnparsedValue('10%'), desc: 'a custom property' },
];
for (const {property, value, expected, desc} of gValidNonListTests) {
......
This is a testharness.js-based test.
FAIL Computed StylePropertyMap contains every CSS property assert_equals: expected 296 but got 294
PASS Computed StylePropertyMap contains CSS property declarations in style rules
FAIL Computed StylePropertyMap contains custom property declarations in style rules assert_equals: expected "CSSUnparsedValue" but got "CSSStyleValue"
PASS Computed StylePropertyMap contains custom property declarations in style rules
PASS Computed StylePropertyMap contains CSS property declarations in inline styles
FAIL Computed StylePropertyMap contains custom property declarations in inline rules assert_equals: expected "CSSUnparsedValue" but got "CSSStyleValue"
PASS Computed StylePropertyMap contains custom property declarations in inline rules
PASS Computed StylePropertyMap contains computed values and not resolved values
PASS Computed StylePropertyMap is live
Harness: the test ran to completion.
......
This is a testharness.js-based test.
PASS Calling StylePropertyMap.get with an unsupported property throws a TypeError
PASS Calling StylePropertyMap.get with a property not in the property model returns null
PASS Calling StylePropertyMap.get with a custom property not in the property model returns null
PASS Calling StylePropertyMap.get with a valid property returns the correct entry
PASS StylePropertyMap.get with a valid property in mixed case returns the correct entry
FAIL Calling StylePropertyMap.get with a valid custom property returns the correct entry assert_equals: expected "CSSUnparsedValue" but got "CSSStyleValue"
PASS Calling StylePropertyMap.get with a list-valued property returns only the first value
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Calling StylePropertyMap.getAll with an unsupported property throws a TypeError
PASS Calling StylePropertyMap.getAll with a property not in the property model returns an empty list
PASS Calling StylePropertyMap.getAll with a custom property not in the property model returns an empty list
PASS Calling StylePropertyMap.getAll with a valid property returns a single element list with the correct entry
PASS StylePropertyMap.getAll is case-insensitive
FAIL Calling StylePropertyMap.getAll with a valid custom property returns a single element list with the correct entry assert_equals: expected "CSSUnparsedValue" but got "CSSStyleValue"
PASS Calling StylePropertyMap.getAll with a list-valued property returns all the values
Harness: the test ran to completion.
......@@ -23,8 +23,7 @@ CSSStyleValueVector ParseCSSStyleValue(
ExceptionState& exception_state) {
const CSSPropertyID property_id = cssPropertyID(property_name);
// TODO(775804): Handle custom properties
if (property_id == CSSPropertyInvalid || property_id == CSSPropertyVariable) {
if (property_id == CSSPropertyInvalid) {
exception_state.ThrowTypeError("Invalid property name");
return CSSStyleValueVector();
}
......
......@@ -4,6 +4,8 @@
#include "core/css/cssom/CSSUnparsedValue.h"
#include "core/css/CSSVariableData.h"
#include "core/css/CSSVariableReferenceValue.h"
#include "core/css/cssom/CSSStyleVariableReferenceValue.h"
#include "core/css/parser/CSSTokenizer.h"
#include "platform/wtf/text/StringBuilder.h"
......@@ -65,9 +67,13 @@ HeapVector<StringOrCSSVariableReferenceValue> ParserTokenRangeToTokens(
} // namespace
CSSUnparsedValue* CSSUnparsedValue::FromCSSValue(
const CSSVariableReferenceValue& css_variable_reference_value) {
return CSSUnparsedValue::Create(ParserTokenRangeToTokens(
css_variable_reference_value.VariableDataValue()->TokenRange()));
const CSSVariableReferenceValue& value) {
DCHECK(value.VariableDataValue());
return FromCSSValue(*value.VariableDataValue());
}
CSSUnparsedValue* CSSUnparsedValue::FromCSSValue(const CSSVariableData& value) {
return CSSUnparsedValue::Create(ParserTokenRangeToTokens(value.TokenRange()));
}
const CSSValue* CSSUnparsedValue::ToCSSValue(
......
......@@ -7,12 +7,14 @@
#include "base/macros.h"
#include "bindings/core/v8/string_or_css_variable_reference_value.h"
#include "core/css/CSSVariableReferenceValue.h"
#include "core/css/cssom/CSSStyleValue.h"
#include "platform/wtf/Vector.h"
namespace blink {
class CSSVariableReferenceValue;
class CSSVariableData;
class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
DEFINE_WRAPPERTYPEINFO();
......@@ -23,6 +25,7 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
}
static CSSUnparsedValue* FromCSSValue(const CSSVariableReferenceValue&);
static CSSUnparsedValue* FromCSSValue(const CSSVariableData&);
const CSSValue* ToCSSValue(SecureContextMode) const override;
......
......@@ -4,8 +4,10 @@
#include "core/css/cssom/StyleValueFactory.h"
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSValue.h"
#include "core/css/CSSVariableReferenceValue.h"
#include "core/css/cssom/CSSKeywordValue.h"
#include "core/css/cssom/CSSNumericValue.h"
#include "core/css/cssom/CSSOMTypes.h"
......@@ -44,6 +46,12 @@ CSSStyleValue* CreateStyleValue(const CSSValue& value) {
return CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value));
if (value.IsVariableReferenceValue())
return CSSUnparsedValue::FromCSSValue(ToCSSVariableReferenceValue(value));
if (value.IsCustomPropertyDeclaration()) {
const CSSVariableData* variable_data =
ToCSSCustomPropertyDeclaration(value).Value();
DCHECK(variable_data);
return CSSUnparsedValue::FromCSSValue(*variable_data);
}
if (value.IsImageValue()) {
return CSSURLImageValue::Create(ToCSSImageValue(value).Clone());
}
......@@ -73,12 +81,15 @@ const CSSValue* ParseProperty(CSSPropertyID property_id,
const auto tokens = tokenizer.TokenizeToEOF();
const CSSParserTokenRange range(tokens);
if (const CSSValue* value =
CSSPropertyParser::ParseSingleValue(property_id, range, context)) {
return value;
if (property_id != CSSPropertyVariable) {
if (const CSSValue* value =
CSSPropertyParser::ParseSingleValue(property_id, range, context)) {
return value;
}
}
if (CSSVariableParser::ContainsValidVariableReferences(range)) {
if (property_id == CSSPropertyVariable ||
CSSVariableParser::ContainsValidVariableReferences(range)) {
return CSSVariableReferenceValue::Create(
CSSVariableData::Create(range, false /* is_animation_tainted */,
false /* needs variable resolution */),
......@@ -97,11 +108,6 @@ CSSStyleValueVector StyleValueFactory::FromString(
DCHECK_NE(property_id, CSSPropertyInvalid);
DCHECK(!CSSProperty::Get(property_id).IsShorthand());
// TODO(775804): Handle custom properties
if (property_id == CSSPropertyVariable) {
return CSSStyleValueVector();
}
const CSSValue* value = ParseProperty(property_id, css_text, parser_context);
if (!value)
return CSSStyleValueVector();
......
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