WebKit Bugzilla
Attachment 357578 Details for
Bug 192800
: Update CSS Properties and Values API to use new cycle fallback behaviour
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192800-20181218101031.patch (text/plain), 138.95 KB, created by
Justin Michaud
on 2018-12-18 10:10:36 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Justin Michaud
Created:
2018-12-18 10:10:36 PST
Size:
138.95 KB
patch
obsolete
>Subversion Revision: 239188 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index e3922d25c4a1888769c6b90d3af78d3c2c941cfc..ac9d50fd52e3b8a4e301eac016883ce91ffa9cee 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,23 @@ >+2018-12-17 Justin Michaud <justin_michaud@apple.com> >+ >+ Update CSS Properties and Values API to use new cycle fallback behaviour >+ https://bugs.webkit.org/show_bug.cgi?id=192800 >+ >+ Reviewed by Antti Koivisto. >+ >+ Make CSS variables that are registered and involved in a cycle be treated as invalid. This also fixes a crash in the >+ wpt tests where relative units and calc() in a registered property's initial value would break things instead of failing. >+ >+ * css/CSSCustomPropertyValue.h: >+ * css/CSSVariableReferenceValue.cpp: >+ (WebCore::resolveVariableReference): >+ * css/DOMCSSRegisterCustomProperty.cpp: >+ (WebCore::DOMCSSRegisterCustomProperty::registerProperty): >+ * css/StyleResolver.cpp: >+ (WebCore::StyleResolver::applyCascadedCustomProperty): >+ * css/parser/CSSPropertyParser.cpp: >+ (WebCore::CSSPropertyParser::parseTypedCustomPropertyValue): >+ > 2018-12-13 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] Support dropping contact card data (public.vcard) in editable content >diff --git a/Source/WebCore/css/CSSCustomPropertyValue.h b/Source/WebCore/css/CSSCustomPropertyValue.h >index fe8502558c41e35dac9be0e78439dc437aa9b944..bdaa74d55a0f871926df586b66bc02aac90e6783 100644 >--- a/Source/WebCore/css/CSSCustomPropertyValue.h >+++ b/Source/WebCore/css/CSSCustomPropertyValue.h >@@ -67,6 +67,8 @@ public: > > static Ref<CSSCustomPropertyValue> createSyntaxLength(const AtomicString& name, Length value) > { >+ ASSERT(!value.isUndefined()); >+ ASSERT(!value.isCalculated()); > return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) })); > } > >diff --git a/Source/WebCore/css/CSSVariableReferenceValue.cpp b/Source/WebCore/css/CSSVariableReferenceValue.cpp >index 77a523e4d7ddadf030a12405de7fc2fcc7a114fc..94d63a3b58918aeab4efa9d7093b58f85d77e130 100644 >--- a/Source/WebCore/css/CSSVariableReferenceValue.cpp >+++ b/Source/WebCore/css/CSSVariableReferenceValue.cpp >@@ -70,16 +70,20 @@ static bool resolveVariableReference(CSSParserTokenRange range, Vector<CSSParser > > // Apply fallback to detect cycles > Vector<CSSParserToken> fallbackResult; >- resolveVariableFallback(CSSParserTokenRange(range), fallbackResult, state); >+ bool fallbackReturn = resolveVariableFallback(CSSParserTokenRange(range), fallbackResult, state); > > auto* property = style.getCustomProperty(variableName); > >- if (!property || property->isUnset() || property->isInvalid()) { >+ if (!property || property->isUnset()) { > auto* registered = registeredProperties.get(variableName); > if (registered && registered->initialValue()) > property = registered->initialValue(); >- else >- return resolveVariableFallback(range, result, state); >+ } >+ >+ if (!property || property->isInvalid()) { >+ if (fallbackReturn) >+ result.appendVector(fallbackResult); >+ return fallbackReturn; > } > > ASSERT(property->isResolved()); >diff --git a/Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp b/Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp >index a890669f655010636be21a7a98da5f30da020368..7ecd93d7dc3d432eaf82bc956e61d489a510625b 100644 >--- a/Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp >+++ b/Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp >@@ -40,6 +40,9 @@ namespace WebCore { > > ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& document, const DOMCSSCustomPropertyDescriptor& descriptor) > { >+ if (!isCustomPropertyName(descriptor.name)) >+ return Exception { SyntaxError, "The name of this property is not a custom property name." }; >+ > RefPtr<CSSCustomPropertyValue> initialValue; > if (!descriptor.initialValue.isEmpty()) { > CSSTokenizer tokenizer(descriptor.initialValue); >@@ -50,12 +53,17 @@ ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& docum > styleResolver.applyPropertyToStyle(CSSPropertyInvalid, nullptr, styleResolver.defaultStyleForElement()); > styleResolver.updateFont(); > >+ HashSet<CSSPropertyID> dependencies; >+ CSSPropertyParser::collectParsedCustomPropertyValueDependencies(descriptor.syntax, false, dependencies, tokenizer.tokenRange(), strictCSSParserContext()); >+ >+ if (!dependencies.isEmpty()) >+ return Exception { SyntaxError, "The given initial value must be computationally independent." }; >+ > initialValue = CSSPropertyParser::parseTypedCustomPropertyValue(descriptor.name, descriptor.syntax, tokenizer.tokenRange(), styleResolver, strictCSSParserContext()); > > if (!initialValue || !initialValue->isResolved()) > return Exception { SyntaxError, "The given initial value does not parse for the given syntax." }; > >- HashSet<CSSPropertyID> dependencies; > initialValue->collectDirectComputationalDependencies(dependencies); > initialValue->collectDirectRootComputationalDependencies(dependencies); > >diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp >index 74fa3f5398fe6fbe4246ce6c10d38d59f8e2b3a6..d5ee934d2301e8b30182dfd97d50d102626a43e1 100644 >--- a/Source/WebCore/css/StyleResolver.cpp >+++ b/Source/WebCore/css/StyleResolver.cpp >@@ -2319,6 +2319,7 @@ void StyleResolver::applyCascadedCustomProperty(const String& name, ApplyCascade > return; > > auto property = state.cascade->customProperties().get(name); >+ bool inCycle = state.inProgressPropertiesCustom.contains(name); > > for (auto index : { SelectorChecker::MatchDefault, SelectorChecker::MatchLink, SelectorChecker::MatchVisited }) { > if (!property.cssValue[index]) >@@ -2328,13 +2329,9 @@ void StyleResolver::applyCascadedCustomProperty(const String& name, ApplyCascade > > Ref<CSSCustomPropertyValue> valueToApply = CSSCustomPropertyValue::create(downcast<CSSCustomPropertyValue>(*property.cssValue[index])); > >- if (state.inProgressPropertiesCustom.contains(name)) { >- // We are in a cycle, so reset the value. >- state.appliedCustomProperties.add(name); >- // Resolve this value so that we reset its dependencies >- if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) >- resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state); >- valueToApply = CSSCustomPropertyValue::createWithID(name, CSSValueUnset); >+ if (inCycle) { >+ state.appliedCustomProperties.add(name); // Make sure we do not try to apply this property again while resolving it. >+ valueToApply = CSSCustomPropertyValue::createWithID(name, CSSValueInvalid); > } > > state.inProgressPropertiesCustom.add(name); >@@ -2342,6 +2339,9 @@ void StyleResolver::applyCascadedCustomProperty(const String& name, ApplyCascade > if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) { > RefPtr<CSSValue> parsedValue = resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state); > >+ if (state.appliedCustomProperties.contains(name)) >+ return; // There was a cycle and the value was reset, so bail. >+ > if (!parsedValue) > parsedValue = CSSCustomPropertyValue::createWithID(name, CSSValueUnset); > >@@ -2365,8 +2365,23 @@ void StyleResolver::applyCascadedCustomProperty(const String& name, ApplyCascade > } > applyProperty(CSSPropertyCustom, valueToApply.ptr(), state, index); > } >- state.inProgressPropertiesCustom.remove(name); >- state.appliedCustomProperties.add(name); >+ } >+ >+ state.inProgressPropertiesCustom.remove(name); >+ state.appliedCustomProperties.add(name); >+ >+ for (auto index : { SelectorChecker::MatchDefault, SelectorChecker::MatchLink, SelectorChecker::MatchVisited }) { >+ if (!property.cssValue[index]) >+ continue; >+ if (index != SelectorChecker::MatchDefault && this->state().style()->insideLink() == InsideLink::NotInside) >+ continue; >+ >+ Ref<CSSCustomPropertyValue> valueToApply = CSSCustomPropertyValue::create(downcast<CSSCustomPropertyValue>(*property.cssValue[index])); >+ >+ if (inCycle && WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) { >+ // Resolve this value so that we reset its dependencies. >+ resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state); >+ } > } > } > >diff --git a/Source/WebCore/css/parser/CSSPropertyParser.cpp b/Source/WebCore/css/parser/CSSPropertyParser.cpp >index 5cb8945b38fa810b2773e02f83678e9b66b209c2..98df41895a30c7a0bed6535afaf5690bcfb6f637 100644 >--- a/Source/WebCore/css/parser/CSSPropertyParser.cpp >+++ b/Source/WebCore/css/parser/CSSPropertyParser.cpp >@@ -4393,8 +4393,11 @@ RefPtr<CSSCustomPropertyValue> CSSPropertyParser::parseTypedCustomPropertyValue( > if (syntax != "*") { > m_range.consumeWhitespace(); > auto primitiveVal = consumeWidthOrHeight(m_range, m_context); >- if (primitiveVal && primitiveVal->isPrimitiveValue()) >- return CSSCustomPropertyValue::createSyntaxLength(name, StyleBuilderConverter::convertLength(styleResolver, *primitiveVal)); >+ if (primitiveVal && primitiveVal->isPrimitiveValue() && downcast<CSSPrimitiveValue>(*primitiveVal).isLength()) { >+ auto length = StyleBuilderConverter::convertLength(styleResolver, *primitiveVal); >+ if (!length.isCalculated() && !length.isUndefined()) >+ return CSSCustomPropertyValue::createSyntaxLength(name, WTFMove(length)); >+ } > } else { > auto propertyValue = CSSCustomPropertyValue::createSyntaxAll(name, CSSVariableData::create(m_range)); > while (!m_range.atEnd()) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 068bdaf2dd3756f72fc9187c52a8f75efb4244f9..9fba955f6227a344060871beeabadb1089f97100 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,16 @@ >+2018-12-17 Justin Michaud <justin_michaud@apple.com> >+ >+ Update CSS Properties and Values API to use new cycle fallback behaviour >+ https://bugs.webkit.org/show_bug.cgi?id=192800 >+ >+ Reviewed by Antti Koivisto. >+ >+ * css-custom-properties-api/crash.html: >+ * css-custom-properties-api/inherits-expected.txt: >+ * css-custom-properties-api/inherits.html: >+ * css-custom-properties-api/registerProperty-expected.txt: >+ * css-custom-properties-api/registerProperty.html: >+ > 2018-12-13 Per Arne Vollan <pvollan@apple.com> > > [macOS] Inline WebVTT styles should override styles from Captions settings in System Preferences >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 7ff7fd9b4674abb2c0397a1af773535fe0a7219d..b30fce64d16ac7e32449a5ed7bc39fbf5e8c922d 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,43 @@ >+2018-12-17 Justin Michaud <justin_michaud@apple.com> >+ >+ Update CSS Properties and Values API to use new cycle fallback behaviour >+ https://bugs.webkit.org/show_bug.cgi?id=192800 >+ >+ Reviewed by Antti Koivisto. >+ >+ Re-import tests and adjust expected results. Some of the tests go from pass to fail because >+ this patch adds some extra dependency checking to property registrations to fix a crash, but >+ now unsupported syntaxes like <length-percentage> do not register properly. >+ >+ * web-platform-tests/css/css-properties-values-api/register-property-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html: >+ * web-platform-tests/css/css-properties-values-api/register-property.html: >+ * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html: >+ * web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/registered-property-computation.html: >+ * web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/registered-property-cssom.html: >+ * web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/registered-property-initial.html: >+ * web-platform-tests/css/css-properties-values-api/resources/utils.js: Added. >+ (generate_name): >+ (any_initial_value): >+ (generate_property): >+ (all_syntaxes): >+ * web-platform-tests/css/css-properties-values-api/resources/w3c-import.log: Added. >+ * web-platform-tests/css/css-properties-values-api/self-utils-expected.txt: Added. >+ * web-platform-tests/css/css-properties-values-api/self-utils.html: Added. >+ * web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/typedom.tentative.html: >+ * web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/unit-cycles.html: >+ * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html: >+ * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt: >+ * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html: >+ * web-platform-tests/css/css-properties-values-api/w3c-import.log: >+ > 2018-12-10 Rob Buis <rbuis@igalia.com> > > XMLHttpRequest removes spaces from content-types before processing >diff --git a/LayoutTests/css-custom-properties-api/crash.html b/LayoutTests/css-custom-properties-api/crash.html >index 7f2cd70a2a31deab99f0032c41fea7a5c8ab7f9b..620568897d9772b3a152b87f75a524da4155f824 100644 >--- a/LayoutTests/css-custom-properties-api/crash.html >+++ b/LayoutTests/css-custom-properties-api/crash.html >@@ -48,15 +48,15 @@ test(function() { > test(function() { > inlineStyle.setProperty('--baz', ' 40px'); > assert_equals(computedStyle.getPropertyValue('--baz'), '40px'); >- assert_equals(computedStyle.getPropertyValue('--foo'), '200px'); >- assert_equals(computedStyle.getPropertyValue('--bar'), '200px'); >+ assert_equals(computedStyle.getPropertyValue('--foo'), ''); >+ assert_equals(computedStyle.getPropertyValue('--bar'), ''); > assert_equals(computedStyle.getPropertyValue('--baz'), '40px'); >- assert_equals(computedStyle.getPropertyValue('font-size'), '200px'); >+ assert_equals(computedStyle.getPropertyValue('font-size'), '30px'); > inlineStyle.removeProperty('--baz'); > assert_equals(computedStyle.getPropertyValue('--baz'), '200px'); >- assert_equals(computedStyle.getPropertyValue('--foo'), '200px'); >- assert_equals(computedStyle.getPropertyValue('--bar'), '200px'); >- assert_equals(computedStyle.getPropertyValue('font-size'), '200px'); >+ assert_equals(computedStyle.getPropertyValue('--foo'), ''); >+ assert_equals(computedStyle.getPropertyValue('--bar'), ''); >+ assert_equals(computedStyle.getPropertyValue('font-size'), '30px'); > assert_equals(computedStyle.getPropertyValue('--baz'), '200px'); > }, "Setting the inline style is handled correctly when registered"); > >diff --git a/LayoutTests/css-custom-properties-api/inherits-expected.txt b/LayoutTests/css-custom-properties-api/inherits-expected.txt >index 09e206cbc008c65a6be2f1664bac70aae6066b15..5af1db3ab2a5b0669e4991f166e8faafb89a7c18 100644 >--- a/LayoutTests/css-custom-properties-api/inherits-expected.txt >+++ b/LayoutTests/css-custom-properties-api/inherits-expected.txt >@@ -1,62 +1,62 @@ > Specified in parent, inherits=true > >-100px green >+test > > Specified in parent, inherits=false > >-200px green >+test > > Specified in parent, not registered > >-100px green >+test > > Initial > >-200px green >+test > > Unset, inherits=true > >-100px green >+test > > Unset, inherits=false > >-200px green >+test > > A cycle between an inherits=true and inherits=false property > >-200px green >+test > > A cycle between an inherits=true and inherits=false property > >-200px green >+test > > A cycle between an inherits=true and inherits=false property with fallback > >-200px green >+test > > Inheritance should not create a cycle > >-110px green >+test > > A cycle between two unregistered properties > >-300px green >+test > > Revert, inherits=true > >-190px purple >+test > > Revert, inherits=false > >-200px purple >+test > > Revert, unregistered > >-purple >+test > > Inherit, unregistered > >-purple >+test > > Test that inherited properties do variable substitution before being inherited - registered > >@@ -68,15 +68,15 @@ test > > No initial value in registered property should act like unregistered > >-200px green >+test > > (unregistered) > >-500px green >+test > > Inherit should be substituted for unregistered property > >-500px green >+test > > > PASS Registration is successful >diff --git a/LayoutTests/css-custom-properties-api/inherits.html b/LayoutTests/css-custom-properties-api/inherits.html >index 8ee4fcf28801f3ed9c996761a7df3e7e4ec303dc..7fa53d50329d75a6c3ce509a92b1e5b669b98413 100644 >--- a/LayoutTests/css-custom-properties-api/inherits.html >+++ b/LayoutTests/css-custom-properties-api/inherits.html >@@ -244,36 +244,36 @@ > </style> > <div> > <p> Specified in parent, inherits=true</p> >- <div id="parent1"><div id="child1"><p>100px green</p></div> </div> >+ <div id="parent1"><div id="child1"><p>test</p></div> </div> > <p> Specified in parent, inherits=false </p> >- <div id="parent2"><div id="child2"><p>200px green</p></div> </div> >+ <div id="parent2"><div id="child2"><p>test</p></div> </div> > <p> Specified in parent, not registered </p> >- <div id="parent3"><div id="child3"><p>100px green</p></div> </div> >+ <div id="parent3"><div id="child3"><p>test</p></div> </div> > <p> Initial </p> >- <div id="parent4"><div id="child4"><p>200px green</p></div> </div> >+ <div id="parent4"><div id="child4"><p>test</p></div> </div> > <p> Unset, inherits=true </p> >- <div id="parent5"><div id="child5"><p>100px green</p></div> </div> >+ <div id="parent5"><div id="child5"><p>test</p></div> </div> > <p> Unset, inherits=false </p> >- <div id="parent6"><div id="child6"><p>200px green</p></div> </div> >+ <div id="parent6"><div id="child6"><p>test</p></div> </div> > <p> A cycle between an inherits=true and inherits=false property </p> >- <div id="parent7"><div id="child7"><p>200px green</p></div> </div> >+ <div id="parent7"><div id="child7"><p>test</p></div> </div> > <p> A cycle between an inherits=true and inherits=false property </p> >- <div id="parent8"><div id="child8"><p>200px green</p></div> </div> >+ <div id="parent8"><div id="child8"><p>test</p></div> </div> > <p> A cycle between an inherits=true and inherits=false property with fallback </p> >- <div id="parent9"><div id="child9"><p>200px green</p></div> </div> >+ <div id="parent9"><div id="child9"><p>test</p></div> </div> > <p> Inheritance should not create a cycle </p> >- <div id="parent10"><div id="child10"><p>110px green</p></div></div> >+ <div id="parent10"><div id="child10"><p>test</p></div></div> > <p> A cycle between two unregistered properties </p> >- <div id="parent11"><div id="child11"><p>300px green</p></div> </div> >+ <div id="parent11"><div id="child11"><p>test</p></div> </div> > > <p> Revert, inherits=true </p> >- <div id="parent12"><div id="child12"><div id="childchild12"><p>190px purple</p></div></div></div> >+ <div id="parent12"><div id="child12"><div id="childchild12"><p>test</p></div></div></div> > <p> Revert, inherits=false </p> >- <div id="parent13"><div id="child13"><div id="childchild13"><p>200px purple</p></div></div> </div> >+ <div id="parent13"><div id="child13"><div id="childchild13"><p>test</p></div></div> </div> > <p> Revert, unregistered </p> >- <div id="parent14"><div id="child14"><div id="childchild14"><p>purple</p></div></div> </div> >+ <div id="parent14"><div id="child14"><div id="childchild14"><p>test</p></div></div> </div> > <p> Inherit, unregistered </p> >- <div id="parent14-1"><div id="child14-1"><div id="childchild14-1"><p>purple</p></div></div> </div> >+ <div id="parent14-1"><div id="child14-1"><div id="childchild14-1"><p>test</p></div></div> </div> > > <p> Test that inherited properties do variable substitution before being inherited - registered</p> > <div id="parent15"><div id="child15"><p>test</p></div> </div> >@@ -281,12 +281,12 @@ > <div id="parent16"><div id="child16"><p>test</p></div> </div> > > <p> No initial value in registered property should act like unregistered</p> >- <div id="parent17"><div id="child17"><p>200px green</p></div> </div> >+ <div id="parent17"><div id="child17"><p>test</p></div> </div> > <p> (unregistered) </p> >- <div id="parent18"><div id="child18"><p>500px green</p></div> </div> >+ <div id="parent18"><div id="child18"><p>test</p></div> </div> > > <p>Inherit should be substituted for unregistered property</p> >- <div id="parent19"><div id="child19"><p>500px green</p></div> </div> >+ <div id="parent19"><div id="child19"><p>test</p></div> </div> > </div> > <script> > >@@ -346,19 +346,19 @@ test(function() { > test_prop('child6', '--my-custom-prop2', '200px'); > }, "JS Attributes are valid for element 6"); > test(function() { >- test_prop('child7', 'width', '200px'); >- test_prop('child7', '--my-custom-prop', '100px'); >- test_prop('child7', '--my-custom-prop2', '200px'); >+ test_prop('child7', 'width', '300px'); >+ test_prop('child7', '--my-custom-prop', ''); >+ test_prop('child7', '--my-custom-prop2', ''); > }, "JS Attributes are valid for element 7"); > test(function() { >- test_prop('child8', 'width', '200px'); >- test_prop('child8', '--my-custom-prop', '200px'); >- test_prop('child8', '--my-custom-prop2', '200px'); >+ test_prop('child8', 'width', '300px'); >+ test_prop('child8', '--my-custom-prop', ''); >+ test_prop('child8', '--my-custom-prop2', ''); > }, "JS Attributes are valid for element 8"); > test(function() { >- test_prop('child9', 'width', '200px'); >- test_prop('child9', '--my-custom-prop', '100px'); >- test_prop('child9', '--my-custom-prop2', '200px'); >+ test_prop('child9', 'width', '300px'); >+ test_prop('child9', '--my-custom-prop', ''); >+ test_prop('child9', '--my-custom-prop2', ''); > }, "JS Attributes are valid for element 9"); > test(function() { > test_prop('child10', 'width', '110px'); >diff --git a/LayoutTests/css-custom-properties-api/registerProperty-expected.txt b/LayoutTests/css-custom-properties-api/registerProperty-expected.txt >index b3082e11799745da1de127845647493af0b6d1a1..44d215ae873a8921fbbe5f446b5e8e20d73c32fb 100644 >--- a/LayoutTests/css-custom-properties-api/registerProperty-expected.txt >+++ b/LayoutTests/css-custom-properties-api/registerProperty-expected.txt >@@ -3,4 +3,5 @@ PASS registerProperty requires a Dictionary type > PASS registerProperty requires a name matching <custom-property-name> > PASS registerProperty always allows omitting initialValue and syntax, requires name and inherits > PASS registerProperty requires inherits and name >+PASS registerProperty requires initialValue to be computationally independent > >diff --git a/LayoutTests/css-custom-properties-api/registerProperty.html b/LayoutTests/css-custom-properties-api/registerProperty.html >index 1f576664de863f45034b92f4084a3722134ebe94..3dbcb0ccac572d22eb2834ab819eb7cc94f9579d 100644 >--- a/LayoutTests/css-custom-properties-api/registerProperty.html >+++ b/LayoutTests/css-custom-properties-api/registerProperty.html >@@ -2,6 +2,7 @@ > <!-- https://chromium.googlesource.com/chromium/src/+/01ce431409e3a019858677626a983c55168da6dc/third_party/WebKit/LayoutTests/custom-properties/register-property.html --> > <script src="../resources/testharness.js"></script> > <script src="../resources/testharnessreport.js"></script> >+<div id="el"></div> > <script> > // Tests for error checking during property registration > test(function() { >@@ -18,9 +19,9 @@ test(function() { > CSS.registerProperty({name: '--name2, no need for escapes', inherits: false}); > CSS.registerProperty({name: ['--name', 3], inherits: false}); > // Invalid property names >- //assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash', inherits: false})); >- //assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '', inherits: false})); >- //assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name', inherits: false})); >+ assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash', inherits: false})); >+ assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '', inherits: false})); >+ assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name', inherits: false})); > }, "registerProperty requires a name matching <custom-property-name>"); > test(function() { > CSS.registerProperty({name: '--syntax-test-1', inherits: false, syntax: '*'}); >@@ -37,4 +38,15 @@ test(function() { > CSS.registerProperty({name: '--syntax-test-4', inherits: false, syntax: '*'}); > CSS.registerProperty({name: '--syntax-test-5', inherits: false, syntax: ' * '}); > }, "registerProperty requires inherits and name"); >+test(function() { >+ CSS.registerProperty({name: '--initialvalue-test-0', inherits: false, syntax: '<length>', initialValue: 'calc(10px + 10in)'}); >+ assert_equals(window.getComputedStyle(el).getPropertyValue('--initialvalue-test-0').toString(), '970px'); >+ >+ assert_throws(new SyntaxError(), >+ () => CSS.registerProperty({name: '--initialvalue-test-1', inherits: false, syntax: '<length>', initialValue: '10em'})); >+ assert_throws(new SyntaxError(), >+ () => CSS.registerProperty({name: '--initialvalue-test-2', inherits: false, syntax: '<length>', initialValue: 'calc(10px + 10em)'})); >+ assert_throws(new SyntaxError(), >+ () => CSS.registerProperty({name: '--initialvalue-test-3', inherits: false, syntax: '<length>', initialValue: 'calc(10px + 10%)'})); >+}, "registerProperty requires initialValue to be computationally independent"); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-expected.txt >index 567db3178541436c267b7d586b33b0e60b14d1ca..cf9c8d43ed0bacb23302411d77e14b6ebd6d4727 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-expected.txt >@@ -1,7 +1,8 @@ > > PASS registerProperty requires a Dictionary type >-FAIL registerProperty requires a name matching <custom-property-name> assert_throws: function "() => CSS.registerProperty({name: 'no-leading-dash', inherits: false})" did not throw >+PASS registerProperty requires a name matching <custom-property-name> > FAIL registerProperty only allows omitting initialValue if syntax is '*' assert_throws: function "() => CSS.registerProperty({name: '--syntax-test-3', syntax: 'length', inherits: false})" did not throw >-PASS registerProperty fails for an already registered property >+FAIL registerProperty fails for an already registered property assert_throws: function "() => CSS.registerProperty({name: '--re-register', syntax: '<percentage>', initialValue: '0%', inherits: false})" threw object "SyntaxError: The given initial value does not parse for the given syntax." ("SyntaxError") expected object "[object Object]" ("InvalidModificationError") > PASS registerProperty requires inherits >+FAIL Registering a property should not cause a transition The given initial value does not parse for the given syntax. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt >index 2ea78e29806068e5b3c3f6ec79f6bf9a8a6b18cd..376e48bfba2526c460cfad8f82ceffb8adc24319 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt >@@ -3,7 +3,7 @@ PASS syntax:'*', initialValue:'a' is valid > FAIL syntax:' * ', initialValue:'b' is valid The given initial value does not parse for the given syntax. > PASS syntax:'<length>', initialValue:'2px' is valid > FAIL syntax:' <number>', initialValue:'5' is valid The given initial value does not parse for the given syntax. >-PASS syntax:'<percentage> ', initialValue:'10%' is valid >+FAIL syntax:'<percentage> ', initialValue:'10%' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<color>+', initialValue:'red' is valid The given initial value does not parse for the given syntax. > FAIL syntax:' <length>+ | <percentage>', initialValue:'2px 8px' is valid The given initial value does not parse for the given syntax. > PASS syntax:'<length>|<percentage>|<length-percentage>', initialValue:'2px' is valid >@@ -21,14 +21,19 @@ PASS syntax:'<length>', initialValue:'calc(2px*4 + 10px)' is valid > PASS syntax:'<length>', initialValue:'7.1e-4cm' is valid > PASS syntax:'<length>', initialValue:'calc(7in - 12px)' is valid > FAIL syntax:'<length>+', initialValue:'2px 7px calc(8px)' is valid The given initial value does not parse for the given syntax. >+FAIL syntax:'<length>#', initialValue:'2px, 7px, calc(8px)' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<percentage>', initialValue:'-9.3e3%' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<length-percentage>', initialValue:'-54%' is valid The given initial value does not parse for the given syntax. > PASS syntax:'<length-percentage>', initialValue:'0' is valid >-PASS syntax:'<length-percentage>', initialValue:'calc(-11px + 10.4%)' is valid >+FAIL syntax:'<length-percentage>', initialValue:'calc(-11px + 10.4%)' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<number>', initialValue:'-109' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<number>', initialValue:'2.3e4' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<integer>', initialValue:'-109' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<integer>', initialValue:'19' is valid The given initial value does not parse for the given syntax. >+FAIL syntax:'<integer>', initialValue:'calc(1)' is valid The given initial value does not parse for the given syntax. >+FAIL syntax:'<integer>', initialValue:'calc(1 + 2)' is valid The given initial value does not parse for the given syntax. >+FAIL syntax:'<integer>', initialValue:'calc(3.1415)' is valid The given initial value does not parse for the given syntax. >+FAIL syntax:'<integer>', initialValue:'calc(3.1415 + 3.1415)' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<angle>', initialValue:'10deg' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<angle>', initialValue:'20.5rad' is valid The given initial value does not parse for the given syntax. > FAIL syntax:'<angle>', initialValue:'calc(50grad + 3.14159rad)' is valid The given initial value does not parse for the given syntax. >@@ -84,7 +89,7 @@ PASS syntax:'inherit', initialValue:'inherit' is invalid > PASS syntax:'unset', initialValue:'unset' is invalid > FAIL syntax:'<length>|initial', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw > FAIL syntax:'<length>|INHERIT', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >-FAIL syntax:'<percentage>|unsEt', initialValue:'2%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+PASS syntax:'<percentage>|unsEt', initialValue:'2%' is invalid > FAIL syntax:'*', initialValue:'initial' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw > FAIL syntax:'*', initialValue:'inherit' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw > FAIL syntax:'*', initialValue:'unset' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >@@ -103,24 +108,26 @@ FAIL syntax:'*', initialValue:'var(--foo)' is invalid assert_throws: function "( > PASS syntax:'banana', initialValue:'bAnAnA' is invalid > PASS syntax:'<length>', initialValue:'var(--moo)' is invalid > PASS syntax:'<length>', initialValue:'10' is invalid >-FAIL syntax:'<length>', initialValue:'10%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >-FAIL syntax:'<length>', initialValue:'calc(5px + 10%)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+PASS syntax:'<length>', initialValue:'10%' is invalid >+PASS syntax:'<length>', initialValue:'calc(5px + 10%)' is invalid > PASS syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is invalid >-FAIL syntax:'<length>', initialValue:'10em' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+PASS syntax:'<length>', initialValue:'10em' is invalid > FAIL syntax:'<length>', initialValue:'10vmin' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >-FAIL syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >-FAIL syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >-FAIL syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+PASS syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid >+PASS syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid >+PASS syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid > PASS syntax:'<length>+', initialValue:'10px calc(20px + 4rem)' is invalid >+FAIL syntax:'<length>+', initialValue:'' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+FAIL syntax:'<length>#', initialValue:'' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw > PASS syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid > PASS syntax:'<length>', initialValue:'10px;' is invalid >-FAIL syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+PASS syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid > FAIL syntax:'<percentage>', initialValue:'0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw > PASS syntax:'<integer>', initialValue:'1.0' is invalid > PASS syntax:'<integer>', initialValue:'1e0' is invalid > PASS syntax:'<number>|foo', initialValue:'foo var(--foo, bla)' is invalid > FAIL syntax:'<angle>', initialValue:'0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >-FAIL syntax:'<angle>', initialValue:'10%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw >+PASS syntax:'<angle>', initialValue:'10%' is invalid > FAIL syntax:'<time>', initialValue:'2px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw > PASS syntax:'<resolution>', initialValue:'10' is invalid > PASS syntax:'<transform-function>', initialValue:'scale()' is invalid >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html >index 15a4ab6040ee2438c07282a4de1e9bedb2c86712..4ce514f01c87917d2e5aac4d402176ba88daf5a0 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html >@@ -46,6 +46,7 @@ assert_valid("<length>", "calc(2px*4 + 10px)"); > assert_valid("<length>", "7.1e-4cm"); > assert_valid("<length>", "calc(7in - 12px)"); > assert_valid("<length>+", "2px 7px calc(8px)"); >+assert_valid("<length>#", "2px, 7px, calc(8px)"); > assert_valid("<percentage>", "-9.3e3%"); > assert_valid("<length-percentage>", "-54%"); > assert_valid("<length-percentage>", "0"); >@@ -55,6 +56,10 @@ assert_valid("<number>", "-109"); > assert_valid("<number>", "2.3e4"); > assert_valid("<integer>", "-109"); > assert_valid("<integer>", "19"); >+assert_valid("<integer>", "calc(1)"); >+assert_valid("<integer>", "calc(1 + 2)"); >+assert_valid("<integer>", "calc(3.1415)"); >+assert_valid("<integer>", "calc(3.1415 + 3.1415)"); > > assert_valid("<angle>", "10deg"); > assert_valid("<angle>", "20.5rad"); >@@ -147,6 +152,8 @@ assert_invalid("<length>", "calc(4px + 3em)"); > assert_invalid("<length>", "calc(4px + calc(8 * 2em))"); > assert_invalid("<length>+", "calc(2ex + 16px)"); > assert_invalid("<length>+", "10px calc(20px + 4rem)"); >+assert_invalid("<length>+", ""); >+assert_invalid("<length>#", ""); > assert_invalid("<percentage> | <length>+", "calc(100vh - 10px) 30px"); > assert_invalid("<length>", "10px;"); > assert_invalid("<length-percentage>", "calc(2px + 10% + 7ex)"); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property.html >index 62ad23622bd4ddc2e8d534ec72072f5e5fe9f334..5842b83b0a48715f12effa6212cc0cccbd890861 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property.html >@@ -2,6 +2,8 @@ > <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" /> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> >+<script src="./resources/utils.js"></script> >+<div id=target></div> > <script> > // Tests for error checking during property registration > >@@ -45,4 +47,29 @@ test(function(){ > CSS.registerProperty({name: '--inherit-test-2', syntax: '<length>', initialValue: '0px', inherits: false}); > assert_throws(new TypeError(), () => CSS.registerProperty({name: '--inherit-test-3', syntax: '<length>', initialValue: '0px'})); > }, "registerProperty requires inherits"); >+ >+test(function(){ >+ try { >+ let name = generate_name(); >+ >+ target.style.setProperty(name, 'green'); >+ target.style.transitionProperty = name; >+ target.style.transitionDuration = '1s'; >+ target.style.transitionTimingFunction = 'steps(1, end)'; >+ >+ assert_equals(getComputedStyle(target).getPropertyValue(name), 'green'); >+ >+ CSS.registerProperty({ >+ name: name, >+ syntax: '<color>', >+ initialValue: 'red', >+ inherits: false >+ }); >+ >+ assert_equals(getComputedStyle(target).getPropertyValue(name), 'rgb(0, 128, 0)'); >+ } finally { >+ target.style = ''; >+ } >+}, 'Registering a property should not cause a transition'); >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt >index 5654e82c6a82a4c2e29cb1f356041225d211e23a..d2234f08622ad71dca199b5e19f197681ebda389 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt >@@ -4,4 +4,6 @@ PASS Explicitly inheriting from a parent with an invalid value results in initia > PASS Explicitly inheriting from a parent with no value results in initial value. > PASS Reference to undefined variable results in inherited value > PASS Reference to syntax-incompatible variable results in inherited value >+PASS Font-relative units are absolutized before before inheritance >+PASS Calc expressions are resolved before inheritance > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html >index 8f9eafee19e5c2500811f05723902808a27760df..614a72a797bc91a76742efc990e07669bee87c11 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html >@@ -72,4 +72,18 @@ test(function(){ > assert_equals(getComputedStyle(inner).getPropertyValue('--inherited-length-5'), '42px'); > }, "Reference to syntax-incompatible variable results in inherited value"); > >+test(function(){ >+ CSS.registerProperty({name: '--inherited-em', syntax: '<length>', initialValue: '0px', inherits: true}); >+ outer.style = 'font-size: 11px; --inherited-em: 10em;'; >+ inner.style = 'font-size: 22px; --unregistered:var(--inherited-em);'; >+ assert_equals(getComputedStyle(inner).getPropertyValue('--unregistered'), '110px'); >+}, "Font-relative units are absolutized before before inheritance"); >+ >+test(function(){ >+ CSS.registerProperty({name: '--calc-length', syntax: '<length>', initialValue: '0px', inherits: true}); >+ outer.style = '--calc-length: calc(10px + 10px);'; >+ inner.style = '--unregistered:var(--calc-length);'; >+ assert_equals(getComputedStyle(inner).getPropertyValue('--unregistered'), '20px'); >+}, "Calc expressions are resolved before inheritance"); >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt >index 426e96e4f0a2c2c6f867bf30dfed895fab728788..1bf7eb6b9d7032b5fa8a69f58a5b5e5022e27204 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt >@@ -1,17 +1,57 @@ > >-FAIL CSS.registerProperty The given initial value does not parse for the given syntax. >-PASS <length> values are computed correctly for divWithFontSizeSet >-FAIL <length-percentage> values are computed correctly for divWithFontSizeSet assert_equals: expected "calc(190px + -2%)" but got "calc(190px - 2%)" >-FAIL <length># values are computed correctly for divWithFontSizeSet assert_equals: expected "10px, 30px" but got "0px" >-FAIL <length-percentage># values are computed correctly for divWithFontSizeSet assert_equals: expected "3%, 80px, 22px" but got "0px" >-FAIL <length>+ values are computed correctly for divWithFontSizeSet assert_equals: expected "10px 30px" but got "0px" >-FAIL <length-percentage>+ values are computed correctly for divWithFontSizeSet assert_equals: expected "3% 80px 22px" but got "0px" >-FAIL <transform-function> values are computed correctly for divWithFontSizeSet assert_equals: expected "translateX(2px)" but got " translateX(2px)" >-PASS <length> values are computed correctly for divWithFontSizeInherited >-FAIL <length-percentage> values are computed correctly for divWithFontSizeInherited assert_equals: expected "calc(190px + -2%)" but got "calc(190px - 2%)" >-FAIL <length># values are computed correctly for divWithFontSizeInherited assert_equals: expected "10px, 30px" but got "0px" >-FAIL <length-percentage># values are computed correctly for divWithFontSizeInherited assert_equals: expected "3%, 80px, 22px" but got "0px" >-FAIL <length>+ values are computed correctly for divWithFontSizeInherited assert_equals: expected "10px 30px" but got "0px" >-FAIL <length-percentage>+ values are computed correctly for divWithFontSizeInherited assert_equals: expected "3% 80px 22px" but got "0px" >-FAIL <transform-function> values are computed correctly for divWithFontSizeInherited assert_equals: expected "translateX(2px)" but got " translateX(2px)" >+PASS <length> values computed are correctly via var()-reference >+PASS <length> values computed are correctly via var()-reference when font-size is inherited >+PASS <length> values are computed correctly when font-size is inherited [14em] >+PASS <length> values are computed correctly when font-size is inherited [calc(14em + 10px)] >+PASS <length> values are computed correctly [12px] >+PASS <length> values are computed correctly [13vw] >+PASS <length> values are computed correctly [14em] >+PASS <length> values are computed correctly [15vmin] >+PASS <length> values are computed correctly [calc(16px - 7em + 10vh)] >+PASS <length-percentage> values are computed correctly [17em] >+FAIL <length-percentage> values are computed correctly [18%] assert_equals: expected "18%" but got "0px" >+FAIL <length-percentage> values are computed correctly [calc(19em - 2%)] assert_equals: expected "calc(-2% + 190px)" but got "0px" >+FAIL <length># values are computed correctly [10px, 3em] assert_equals: expected "10px, 30px" but got "0px" >+FAIL <length># values are computed correctly [4em ,9px] assert_equals: expected "40px, 9px" but got "0px" >+PASS <length># values are computed correctly [8em] >+FAIL <length-percentage># values are computed correctly [3% , 10vmax , 22px] assert_equals: expected "3%, 80px, 22px" but got "0px" >+FAIL <length-percentage># values are computed correctly [calc(50% + 1em), 4px] assert_equals: expected "calc(50% + 10px), 4px" but got "0px" >+FAIL <length-percentage># values are computed correctly [calc(13% + 37px)] assert_equals: expected "calc(13% + 37px)" but got "0px" >+FAIL <length>+ values are computed correctly [10px 3em] assert_equals: expected "10px 30px" but got "0px" >+FAIL <length>+ values are computed correctly [4em 9px] assert_equals: expected "40px 9px" but got "0px" >+FAIL <length-percentage>+ values are computed correctly [3% 10vmax 22px] assert_equals: expected "3% 80px 22px" but got "0px" >+FAIL <length-percentage>+ values are computed correctly [calc(50% + 1em) 4px] assert_equals: expected "calc(50% + 10px) 4px" but got "0px" >+FAIL <transform-function> values are computed correctly [translateX(2px)] The given initial value does not parse for the given syntax. >+FAIL <transform-function> values are computed correctly [translateX(10em)] The given initial value does not parse for the given syntax. >+FAIL <transform-function> values are computed correctly [translateX(calc(11em + 10%))] The given initial value does not parse for the given syntax. >+FAIL <transform-function>+ values are computed correctly [translateX(10%) scale(2)] The given initial value does not parse for the given syntax. >+FAIL <integer> values are computed correctly [15] assert_equals: expected "15" but got "0px" >+FAIL <integer> values are computed correctly [calc(15 + 15)] assert_equals: expected "30" but got "0px" >+FAIL <integer> values are computed correctly [calc(2.4)] assert_equals: expected "2" but got "0px" >+FAIL <integer> values are computed correctly [calc(2.6)] assert_equals: expected "3" but got "0px" >+FAIL <integer> values are computed correctly [calc(2.6 + 3.1)] assert_equals: expected "6" but got "0px" >+FAIL <integer>+ values are computed correctly [15 calc(2.4) calc(2.6)] assert_equals: expected "15 2 3" but got "0px" >+FAIL <color> values are computed correctly [#ff0000] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [#000f00] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [#00000a] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [#badbee] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [#badbee33] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [tomato] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [plum] The given initial value does not parse for the given syntax. >+FAIL <color> values are computed correctly [currentcolor] The given initial value does not parse for the given syntax. >+PASS * values are computed correctly [tomato] >+FAIL tomato | plum values are computed correctly [plum] The given initial value does not parse for the given syntax. >+FAIL tomato | plum | <color> values are computed correctly [plum] The given initial value does not parse for the given syntax. >+PASS * values are computed correctly [-50grad] >+FAIL <angle> values are computed correctly [180deg] The given initial value does not parse for the given syntax. >+FAIL <angle> values are computed correctly [400grad] The given initial value does not parse for the given syntax. >+FAIL <angle> values are computed correctly [calc(360deg + 400grad)] The given initial value does not parse for the given syntax. >+PASS * values are computed correctly [50s] >+FAIL <time> values are computed correctly [1s] The given initial value does not parse for the given syntax. >+FAIL <time> values are computed correctly [1000ms] The given initial value does not parse for the given syntax. >+FAIL <time> values are computed correctly [calc(1000ms + 1s)] The given initial value does not parse for the given syntax. >+PASS * values are computed correctly [50dpi] >+FAIL <resolution> values are computed correctly [1dppx] The given initial value does not parse for the given syntax. >+FAIL <resolution> values are computed correctly [96dpi] The given initial value does not parse for the given syntax. >+FAIL <resolution> values are computed correctly [calc(1dppx + 96dpi)] The given initial value does not parse for the given syntax. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation.html >index 30d6b4bd609bf01f1bb10a485baa787f22b635dc..b1e5d23738b9dda1ea280dfd321bc5b2838b519a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation.html >@@ -1,117 +1,164 @@ >-<!DOCTYPE HTML> >+<!DOCTYPE html> > <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" /> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> >+<script src="./resources/utils.js"></script> > > <style> > #divWithFontSizeSet, #parentDiv { > font-size: 10px; > } >-#divWithFontSizeSet, #divWithFontSizeInherited { >- --length-1: 12px; >- --length-2: 13vw; >- --length-3: 14em; >- --length-4: 15vmin; >- --length-5: calc(16px - 7em + 10vh); >- --length-6: var(--length-3); >- --length-percentage-1: 17em; >- --length-percentage-2: 18%; >- --length-percentage-3: calc(19em - 2%); >- --csv-1: 10px, 3em; >- --csv-2: 4em ,9px; >- --csv-3: 8em; >- --csv-4: 3% , 10vmax , 22px; >- --csv-5: calc(50% + 1em), 4px; >- --csv-6: calc(13% + 37px); >- --list-1: 10px 3em; >- --list-2: 4em 9px; >- --list-3: 3% 10vmax 22px; >- --list-4: calc(50% + 1em) 4px; >- --transform-function-1: translateX(2px); >- --transform-function-2: translateX(10em); >- --transform-function-3: translateX(calc(11em + 10%)); >- --transform-function-4: translateX(10%) scale(2); >-} > </style> > > <div id=divWithFontSizeSet></div> > <div id=parentDiv> > <div id=divWithFontSizeInherited></div> > </div> >+<div id="ref"></div> > > <script> >-test(() => { >- CSS.registerProperty({name: '--length-1', syntax: '<length>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-2', syntax: '<length>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-3', syntax: '<length>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-4', syntax: '<length>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-5', syntax: '<length>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-6', syntax: '<length>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--csv-1', syntax: '<length>#', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--csv-2', syntax: '<length>#', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--csv-3', syntax: '<length>#', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--csv-4', syntax: '<length-percentage>#', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--csv-5', syntax: '<length-percentage>#', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--csv-6', syntax: '<length-percentage>#', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--list-4', syntax: '<length-percentage>+', initialValue: '0px', inherits: false}); >- CSS.registerProperty({name: '--transform-function-1', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false}); >- CSS.registerProperty({name: '--transform-function-2', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false}); >- CSS.registerProperty({name: '--transform-function-3', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false}); >- CSS.registerProperty({name: '--transform-function-4', syntax: '<transform-function>+', initialValue: 'translateX(0px)', inherits: false}); >-}, "CSS.registerProperty"); >- >-for (var element of [divWithFontSizeSet, divWithFontSizeInherited]) { >- var id = element.id; >- var computedStyle = getComputedStyle(element); > >- test(function() { >- assert_equals(computedStyle.getPropertyValue('--length-1'), '12px'); >- assert_equals(computedStyle.getPropertyValue('--length-2'), '104px'); >- assert_equals(computedStyle.getPropertyValue('--length-3'), '140px'); >- assert_equals(computedStyle.getPropertyValue('--length-4'), '90px'); >- assert_equals(computedStyle.getPropertyValue('--length-5'), '6px'); >- assert_equals(computedStyle.getPropertyValue('--length-6'), '140px'); >- }, "<length> values are computed correctly for " + id); >+// Generate a property and temporarily set its value. Then call 'fn' with >+// the name of the generated property. >+function with_custom_property(element, reg, value, fn) { >+ if (element.id.length == 0) >+ throw 'The specified element must have an ID'; > >- test(function() { >- assert_equals(computedStyle.getPropertyValue('--length-percentage-1'), '170px'); >- assert_equals(computedStyle.getPropertyValue('--length-percentage-2'), '18%'); >- assert_equals(computedStyle.getPropertyValue('--length-percentage-3'), 'calc(190px + -2%)'); >- }, "<length-percentage> values are computed correctly for " + id); >+ let name = generate_property(reg); > >- test(function() { >- assert_equals(computedStyle.getPropertyValue('--csv-1'), '10px, 30px'); >- assert_equals(computedStyle.getPropertyValue('--csv-2'), '40px, 9px'); >- assert_equals(computedStyle.getPropertyValue('--csv-3'), '80px'); >- }, "<length># values are computed correctly for " + id); >+ // Because we want to include the parsing step, insert a stylesheet >+ // node with textContent. >+ let node = document.createElement('style'); >+ node.textContent = `#${element.id} { ${name}:${value}; }`; >+ document.body.append(node); > >- test(function() { >- assert_equals(computedStyle.getPropertyValue('--csv-4'), '3%, 80px, 22px'); >- assert_equals(computedStyle.getPropertyValue('--csv-5'), 'calc(10px + 50%), 4px'); >- assert_equals(computedStyle.getPropertyValue('--csv-6'), 'calc(37px + 13%)'); >- }, "<length-percentage># values are computed correctly for " + id); >+ try { >+ fn(name); >+ } finally { >+ node.remove(); >+ } >+} > >- test(function() { >- assert_equals(computedStyle.getPropertyValue('--list-1'), '10px 30px'); >- assert_equals(computedStyle.getPropertyValue('--list-2'), '40px 9px'); >- }, "<length>+ values are computed correctly for " + id); >+function assert_computed_value(element, syntax, value, expected) { >+ with_custom_property(element, syntax, value, (name) => { >+ let actual = getComputedStyle(element).getPropertyValue(name); >+ assert_equals(actual, expected); >+ }); >+} > >- test(function() { >- assert_equals(computedStyle.getPropertyValue('--list-3'), '3% 80px 22px'); >- assert_equals(computedStyle.getPropertyValue('--list-4'), 'calc(10px + 50%) 4px'); >- }, "<length-percentage>+ values are computed correctly for " + id); >+// Computes an absolute reference value for some length. >+// >+// E.g. to figure out how many pixels '10vh' is, do length_ref('10vh'). >+function length_ref(value, refnode = ref) { >+ try { >+ // The reference property 'min-height' is chosen arbitrarily, but >+ // avoid properties with "resolved value is used value"-behavior >+ // [1], as it may affect rounding, and custom properties do not >+ // have this behavior. >+ // >+ // [1] https://drafts.csswg.org/cssom/#resolved-values >+ const ref_property = 'min-height'; >+ refnode.style = `${ref_property}: ${value}`; >+ return getComputedStyle(refnode).getPropertyValue(ref_property); >+ } finally { >+ refnode.style = ''; >+ } >+} > >+function test_computed_value(syntax, value, expected) { > test(function() { >- assert_equals(computedStyle.getPropertyValue('--transform-function-1'), 'translateX(2px)'); >- assert_equals(computedStyle.getPropertyValue('--transform-function-2'), 'translateX(100px)'); >- assert_equals(computedStyle.getPropertyValue('--transform-function-3'), 'translateX(calc(110px + 10%))'); >- assert_equals(computedStyle.getPropertyValue('--transform-function-4'), 'translateX(10%) scale(2)'); >- }, "<transform-function> values are computed correctly for " + id); >+ assert_computed_value(divWithFontSizeSet, syntax, value, expected); >+ }, `${syntax} values are computed correctly [${value}]`); > } >+ >+test(function(){ >+ const element = divWithFontSizeSet; >+ with_custom_property(element, '<length>', '14em', (name) => { >+ assert_computed_value(element, '<length>', `var(${name})`, '140px'); >+ }); >+}, '<length> values computed are correctly via var()-reference'); >+ >+test(function(){ >+ const element = divWithFontSizeInherited; >+ with_custom_property(element, '<length>', '14em', (name) => { >+ assert_computed_value(element, '<length>', `var(${name})`, '140px'); >+ }); >+}, '<length> values computed are correctly via var()-reference when font-size is inherited'); >+ >+test(function(){ >+ const element = divWithFontSizeInherited; >+ assert_computed_value(element, '<length>', '14em', '140px'); >+}, '<length> values are computed correctly when font-size is inherited [14em]'); >+ >+test(function(){ >+ const element = divWithFontSizeInherited; >+ assert_computed_value(element, '<length>', 'calc(14em + 10px)', '150px'); >+}, '<length> values are computed correctly when font-size is inherited [calc(14em + 10px)]'); >+ >+test_computed_value('<length>', '12px', '12px'); >+test_computed_value('<length>', '13vw', length_ref('13vw')); >+test_computed_value('<length>', '14em', '140px'); >+test_computed_value('<length>', '15vmin', length_ref('15vmin')); >+test_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)')); >+ >+test_computed_value('<length-percentage>', '17em', '170px'); >+test_computed_value('<length-percentage>', '18%', '18%'); >+test_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(-2% + 190px)'); >+ >+test_computed_value('<length>#', '10px, 3em', '10px, 30px'); >+test_computed_value('<length>#', '4em ,9px', '40px, 9px'); >+test_computed_value('<length>#', '8em', '80px'); >+ >+test_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', ')); >+test_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(50% + 10px), 4px'); >+test_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(13% + 37px)'); >+ >+test_computed_value('<length>+', '10px 3em', '10px 30px'); >+test_computed_value('<length>+', '4em 9px', '40px 9px'); >+ >+test_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' ')); >+test_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(50% + 10px) 4px'); >+ >+test_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)'); >+test_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)'); >+test_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(10% + 110px))'); >+test_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); >+ >+test_computed_value('<integer>', '15', '15'); >+test_computed_value('<integer>', 'calc(15 + 15)', '30'); >+test_computed_value('<integer>', 'calc(2.4)', '2'); >+test_computed_value('<integer>', 'calc(2.6)', '3'); >+test_computed_value('<integer>', 'calc(2.6 + 3.1)', '6'); >+ >+test_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3'); >+ >+test_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)'); >+test_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)'); >+test_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)'); >+test_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)'); >+test_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)'); >+test_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)'); >+test_computed_value('<color>', 'plum', 'rgb(221, 160, 221)'); >+test_computed_value('<color>', 'currentcolor', 'currentcolor'); >+ >+// Custom ident values that look like color keywords should not be converted. >+test_computed_value('*', 'tomato', 'tomato'); >+test_computed_value('tomato | plum', 'plum', 'plum'); >+test_computed_value('tomato | plum | <color>', 'plum', 'plum'); >+ >+test_computed_value('*', '-50grad', '-50grad'); >+test_computed_value('<angle>', '180deg', '180deg'); >+test_computed_value('<angle>', '400grad', '360deg'); >+test_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg'); >+ >+test_computed_value('*', '50s', '50s'); >+test_computed_value('<time>', '1s', '1s'); >+test_computed_value('<time>', '1000ms', '1s'); >+test_computed_value('<time>', 'calc(1000ms + 1s)', '2s'); >+ >+test_computed_value('*', '50dpi', '50dpi'); >+test_computed_value('<resolution>', '1dppx', '1dppx'); >+test_computed_value('<resolution>', '96dpi', '1dppx'); >+test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx'); >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt >index efcc5c2ecf8ef5a8e42f82dfc63e4fb182a479ef..1dfea79503f519656f8091019114354a1f03eb7c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt >@@ -1,9 +1,9 @@ > > PASS CSSOM setters function as expected for unregistered properties > FAIL CSS.registerProperty The given initial value does not parse for the given syntax. >-FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "blue" but got "hello" >+FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "rgb(0, 0, 255)" but got "hello" > FAIL Values not matching the registered type can't be set assert_equals: expected "hello" but got "20" >-FAIL Values can be removed from inline styles assert_equals: expected "red" but got " red" >+FAIL Values can be removed from inline styles assert_equals: expected "rgb(255, 0, 0)" but got " red" > PASS Stylesheets can be modified by CSSOM >-FAIL Valid values can be set on inline styles assert_equals: expected "blue" but got " blue" >+FAIL Valid values can be set on inline styles assert_equals: expected "rgb(255, 192, 203)" but got "pink" > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html >index 019778e95e03689aaab5e47a0fd6be2382f3fb99..59443b3323a89f64e2ae5b07508819b2872ead12 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html >@@ -46,7 +46,7 @@ test(function() { > assert_equals(inlineStyle.getPropertyValue('--length'), '5'); > assert_equals(inlineStyle.getPropertyValue('--color'), 'hello'); > assert_equals(computedStyle.getPropertyValue('--length'), '0px'); >- assert_equals(computedStyle.getPropertyValue('--color'), 'blue'); >+ assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(0, 0, 255)'); > }, "Formerly valid values are still readable from inline styles but are computed as the unset value"); > > test(function() { >@@ -62,7 +62,7 @@ test(function() { > assert_equals(inlineStyle.getPropertyValue('--length'), ''); > assert_equals(inlineStyle.getPropertyValue('--color'), ''); > assert_equals(computedStyle.getPropertyValue('--length'), '10px'); >- assert_equals(computedStyle.getPropertyValue('--color'), 'red'); >+ assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(255, 0, 0)'); > }, "Values can be removed from inline styles"); > > test(function() { >@@ -80,9 +80,9 @@ test(function() { > assert_equals(inlineStyle.getPropertyValue('--length'), '30px'); > assert_equals(inlineStyle.getPropertyValue('--color'), 'pink'); > assert_equals(computedStyle.getPropertyValue('--length'), '30px'); >- assert_equals(computedStyle.getPropertyValue('--color'), 'pink'); >+ assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(255, 192, 203)'); > inlineStyle.setProperty('--color', 'inherit'); > assert_equals(inlineStyle.getPropertyValue('--color'), 'inherit'); >- assert_equals(computedStyle.getPropertyValue('--color'), 'blue'); >+ assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(0, 0, 255)'); > }, "Valid values can be set on inline styles"); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt >index 86c5a11e020495f3be43ca87c08cf7d42b198f97..a3b762a851f35bdc69f7e46c9e66dc5047e4e79c 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt >@@ -1,3 +1,11 @@ > >-FAIL Initial values of registered properties can be referenced when no custom properties are explicitly set. The given initial value does not parse for the given syntax. >+PASS Initial value for <length> correctly computed [calc(10px + 15px)] >+FAIL Initial value for <length-percentage> correctly computed [calc(1in + 10% + 4px)] The given initial value does not parse for the given syntax. >+FAIL Initial value for <color> correctly computed [pink, inherits] The given initial value does not parse for the given syntax. >+FAIL Initial value for <color> correctly computed [purple] The given initial value does not parse for the given syntax. >+FAIL Initial value for <transform-function> correctly computed [rotate(42deg)] The given initial value does not parse for the given syntax. >+FAIL Initial value for <transform-list> correctly computed [scale(calc(2 + 2))] The given initial value does not parse for the given syntax. >+FAIL Initial value for <transform-list> correctly computed [scale(calc(2 + 1)) translateX(calc(3px + 1px))] The given initial value does not parse for the given syntax. >+FAIL Initial inherited value can be substituted [purple, color] The given initial value does not parse for the given syntax. >+FAIL Initial non-inherited value can be substituted [pink, background-color] The given initial value does not parse for the given syntax. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html >index d655af661f7fd95ed0289cddb9c5546467d28592..82a012e2f68532761b18428c3eaed9479ec8c7e5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html >@@ -1,35 +1,45 @@ >-<!DOCTYPE HTML> >+<!DOCTYPE html> > <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-propertydescriptor-initialvalue" /> > <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" /> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> >-<style> >-#target { >- background: var(--inherited-color); >- color: var(--non-inherited-color); >-} >-</style> >+<script src="./resources/utils.js"></script> > <div id=target></div> > <script> >-test(function() { >- CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: 'calc(10px + 15px)', inherits: false}); >- CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)', inherits: false}); >- CSS.registerProperty({name: '--inherited-color', syntax: '<color>', initialValue: 'pink', inherits: true}); >- CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple', inherits: false}); >- CSS.registerProperty({name: '--transform-function', syntax: '<transform-function>', initialValue: 'rotate(42deg)', inherits: false}); >- CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))', inherits: false}); >- CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))', inherits: false}); > >- computedStyle = getComputedStyle(target); >- assert_equals(computedStyle.getPropertyValue('--length'), '25px'); >- assert_equals(computedStyle.getPropertyValue('--length-percentage'), 'calc(100px + 10%)'); >- assert_equals(computedStyle.getPropertyValue('--inherited-color'), 'pink'); >- assert_equals(computedStyle.getPropertyValue('--non-inherited-color'), 'purple'); >- assert_equals(computedStyle.getPropertyValue('--transform-function'), 'rotate(42deg)'); >- assert_equals(computedStyle.getPropertyValue('--single-transform-list'), 'scale(4)'); >- assert_equals(computedStyle.getPropertyValue('--multiple-transform-list'), 'scale(3) translateX(4px)'); >+function test_initial_value(reg, expected) { >+ let suffix = reg.inherits === true ? ', inherits' : ''; >+ test(function(){ >+ let name = generate_property(reg); >+ let actual = getComputedStyle(target).getPropertyValue(name); >+ assert_equals(actual, expected); >+ }, `Initial value for ${reg.syntax} correctly computed [${reg.initialValue}${suffix}]`); >+} >+ >+test_initial_value({ syntax: '<length>', initialValue: 'calc(10px + 15px)' }, '25px'); >+test_initial_value({ syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)' }, 'calc(10% + 100px)'); >+test_initial_value({ syntax: '<color>', initialValue: 'pink', inherits: true }, 'rgb(255, 192, 203)'); >+test_initial_value({ syntax: '<color>', initialValue: 'purple' }, 'rgb(128, 0, 128)'); >+test_initial_value({ syntax: '<transform-function>', initialValue: 'rotate(42deg)' }, 'rotate(42deg)'); >+test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))' }, 'scale(4)'); >+test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))' }, 'scale(3) translateX(4px)'); >+ >+// Test that the initial value of the custom property 'reg' is successfully >+// substituted into 'property'. >+function test_substituted_value(reg, property, expected) { >+ let inherits_text = reg.inherits === true ? 'inherited' : 'non-inherited'; >+ test(function(){ >+ try { >+ let name = generate_property(reg); >+ target.style = `${property}:var(${name});`; >+ assert_equals(getComputedStyle(target).getPropertyValue(property), expected); >+ } finally { >+ target.style = ''; >+ } >+ }, `Initial ${inherits_text} value can be substituted [${reg.initialValue}, ${property}]`); >+} >+ >+test_substituted_value({ syntax: '<color>', initialValue: 'purple', inherits: true }, 'color', 'rgb(128, 0, 128)'); >+test_substituted_value({ syntax: '<color>', initialValue: 'pink' }, 'background-color', 'rgb(255, 192, 203)'); > >- assert_equals(computedStyle.backgroundColor, 'rgb(255, 192, 203)'); >- assert_equals(computedStyle.color, 'rgb(128, 0, 128)'); >-}, "Initial values of registered properties can be referenced when no custom properties are explicitly set."); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/utils.js b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/utils.js >new file mode 100644 >index 0000000000000000000000000000000000000000..bef59560f68d84ed0d681bb22e0611ea2466024f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/utils.js >@@ -0,0 +1,94 @@ >+let next_property_id = 1; >+ >+// Generate a unique property name on the form --prop-N. >+function generate_name() { >+ return `--prop-${next_property_id++}`; >+} >+ >+// Produce a compatible initial value for the specified syntax. >+function any_initial_value(syntax) { >+ let components = syntax.split('|').map(x => x.trim()) >+ let first_component = components[0]; >+ >+ if (first_component.endsWith('+') || first_component.endsWith('#')) >+ first_component = first_component.slice(0, -1); >+ >+ switch (first_component) { >+ case '*': >+ case '<custom-ident>': >+ return 'NULL'; >+ case '<angle>': >+ return '0deg'; >+ case '<color>': >+ return 'rgb(0, 0, 0)'; >+ case '<image>': >+ case '<url>': >+ return 'url(0)'; >+ case '<integer>': >+ case '<length-percentage>': >+ case '<length>': >+ case '<number>': >+ return '0'; >+ case '<percentage>': >+ return '0%'; >+ case '<resolution>': >+ return '0dpi'; >+ case '<time>': >+ return '0s'; >+ case '<transform-function>': >+ case '<transform-list>': >+ return 'matrix(0, 0, 0, 0, 0, 0)'; >+ default: >+ // We assume syntax is a specific custom ident. >+ return first_component; >+ } >+} >+ >+// Registers a unique property on the form '--prop-N' and returns the name. >+// Any value except 'syntax' may be omitted, in which case the property will >+// not inherit, and some undefined (but compatible) initial value will be >+// generated. If a single string is used as the argument, it is assumed to be >+// the syntax. >+function generate_property(reg) { >+ // Verify that only valid keys are specified. This prevents the caller from >+ // accidentally supplying 'inherited' instead of 'inherits', for example. >+ if (typeof(reg) === 'object') { >+ const permitted = new Set(['name', 'syntax', 'initialValue', 'inherits']); >+ if (!Object.keys(reg).every(k => permitted.has(k))) >+ throw new Error('generate_property: invalid parameter'); >+ } >+ >+ let syntax = typeof(reg) === 'string' ? reg : reg.syntax; >+ let initial = typeof(reg.initialValue) === 'undefined' ? any_initial_value(syntax) >+ : reg.initialValue; >+ let inherits = typeof(reg.inherits) === 'undefined' ? false : reg.inherits; >+ >+ let name = generate_name(); >+ CSS.registerProperty({ >+ name: name, >+ syntax: syntax, >+ initialValue: initial, >+ inherits: inherits >+ }); >+ return name; >+} >+ >+function all_syntaxes() { >+ return [ >+ '*', >+ '<angle>', >+ '<color>', >+ '<custom-ident>', >+ '<image>', >+ '<integer>', >+ '<length-percentage>', >+ '<length>', >+ '<number>', >+ '<percentage>', >+ '<resolution>', >+ '<time>', >+ '<transform-function>', >+ '<transform-list>', >+ '<url>' >+ ] >+} >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..e3e85587bc95100f5ffaf561ec6c6ad3819be0ff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/w3c-import.log >@@ -0,0 +1,17 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/web-platform-tests/wpt >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/resources/utils.js >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d3cec37ef6d0c478d932c5a957806223d9bb6941 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils-expected.txt >@@ -0,0 +1,5 @@ >+ >+FAIL Default initial values of generated properties are valid (self-test). The given initial value does not parse for the given syntax. >+PASS Generated properties respect inherits flag >+PASS Can't generate property with unknown fields >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils.html >new file mode 100644 >index 0000000000000000000000000000000000000000..05aa4b2fb03b29feee47177624715230768a44a0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils.html >@@ -0,0 +1,41 @@ >+<!DOCTYPE html> >+<title>Self-test for utils.js</title> >+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/"> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/utils.js"></script> >+<div id=outer><div id=inner></div></div> >+<script> >+ >+test(function(){ >+ let syntaxes = all_syntaxes().concat([ >+ 'foo', >+ 'bar | <length>', >+ '<angle> | <length>' >+ ]); >+ // Don't throw: >+ syntaxes.forEach(generate_property); >+}, 'Default initial values of generated properties are valid (self-test).'); >+ >+test(function(){ >+ try { >+ let inherited = generate_property({ syntax: '<length>', inherits: true }); >+ let non_inherited = generate_property({ syntax: '<length>', inherits: false, initialValue: '5px' }); >+ outer.style = `${inherited}: 10px; ${non_inherited}: 11px;`; >+ assert_equals(getComputedStyle(outer).getPropertyValue(inherited), '10px'); >+ assert_equals(getComputedStyle(outer).getPropertyValue(non_inherited), '11px'); >+ assert_equals(getComputedStyle(inner).getPropertyValue(inherited), '10px'); >+ assert_equals(getComputedStyle(inner).getPropertyValue(non_inherited), '5px'); >+ } finally { >+ outer.style = ''; >+ inner.style = ''; >+ } >+}, 'Generated properties respect inherits flag'); >+ >+test(function(){ >+ assert_throws(new Error(), () => generate_property({syntax: '<length>', foo: 1})); >+ assert_throws(new Error(), () => generate_property({syntax: '<length>', inherited: false})); >+ assert_throws(new Error(), () => generate_property({syntax: '<length>', initial: '10px'})); >+}, 'Can\'t generate property with unknown fields'); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt >index 1366c0adb361b1c0c042b449653499b0d276acda..aaf90a4a053429b81ce1dd3ae960852f57f2a919 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt >@@ -1,69 +1,6 @@ >-CONSOLE MESSAGE: line 349: TypeError: CSS.px is not a function. (In 'CSS.px(15)', 'CSS.px' is undefined) >+CONSOLE MESSAGE: line 38: TypeError: undefined is not an object (evaluating 'target.attributeStyleMap.clear') > >-Harness Error (FAIL), message = TypeError: CSS.px is not a function. (In 'CSS.px(15)', 'CSS.px' is undefined) >+Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'target.attributeStyleMap.clear') > > FAIL Computed * is reified as CSSUnparsedValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined) >-FAIL Computed <angle> is reified as CSSUnitValue The given initial value does not parse for the given syntax. >-FAIL Computed <color> is reified as CSSStyleValue The given initial value does not parse for the given syntax. >-FAIL Computed <custom-ident> is reified as CSSKeywordValue The given initial value does not parse for the given syntax. >-FAIL Computed <image> [url] is reified as CSSImageValue The given initial value does not parse for the given syntax. >-FAIL Computed <integer> is reified as CSSUnitValue The given initial value does not parse for the given syntax. >-FAIL Computed <length-percentage> [%] is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined) >-FAIL Computed <length-percentage> [px] is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined) >-FAIL Computed <length-percentage> [px + %] is reified as CSSMathSum Can't find variable: CSSMathSum >-FAIL Computed <length> is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined) >-FAIL Computed <number> is reified as CSSUnitValue The given initial value does not parse for the given syntax. >-FAIL Computed <percentage> is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined) >-FAIL Computed <resolution> is reified as CSSUnitValue The given initial value does not parse for the given syntax. >-FAIL Computed <time> is reified as CSSUnitValue The given initial value does not parse for the given syntax. >-FAIL Computed <url> is reified as CSSStyleValue The given initial value does not parse for the given syntax. >-FAIL Computed ident is reified as CSSKeywordValue The given initial value does not parse for the given syntax. >-FAIL First computed value correctly reified in space-separated list The given initial value does not parse for the given syntax. >-FAIL First computed value correctly reified in comma-separated list The given initial value does not parse for the given syntax. >-FAIL All computed values correctly reified in space-separated list The given initial value does not parse for the given syntax. >-FAIL All computed values correctly reified in comma-separated list The given initial value does not parse for the given syntax. >-FAIL attributeStyleMap.get returns CSSUnparsedValue for value with var references undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnparsedValue for value with var references undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnparsedValue for value with var references in list undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnparsedValue for value with var references in list undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnparsedValue for * undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnparsedValue for * undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <angle> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <angle> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSStyleValue for <color> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSStyleValue for <color> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSKeywordValue for <custom-ident> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSKeywordValue for <custom-ident> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSImageValue for <image> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSImageValue for <image> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <integer> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <integer> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <length-percentage> [10%] undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <length-percentage> [10%] undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <length-percentage> [10px] undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <length-percentage> [10px] undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <length> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <length> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <number> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <number> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <percentage> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <percentage> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <resolution> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <resolution> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <time> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <time> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSStyleValue for <url> undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSStyleValue for <url> undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSKeywordValue for thing1 | THING2 undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSKeywordValue for thing1 | THING2 undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <length>+ undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <length>+ undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.get returns CSSUnitValue for <length># undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.get returns CSSUnitValue for <length># undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.getAll returns a list of CSSUnitValues for <length>+ undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.getAll returns a list of CSSUnitValues for <length>+ undefined is not an object (evaluating 'rule.styleMap.clear') >-FAIL attributeStyleMap.getAll returns a list of CSSUnitValues for <length># undefined is not an object (evaluating 'target.attributeStyleMap.clear') >-FAIL styleMap.getAll returns a list of CSSUnitValues for <length># undefined is not an object (evaluating 'rule.styleMap.clear') > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html >index 4e5eaa7b8f8fd69b8cb906c3d3ff41318a662b85..14a620445c697f7e3ec8e2b6216c4b964eb7aae4 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html >@@ -33,6 +33,13 @@ function gen_prop(syntax, initialValue) { > return name; > } > >+// Cleans style rules used for testing between every test. >+add_result_callback(function(){ >+ target.attributeStyleMap.clear(); >+ // Clears 'div' rule in #style: >+ style.sheet.rules[0].styleMap.clear(); >+}); >+ > // On the target element, verify that computed value of 'name' is an instance > // of 'expected' and not an instance of CSSUnparsedValue. > // >@@ -214,86 +221,86 @@ test_style_property_map_get(function(styleDecl, propertyMap){ > let name2 = gen_prop('<length>', '0px'); > styleDecl.setProperty(name2, `var(${name1})`); > assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue); >-}, name => `${name}.get returns CSSUnparsedValue for value with var references`); >+}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > let name1 = gen_prop('<length>', '100px'); > let name2 = gen_prop('<length>#', '0px'); > styleDecl.setProperty(name2, `1px, var(${name1}), 3px`); > assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue); >-}, name => `${name}.get returns CSSUnparsedValue for value with var references in list`); >+}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references in list (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '*', 'if(){}', CSSUnparsedValue); >-}, name => `${name}.get returns CSSUnparsedValue for *`); >+}, name => `StylePropertyMap.get returns CSSUnparsedValue for * (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<angle>', '42deg', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <angle>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <angle> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<color>', '#fefefe', CSSStyleValue); >-}, name => `${name}.get returns CSSStyleValue for <color>`); >+}, name => `StylePropertyMap.get returns CSSStyleValue for <color> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<custom-ident>', 'none', CSSKeywordValue); >-}, name => `${name}.get returns CSSKeywordValue for <custom-ident>`); >+}, name => `StylePropertyMap.get returns CSSKeywordValue for <custom-ident> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<image>', 'url(thing.png)', CSSImageValue); >-}, name => `${name}.get returns CSSImageValue for <image>`); >+}, name => `StylePropertyMap.get returns CSSImageValue for <image> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<integer>', '100', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <integer>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <integer> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', '10%', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <length-percentage> [10%]`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <length-percentage> [10%] (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', '10px', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <length-percentage> [10px]`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <length-percentage> [10px] (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', 'calc(10px + 10%)', CSSMathSum); >-}, name => `${name}.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)]`); >+}, name => `StylePropertyMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<length>', '10px', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <length>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <length> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<number>', '42', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <number>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <number> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<percentage>', '10%', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <percentage>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <percentage> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<resolution>', '300dpi', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <resolution>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <resolution> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<time>', '42s', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <time>`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <time> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<url>', 'url(a)', CSSStyleValue); >-}, name => `${name}.get returns CSSStyleValue for <url>`); >+}, name => `StylePropertyMap.get returns CSSStyleValue for <url> (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, 'thing1 | THING2', 'thing1', CSSKeywordValue); >-}, name => `${name}.get returns CSSKeywordValue for thing1 | THING2`); >+}, name => `StylePropertyMap.get returns CSSKeywordValue for thing1 | THING2 (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<length>+', '10px 20px', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <length>+`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <length>+ (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > assert_attribute_get_type(styleDecl, propertyMap, '<length>#', '10px 20px', CSSUnitValue); >-}, name => `${name}.get returns CSSUnitValue for <length>#`); >+}, name => `StylePropertyMap.get returns CSSUnitValue for <length># (${name})`); > > // attributeStyleMap.getAll > >@@ -302,14 +309,14 @@ test_style_property_map_get(function(styleDecl, propertyMap){ > styleDecl.setProperty(name, '10px 20px 30px'); > assert_equals(propertyMap.getAll(name).length, 3); > assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue)); >-}, name => `${name}.getAll returns a list of CSSUnitValues for <length>+`); >+}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for <length>+ (${name})`); > > test_style_property_map_get(function(styleDecl, propertyMap){ > let name = gen_prop('<length>#', '0px'); > styleDecl.setProperty(name, '10px, 20px, 30px'); > assert_equals(propertyMap.getAll(name).length, 3); > assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue)); >-}, name => `${name}.getAll returns a list of CSSUnitValues for <length>#`); >+}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for <length># (${name})`); > > // StylePropertyMap.set > >@@ -318,13 +325,15 @@ function test_style_property_map_set_using_property_map(propertyMapName, propert > let name = gen_prop(options.syntax, options.initialValue); > propertyMap.clear(); > >+ let ensureArray = v => v.constructor === Array ? v : [v]; >+ > for (let value of options.shouldAccept) >- propertyMap.set(name, value); >+ propertyMap.set(name, ...ensureArray(value)); > > for (let value of options.shouldReject) { >- assert_throws(new TypeError(), () => propertyMap.set(name, value)); >+ assert_throws(new TypeError(), () => propertyMap.set(name, ...ensureArray(value))); > } >- }, `${propertyMapName}.set accepts correct CSSUnitValues for ${options.syntax}`); >+ }, `StylePropertyMap.set accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`); > } > > // Verify that the correct CSSStyleValues are accepted/rejected for a registered >@@ -353,77 +362,77 @@ test_style_property_map_set({ > syntax: '<angle>', > initialValue: '0deg', > shouldAccept: [CSS.deg(42), CSS.turn(2), '42deg'], >- shouldReject: [unparsed('42deg'), CSS.px(15), '50px'], >+ shouldReject: [unparsed('42deg'), CSS.px(15), '50px', [CSS.deg(15), '10deg']], > }); > > test_style_property_map_set({ > syntax: '<custom-ident>', > initialValue: 'none', > shouldAccept: [keyword('foo'), 'foo'], >- shouldReject: [unparsed('foo'), CSS.px(15), '15px'], >+ shouldReject: [unparsed('foo'), CSS.px(15), '15px', [keyword('foo'), 'foo']], > }); > > test_style_property_map_set({ > syntax: '<image>', > initialValue: 'url(a)', > shouldAccept: [url_image('url(b)'), 'url(b)'], >- shouldReject: [unparsed('url(b)'), CSS.px(100), '50px'], >+ shouldReject: [unparsed('url(b)'), CSS.px(100), '50px', [url_image('url(1)'), 'url(2)']], > }); > > test_style_property_map_set({ > syntax: '<integer>', > initialValue: '0', >- shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42'], >- shouldReject: [unparsed('42'), CSS.px(100), '50px'], >+ shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42', 'calc(2.4)'], >+ shouldReject: [unparsed('42'), CSS.px(100), '50px', [CSS.number(42), '42'], 'calc(2px + 1px)'], > }); > > test_style_property_map_set({ > syntax: '<length-percentage>', > initialValue: '0px', > shouldAccept: [CSS.percent(10), CSS.px(1), CSS.em(1), '10px', '10%'], >- shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1), 'url(b)'], >+ shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1), 'url(b)', [CSS.percent(10), '10%']], > }); > > test_style_property_map_set({ > syntax: '<length>', > initialValue: '0px', > shouldAccept: [CSS.px(10), CSS.em(10), CSS.vh(200), sum(CSS.px(10), CSS.em(20)), '10em', 'calc(10px + 10em)'], >- shouldReject: [unparsed('10px'), CSS.percent(1), 'url(b)'], >+ shouldReject: [unparsed('10px'), CSS.percent(1), 'url(b)', [CSS.em(10), '10px']], > }); > > test_style_property_map_set({ > syntax: '<number>', > initialValue: '0', > shouldAccept: [CSS.number(1337), CSS.number(-42.5), '1337', '-42.5'], >- shouldReject: [unparsed('42'), CSS.px(15), '#fef'], >+ shouldReject: [unparsed('42'), CSS.px(15), '#fef', [CSS.number(-42.5), '42.5']], > }); > > test_style_property_map_set({ > syntax: '<percentage>', > initialValue: '0%', > shouldAccept: [CSS.percent(10), '10%'], >- shouldReject: [unparsed('10%'), CSS.px(1), '#fef'], >+ shouldReject: [unparsed('10%'), CSS.px(1), '#fef', [CSS.percent(10), '1%']], > }); > > test_style_property_map_set({ > syntax: '<resolution>', > initialValue: '0dpi', > shouldAccept: [CSS.dpi(100), CSS.dpcm(10), CSS.dppx(50), '100dpi'], >- shouldReject: [unparsed('42'), CSS.px(15), '#fef'], >+ shouldReject: [unparsed('42'), CSS.px(15), '#fef', [CSS.dpi(1), '2dpi']], > }); > > test_style_property_map_set({ > syntax: '<time>', > initialValue: '0s', > shouldAccept: [CSS.s(42), CSS.ms(16), '16ms'], >- shouldReject: [unparsed('42s'), CSS.px(15), '#fef'], >+ shouldReject: [unparsed('42s'), CSS.px(15), '#fef', [CSS.s(5), '6s']], > }); > > test_style_property_map_set({ > syntax: '<url>', > initialValue: 'url(a)', > shouldAccept: [url_image('url(b)')], >- shouldReject: [unparsed('url(b)'), CSS.px(100), '#fef'], >+ shouldReject: [unparsed('url(b)'), CSS.px(100), '#fef', [url_image('url(1)'), 'url(2)']], > }); > > test_style_property_map_set({ >@@ -437,14 +446,308 @@ test_style_property_map_set({ > syntax: 'none | thing | THING', > initialValue: 'none', > shouldAccept: [keyword('thing'), keyword('THING'), 'thing'], >- shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing'), 'notathing'], >+ shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing'), 'notathing', [keyword('thing'), keyword('thing')]], > }); > > test_style_property_map_set({ > syntax: '<angle> | <length>', > initialValue: '0deg', > shouldAccept: [CSS.deg(42), CSS.turn(2), CSS.px(10), CSS.em(10), '10deg', '10px'], >- shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1), '#fef'], >+ shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1), '#fef', [CSS.deg(42), '21deg']], >+}); >+ >+// StylePropertyMap.set for list-valued properties: >+ >+test_style_property_map_set({ >+ syntax: '<angle>+', >+ initialValue: '0deg', >+ shouldAccept: [CSS.deg(15), [CSS.deg(15), '10deg'], '15deg 10deg'], >+ shouldReject: [[CSS.deg(15), CSS.px(10)], '15deg 10px'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<custom-ident>+', >+ initialValue: 'none', >+ shouldAccept: [keyword('foo'), [keyword('foo'), 'bar'], 'foo bar'], >+ shouldReject: [[keyword('foo'), CSS.px(10)], 'foo 10px'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<image>+', >+ initialValue: 'url(a)', >+ shouldAccept: [url_image('url(1)'), [url_image('url(1)'), 'url(2)'], 'url(1) url(2)'], >+ shouldReject: [[url_image('url(1)'), CSS.px(10)], 'url(1) 10px'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<integer>+', >+ initialValue: '0', >+ shouldAccept: [CSS.number(42), [CSS.number(42), '42'], '42 42', 'calc(2.4) calc(2.6)'], >+ shouldReject: [[CSS.number(42), keyword('noint')], '42 noint', 'calc(2px + 2px)'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<length-percentage>+', >+ initialValue: '0px', >+ shouldAccept: [CSS.percent(10), [CSS.percent(10), '10%']], >+ shouldReject: [[CSS.percent(10), keyword('nolength')], '10% nolength'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<length>+', >+ initialValue: '0px', >+ shouldAccept: [CSS.em(10), [CSS.em(10), '10px']], >+ shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<number>+', >+ initialValue: '0', >+ shouldAccept: [CSS.number(-42.5), [CSS.number(-42.5), '42.5'], '-42.5 42.5'], >+ shouldReject: [[CSS.number(-42.5), CSS.px(10)], '-42.5 10px'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<percentage>+', >+ initialValue: '0%', >+ shouldAccept: [CSS.percent(10), [CSS.percent(10), '1%'], '10% 1%'], >+ shouldReject: [[CSS.percent(10), keyword('foo')], '10% foo'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<resolution>+', >+ initialValue: '0dpi', >+ shouldAccept: [CSS.dpi(1), [CSS.dpi(1), '2dpi'], '1dpi 2dpi'], >+ shouldReject: [[CSS.dpi(1), keyword('foo')], '1dpi foo'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<time>+', >+ initialValue: '0s', >+ shouldAccept: [CSS.s(5), [CSS.s(5), '6s'], '5s 6s'], >+ shouldReject: [[CSS.s(5), keyword('foo')], '5s foo'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<url>+', >+ initialValue: 'url(a)', >+ shouldAccept: [url_image('url(1)'), [url_image('url(1)'), 'url(2)'], 'url(1) url(2)'], >+ shouldReject: [[url_image('url(1)'), CSS.px(10)], 'url(1) 10px'], >+}); >+ >+test_style_property_map_set({ >+ syntax: 'thing+', >+ initialValue: 'thing', >+ shouldAccept: [keyword('thing'), [keyword('thing'), 'thing'], 'thing thing'], >+ shouldReject: [[keyword('thing'), CSS.px(10)], 'thing 10px'], >+}); >+ >+test_style_property_map_set({ >+ syntax: '<length>#', >+ initialValue: '0px', >+ shouldAccept: [CSS.em(10), [CSS.em(10), '10px']], >+ shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']], >+}); >+ >+function test_append_for_property_map(propertyMapName, propertyMap, options) { >+ test(function(){ >+ let name = gen_prop(options.syntax, options.initialValue); >+ >+ let ensureArray = v => v.constructor === Array ? v : [v]; >+ >+ for (let value of options.values) { >+ propertyMap.clear(); >+ >+ if (value.base !== null) >+ propertyMap.set(name, ...ensureArray(value.base)); >+ >+ // If 'null' is expected, it means we expect the append to fail. >+ if (value.expect !== null) { >+ propertyMap.append(name, ...ensureArray(value.append)); >+ let actual = Array.from(propertyMap.getAll(name)).join(' '); >+ assert_equals(actual, value.expect); >+ } else { >+ assert_throws(new TypeError(), () => propertyMap.append(name, ...ensureArray(value.append))); >+ } >+ } >+ }, `StylePropertyMap.append accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`); >+} >+ >+// Verify that the correct CSSStyleValues are accepted/rejected when >+// appending values to list-valued properties. >+// >+// The same test is performed twice: once for attributeStyleMap, and once >+// for styleMap. >+function test_append(options) { >+ test_append_for_property_map('attributeStyleMap', target.attributeStyleMap, options); >+ test_append_for_property_map('styleMap', style.sheet.rules[0].styleMap, options); >+} >+ >+test_append({ >+ syntax: '<angle>+', >+ initialValue: '0deg', >+ values: [ >+ { base: [CSS.deg(1)], append: [CSS.px(1)], expect: null }, >+ { base: [CSS.deg(1)], append: [CSS.deg(2), CSS.px(1)], expect: null }, >+ { base: [CSS.deg(1)], append: [CSS.deg(2), '1px'], expect: null }, >+ { base: [CSS.deg(1)], append: [CSS.turn(2), CSS.deg(3)], expect: '1deg 2turn 3deg' }, >+ { base: [CSS.deg(1), CSS.deg(2)], append: [CSS.deg(3)], expect: '1deg 2deg 3deg' }, >+ { base: [CSS.deg(1)], append: [CSS.deg(2), '3deg'], expect: '1deg 2deg 3deg' }, >+ { base: [CSS.deg(1)], append: [CSS.deg(2), '3turn 4deg'], expect: '1deg 2deg 3turn 4deg' }, >+ { base: null, append: [CSS.deg(1), '2deg'], expect: '1deg 2deg' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<custom-ident>+', >+ initialValue: 'none', >+ values: [ >+ { base: [keyword('foo')], append: [CSS.px(1)], expect: null }, >+ { base: [keyword('foo')], append: [keyword('bar'), CSS.px(1)], expect: null }, >+ { base: [keyword('foo')], append: [keyword('bar'), '1px'], expect: null }, >+ { base: [keyword('foo')], append: [keyword('bar'), keyword('baz')], expect: 'foo bar baz' }, >+ { base: [keyword('foo'), keyword('bar')], append: [keyword('baz')], expect: 'foo bar baz' }, >+ { base: [keyword('foo')], append: [keyword('bar'), 'baz'], expect: 'foo bar baz' }, >+ { base: [keyword('foo')], append: [keyword('bar'), 'baz zim'], expect: 'foo bar baz zim' }, >+ { base: null, append: [keyword('foo'), 'bar'], expect: 'foo bar' }, >+ ], >+}); >+ >+['<image>+', '<url>+'].forEach((syntax) => { >+ test_append({ >+ syntax: syntax, >+ initialValue: 'url(0)', >+ values: [ >+ { base: [url_image('url("1")')], append: [CSS.px(1)], expect: null }, >+ { base: [url_image('url("1")')], append: [url_image('url("2")'), CSS.px(1)], expect: null }, >+ { base: [url_image('url("1")')], append: [url_image('url("2")'), '1px'], expect: null }, >+ { base: [url_image('url("1")')], append: [url_image('url("2")'), url_image('url("3")')], expect: 'url("1") url("2") url("3")' }, >+ { base: [url_image('url("1")'), url_image('url("2")')], append: [url_image('url("3")')], expect: 'url("1") url("2") url("3")' }, >+ { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3")'], expect: 'url("1") url("2") url("3")' }, >+ { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3") url("4")'], expect: 'url("1") url("2") url("3") url("4")' }, >+ { base: null, append: [url_image('url("1")'), 'url("2")'], expect: 'url("1") url("2")' }, >+ ], >+ }); >+}); >+ >+test_append({ >+ syntax: '<integer>+', >+ initialValue: '0', >+ values: [ >+ { base: [CSS.number(1)], append: [CSS.px(1)], expect: null }, >+ { base: [CSS.number(1)], append: [CSS.number(2), CSS.px(1)], expect: null }, >+ { base: [CSS.number(1)], append: [CSS.number(2), 'noint'], expect: null }, >+ { base: [CSS.number(1)], append: [CSS.number(2), CSS.number(3)], expect: '1 2 3' }, >+ { base: [CSS.number(1), CSS.number(2)], append: [CSS.number(3)], expect: '1 2 3' }, >+ { base: [CSS.number(1)], append: [CSS.number(2), '3'], expect: '1 2 3' }, >+ { base: [CSS.number(1)], append: [CSS.number(2), '3 4'], expect: '1 2 3 4' }, >+ { base: null, append: [CSS.number(1), '2'], expect: '1 2' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<length-percentage>+', >+ initialValue: '0px', >+ values: [ >+ { base: [CSS.px(1)], append: [keyword('nolength')], expect: null }, >+ { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null }, >+ { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null }, >+ { base: [CSS.px(1)], append: [CSS.px(2), CSS.percent(3)], expect: '1px 2px 3%' }, >+ { base: [CSS.px(1), CSS.px(2)], append: [CSS.percent(3)], expect: '1px 2px 3%' }, >+ { base: [CSS.px(1)], append: [CSS.percent(2), '3px'], expect: '1px 2% 3px' }, >+ { base: [CSS.px(1)], append: [CSS.px(2), '3% 4px'], expect: '1px 2px 3% 4px' }, >+ { base: null, append: [CSS.px(1), '2%'], expect: '1px 2%' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<length>+', >+ initialValue: '0', >+ values: [ >+ { base: [CSS.px(1)], append: [keyword('nolength')], expect: null }, >+ { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null }, >+ { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null }, >+ { base: [CSS.px(1)], append: [CSS.em(2), CSS.px(3)], expect: '1px 2em 3px' }, >+ { base: [CSS.px(1), CSS.em(2)], append: [CSS.vh(3)], expect: '1px 2em 3vh' }, >+ { base: [CSS.px(1)], append: [CSS.em(2), '3px'], expect: '1px 2em 3px' }, >+ { base: [CSS.px(1)], append: [CSS.px(2), '3em 4cm'], expect: '1px 2px 3em 4cm' }, >+ { base: null, append: [CSS.vh(1), '2px'], expect: '1vh 2px' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<number>+', >+ initialValue: '0', >+ values: [ >+ { base: [CSS.number(-1)], append: [keyword('NaN')], expect: null }, >+ { base: [CSS.number(-1)], append: [CSS.number(2.5), keyword('NaN')], expect: null }, >+ { base: [CSS.number(-1)], append: [CSS.number(2.5), '1px'], expect: null }, >+ { base: [CSS.number(-1)], append: [CSS.number(2.5), CSS.number(3.2)], expect: '-1 2.5 3.2' }, >+ { base: [CSS.number(-1), CSS.number(2.5)], append: [CSS.number(3.2)], expect: '-1 2.5 3.2' }, >+ { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2'], expect: '-1 2.5 3.2' }, >+ { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2 4'], expect: '-1 2.5 3.2 4' }, >+ { base: null, append: [CSS.number(-1), '2.5'], expect: '-1 2.5' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<percentage>+', >+ initialValue: '0%', >+ values: [ >+ { base: [CSS.percent(1)], append: [CSS.px(1)], expect: null }, >+ { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.px(1)], expect: null }, >+ { base: [CSS.percent(1)], append: [CSS.percent(2), '1px'], expect: null }, >+ { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.percent(3)], expect: '1% 2% 3%' }, >+ { base: [CSS.percent(1), CSS.percent(2)], append: [CSS.percent(3)], expect: '1% 2% 3%' }, >+ { base: [CSS.percent(1)], append: [CSS.percent(2), '3%'], expect: '1% 2% 3%' }, >+ { base: [CSS.percent(1)], append: [CSS.percent(2), '3% 4%'], expect: '1% 2% 3% 4%' }, >+ { base: null, append: [CSS.percent(1), '2%'], expect: '1% 2%' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<resolution>+', >+ initialValue: '0dpi', >+ values: [ >+ { base: [CSS.dpi(1)], append: [CSS.px(1)], expect: null }, >+ { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.px(1)], expect: null }, >+ { base: [CSS.dpi(1)], append: [CSS.dpi(2), '1px'], expect: null }, >+ { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' }, >+ { base: [CSS.dpi(1), CSS.dpi(2)], append: [CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' }, >+ { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi'], expect: '1dpi 2dpi 3dpi' }, >+ { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi 4dpi'], expect: '1dpi 2dpi 3dpi 4dpi' }, >+ { base: null, append: [CSS.dpi(1), '2dpi'], expect: '1dpi 2dpi' }, >+ ], >+}); >+ >+test_append({ >+ syntax: '<time>+', >+ initialValue: '0s', >+ values: [ >+ { base: [CSS.s(1)], append: [CSS.px(1)], expect: null }, >+ { base: [CSS.s(1)], append: [CSS.s(2), CSS.px(1)], expect: null }, >+ { base: [CSS.s(1)], append: [CSS.ms(2), '1px'], expect: null }, >+ { base: [CSS.s(1)], append: [CSS.ms(2), CSS.s(3)], expect: '1s 2ms 3s' }, >+ { base: [CSS.s(1), CSS.s(2)], append: [CSS.s(3)], expect: '1s 2s 3s' }, >+ { base: [CSS.s(1)], append: [CSS.s(2), '3s'], expect: '1s 2s 3s' }, >+ { base: [CSS.s(1)], append: [CSS.s(2), '3ms 4s'], expect: '1s 2s 3ms 4s' }, >+ { base: null, append: [CSS.s(1), '2s'], expect: '1s 2s' }, >+ ], >+}); >+ >+test_append({ >+ syntax: 'foo+', >+ initialValue: 'foo', >+ values: [ >+ { base: [keyword('foo')], append: [CSS.px(1)], expect: null }, >+ { base: [keyword('foo')], append: [keyword('foo'), CSS.px(1)], expect: null }, >+ { base: [keyword('foo')], append: [keyword('foo'), '1px'], expect: null }, >+ { base: [keyword('foo')], append: [keyword('foo'), keyword('foo')], expect: 'foo foo foo' }, >+ { base: [keyword('foo'), keyword('foo')], append: [keyword('foo')], expect: 'foo foo foo' }, >+ { base: [keyword('foo')], append: [keyword('foo'), 'foo'], expect: 'foo foo foo' }, >+ { base: [keyword('foo')], append: [keyword('foo'), 'foo foo'], expect: 'foo foo foo foo' }, >+ { base: null, append: [keyword('foo'), keyword('foo')], expect: 'foo foo' }, >+ ], > }); > > // CSSStyleValue.parse/parseAll >@@ -537,4 +840,181 @@ test(function(){ > assert_parsed_type(gen_prop('<length># | fail', 'fail'), '10px, 20px', CSSUnitValue); > }, 'CSSStyleValue.parse[All] returns list of CSSUnitValues for <length>#'); > >+// Direct CSSStyleValue objects: >+ >+function gen_all_props() { >+ return [ >+ gen_prop('*', 'foo'), >+ gen_prop('foo', 'foo'), >+ gen_prop('<angle>', '0deg'), >+ gen_prop('<color>', 'rgb(1, 2, 3)'), >+ gen_prop('<custom-ident>', 'thing'), >+ gen_prop('<image>', 'url(a)'), >+ gen_prop('<integer>', '0'), >+ gen_prop('<length-percentage>', 'calc(10px + 10%)'), >+ gen_prop('<length>', '0px'), >+ gen_prop('<number>', '0.5'), >+ gen_prop('<percentage>', '0%'), >+ gen_prop('<resolution>', '0dpi'), >+ gen_prop('<time>', '0s'), >+ gen_prop('<transform-function>', 'rotateX(0deg)'), >+ gen_prop('<transform-list>', 'rotateX(0deg)'), >+ gen_prop('<url>', 'url(a)') >+ ]; >+} >+ >+test(function(){ >+ let props0 = gen_all_props(); >+ let props1 = gen_all_props(); >+ >+ for (let i = 0; i < props0.length; i++) { >+ let prop0 = props0[i]; >+ let prop1 = props1[i]; >+ >+ // Abuse computedStyleMap to get the initialValue (just to get some >+ // value that will parse for prop0/1's syntax). >+ let initialValue = target.computedStyleMap().get(prop0); >+ >+ // We only care about direct CSSStyleValue instances in this test. >+ // Ultimately, in some future version of CSS TypedOM, we may have no >+ // direct CSSStyleValue instances at all, which is fine. >+ if (initialValue.constructor !== CSSStyleValue) { >+ continue; >+ } >+ >+ let value = CSSStyleValue.parse(prop0, initialValue.toString()); >+ >+ // A value parsed for prop0 must be assignable to prop0. >+ target.attributeStyleMap.clear(); >+ target.attributeStyleMap.set(prop0, value); // Don't throw. >+ >+ // A value parsed for prop0 must not be assignable to prop1, even if >+ // the properties have compatible syntaxes. >+ assert_throws(new TypeError(), () => { >+ target.attributeStyleMap.clear(); >+ target.attributeStyleMap.set(prop1, value); >+ }); >+ } >+}, 'Direct CSSStyleValue instances are tied to their associated property'); >+ >+// StylePropertyMapReadOnly iteration >+ >+test(function(){ >+ let name = gen_prop('<length>', '10px'); >+ let result = Array.from(target.computedStyleMap()).filter(e => e[0] == name)[0]; >+ assert_true(typeof(result) !== 'undefined'); >+}, 'Registered property with initial value show up on iteration of computedStyleMap'); >+ >+// Verifies that iterating a StylePropertyMap[ReadOnly] yields correctly >+// typed objects for a given syntax/value. >+function test_iteration_type_for_property_map(propertyMapName, propertyMap, options) { >+ test(function(){ >+ let name = gen_prop(options.syntax, options.initialValue); >+ if (propertyMap instanceof StylePropertyMap) { >+ // Only set the value if the propertyMap is mutable. >+ propertyMap.set(name, options.value); >+ } >+ let result = Array.from(propertyMap).filter(e => e[0] == name)[0]; >+ let value = result[1]; >+ assert_true(options.expect(value)); >+ }, `Iteration on ${propertyMapName} produces correct type for ${options.syntax}`); >+} >+ >+function test_iteration_type(options) { >+ test_iteration_type_for_property_map('computedStyleMap', target.computedStyleMap(), options); >+ test_iteration_type_for_property_map('attributeStyleMap', target.attributeStyleMap, options); >+ test_iteration_type_for_property_map('styleMap', style.sheet.rules[0].styleMap, options); >+} >+ >+test_iteration_type({ >+ syntax: '*', >+ initialValue: 'none', >+ value: 'thing', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnparsedValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<angle>', >+ initialValue: '0deg', >+ value: '42deg', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<custom-ident>', >+ initialValue: 'none', >+ value: 'thing', >+ expect: v => v.length == 1 && v[0] instanceof CSSKeywordValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<image>', >+ initialValue: 'url(a)', >+ value: 'url(b)', >+ expect: v => v.length == 1 && v[0] instanceof CSSImageValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<integer>', >+ initialValue: '0', >+ value: '100', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<length>', >+ initialValue: '0px', >+ value: '10px', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<number>', >+ initialValue: '0', >+ value: '42', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<percentage>', >+ initialValue: '0%', >+ value: '10%', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<resolution>', >+ initialValue: '0dpi', >+ value: '300dpi', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<time>', >+ initialValue: '0s', >+ value: '10s', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<url>', >+ initialValue: 'url(a)', >+ value: 'url(b)', >+ expect: v => v.length == 1 && v[0].constructor === CSSStyleValue, >+}); >+ >+test_iteration_type({ >+ syntax: 'none | thing | THING', >+ initialValue: 'none', >+ value: 'THING', >+ expect: v => v.length == 1 && v[0] instanceof CSSKeywordValue, >+}); >+ >+test_iteration_type({ >+ syntax: '<angle> | <length>', >+ initialValue: '0deg', >+ value: '10px', >+ expect: v => v.length == 1 && v[0] instanceof CSSUnitValue, >+}); >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt >index c06da9ba73d569b14e1710522cdcf33dda34cf10..5e819b3c58def74fe777457f5d58c4a19555da04 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt >@@ -1,4 +1,4 @@ >-CONSOLE MESSAGE: line 63: TypeError: undefined is not an object (evaluating 'element.attributeStyleMap.clear') >+CONSOLE MESSAGE: line 74: TypeError: undefined is not an object (evaluating 'element.attributeStyleMap.clear') > > FAIL Untitled TypeError: undefined is not an object (evaluating 'element.attributeStyleMap.clear') > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html >index d65348543c4145bbd693aac67372390bfd91fc11..c26e1cda1f6842655e7e0158d6a934e470f486ae 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html >@@ -4,12 +4,12 @@ > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> > <script> >- function register_length(name) { >+ function register_length(name, inherits=true) { > CSS.registerProperty({ > name: name, > syntax: '<length>', > initialValue: '0px', >- inherits: false >+ inherits: inherits > }); > } > >@@ -22,6 +22,9 @@ > register_length('--font-size-rem-via-var'); > register_length('--font-size-ex-via-var'); > register_length('--font-size-ch-via-var'); >+ register_length('--font-size-em-inherited', true); >+ register_length('--font-size-ex-inherited', true); >+ register_length('--font-size-ch-inherited', true); > </script> > <style> > :root { >@@ -43,12 +46,20 @@ > --font-size-ch-via-var: var(--unregistered-ch); > } > >+ #parent { >+ --font-size-em-inherited: 4em; >+ --font-size-ex-inherited: 4ex; >+ --font-size-ch-inherited: 4ch; >+ } >+ > #target { > font-size: 11px; > } > </style> > >-<div id=target></div> >+<div id=parent> >+ <div id=target></div> >+</div> > <div id=ref></div> > > <script> >@@ -170,4 +181,25 @@ > assert_property_equals('--font-size-rem-via-var', expected10rem, root); > }, 'Lengths with rem units are detected via var references'); > >+ test(function() { >+ let expected4em = compute_dimension('4em', 'unset'); >+ target.style = 'font-size: var(--font-size-em-inherited);'; >+ assert_property_equals('font-size', expected4em); >+ assert_property_equals('--font-size-em-inherited', expected4em); >+ }, 'Inherited lengths with em units may be used'); >+ >+ test(function() { >+ let expected4ex = compute_dimension('4ex', 'unset'); >+ target.style = 'font-size: var(--font-size-ex-inherited);'; >+ assert_property_equals('font-size', expected4ex); >+ assert_property_equals('--font-size-ex-inherited', expected4ex); >+ }, 'Inherited lengths with ex units may be used'); >+ >+ test(function() { >+ let expected4ch = compute_dimension('4ch', 'unset'); >+ target.style = 'font-size: var(--font-size-ch-inherited);'; >+ assert_property_equals('font-size', expected4ch); >+ assert_property_equals('--font-size-ch-inherited', expected4ch); >+ }, 'Inherited lengths with ch units may be used'); >+ > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html >index 58d6c846ae3a4a1c62f239786dfe8827eb921d05..65d11697355c17fca39b4e9fa0dcf0db404e22eb 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html >@@ -25,14 +25,13 @@ test(function() { > CSS.registerProperty({name: '--registered-1-d', syntax: '<length>', initialValue: '4px', inherits: false}); > > computedStyle = getComputedStyle(test1); >- assert_equals(computedStyle.getPropertyValue('--registered-1-a'), '1px'); >- assert_equals(computedStyle.getPropertyValue('--registered-1-b'), '2px'); >- >- assert_equals(computedStyle.getPropertyValue('--registered-1-c'), '2px'); >- assert_equals(computedStyle.getPropertyValue('--registered-1-d'), '2px'); >- assert_equals(computedStyle.getPropertyValue('--unregistered-1-a'), '1px'); >- assert_equals(computedStyle.left, '1px'); >- assert_equals(computedStyle.top, '2px'); >+ assert_equals(computedStyle.getPropertyValue('--registered-1-a'), ''); >+ assert_equals(computedStyle.getPropertyValue('--registered-1-b'), ''); >+ assert_equals(computedStyle.getPropertyValue('--registered-1-c'), '30px'); >+ assert_equals(computedStyle.getPropertyValue('--registered-1-d'), '4px'); >+ assert_equals(computedStyle.getPropertyValue('--unregistered-1-a'), ''); >+ assert_equals(computedStyle.left, '50px'); >+ assert_equals(computedStyle.top, '60px'); > }, "A var() cycle between two registered properties is handled correctly."); > </script> > >@@ -63,18 +62,18 @@ test(function() { > CSS.registerProperty({name: '--registered-2-e', syntax: '<length>', initialValue: '5px', inherits: false}); > > computedStyle = getComputedStyle(test2); >- assert_equals(computedStyle.getPropertyValue('--registered-2-a'), '1px'); >+ assert_equals(computedStyle.getPropertyValue('--registered-2-a'), ''); > assert_equals(computedStyle.getPropertyValue('--unregistered-2-a'), ''); > >- assert_equals(computedStyle.getPropertyValue('--registered-2-b'), '1px'); >- assert_equals(computedStyle.getPropertyValue('--registered-2-c'), '1px'); >+ assert_equals(computedStyle.getPropertyValue('--registered-2-b'), '30px'); >+ assert_equals(computedStyle.getPropertyValue('--registered-2-c'), '3px'); > assert_equals(computedStyle.getPropertyValue('--registered-2-d'), '40px'); > assert_equals(computedStyle.getPropertyValue('--registered-2-e'), '5px'); >- assert_equals(computedStyle.getPropertyValue('--unregistered-2-b'), '1px'); >- assert_equals(computedStyle.getPropertyValue('--unregistered-2-c'), '1px'); >+ assert_equals(computedStyle.getPropertyValue('--unregistered-2-b'), '50px'); >+ assert_equals(computedStyle.getPropertyValue('--unregistered-2-c'), ''); > assert_equals(computedStyle.getPropertyValue('--unregistered-2-d'), '60px'); > assert_equals(computedStyle.getPropertyValue('--unregistered-2-e'), ''); >- assert_equals(computedStyle.left, '1px'); >+ assert_equals(computedStyle.left, '70px'); > assert_equals(computedStyle.top, '80px'); > }, "A var() cycle between a registered properties and an unregistered property is handled correctly."); > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt >index 39e675d434ae1a90e52da9eab6f402664d9c0373..4285a41e85f40cca6111be63f3bba6dd3afddf6a 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt >@@ -1,6 +1,15 @@ > >-FAIL var() references work with registered properties assert_equals: expected " 10px" but got " 10px" >+PASS var() references work with registered properties > FAIL References to registered var()-properties work in registered lists assert_equals: expected "1px, 10px, 2px" but got "0px" > FAIL References to mixed registered and unregistered var()-properties work in registered lists assert_equals: expected "1px, 20px, 10px, 2px" but got "0px" > FAIL Registered lists may be concatenated assert_equals: expected "1px, 10px, 2px, 1px, 20px, 10px, 2px" but got "0px" >+PASS Font-relative units are absolutized when substituting >+PASS Calc expressions are resolved when substituting >+FAIL Lists with relative units are absolutized when substituting assert_equals: expected "110px, 120px" but got "0px" >+PASS Valid fallback does not invalidate var()-reference [<length>, 10px] >+PASS Valid fallback does not invalidate var()-reference [<length> | <color>, red] >+PASS Valid fallback does not invalidate var()-reference [<length> | none, none] >+FAIL Invalid fallback invalidates var()-reference [<length>, red] assert_equals: expected "" but got "40px" >+FAIL Invalid fallback invalidates var()-reference [<length> | none, nolength] assert_equals: expected "" but got "40px" >+FAIL Invalid fallback invalidates var()-reference [<length>, var(--novar)] assert_equals: expected "" but got "40px" > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html >index d8a831571252cdeb3e6c3c6e582a2b74376e905c..166754574faa025807847209f1ab157111a4a6d8 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html >@@ -2,6 +2,7 @@ > <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" /> > <script src="/resources/testharness.js"></script> > <script src="/resources/testharnessreport.js"></script> >+<script src="./resources/utils.js"></script> > <style> > div { > --registered-length-1: 10px; >@@ -54,7 +55,7 @@ test(function() { > assert_equals(computedStyle.getPropertyValue('--registered-length-6'), '80px'); > assert_equals(computedStyle.getPropertyValue('--registered-length-7'), '123px'); > assert_equals(computedStyle.getPropertyValue('--length-1'), ' 20px'); >- assert_equals(computedStyle.getPropertyValue('--length-2'), ' 10px'); >+ assert_equals(computedStyle.getPropertyValue('--length-2'), ' 10px'); > assert_equals(computedStyle.getPropertyValue('--length-3'), ' calc(123px + 123px)'); > assert_equals(computedStyle.getPropertyValue('--registered-length-invalid'), '15px'); > >@@ -96,5 +97,77 @@ test(function(){ > assert_equals(computedStyle.getPropertyValue('--registered-length-list-3'), '1px, 10px, 2px, 1px, 20px, 10px, 2px'); > }, 'Registered lists may be concatenated'); > >+test(function(){ >+ CSS.registerProperty({ >+ name: '--length-em', >+ syntax: '<length>', >+ initialValue: '0px', >+ inherits: false >+ }); >+ element.style = 'font-size: 11px; --length-em: 10em; --unregistered:var(--length-em);'; >+ let computedStyle = getComputedStyle(element); >+ assert_equals(computedStyle.getPropertyValue('--unregistered'), '110px'); >+ element.style = ''; >+}, 'Font-relative units are absolutized when substituting'); >+ >+test(function(){ >+ CSS.registerProperty({ >+ name: '--length-calc', >+ syntax: '<length>', >+ initialValue: '0px', >+ inherits: false >+ }); >+ element.style = 'font-size: 11px; --length-calc: calc(10em + 10px); --unregistered:var(--length-calc);'; >+ let computedStyle = getComputedStyle(element); >+ assert_equals(computedStyle.getPropertyValue('--unregistered'), '120px'); >+ element.style = ''; >+}, 'Calc expressions are resolved when substituting'); >+ >+test(function(){ >+ CSS.registerProperty({ >+ name: '--length-calc-list', >+ syntax: '<length>#', >+ initialValue: '0px', >+ inherits: false >+ }); >+ element.style = 'font-size: 11px; --length-calc-list: 10em, calc(10em + 10px); --unregistered:var(--length-calc-list);'; >+ let computedStyle = getComputedStyle(element); >+ assert_equals(computedStyle.getPropertyValue('--unregistered'), '110px, 120px'); >+ element.style = ''; >+}, 'Lists with relative units are absolutized when substituting'); >+ >+function test_valid_fallback(syntax, value, fallback) { >+ test(function(){ >+ let name = generate_property(syntax); >+ try { >+ element.style = `${name}: ${value}; --x:var(${name},${fallback})`; >+ let computedStyle = getComputedStyle(element); >+ assert_equals(computedStyle.getPropertyValue('--x'), value); >+ } finally { >+ element.style = ''; >+ } >+ }, `Valid fallback does not invalidate var()-reference [${syntax}, ${fallback}]`); >+} >+ >+function test_invalid_fallback(syntax, value, fallback) { >+ test(function(){ >+ let name = generate_property(syntax); >+ try { >+ element.style = `${name}: ${value}; --x:var(${name},${fallback})`; >+ let computedStyle = getComputedStyle(element); >+ assert_equals(computedStyle.getPropertyValue('--x'), ''); >+ } finally { >+ element.style = ''; >+ } >+ }, `Invalid fallback invalidates var()-reference [${syntax}, ${fallback}]`); >+} >+ >+test_valid_fallback('<length>', '40px', '10px'); >+test_valid_fallback('<length> | <color>', '40px', 'red'); >+test_valid_fallback('<length> | none', '40px', 'none'); >+ >+test_invalid_fallback('<length>', '40px', 'red'); >+test_invalid_fallback('<length> | none', '40px', 'nolength'); >+test_invalid_fallback('<length>', '40px', 'var(--novar)'); > > </script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/w3c-import.log >index 86cd8dd0c16fa91cdd0d785944adec742c5e780d..6307bcdd7942ea76e8816b7d864ac9dcee25f9f8 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/w3c-import.log >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/w3c-import.log >@@ -23,6 +23,7 @@ List of files: > /LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html >+/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html > /LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/url-resolution.html
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 192800
:
357532
|
357578
|
357624