Registered custom properties should allow inheritance to be controlled
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Oct 2018 06:23:02 +0000 (06:23 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Oct 2018 06:23:02 +0000 (06:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190038

Patch by Justin Michaud <justin_michaud@apple.com> on 2018-10-03
Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Update web platform tests for css registered custom properties to fail in a different way.

* web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt:
* web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt:
* web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt:
* web-platform-tests/css/css-properties-values-api/url-resolution-expected.txt:
* web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles-expected.txt:
* web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt:

Source/WebCore:

Tests: css-custom-properties-api/inherits.html
       css-custom-properties-api/length.html
       css-custom-properties-api/length2.html

Add support for inherits property on registered css custom properties, as well
as a starting point for evaluating registered custom properties with types. Registered
custom properties are evaluated as length values before being substituted. Currently,
relative unit cycles are not detected.

A proper solution is still needed to resolve relative unit cycles, and to apply properties like font
and line-height before they are needed by custom properties. In this patch, the font-size property is
applied twice, once before and once after resolving custom property values.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::customPropertyValue):
(WebCore::CSSComputedStyleDeclaration::length const):
(WebCore::CSSComputedStyleDeclaration::item const):

Allow JS to get custom properties that have been resolved to a length. Also add properties from
m_rareNonInheritedData.

* css/CSSCustomPropertyValue.cpp:
(WebCore::CSSCustomPropertyValue::checkVariablesForCycles const):
(WebCore::CSSCustomPropertyValue::resolveVariableReferences const):
* css/CSSCustomPropertyValue.h:
* css/CSSRegisteredCustomProperty.cpp: Copied from Source/WebCore/css/CSSRegisteredCustomProperty.h.
(WebCore::CSSRegisteredCustomProperty::CSSRegisteredCustomProperty):
(WebCore::CSSRegisteredCustomProperty::initialValueCopy const):
* css/CSSRegisteredCustomProperty.h:
(WebCore::CSSRegisteredCustomProperty::initialValue const):
* css/CSSVariableData.cpp:
(WebCore::CSSVariableData::checkVariablesForCycles const):
(WebCore::CSSVariableData::checkVariablesForCyclesWithRange const):
(WebCore::CSSVariableData::resolveVariableFallback const):
(WebCore::CSSVariableData::resolveVariableReference const):
(WebCore::CSSVariableData::resolveVariableReferences const):
(WebCore::CSSVariableData::resolveTokenRange const):
* css/CSSVariableData.h:
* css/CSSVariableReferenceValue.cpp:
(WebCore::CSSVariableReferenceValue::checkVariablesForCycles const):
* css/CSSVariableReferenceValue.h:
* css/DOMCSSRegisterCustomProperty.cpp:
(WebCore::DOMCSSRegisterCustomProperty::registerProperty):

Use RenderStyle over passing in a customProperties map.

* css/StyleBuilder.h:
* css/StyleBuilderConverter.h:
(WebCore::StyleBuilderConverter::convertLength):
(WebCore::StyleBuilderConverter::convertLengthOrAuto):
(WebCore::StyleBuilderConverter::convertLengthSizing):
(WebCore::StyleBuilderConverter::convertLengthMaxSizing):
* css/StyleBuilderCustom.h:
(WebCore::StyleBuilderCustom::applyInitialCustomProperty):
(WebCore::StyleBuilderCustom::applyInheritCustomProperty):
(WebCore::StyleBuilderCustom::applyValueCustomProperty):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::useSVGZoomRules const):
(WebCore::StyleResolver::useSVGZoomRulesForLength const):
(WebCore::StyleResolver::applyProperty):
(WebCore::StyleResolver::resolvedVariableValue const):
(WebCore::StyleResolver::applyCascadedProperties):
(WebCore::StyleResolver::useSVGZoomRules): Deleted.
(WebCore::StyleResolver::useSVGZoomRulesForLength): Deleted.
(WebCore::StyleResolver::resolvedVariableValue): Deleted.
* css/StyleResolver.h:
* css/makeprop.pl:

Move custom property initial values to StyleBuilerCustom. Hook them up to correctly deal with
inheritance, unset and revert values.

* css/parser/CSSParser.cpp:
(WebCore::CSSParser::parseValueWithVariableReferences):
* css/parser/CSSParser.h:
* css/parser/CSSParserContext.cpp:
(WebCore::CSSParserContext::CSSParserContext):
* css/parser/CSSParserContext.h:
* css/parser/CSSPropertyParser.cpp:
(WebCore::CSSPropertyParser::parseSingleValue):

Allow parsing custom property values as lengths.

* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::checkVariablesInCustomProperties):
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::inheritedCustomProperties const):
(WebCore::RenderStyle::nonInheritedCustomProperties const):
(WebCore::RenderStyle::setInheritedCustomPropertyValue):
(WebCore::RenderStyle::setNonInheritedCustomPropertyValue):
(WebCore::RenderStyle::getCustomProperty const):
(WebCore::RenderStyle::customProperties const): Deleted.
(WebCore::RenderStyle::setCustomPropertyValue): Deleted.
* rendering/style/StyleRareNonInheritedData.cpp:
(WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
(WebCore::StyleRareNonInheritedData::operator== const):
* rendering/style/StyleRareNonInheritedData.h:
* style/StyleResolveForDocument.cpp:
(WebCore::Style::resolveForDocument):

Add support for RenderStyle to deal with both inherited and non-inherited properties, and to find
cycles between them.

LayoutTests:

Add tests to check css registered custom properties with inherits. Also test
calc expression evaluation for inherited registered custom properties.

* css-custom-properties-api/inherits-expected.txt: Added.
* css-custom-properties-api/inherits.html: Added.
* css-custom-properties-api/length-expected.txt: Added.
* css-custom-properties-api/length.html: Added.
* css-custom-properties-api/length2-expected.txt: Added.
* css-custom-properties-api/length2.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236828 268f45cc-cd09-0410-ab3c-d52691b4dbfc

48 files changed:
LayoutTests/ChangeLog
LayoutTests/css-custom-properties-api/inherits-expected.txt [new file with mode: 0644]
LayoutTests/css-custom-properties-api/inherits.html [new file with mode: 0644]
LayoutTests/css-custom-properties-api/length-expected.txt [new file with mode: 0644]
LayoutTests/css-custom-properties-api/length.html [new file with mode: 0644]
LayoutTests/css-custom-properties-api/length2-expected.txt [new file with mode: 0644]
LayoutTests/css-custom-properties-api/length2.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/property-cascade-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/url-resolution-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSCustomPropertyValue.cpp
Source/WebCore/css/CSSCustomPropertyValue.h
Source/WebCore/css/CSSRegisteredCustomProperty.cpp [new file with mode: 0644]
Source/WebCore/css/CSSRegisteredCustomProperty.h
Source/WebCore/css/CSSVariableData.cpp
Source/WebCore/css/CSSVariableData.h
Source/WebCore/css/CSSVariableReferenceValue.cpp
Source/WebCore/css/CSSVariableReferenceValue.h
Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp
Source/WebCore/css/StyleBuilder.h
Source/WebCore/css/StyleBuilderConverter.h
Source/WebCore/css/StyleBuilderCustom.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/css/makeprop.pl
Source/WebCore/css/parser/CSSParser.cpp
Source/WebCore/css/parser/CSSParser.h
Source/WebCore/css/parser/CSSParserContext.cpp
Source/WebCore/css/parser/CSSParserContext.h
Source/WebCore/css/parser/CSSPropertyParser.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/StyleCustomPropertyData.h
Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp
Source/WebCore/rendering/style/StyleRareNonInheritedData.h
Source/WebCore/style/StyleResolveForDocument.cpp

index 94fd24a..db408d1 100644 (file)
@@ -1,3 +1,20 @@
+2018-10-03  Justin Michaud  <justin_michaud@apple.com>
+
+        Registered custom properties should allow inheritance to be controlled
+        https://bugs.webkit.org/show_bug.cgi?id=190038
+
+        Reviewed by Antti Koivisto.
+
+        Add tests to check css registered custom properties with inherits. Also test
+        calc expression evaluation for inherited registered custom properties.
+
+        * css-custom-properties-api/inherits-expected.txt: Added.
+        * css-custom-properties-api/inherits.html: Added.
+        * css-custom-properties-api/length-expected.txt: Added.
+        * css-custom-properties-api/length.html: Added.
+        * css-custom-properties-api/length2-expected.txt: Added.
+        * css-custom-properties-api/length2.html: Added.
+
 2018-10-03  Youenn Fablet  <youenn@apple.com>
 
         Add VP8 support to WebRTC
diff --git a/LayoutTests/css-custom-properties-api/inherits-expected.txt b/LayoutTests/css-custom-properties-api/inherits-expected.txt
new file mode 100644 (file)
index 0000000..09e206c
--- /dev/null
@@ -0,0 +1,103 @@
+Specified in parent, inherits=true
+
+100px green
+
+Specified in parent, inherits=false
+
+200px green
+
+Specified in parent, not registered
+
+100px green
+
+Initial
+
+200px green
+
+Unset, inherits=true
+
+100px green
+
+Unset, inherits=false
+
+200px green
+
+A cycle between an inherits=true and inherits=false property
+
+200px green
+
+A cycle between an inherits=true and inherits=false property
+
+200px green
+
+A cycle between an inherits=true and inherits=false property with fallback
+
+200px green
+
+Inheritance should not create a cycle
+
+110px green
+
+A cycle between two unregistered properties
+
+300px green
+
+Revert, inherits=true
+
+190px purple
+
+Revert, inherits=false
+
+200px purple
+
+Revert, unregistered
+
+purple
+
+Inherit, unregistered
+
+purple
+
+Test that inherited properties do variable substitution before being inherited - registered
+
+test
+
+Test that inherited properties do variable substitution before being inherited - unregistered
+
+test
+
+No initial value in registered property should act like unregistered
+
+200px green
+
+(unregistered)
+
+500px green
+
+Inherit should be substituted for unregistered property
+
+500px green
+
+
+PASS Registration is successful 
+PASS JS Attributes are valid for element 1 
+PASS JS Attributes are valid for element 2 
+PASS JS Attributes are valid for element 3 
+PASS JS Attributes are valid for element 4 
+PASS JS Attributes are valid for element 5 
+PASS JS Attributes are valid for element 6 
+PASS JS Attributes are valid for element 7 
+PASS JS Attributes are valid for element 8 
+PASS JS Attributes are valid for element 9 
+PASS JS Attributes are valid for element 10 
+PASS JS Attributes are valid for element 11 
+PASS JS Attributes are valid for element 12 
+PASS JS Attributes are valid for element 13 
+PASS JS Attributes are valid for element 14 
+PASS JS Attributes are valid for element 14-1 
+PASS JS Attributes are valid for element 15 
+PASS JS Attributes are valid for element 16 
+PASS JS Attributes are valid for element 17 
+PASS JS Attributes are valid for element 18 
+PASS JS Attributes are valid for element 19 
+
diff --git a/LayoutTests/css-custom-properties-api/inherits.html b/LayoutTests/css-custom-properties-api/inherits.html
new file mode 100644 (file)
index 0000000..8ee4fcf
--- /dev/null
@@ -0,0 +1,431 @@
+<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSCustomPropertiesAndValuesEnabled=true ] -->
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+
+<style>
+  #parent1 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child1 {
+    background: green;
+    width: var(--my-custom-prop);
+  }
+
+  #parent2 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop2: 100px;
+  }
+  #child2 {
+    background: green;
+    width: var(--my-custom-prop2);
+  }
+
+  #parent3 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop3: 100px;
+  }
+  #child3 {
+    background: green;
+    width: var(--my-custom-prop3);
+  }
+
+  #parent4 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child4 {
+    background: green;
+    --my-custom-prop: initial;
+    width: var(--my-custom-prop, 300px);
+  }
+
+  #parent5 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child5 {
+    background: green;
+    --my-custom-prop: unset;
+    width: var(--my-custom-prop, 300px);
+  }
+
+  #parent6 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop2: 100px;
+  }
+  #child6 {
+    background: green;
+    --my-custom-prop2: unset;
+    width: var(--my-custom-prop2, 300px);
+  }
+
+  #parent7 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child7 {
+    background: green;
+    --my-custom-prop: var(--my-custom-prop2);
+    --my-custom-prop2: var(--my-custom-prop);
+    width: var(--my-custom-prop2, 300px);
+  }
+
+  #parent8 {
+    width: 500px;
+    background: blue;
+  }
+  #child8 {
+    background: green;
+    --my-custom-prop: 400px;
+    --my-custom-prop2: var(--my-custom-prop);
+    --my-custom-prop: var(--my-custom-prop2);
+    width: var(--my-custom-prop, 300px);
+  }
+
+  #parent9 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child9 {
+    background: green;
+    --my-custom-prop: var(--my-custom-prop2, 400px);
+    --my-custom-prop2: var(--my-custom-prop);
+    width: var(--my-custom-prop2, 300px);
+  }
+
+  #parent10 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child10 {
+    background: green;
+    --my-custom-prop2: calc(var(--my-custom-prop) + 10px);
+    width: var(--my-custom-prop2, 300px);
+  }
+
+  #parent11 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop-unreg2: 100px;
+  }
+  #child11 {
+    background: green;
+    --my-custom-prop-unreg: var(--my-custom-prop2-unreg);
+    --my-custom-prop2-unreg: var(--my-custom-prop-unreg);
+    width: var(--my-custom-prop2-unreg, 300px);
+  }
+
+  #parent12 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop: 100px;
+  }
+  #child12 {
+    background: green;
+    --my-custom-prop: 190px;
+    width: calc(var(--my-custom-prop, 300px) + 5px);
+  }
+  #childchild12 {
+    background: purple;
+    --my-custom-prop: revert;
+    width: var(--my-custom-prop, 300px);
+  }
+
+  #parent13 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop2: 100px;
+  }
+  #child13 {
+    background: green;
+    --my-custom-prop2: 190px;
+    width: var(--my-custom-prop2, 300px);
+  }
+  #childchild13 {
+    background: purple;
+    --my-custom-prop2: revert;
+    width: var(--my-custom-prop2, 300px);
+  }
+
+  #parent14 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop-unreg: 100px;
+  }
+  #child14 {
+    background: green;
+    --my-custom-prop-unreg: 190px;
+    width: calc(var(--my-custom-prop-unreg, 300px) + 5px);
+  }
+  #childchild14 {
+    background: purple;
+    --my-custom-prop-unreg: revert;
+    width: var(--my-custom-prop-unreg, 300px);
+  }
+
+  #parent14-1 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop-unreg: 100px;
+  }
+  #child14-1 {
+    background: green;
+    --my-custom-prop-unreg: 190px;
+    width: calc(var(--my-custom-prop-unreg, 300px) + 5px);
+  }
+  #childchild14-1 {
+    background: purple;
+    --my-custom-prop-unreg: inherit;
+    width: var(--my-custom-prop-unreg, 300px);
+  }
+
+  #parent15 {
+    width: 500px;
+    background: blue;
+    font-size: 16px;
+    --my-custom-prop: calc(1em + 10px);
+    word-spacing: var(--my-custom-prop);
+  }
+  #child15 {
+    font-size: 32px;
+  }
+
+  #parent16 {
+    width: 500px;
+    background: blue;
+    font-size: 16px;
+    --my-custom-prop-unreg: calc(1em + 10px);
+    word-spacing: var(--my-custom-prop-unreg);
+  }
+  #child16 {
+    font-size: 32px;
+  }
+
+  #parent17 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop2: 100px;
+  }
+  #child17 {
+    background: green;
+    width: var(--my-custom-prop2);
+  }
+
+  #parent18 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop-no-initial-value: 100px;
+  }
+  #child18 {
+    background: green;
+    width: var(--my-custom-prop-no-initial-value);
+  }
+
+  #parent19 {
+    width: 500px;
+    background: blue;
+    --my-custom-prop-unreg: 100px;
+  }
+  #child19 {
+    background: green;
+    --my-custom-prop-unreg: inherit;
+    width: var(--my-custom-prop-unreg);
+  }
+</style>
+<div>
+  <p> Specified in parent, inherits=true</p>
+  <div id="parent1"><div id="child1"><p>100px green</p></div> </div>
+  <p> Specified in parent, inherits=false </p>
+  <div id="parent2"><div id="child2"><p>200px green</p></div> </div>
+  <p> Specified in parent, not registered </p>
+  <div id="parent3"><div id="child3"><p>100px green</p></div> </div>
+  <p> Initial </p>
+  <div id="parent4"><div id="child4"><p>200px green</p></div> </div>
+  <p> Unset, inherits=true </p>
+  <div id="parent5"><div id="child5"><p>100px green</p></div> </div>
+  <p> Unset, inherits=false </p>
+  <div id="parent6"><div id="child6"><p>200px green</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>
+  <p> A cycle between an inherits=true and inherits=false property </p>
+  <div id="parent8"><div id="child8"><p>200px green</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>
+  <p> Inheritance should not create a cycle </p>
+  <div id="parent10"><div id="child10"><p>110px green</p></div></div>
+  <p> A cycle between two unregistered properties </p>
+  <div id="parent11"><div id="child11"><p>300px green</p></div> </div>
+
+  <p> Revert, inherits=true </p>
+  <div id="parent12"><div id="child12"><div id="childchild12"><p>190px purple</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>
+  <p> Revert, unregistered </p>
+  <div id="parent14"><div id="child14"><div id="childchild14"><p>purple</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>
+
+  <p> Test that inherited properties do variable substitution before being inherited - registered</p>
+  <div id="parent15"><div id="child15"><p>test</p></div> </div>
+  <p> Test that inherited properties do variable substitution before being inherited - unregistered</p>
+  <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>
+  <p> (unregistered) </p>
+  <div id="parent18"><div id="child18"><p>500px green</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>
+<script>
+
+function test_prop(id, prop, expected) {
+  assert_equals(window.getComputedStyle(document.getElementById(id)).getPropertyValue(prop).trim(), expected);
+}
+
+test(function() {
+  CSS.registerProperty({
+    name: '--my-custom-prop',
+    syntax: '<length>',
+    inherits: true,
+    initialValue: '200px'
+  })
+
+  CSS.registerProperty({
+    name: '--my-custom-prop2',
+    syntax: '<length>',
+    inherits: false,
+    initialValue: '200px'
+  })
+
+  CSS.registerProperty({
+    name: '--my-custom-prop-no-initial-value',
+    syntax: '*',
+    inherits: false
+  })
+}, "Registration is successful");
+test(function() {
+  test_prop('child1', 'width', '100px');
+  test_prop('child1', '--my-custom-prop', '100px');
+  test_prop('child1', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 1");
+test(function() {
+  test_prop('child2', 'width', '200px');
+  test_prop('child2', '--my-custom-prop', '200px');
+  test_prop('child2', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 2");
+test(function() {
+  test_prop('child3', 'width', '100px');
+  test_prop('child3', '--my-custom-prop3', '100px');
+  test_prop('child3', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 3");
+test(function() {
+  test_prop('child4', 'width', '200px');
+  test_prop('child4', '--my-custom-prop', '200px');
+  test_prop('child4', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 4");
+test(function() {
+  test_prop('child5', 'width', '100px');
+  test_prop('child5', '--my-custom-prop', '100px');
+  test_prop('child5', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 5");
+test(function() {
+  test_prop('child6', 'width', '200px');
+  test_prop('child6', '--my-custom-prop', '200px');
+  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');
+}, "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');
+}, "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');
+}, "JS Attributes are valid for element 9");
+test(function() {
+  test_prop('child10', 'width', '110px');
+  test_prop('child10', '--my-custom-prop', '100px');
+  test_prop('child10', '--my-custom-prop2', '110px');
+}, "JS Attributes are valid for element 10");
+test(function() {
+  test_prop('child11', 'width', '300px');
+  test_prop('child11', '--my-custom-prop-unreg', '');
+  test_prop('child11', '--my-custom-prop2-unreg', '');
+}, "JS Attributes are valid for element 11");
+
+test(function() {
+  test_prop('childchild12', 'width', '190px');
+  test_prop('childchild12', '--my-custom-prop', '190px');
+  test_prop('child12', 'width', '195px');
+  test_prop('child12', '--my-custom-prop', '190px');
+  test_prop('parent12', '--my-custom-prop', '100px');
+}, "JS Attributes are valid for element 12");
+test(function() {
+  test_prop('childchild13', 'width', '200px');
+  test_prop('childchild13', '--my-custom-prop2', '200px');
+  test_prop('child13', 'width', '190px');
+  test_prop('child13', '--my-custom-prop2', '190px');
+  test_prop('parent13', '--my-custom-prop2', '100px');
+}, "JS Attributes are valid for element 13");
+test(function() {
+  // Chrome and firefox do not pass this because they do not
+  // support revert, as of September 2018
+  test_prop('childchild14', 'width', '190px');
+  test_prop('childchild14', '--my-custom-prop-unreg', '190px');
+  test_prop('child14', 'width', '195px');
+  test_prop('child14', '--my-custom-prop-unreg', '190px');
+  test_prop('parent14', '--my-custom-prop-unreg', '100px');
+}, "JS Attributes are valid for element 14");
+test(function() {
+  test_prop('childchild14-1', 'width', '190px');
+  test_prop('childchild14-1', '--my-custom-prop-unreg', '190px');
+  test_prop('child14-1', 'width', '195px');
+  test_prop('child14-1', '--my-custom-prop-unreg', '190px');
+  test_prop('parent14-1', '--my-custom-prop-unreg', '100px');
+}, "JS Attributes are valid for element 14-1");
+
+test(function() {
+  test_prop('parent15', 'word-spacing', '26px');
+  test_prop('child15', 'word-spacing', '26px');
+  test_prop('parent15', '--my-custom-prop', '26px');
+  test_prop('child15', '--my-custom-prop', '26px');
+}, "JS Attributes are valid for element 15");
+test(function() {
+  test_prop('parent16', 'word-spacing', '26px');
+  test_prop('child16', 'word-spacing', '26px');
+  test_prop('parent16', '--my-custom-prop-unreg', 'calc(1em + 10px)');
+  test_prop('child16', '--my-custom-prop-unreg', 'calc(1em + 10px)');
+}, "JS Attributes are valid for element 16");
+
+test(function() {
+  test_prop('child17', 'width', '200px');
+  test_prop('child17', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 17");
+test(function() {
+  test_prop('child18', 'width', '500px');
+  test_prop('child18', '--my-custom-prop-no-initial-value', '');
+}, "JS Attributes are valid for element 18");
+
+test(function() {
+  test_prop('child19', 'width', '100px');
+  test_prop('child19', '--my-custom-prop-unreg', '100px');
+}, "JS Attributes are valid for element 19");
+</script>
diff --git a/LayoutTests/css-custom-properties-api/length-expected.txt b/LayoutTests/css-custom-properties-api/length-expected.txt
new file mode 100644 (file)
index 0000000..d6d106b
--- /dev/null
@@ -0,0 +1,30 @@
+Test calc + inherits, registered, inherits=true
+
+170px green
+
+Test calc + inherits, registered, inherits=false
+
+200px green
+
+Test calc + inherits, not registered
+
+330px green
+
+Calc test with unregistered property
+
+Calc test with registered property
+
+Calc test with registered property
+
+Substitution test
+
+
+PASS Registration is successful 
+PASS JS Attributes are valid for element 1 
+PASS JS Attributes are valid for element 2 
+PASS JS Attributes are valid for element 3 
+PASS Test that calc is not substituted for unregistered property 
+PASS Test that calc is substituted for custom property with length syntax 
+PASS Test that calc is substituted for custom property with length syntax 
+PASS Test that variables are substituted from JS 
+
diff --git a/LayoutTests/css-custom-properties-api/length.html b/LayoutTests/css-custom-properties-api/length.html
new file mode 100644 (file)
index 0000000..4549eea
--- /dev/null
@@ -0,0 +1,117 @@
+<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSCustomPropertiesAndValuesEnabled=true ] -->
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+
+<style>
+  #parent1 {
+    width: 500px;
+    background: blue;
+    font-size: 16px;
+    --my-custom-prop: calc(10em + 10px);
+  }
+  #child1 {
+    background: green;
+    font-size: 32px;
+    width: var(--my-custom-prop);
+  }
+
+  #parent2 {
+    width: 500px;
+    background: blue;
+    font-size: 16px;
+    --my-custom-prop2: calc(10em + 10px);
+  }
+  #child2 {
+    background: green;
+    font-size: 32px;
+    width: var(--my-custom-prop2);
+  }
+
+  #parent3 {
+    width: 500px;
+    background: blue;
+    font-size: 16px;
+    --my-custom-prop-unreg: calc(10em + 10px);
+  }
+  #child3 {
+    background: green;
+    font-size: 32px;
+    width: var(--my-custom-prop-unreg);
+  }
+
+  #calcTest {
+    --my-custom-prop-unreg: calc(var(--my-custom-prop) + 10px);
+  }
+  #calcTest2 {
+    --my-custom-prop2: calc(var(--my-custom-prop) + 10px);
+  }
+  #calcTest3 {
+    --my-custom-prop2: calc(100px + 10px);
+  }
+
+  #subTest {
+    --my-custom-prop-unreg: var(--my-custom-prop);
+  }
+</style>
+<div>
+  <p> Test calc + inherits, registered, inherits=true</p>
+  <div id="parent1"><div id="child1"><p>170px green</p></div> </div>
+  <p> Test calc + inherits, registered, inherits=false </p>
+  <div id="parent2"><div id="child2"><p>200px green</p></div> </div>
+  <p> Test calc + inherits, not registered </p>
+  <div id="parent3"><div id="child3"><p>330px green</p></div> </div>
+  <div id="calcTest"><p>Calc test with unregistered property</p></div>
+  <div id="calcTest2"><p>Calc test with registered property</p></div>
+  <div id="calcTest3"><p>Calc test with registered property</p></div>
+  <div id="subTest"><p>Substitution test</p></div>
+</div>
+<script>
+
+function test_prop(id, prop, expected) {
+  assert_equals(window.getComputedStyle(document.getElementById(id)).getPropertyValue(prop).trim(), expected);
+}
+
+test(function() {
+  CSS.registerProperty({
+    name: '--my-custom-prop',
+    syntax: '<length>',
+    inherits: true,
+    initialValue: '200px'
+  })
+
+  CSS.registerProperty({
+    name: '--my-custom-prop2',
+    syntax: '<length>',
+    inherits: false,
+    initialValue: '200px'
+  })
+}, "Registration is successful");
+test(function() {
+  test_prop('parent1', '--my-custom-prop', '170px');
+  test_prop('child1', '--my-custom-prop', '170px');
+  test_prop('child1', 'width', '170px');
+  test_prop('child1', '--my-custom-prop2', '200px');
+}, "JS Attributes are valid for element 1");
+test(function() {
+  test_prop('parent2', '--my-custom-prop2', '170px');
+  test_prop('child2', '--my-custom-prop2', '200px');
+  test_prop('child2', 'width', '200px');
+}, "JS Attributes are valid for element 2");
+test(function() {
+  test_prop('parent3', '--my-custom-prop-unreg', 'calc(10em + 10px)');
+  test_prop('child3', '--my-custom-prop-unreg', 'calc(10em + 10px)');
+  test_prop('child3', 'width', '330px');
+}, "JS Attributes are valid for element 3");
+test(function() {
+  test_prop('calcTest', '--my-custom-prop-unreg', 'calc(200px + 10px)');
+}, "Test that calc is not substituted for unregistered property");
+test(function() {
+  test_prop('calcTest2', '--my-custom-prop2', '210px');
+}, "Test that calc is substituted for custom property with length syntax");
+test(function() {
+  test_prop('calcTest3', '--my-custom-prop2', '110px');
+}, "Test that calc is substituted for custom property with length syntax");
+test(function() {
+  test_prop('subTest', '--my-custom-prop-unreg', '200px');
+}, "Test that variables are substituted from JS");
+</script>
diff --git a/LayoutTests/css-custom-properties-api/length2-expected.txt b/LayoutTests/css-custom-properties-api/length2-expected.txt
new file mode 100644 (file)
index 0000000..5f150e5
--- /dev/null
@@ -0,0 +1,12 @@
+test
+
+test
+
+test
+
+
+PASS Registration is successful 
+PASS Test 1 
+PASS Test 2 
+PASS Test 3 
+
diff --git a/LayoutTests/css-custom-properties-api/length2.html b/LayoutTests/css-custom-properties-api/length2.html
new file mode 100644 (file)
index 0000000..7b7e880
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSCustomPropertiesAndValuesEnabled=true ] -->
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+
+<style>
+  #test1 {
+    font-size: 10px;
+    --my-custom-prop: 10em;
+    width: var(--my-custom-prop);
+  }
+  #test2 {
+    font-size: 10px;
+    --my-custom-prop: 10ex;
+    width: var(--my-custom-prop);
+  }
+  #test3 {
+    --my-custom-prop: 10px;
+    font-size: calc(var(--my-custom-prop) + 10px);
+    width: calc(var(--my-custom-prop) + 10em);
+  }
+</style>
+<div>
+  <div id="test1"><p>test</p></div>
+  <div id="test2"><p>test</p></div>
+  <div id="test3"><p>test</p></div>
+</div>
+<script>
+
+function test_prop(id, prop, expected) {
+  assert_equals(window.getComputedStyle(document.getElementById(id)).getPropertyValue(prop).trim(), expected);
+}
+
+test(function() {
+  CSS.registerProperty({
+    name: '--my-custom-prop',
+    syntax: '<length>',
+    inherits: true,
+    initialValue: '0px'
+  })
+}, "Registration is successful");
+test(function() {
+  test_prop('test1', '--my-custom-prop', '100px');
+  test_prop('test1', 'width', '100px');
+}, "Test 1");
+test(function() {
+  const floatA = parseFloat(window.getComputedStyle(document.getElementById('test2')).getPropertyValue('--my-custom-prop').trim().replace(/px/gi, ''));
+  const floatB = parseFloat(window.getComputedStyle(document.getElementById('test2')).getPropertyValue('width').trim().replace(/px/gi, ''));
+  assert_true(Math.abs(floatA - 44.8) < 0.1);
+  assert_true(Math.abs(floatB - 44.8) < 0.1);
+}, "Test 2");
+test(function() {
+  test_prop('test3', '--my-custom-prop', '10px');
+  test_prop('test3', 'font-size', '20px');
+  test_prop('test3', 'width', '210px');
+}, "Test 3");
+</script>
index 5e3ac5d..fc7d308 100644 (file)
@@ -1,3 +1,19 @@
+2018-10-03  Justin Michaud  <justin_michaud@apple.com>
+
+        Registered custom properties should allow inheritance to be controlled
+        https://bugs.webkit.org/show_bug.cgi?id=190038
+
+        Reviewed by Antti Koivisto.
+
+        Update web platform tests for css registered custom properties to fail in a different way.
+
+        * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/url-resolution-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt:
+
 2018-10-03  Youenn Fablet  <youenn@apple.com>
 
         Add VP8 support to WebRTC
index 4d90f1f..e19223e 100644 (file)
@@ -1,4 +1,4 @@
 
 FAIL Registering a property does not affect cascade inner.computedStyleMap is not a function. (In 'inner.computedStyleMap()', 'inner.computedStyleMap' is undefined)
-FAIL Registering a property does not affect parsing element.computedStyleMap is not a function. (In 'element.computedStyleMap()', 'element.computedStyleMap' is undefined)
+FAIL Registering a property does not affect parsing The given initial value does not parse for the given syntax.
 
index db56ca8..1e728fd 100644 (file)
@@ -1,75 +1,75 @@
 
-PASS syntax:'*', initialValue:'a' is valid 
-PASS syntax:' * ', initialValue:'b' is valid 
+FAIL syntax:'*', initialValue:'a' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:' * ', initialValue:'b' is valid The given initial value does not parse for the given syntax.
 PASS syntax:'<length>', initialValue:'2px' is valid 
-PASS syntax:' <number>', initialValue:'5' 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 
-PASS syntax:'<color>+', initialValue:'red' is valid 
-PASS syntax:' <length>+ | <percentage>', initialValue:'2px 8px' is valid 
+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 
-PASS syntax:'<color> | <image> | <url> | <integer> | <angle>', initialValue:'red' is valid 
-PASS syntax:'<time> | <resolution> | <transform-list> | <custom-ident>', initialValue:'red' is valid 
-PASS syntax:'*', initialValue:':> hello' is valid 
-PASS syntax:'*', initialValue:'([ brackets ]) { yay (??)}' is valid 
-PASS syntax:'*', initialValue:'yep 'this is valid too'' is valid 
-PASS syntax:'*', initialValue:'unmatched opening bracket is valid :(' is valid 
-PASS syntax:'*', initialValue:'"' is valid 
+FAIL syntax:'<color> | <image> | <url> | <integer> | <angle>', initialValue:'red' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<time> | <resolution> | <transform-list> | <custom-ident>', initialValue:'red' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'*', initialValue:':> hello' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'*', initialValue:'([ brackets ]) { yay (??)}' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'*', initialValue:'yep 'this is valid too'' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'*', initialValue:'unmatched opening bracket is valid :(' is valid The given initial value must be computationally independent.
+FAIL syntax:'*', initialValue:'"' is valid The given initial value does not parse for the given syntax.
 PASS syntax:'<length>', initialValue:'0' is valid 
 PASS syntax:'<length>', initialValue:'10px /*:)*/' is valid 
 PASS syntax:'<length>', initialValue:' calc(-2px)' is valid 
 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 
-PASS syntax:'<length>+', initialValue:'2px 7px calc(8px)' is valid 
-PASS syntax:'<percentage>', initialValue:'-9.3e3%' is valid 
-PASS syntax:'<length-percentage>', initialValue:'-54%' 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:'<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 
-PASS syntax:'<number>', initialValue:'-109' is valid 
-PASS syntax:'<number>', initialValue:'2.3e4' is valid 
-PASS syntax:'<integer>', initialValue:'-109' is valid 
-PASS syntax:'<integer>', initialValue:'19' is valid 
-PASS syntax:'<angle>', initialValue:'10deg' is valid 
-PASS syntax:'<angle>', initialValue:'20.5rad' is valid 
-PASS syntax:'<angle>', initialValue:'calc(50grad + 3.14159rad)' is valid 
-PASS syntax:'<time>', initialValue:'2s' is valid 
-PASS syntax:'<time>', initialValue:'calc(2s - 9ms)' is valid 
-PASS syntax:'<resolution>', initialValue:'10dpi' is valid 
-PASS syntax:'<resolution>', initialValue:'3dPpX' is valid 
-PASS syntax:'<resolution>', initialValue:'-5.3dpcm' is valid 
-PASS syntax:'<transform-function>', initialValue:'translateX(2px)' is valid 
-PASS syntax:'<transform-function>|<integer>', initialValue:'5' is valid 
-PASS syntax:'<transform-function>|<integer>', initialValue:'scale(2)' is valid 
-PASS syntax:'<transform-function>+', initialValue:'translateX(2px) rotate(42deg)' is valid 
-PASS syntax:'<transform-list>', initialValue:'scale(2)' is valid 
-PASS syntax:'<transform-list>', initialValue:'translateX(2px) rotate(20deg)' is valid 
-PASS syntax:'<color>', initialValue:'rgb(12, 34, 56)' is valid 
-PASS syntax:'<color>', initialValue:'lightgoldenrodyellow' is valid 
-PASS syntax:'<image>', initialValue:'url(a)' is valid 
-PASS syntax:'<image>', initialValue:'linear-gradient(yellow, blue)' is valid 
-PASS syntax:'<url>', initialValue:'url(a)' is valid 
-PASS syntax:'banana', initialValue:'banana' is valid 
-PASS syntax:'bAnAnA', initialValue:'bAnAnA' is valid 
-PASS syntax:'ba-na-nya', initialValue:'ba-na-nya' is valid 
-PASS syntax:'banana', initialValue:'banan\61' is valid 
-PASS syntax:'<custom-ident>', initialValue:'banan\61' is valid 
-PASS syntax:'big | bigger | BIGGER', initialValue:'bigger' is valid 
-PASS syntax:'foo+|bar', initialValue:'foo foo foo' is valid 
-PASS syntax:'default', initialValue:'default' is valid 
-PASS syntax:'banana    ', initialValue:'banana' is valid 
-PASS 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:'<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.
+FAIL syntax:'<time>', initialValue:'2s' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<time>', initialValue:'calc(2s - 9ms)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<resolution>', initialValue:'10dpi' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<resolution>', initialValue:'3dPpX' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<resolution>', initialValue:'-5.3dpcm' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<transform-function>', initialValue:'translateX(2px)' is valid The given initial value must be computationally independent.
+FAIL syntax:'<transform-function>|<integer>', initialValue:'5' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<transform-function>|<integer>', initialValue:'scale(2)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<transform-function>+', initialValue:'translateX(2px) rotate(42deg)' is valid The given initial value must be computationally independent.
+FAIL syntax:'<transform-list>', initialValue:'scale(2)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<transform-list>', initialValue:'translateX(2px) rotate(20deg)' is valid The given initial value must be computationally independent.
+FAIL syntax:'<color>', initialValue:'rgb(12, 34, 56)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<color>', initialValue:'lightgoldenrodyellow' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<image>', initialValue:'url(a)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<image>', initialValue:'linear-gradient(yellow, blue)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<url>', initialValue:'url(a)' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'banana', initialValue:'banana' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'bAnAnA', initialValue:'bAnAnA' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'ba-na-nya', initialValue:'ba-na-nya' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'banana', initialValue:'banan\61' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'<custom-ident>', initialValue:'banan\61' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'big | bigger | BIGGER', initialValue:'bigger' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'foo+|bar', initialValue:'foo foo foo' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'default', initialValue:'default' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'banana    ', initialValue:'banana' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'
 banana\r
-', initialValue:'banana' is valid 
-PASS syntax:'ba\f
-|      na\r|nya', initialValue:'nya' is valid 
-PASS syntax:'null', initialValue:'null' is valid 
-PASS syntax:'undefined', initialValue:'undefined' is valid 
-PASS syntax:'array', initialValue:'array' is valid 
-FAIL syntax:'banana,nya', initialValue:'banana' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'banan\61', initialValue:'banana' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+', initialValue:'banana' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'ba\f
+|      na\r|nya', initialValue:'nya' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'null', initialValue:'null' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'undefined', initialValue:'undefined' is valid The given initial value does not parse for the given syntax.
+FAIL syntax:'array', initialValue:'array' is valid The given initial value does not parse for the given syntax.
+PASS syntax:'banana,nya', initialValue:'banana' is invalid 
+PASS syntax:'banan\61', initialValue:'banana' is invalid 
 FAIL syntax:'<\6c ength>', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<banana>', initialValue:'banana' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<Number>', initialValue:'10' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+PASS syntax:'<banana>', initialValue:'banana' is invalid 
+PASS syntax:'<Number>', initialValue:'10' is invalid 
 FAIL syntax:'<length', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
 FAIL syntax:'<LENGTH>', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
 FAIL syntax:'< length>', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
@@ -77,56 +77,56 @@ FAIL syntax:'<length >', initialValue:'10px' is invalid assert_throws: function
 FAIL syntax:'<length> +', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
 FAIL syntax:'<length>++', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
 FAIL syntax:'<length> | *', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*|banana', initialValue:'banana' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*+', initialValue:'banana' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'initial', initialValue:'initial' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'inherit', initialValue:'inherit' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'unset', initialValue:'unset' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+PASS syntax:'*|banana', initialValue:'banana' is invalid 
+PASS syntax:'*+', initialValue:'banana' is invalid 
+PASS syntax:'initial', initialValue:'initial' is invalid 
+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
-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
-FAIL syntax:'*', initialValue:'revert' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<custom-ident>', initialValue:'initial' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<custom-ident>+', initialValue:'foo inherit bar' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:')' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'([)]' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'whee!' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'"
-' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'url(moo '')' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'semi;colon' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'var(invalid var ref)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'*', initialValue:'var(--foo)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'banana', initialValue:'bAnAnA' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<length>', initialValue:'var(--moo)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<length>', initialValue:'10' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+PASS syntax:'*', initialValue:'initial' is invalid 
+PASS syntax:'*', initialValue:'inherit' is invalid 
+PASS syntax:'*', initialValue:'unset' is invalid 
+PASS syntax:'*', initialValue:'revert' is invalid 
+PASS syntax:'<custom-ident>', initialValue:'initial' is invalid 
+PASS syntax:'<custom-ident>+', initialValue:'foo inherit bar' is invalid 
+PASS syntax:'*', initialValue:')' is invalid 
+PASS syntax:'*', initialValue:'([)]' is invalid 
+PASS syntax:'*', initialValue:'whee!' is invalid 
+PASS syntax:'*', initialValue:'"
+' is invalid 
+PASS syntax:'*', initialValue:'url(moo '')' is invalid 
+PASS syntax:'*', initialValue:'semi;colon' is invalid 
+PASS syntax:'*', initialValue:'var(invalid var ref)' is invalid 
+PASS syntax:'*', initialValue:'var(--foo)' is invalid 
+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
-FAIL syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-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:'calc(5px * 3px / 6px)' is invalid 
+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
-FAIL syntax:'<length>+', initialValue:'10px calc(20px + 4rem)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<length>', initialValue:'10px;' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-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>', 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 
+PASS syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid 
+PASS syntax:'<length>', initialValue:'10px;' is invalid 
+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
-FAIL syntax:'<integer>', initialValue:'1.0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<integer>', initialValue:'1e0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<number>|foo', initialValue:'foo var(--foo, bla)' 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
 FAIL syntax:'<time>', initialValue:'2px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<resolution>', initialValue:'10' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<transform-function>', initialValue:'scale()' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<transform-list>', initialValue:'scale()' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<transform-list>+', initialValue:'translateX(2px) rotate(20deg)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<color>', initialValue:'fancy-looking' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<image>', initialValue:'banana.png' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<url>', initialValue:'banana.png' 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 
+PASS syntax:'<transform-list>', initialValue:'scale()' is invalid 
+PASS syntax:'<transform-list>+', initialValue:'translateX(2px) rotate(20deg)' is invalid 
+PASS syntax:'<color>', initialValue:'fancy-looking' is invalid 
+PASS syntax:'<image>', initialValue:'banana.png' is invalid 
+PASS syntax:'<url>', initialValue:'banana.png' is invalid 
 
index ab06e12..fc27b0d 100644 (file)
@@ -1,7 +1,7 @@
 
-FAIL Registered properties are correctly inherited (or not) depending on the inherits flag. assert_equals: expected "10px" but got " 10px"
-FAIL Explicitly inheriting from a parent with an invalid value results in initial value. assert_equals: expected "0px" but got " notalength"
-FAIL Explicitly inheriting from a parent with no value results in initial value. assert_equals: expected "0px" but got ""
-FAIL Reference to undefined variable results in inherited value assert_equals: expected "42px" but got ""
-FAIL Reference to syntax-incompatible variable results in inherited value assert_equals: expected "42px" but got "  nolength"
+PASS Registered properties are correctly inherited (or not) depending on the inherits flag. 
+PASS Explicitly inheriting from a parent with an invalid value results in initial value. 
+PASS Explicitly inheriting from a parent with no value results in initial value. 
+FAIL Reference to undefined variable results in inherited value assert_equals: expected "42px" but got "0px"
+FAIL Reference to syntax-incompatible variable results in inherited value assert_equals: expected "42px" but got "0px"
 
index c918c4d..b74a18e 100644 (file)
@@ -1,17 +1,17 @@
 
-PASS CSS.registerProperty 
-FAIL <length> values are computed correctly for divWithFontSizeSet assert_equals: expected "12px" but got " 12px"
-FAIL <length-percentage> values are computed correctly for divWithFontSizeSet assert_equals: expected "170px" but got " 17em"
-FAIL <length># values are computed correctly for divWithFontSizeSet assert_equals: expected "10px, 30px" but got " 10px, 3em"
-FAIL <length-percentage># values are computed correctly for divWithFontSizeSet assert_equals: expected "3%, 80px, 22px" but got " 3% , 10vmax , 22px"
-FAIL <length>+ values are computed correctly for divWithFontSizeSet assert_equals: expected "10px 30px" but got " 10px 3em"
-FAIL <length-percentage>+ values are computed correctly for divWithFontSizeSet assert_equals: expected "3% 80px 22px" but got " 3% 10vmax 22px"
+FAIL CSS.registerProperty The given initial value must be computationally independent.
+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)"
-FAIL <length> values are computed correctly for divWithFontSizeInherited assert_equals: expected "12px" but got " 12px"
-FAIL <length-percentage> values are computed correctly for divWithFontSizeInherited assert_equals: expected "170px" but got " 17em"
-FAIL <length># values are computed correctly for divWithFontSizeInherited assert_equals: expected "10px, 30px" but got " 10px, 3em"
-FAIL <length-percentage># values are computed correctly for divWithFontSizeInherited assert_equals: expected "3%, 80px, 22px" but got " 3% , 10vmax , 22px"
-FAIL <length>+ values are computed correctly for divWithFontSizeInherited assert_equals: expected "10px 30px" but got " 10px 3em"
-FAIL <length-percentage>+ values are computed correctly for divWithFontSizeInherited assert_equals: expected "3% 80px 22px" but got " 3% 10vmax 22px"
+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)"
 
index b009c68..0d5561f 100644 (file)
@@ -1,9 +1,9 @@
 
 PASS CSSOM setters function as expected for unregistered properties 
-PASS CSS.registerProperty 
-FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "0px" but got "5"
+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 Values not matching the registered type can't be set assert_equals: expected "5" but got "hi"
-FAIL Values can be removed from inline styles assert_equals: expected "10px" but got " 10px"
-FAIL Stylesheets can be modified by CSSOM assert_equals: expected "10px" but got "banana"
+FAIL Values can be removed from inline styles assert_equals: expected "red" but got " red"
+FAIL Stylesheets can be modified by CSSOM assert_equals: expected "10px" but got "0px"
 FAIL Valid values can be set on inline styles assert_equals: expected "blue" but got " blue"
 
index 99e4461..86c5a11 100644 (file)
@@ -1,3 +1,3 @@
 
-FAIL Initial values of registered properties can be referenced when no custom properties are explicitly set. assert_equals: expected "25px" but got "calc(10px + 15px)"
+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.
 
index 1213922..1e4d270 100644 (file)
@@ -2,26 +2,26 @@ CONSOLE MESSAGE: line 340: ReferenceError: Can't find variable: CSSUnparsedValue
 
 Harness Error (FAIL), message = ReferenceError: Can't find variable: CSSUnparsedValue
 
-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 Can't find variable: CSSUnitValue
-FAIL Computed <color> is reified as CSSStyleValue Can't find variable: CSSStyleValue
-FAIL Computed <custom-ident> is reified as CSSKeywordValue Can't find variable: CSSKeywordValue
-FAIL Computed <image> [url] is reified as CSSImageValue Can't find variable: CSSImageValue
-FAIL Computed <integer> is reified as CSSUnitValue Can't find variable: CSSUnitValue
+FAIL Computed * is reified as CSSUnparsedValue The given initial value does not parse for the given syntax.
+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 Can't find variable: CSSUnitValue
 FAIL Computed <length-percentage> [px] is reified as CSSUnitValue Can't find variable: CSSUnitValue
 FAIL Computed <length-percentage> [px + %] is reified as CSSMathSum Can't find variable: CSSMathSum
 FAIL Computed <length> is reified as CSSUnitValue Can't find variable: CSSUnitValue
-FAIL Computed <number> is reified as CSSUnitValue Can't find variable: CSSUnitValue
+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 Can't find variable: CSSUnitValue
-FAIL Computed <resolution> is reified as CSSUnitValue Can't find variable: CSSUnitValue
-FAIL Computed <time> is reified as CSSUnitValue Can't find variable: CSSUnitValue
-FAIL Computed <url> is reified as CSSStyleValue Can't find variable: CSSStyleValue
-FAIL Computed ident is reified as CSSKeywordValue Can't find variable: CSSKeywordValue
-FAIL First computed value correctly reified in space-separated list Can't find variable: CSSUnitValue
-FAIL First computed value correctly reified in comma-separated list Can't find variable: CSSUnitValue
-FAIL All computed values correctly reified in space-separated list target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined)
-FAIL All computed values correctly reified in comma-separated list 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')
index b3525dc..6d5601b 100644 (file)
@@ -1,20 +1,6 @@
+CONSOLE MESSAGE: line 2: SyntaxError: The given initial value does not parse for the given syntax.
+CONSOLE MESSAGE: line 2: SyntaxError: The given initial value does not parse for the given syntax.
+CONSOLE MESSAGE: line 1401: Error: Tried to create a test with file_is_test
 
-PASS Unregistered property resolves against document (URL token) 
-PASS Unregistered property resolves against document (URL function) 
-FAIL Registered non-inherited <url> resolves against sheet (URL token) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered non-inherited <url> resolves against sheet (URL function) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered inherited <url> resolves against sheet (URL token) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered inherited <url> resolves against sheet (URL function) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered inherited <url> resolves against sheet (Child node, URL token) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered inherited <url> resolves against sheet (Child node, URL function) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered property with unregistered var reference resolves against sheet (URL token) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered property with unregistered var reference resolves against sheet. (URL function) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered property with registered var reference resolves against sheet of referenced property (URL token) assert_equals: expected "/css/css-properties-values-api/support/alt" but got "/css/css-properties-values-api"
-FAIL Registered property with registered var reference resolves against sheet of referenced property (URL function) assert_equals: expected "/css/css-properties-values-api/support/alt" but got "/css/css-properties-values-api"
-FAIL Unregistered property with registered var reference resolves against sheet of referenced property (URL token) assert_equals: expected "/css/css-properties-values-api/support/alt" but got "/css/css-properties-values-api"
-FAIL Unregistered property with registered var reference resolves against sheet of referenced property (URL function) assert_equals: expected "/css/css-properties-values-api/support/alt" but got "/css/css-properties-values-api"
-FAIL Multiple (registered) var reference resolve against respective sheets (URL token) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Multiple (registered) var reference resolve against respective sheets (URL function) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered UTF16BE-encoded var reference resolve against sheet (URL token) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
-FAIL Registered UTF16BE-encoded var reference resolve against sheet (URL function) assert_equals: expected "/css/css-properties-values-api/support/main" but got "/css/css-properties-values-api"
+FAIL Untitled SyntaxError: The given initial value does not parse for the given syntax.
 
index a0d5c7b..2bedf68 100644 (file)
@@ -1,6 +1,6 @@
 
-FAIL A var() cycle between two registered properties is handled correctly. assert_equals: expected "1px" but got ""
-FAIL A var() cycle between a registered properties and an unregistered property is handled correctly. assert_equals: expected "1px" but got ""
-FAIL A var() cycle between a two unregistered properties is handled correctly. assert_equals: expected "30px" but got ""
-FAIL A var() cycle between a syntax:'*' property and an unregistered property is handled correctly. assert_equals: expected "meow" but got ""
+FAIL A var() cycle between two registered properties is handled correctly. assert_equals: expected "2px" but got "3px"
+FAIL A var() cycle between a registered properties and an unregistered property is handled correctly. assert_equals: expected "1px" but got "2px"
+PASS A var() cycle between a two unregistered properties is handled correctly. 
+FAIL A var() cycle between a syntax:'*' property and an unregistered property is handled correctly. The given initial value does not parse for the given syntax.
 
index 9c17c4e..db535e4 100644 (file)
@@ -1,6 +1,6 @@
 
-FAIL var() references work with registered properties assert_equals: expected "10px" but got " 10px"
-FAIL References to registered var()-properties work in registered lists assert_equals: expected "1px, 10px, 2px" but got " 1px,  10px, 2px"
-FAIL References to mixed registered and unregistered var()-properties work in registered lists assert_equals: expected "1px, 20px, 10px, 2px" but got " 1px,  20px,  10px, 2px"
-FAIL Registered lists may be concatenated assert_equals: expected "1px, 10px, 2px, 1px, 20px, 10px, 2px" but got "  1px,  10px, 2px,  1px,  20px,  10px, 2px"
+FAIL var() references work with registered properties assert_equals: expected "15px" but got "10%"
+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"
 
index 8f841d6..bb37f55 100644 (file)
@@ -1,3 +1,114 @@
+2018-10-03  Justin Michaud  <justin_michaud@apple.com>
+
+        Registered custom properties should allow inheritance to be controlled
+        https://bugs.webkit.org/show_bug.cgi?id=190038
+
+        Reviewed by Antti Koivisto.
+
+        Tests: css-custom-properties-api/inherits.html
+               css-custom-properties-api/length.html
+               css-custom-properties-api/length2.html
+
+        Add support for inherits property on registered css custom properties, as well
+        as a starting point for evaluating registered custom properties with types. Registered
+        custom properties are evaluated as length values before being substituted. Currently,
+        relative unit cycles are not detected.
+
+        A proper solution is still needed to resolve relative unit cycles, and to apply properties like font
+        and line-height before they are needed by custom properties. In this patch, the font-size property is
+        applied twice, once before and once after resolving custom property values.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::customPropertyValue):
+        (WebCore::CSSComputedStyleDeclaration::length const):
+        (WebCore::CSSComputedStyleDeclaration::item const):
+
+        Allow JS to get custom properties that have been resolved to a length. Also add properties from
+        m_rareNonInheritedData.
+
+        * css/CSSCustomPropertyValue.cpp:
+        (WebCore::CSSCustomPropertyValue::checkVariablesForCycles const):
+        (WebCore::CSSCustomPropertyValue::resolveVariableReferences const):
+        * css/CSSCustomPropertyValue.h:
+        * css/CSSRegisteredCustomProperty.cpp: Copied from Source/WebCore/css/CSSRegisteredCustomProperty.h.
+        (WebCore::CSSRegisteredCustomProperty::CSSRegisteredCustomProperty):
+        (WebCore::CSSRegisteredCustomProperty::initialValueCopy const):
+        * css/CSSRegisteredCustomProperty.h:
+        (WebCore::CSSRegisteredCustomProperty::initialValue const):
+        * css/CSSVariableData.cpp:
+        (WebCore::CSSVariableData::checkVariablesForCycles const):
+        (WebCore::CSSVariableData::checkVariablesForCyclesWithRange const):
+        (WebCore::CSSVariableData::resolveVariableFallback const):
+        (WebCore::CSSVariableData::resolveVariableReference const):
+        (WebCore::CSSVariableData::resolveVariableReferences const):
+        (WebCore::CSSVariableData::resolveTokenRange const):
+        * css/CSSVariableData.h:
+        * css/CSSVariableReferenceValue.cpp:
+        (WebCore::CSSVariableReferenceValue::checkVariablesForCycles const):
+        * css/CSSVariableReferenceValue.h:
+        * css/DOMCSSRegisterCustomProperty.cpp:
+        (WebCore::DOMCSSRegisterCustomProperty::registerProperty):
+
+        Use RenderStyle over passing in a customProperties map.
+
+        * css/StyleBuilder.h:
+        * css/StyleBuilderConverter.h:
+        (WebCore::StyleBuilderConverter::convertLength):
+        (WebCore::StyleBuilderConverter::convertLengthOrAuto):
+        (WebCore::StyleBuilderConverter::convertLengthSizing):
+        (WebCore::StyleBuilderConverter::convertLengthMaxSizing):
+        * css/StyleBuilderCustom.h:
+        (WebCore::StyleBuilderCustom::applyInitialCustomProperty):
+        (WebCore::StyleBuilderCustom::applyInheritCustomProperty):
+        (WebCore::StyleBuilderCustom::applyValueCustomProperty):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::useSVGZoomRules const):
+        (WebCore::StyleResolver::useSVGZoomRulesForLength const):
+        (WebCore::StyleResolver::applyProperty):
+        (WebCore::StyleResolver::resolvedVariableValue const):
+        (WebCore::StyleResolver::applyCascadedProperties):
+        (WebCore::StyleResolver::useSVGZoomRules): Deleted.
+        (WebCore::StyleResolver::useSVGZoomRulesForLength): Deleted.
+        (WebCore::StyleResolver::resolvedVariableValue): Deleted.
+        * css/StyleResolver.h:
+        * css/makeprop.pl:
+
+        Move custom property initial values to StyleBuilerCustom. Hook them up to correctly deal with
+        inheritance, unset and revert values.
+
+        * css/parser/CSSParser.cpp:
+        (WebCore::CSSParser::parseValueWithVariableReferences):
+        * css/parser/CSSParser.h:
+        * css/parser/CSSParserContext.cpp:
+        (WebCore::CSSParserContext::CSSParserContext):
+        * css/parser/CSSParserContext.h:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::CSSPropertyParser::parseSingleValue):
+
+        Allow parsing custom property values as lengths.
+
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::checkVariablesInCustomProperties):
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::inheritedCustomProperties const):
+        (WebCore::RenderStyle::nonInheritedCustomProperties const):
+        (WebCore::RenderStyle::setInheritedCustomPropertyValue):
+        (WebCore::RenderStyle::setNonInheritedCustomPropertyValue):
+        (WebCore::RenderStyle::getCustomProperty const):
+        (WebCore::RenderStyle::customProperties const): Deleted.
+        (WebCore::RenderStyle::setCustomPropertyValue): Deleted.
+        * rendering/style/StyleRareNonInheritedData.cpp:
+        (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
+        (WebCore::StyleRareNonInheritedData::operator== const):
+        * rendering/style/StyleRareNonInheritedData.h:
+        * style/StyleResolveForDocument.cpp:
+        (WebCore::Style::resolveForDocument):
+
+        Add support for RenderStyle to deal with both inherited and non-inherited properties, and to find
+        cycles between them.
+
 2018-10-03  Ryosuke Niwa  <rniwa@webkit.org>
 
         Clear m_pendingTargets in MutationObserver::takeRecords
index 91dd246..6f67e57 100644 (file)
@@ -597,6 +597,7 @@ css/CSSPrimitiveValue.cpp
 css/CSSProperty.cpp
 css/CSSPropertySourceData.cpp
 css/CSSReflectValue.cpp
+css/CSSRegisteredCustomProperty.cpp
 css/CSSRevertValue.cpp
 css/CSSRule.cpp
 css/CSSRuleList.cpp
index 9314d08..d724419 100644 (file)
                4AD01007127E642A0015035F /* HTMLOutputElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLOutputElement.idl; sourceTree = "<group>"; };
                4AD0173A127E82860015035F /* JSHTMLOutputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOutputElement.cpp; sourceTree = "<group>"; };
                4AD0173B127E82860015035F /* JSHTMLOutputElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLOutputElement.h; sourceTree = "<group>"; };
+               4B1706642162B42F00E578BB /* CSSRegisteredCustomProperty.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CSSRegisteredCustomProperty.cpp; sourceTree = "<group>"; };
                4B2708C50AF19EE40065127F /* Pasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pasteboard.h; sourceTree = "<group>"; };
                4B2709810AF2E5E00065127F /* PasteboardMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardMac.mm; sourceTree = "<group>"; };
                4B3043CA0AE0373B00A82647 /* Editor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Editor.cpp; sourceTree = "<group>"; };
                                9362640A0DE1137D009D5A00 /* CSSReflectionDirection.h */,
                                BC5A12DD0DC0414800C9AFAD /* CSSReflectValue.cpp */,
                                BC5A12DE0DC0414800C9AFAD /* CSSReflectValue.h */,
+                               4B1706642162B42F00E578BB /* CSSRegisteredCustomProperty.cpp */,
                                4BDA3FFB2151B6F400FD6604 /* CSSRegisteredCustomProperty.h */,
                                BC7D8FF11BD1A47900FFE540 /* CSSRevertValue.cpp */,
                                BC7D8FF21BD1A47900FFE540 /* CSSRevertValue.h */,
index be894bf..5c92c82 100644 (file)
@@ -2585,13 +2585,22 @@ RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& prope
     if (!style)
         return nullptr;
 
-    auto* value = style->customProperties().get(propertyName);
-    if (value)
-        return value;
-
     auto* registered = styledElement->document().getCSSRegisteredCustomPropertySet().get(propertyName);
-    if (registered && registered->initialValue)
-        return registered->initialValue;
+    auto* value = style->getCustomProperty(propertyName);
+
+    if (registered) {
+        // TODO this should be done based on the syntax
+        if (value && value->resolvedTypedValue())
+            return zoomAdjustedPixelValueForLength(*value->resolvedTypedValue(), *style);
+
+        if (registered->initialValue() && registered->initialValue()->resolvedTypedValue())
+            return zoomAdjustedPixelValueForLength(*registered->initialValue()->resolvedTypedValue(), *style);
+
+        return nullptr;
+    }
+
+    if (value)
+        return CSSCustomPropertyValue::create(*value);
 
     return nullptr;
 }
@@ -4087,7 +4096,7 @@ unsigned CSSComputedStyleDeclaration::length() const
     if (!style)
         return 0;
 
-    return numComputedProperties + style->customProperties().size();
+    return numComputedProperties + style->inheritedCustomProperties().size() + style->nonInheritedCustomProperties().size();
 }
 
 String CSSComputedStyleDeclaration::item(unsigned i) const
@@ -4101,15 +4110,17 @@ String CSSComputedStyleDeclaration::item(unsigned i) const
     auto* style = m_element->computedStyle(m_pseudoElementSpecifier);
     if (!style)
         return String();
-    
-    unsigned index = i - numComputedProperties;
-    
-    const auto& customProperties = style->customProperties();
-    if (index >= customProperties.size())
-        return String();
 
-    auto results = copyToVector(customProperties.keys());
-    return results.at(index);
+    const auto& inheritedCustomProperties = style->inheritedCustomProperties();
+
+    if (i < numComputedProperties + inheritedCustomProperties.size()) {
+        auto results = copyToVector(inheritedCustomProperties.keys());
+        return results.at(i - numComputedProperties);
+    }
+
+    const auto& nonInheritedCustomProperties = style->nonInheritedCustomProperties();
+    auto results = copyToVector(nonInheritedCustomProperties.keys());
+    return results.at(i - inheritedCustomProperties.size() - numComputedProperties);
 }
 
 bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSSValue* value)
index 16880ee..3551763 100644 (file)
 
 namespace WebCore {
 
-bool CSSCustomPropertyValue::checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+bool CSSCustomPropertyValue::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
 {
     ASSERT(containsVariables());
     if (m_value)
-        return m_value->checkVariablesForCycles(name, customProperties, seenProperties, invalidProperties);
+        return m_value->checkVariablesForCycles(name, style, seenProperties, invalidProperties);
     return true;
 }
 
-void CSSCustomPropertyValue::resolveVariableReferences(const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet& registeredProperties, Vector<Ref<CSSCustomPropertyValue>>& resolvedValues) const
+void CSSCustomPropertyValue::resolveVariableReferences(const CSSRegisteredCustomPropertySet& registeredProperties, Vector<Ref<CSSCustomPropertyValue>>& resolvedValues, const RenderStyle& style) const
 {
     ASSERT(containsVariables());
     if (!m_value)
         return;
     
     ASSERT(m_value->needsVariableResolution());
-    RefPtr<CSSVariableData> resolvedData = m_value->resolveVariableReferences(customProperties, registeredProperties);
+    RefPtr<CSSVariableData> resolvedData = m_value->resolveVariableReferences(registeredProperties, style);
     if (resolvedData)
         resolvedValues.append(CSSCustomPropertyValue::createWithVariableData(m_name, resolvedData.releaseNonNull()));
     else
index aac11c1..f836184 100644 (file)
@@ -28,6 +28,7 @@
 #include "CSSRegisteredCustomProperty.h"
 #include "CSSValue.h"
 #include "CSSVariableData.h"
+#include "Length.h"
 #include <wtf/RefPtr.h>
 #include <wtf/text/WTFString.h>
 
@@ -49,6 +50,11 @@ public:
     {
         return adoptRef(*new CSSCustomPropertyValue(emptyString(), emptyString()));
     }
+
+    static Ref<CSSCustomPropertyValue> create(const CSSCustomPropertyValue& other)
+    {
+        return adoptRef(*new CSSCustomPropertyValue(other));
+    }
     
     String customCSSText() const
     {
@@ -69,13 +75,16 @@ public:
     bool equals(const CSSCustomPropertyValue& other) const { return m_name == other.m_name && m_value == other.m_value && m_valueId == other.m_valueId; }
 
     bool containsVariables() const { return m_containsVariables; }
-    bool checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+    bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
 
-    void resolveVariableReferences(const CustomPropertyValueMap&, const CSSRegisteredCustomPropertySet&, Vector<Ref<CSSCustomPropertyValue>>&) const;
+    void resolveVariableReferences(const CSSRegisteredCustomPropertySet&, Vector<Ref<CSSCustomPropertyValue>>&, const RenderStyle&) const;
 
     CSSValueID valueID() const { return m_valueId; }
     CSSVariableData* value() const { return m_value.get(); }
 
+    const std::optional<Length>& resolvedTypedValue() const { return m_resolvedTypedValue; }
+    void setResolvedTypedValue(Length length) { m_resolvedTypedValue = WTFMove(length); }
+
 private:
     CSSCustomPropertyValue(const AtomicString& name, const String& serializedValue)
         : CSSValue(CustomPropertyClass)
@@ -101,6 +110,18 @@ private:
         , m_containsVariables(m_value->needsVariableResolution())
     {
     }
+
+    CSSCustomPropertyValue(const CSSCustomPropertyValue& other)
+        : CSSValue(CustomPropertyClass)
+        , m_name(other.m_name)
+        , m_value(other.m_value.copyRef())
+        , m_valueId(other.m_valueId)
+        , m_stringValue(other.m_stringValue)
+        , m_containsVariables(other.m_containsVariables)
+        , m_serialized(other.m_serialized)
+        , m_resolvedTypedValue(other.m_resolvedTypedValue)
+    {
+    }
     
     const AtomicString m_name;
     
@@ -110,6 +131,9 @@ private:
     mutable String m_stringValue;
     bool m_containsVariables { false };
     mutable bool m_serialized { false };
+
+    // FIXME: It should not be possible to express an invalid state, such as containsVariables() && resolvedTypedValue().
+    std::optional<Length> m_resolvedTypedValue;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/CSSRegisteredCustomProperty.cpp b/Source/WebCore/css/CSSRegisteredCustomProperty.cpp
new file mode 100644 (file)
index 0000000..3ea7b92
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSRegisteredCustomProperty.h"
+
+#include "CSSCustomPropertyValue.h"
+
+namespace WebCore {
+
+CSSRegisteredCustomProperty::CSSRegisteredCustomProperty(const String& name, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue)
+    : name(name)
+    , inherits(inherits)
+    , m_initialValue(WTFMove(initialValue))
+{
+}
+
+RefPtr<CSSCustomPropertyValue> CSSRegisteredCustomProperty::initialValueCopy() const
+{
+    if (m_initialValue)
+        return CSSCustomPropertyValue::create(*m_initialValue);
+    return nullptr;
+}
+
+} // namespace WebCore
index b2f9cdb..3427eaa 100644 (file)
@@ -33,8 +33,16 @@ class CSSCustomPropertyValue;
 
 struct CSSRegisteredCustomProperty {
     const String name;
-    /* TODO syntax, inherits */
-    const RefPtr<CSSCustomPropertyValue> initialValue;
+    /* TODO syntax */
+    const bool inherits;
+
+    CSSRegisteredCustomProperty(const String& name, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue);
+
+    const CSSCustomPropertyValue* initialValue() const { return m_initialValue.get(); }
+    RefPtr<CSSCustomPropertyValue> initialValueCopy() const;
+
+private:
+    const RefPtr<CSSCustomPropertyValue> m_initialValue;
 };
 
 using CSSRegisteredCustomPropertySet = HashMap<String, std::unique_ptr<CSSRegisteredCustomProperty>>;
index cdf0ca9..ea03362 100644 (file)
@@ -32,6 +32,9 @@
 
 #include "CSSCustomPropertyValue.h"
 #include "CSSParserTokenRange.h"
+#include "CSSTokenizer.h"
+#include "CSSValuePool.h"
+#include "RenderStyle.h"
 #include <wtf/text/AtomicStringHash.h>
 #include <wtf/text/StringBuilder.h>
 #include <wtf/text/StringView.h>
@@ -82,7 +85,7 @@ CSSVariableData::CSSVariableData(const CSSParserTokenRange& range, bool needsVar
     consumeAndUpdateTokens(range);
 }
 
-bool CSSVariableData::checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+bool CSSVariableData::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
 {
     if (invalidProperties.contains(name))
         return false;
@@ -90,14 +93,14 @@ bool CSSVariableData::checkVariablesForCycles(const AtomicString& name, CustomPr
     HashSet<AtomicString> newSeenProperties = seenProperties;
     newSeenProperties.add(name);
     
-    bool valid = checkVariablesForCyclesWithRange(m_tokens, customProperties, newSeenProperties, invalidProperties);
+    bool valid = checkVariablesForCyclesWithRange(m_tokens, style, newSeenProperties, invalidProperties);
     if (!valid)
         invalidProperties.add(name);
     
     return valid;
 }
     
-bool CSSVariableData::checkVariablesForCyclesWithRange(CSSParserTokenRange range, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+bool CSSVariableData::checkVariablesForCyclesWithRange(CSSParserTokenRange range, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
 {
     while (!range.atEnd()) {
         if (range.peek().functionId() == CSSValueVar || range.peek().functionId() == CSSValueEnv) {
@@ -110,14 +113,14 @@ bool CSSVariableData::checkVariablesForCyclesWithRange(CSSParserTokenRange range
             if (seenProperties.contains(variableName))
                 return false;
 
-            RefPtr<CSSCustomPropertyValue> value = customProperties.get(variableName);
-            if (value && value->containsVariables() && !value->checkVariablesForCycles(variableName, customProperties, seenProperties, invalidProperties))
+            auto* value = style.getCustomProperty(variableName);
+            if (value && value->containsVariables() && !value->checkVariablesForCycles(variableName, style, seenProperties, invalidProperties))
                 return false;
 
             if (range.peek().type() == CommaToken) {
                 // Fallback.
                 range.consume();
-                return checkVariablesForCyclesWithRange(block, customProperties, seenProperties, invalidProperties);
+                return checkVariablesForCyclesWithRange(block, style, seenProperties, invalidProperties);
             }
         } else
             range.consume();
@@ -125,35 +128,45 @@ bool CSSVariableData::checkVariablesForCyclesWithRange(CSSParserTokenRange range
     return true;
 }
 
-bool CSSVariableData::resolveVariableFallback(const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result) const
+bool CSSVariableData::resolveVariableFallback(const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result, const RenderStyle& style) const
 {
     if (range.atEnd())
         return false;
     ASSERT(range.peek().type() == CommaToken);
     range.consume();
-    return resolveTokenRange(customProperties, registeredProperties, range, result);
+    return resolveTokenRange(registeredProperties, range, result, style);
 }
 
-bool CSSVariableData::resolveVariableReference(const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result) const
+bool CSSVariableData::resolveVariableReference(const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result, const RenderStyle& style) const
 {
     range.consumeWhitespace();
     ASSERT(range.peek().type() == IdentToken);
     AtomicString variableName = range.consumeIncludingWhitespace().value().toAtomicString();
     ASSERT(range.atEnd() || (range.peek().type() == CommaToken));
     
-    RefPtr<CSSCustomPropertyValue> property = customProperties.get(variableName);
+    auto* property = style.getCustomProperty(variableName);
+    if (property && property->resolvedTypedValue()) {
+        // FIXME: we should not have to serialize a value that was already resolved.
+        auto textValue = CSSValuePool::singleton().createValue(*property->resolvedTypedValue(), style)->cssText();
+        CSSTokenizer tokenizer(textValue);
+        auto tokenizerRange = tokenizer.tokenRange();
+        while (!tokenizerRange.atEnd())
+            result.append(tokenizerRange.consume());
+        return true;
+    }
+
     if (!property || !property->value()) {
         auto* registered = registeredProperties.get(variableName);
-        if (registered && registered->initialValue)
-            property = registered->initialValue;
+        if (registered && registered->initialValue())
+            property = registered->initialValue();
         else
-            return resolveVariableFallback(customProperties, registeredProperties, range, result);
+            return resolveVariableFallback(registeredProperties, range, result, style);
     }
     ASSERT(property);
     
     if (property->containsVariables()) {
         // FIXME: Avoid doing this work more than once.
-        RefPtr<CSSVariableData> resolvedData = property->value()->resolveVariableReferences(customProperties, registeredProperties);
+        RefPtr<CSSVariableData> resolvedData = property->value()->resolveVariableReferences(registeredProperties, style);
         if (!resolvedData)
             return false;
         result.appendVector(resolvedData->tokens());
@@ -163,21 +176,21 @@ bool CSSVariableData::resolveVariableReference(const CustomPropertyValueMap& cus
     return true;
 }
 
-RefPtr<CSSVariableData> CSSVariableData::resolveVariableReferences(const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet& registeredProperties) const
+RefPtr<CSSVariableData> CSSVariableData::resolveVariableReferences(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style) const
 {
     Vector<CSSParserToken> resolvedTokens;
     CSSParserTokenRange range = m_tokens;
-    if (!resolveTokenRange(customProperties, registeredProperties, range, resolvedTokens))
+    if (!resolveTokenRange(registeredProperties, range, resolvedTokens, style))
         return nullptr;
     return CSSVariableData::createResolved(resolvedTokens, *this);
 }
     
-bool CSSVariableData::resolveTokenRange(const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result) const
+bool CSSVariableData::resolveTokenRange(const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result, const RenderStyle& style) const
 {
     bool success = true;
     while (!range.atEnd()) {
         if (range.peek().functionId() == CSSValueVar || range.peek().functionId() == CSSValueEnv)
-            success &= resolveVariableReference(customProperties, registeredProperties, range.consumeBlock(), result);
+            success &= resolveVariableReference(registeredProperties, range.consumeBlock(), result, style);
         else
             result.append(range.consume());
     }
index 6223b4f..008a6fa 100644 (file)
@@ -61,10 +61,10 @@ public:
 
     bool needsVariableResolution() const { return m_needsVariableResolution; }
 
-    bool checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+    bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
 
-    RefPtr<CSSVariableData> resolveVariableReferences(const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet&) const;
-    bool resolveTokenRange(const CustomPropertyValueMap&, const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&) const;
+    RefPtr<CSSVariableData> resolveVariableReferences(const CSSRegisteredCustomPropertySet&, const RenderStyle&) const;
+    bool resolveTokenRange(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;
 
 private:
     CSSVariableData(const CSSParserTokenRange&, bool needsVariableResolution);
@@ -82,9 +82,9 @@ private:
     void consumeAndUpdateTokens(const CSSParserTokenRange&);
     template<typename CharacterType> void updateTokens(const CSSParserTokenRange&);
     
-    bool checkVariablesForCyclesWithRange(CSSParserTokenRange, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
-    bool resolveVariableReference(const CustomPropertyValueMap&, const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&) const;
-    bool resolveVariableFallback(const CustomPropertyValueMap&, const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&) const;
+    bool checkVariablesForCyclesWithRange(CSSParserTokenRange, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+    bool resolveVariableReference(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;
+    bool resolveVariableFallback(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;
 
     String m_backingString;
     Vector<CSSParserToken> m_tokens;
index 2af5218..38957e4 100644 (file)
@@ -41,10 +41,10 @@ String CSSVariableReferenceValue::customCSSText() const
     return m_stringValue;
 }
     
-bool CSSVariableReferenceValue::checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+bool CSSVariableReferenceValue::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
 {
     ASSERT(m_data);
-    return m_data->checkVariablesForCycles(name, customProperties, seenProperties, invalidProperties);
+    return m_data->checkVariablesForCycles(name, style, seenProperties, invalidProperties);
 }
 
 } // namespace WebCore
index 537f78a..228964e 100644 (file)
@@ -50,7 +50,7 @@ public:
     bool equals(const CSSVariableReferenceValue& other) const { return m_data == other.m_data; }
     String customCSSText() const;
 
-    bool checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+    bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
 
 private:
     CSSVariableReferenceValue(Ref<CSSVariableData>&& data)
index b1308a6..a54ee68 100644 (file)
 #include "CSSTokenizer.h"
 #include "DOMCSSNamespace.h"
 #include "Document.h"
+#include "StyleBuilderConverter.h"
+#include "StyleResolver.h"
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
 ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& document, const DOMCSSCustomPropertyDescriptor& descriptor)
 {
+    auto initialValueLower = descriptor.initialValue.convertToASCIILowercase();
+    for (auto& substring : { "em", "ex", "lh", "cap", "ch", "ic", "var", "env" }) {
+        // FIXME: we should be able to check the dependencies of the parsed value
+        // Right now, we can't because values that fail to parse here will crash
+        if (initialValueLower.contains(substring))
+            return Exception { SyntaxError, "The given initial value must be computationally independent." };
+    }
+
     CSSTokenizer tokenizer(descriptor.initialValue);
     RefPtr<CSSCustomPropertyValue> initialValue;
-    if (!tokenizer.tokenRange().atEnd())
+    if (!tokenizer.tokenRange().atEnd()) {
         initialValue = CSSCustomPropertyValue::createWithVariableData(descriptor.name, CSSVariableData::create(tokenizer.tokenRange(), false));
+        if (initialValue->hasVariableReferences())
+            return Exception { SyntaxError, "The given initial value must not contain variable references." };
+
+        CSSParser parser(document);
+        RenderStyle renderStyle = RenderStyle::create();
+        StyleResolver styleResolver(document);
+
+        auto primitiveVal = parser.parseValueWithVariableReferences(CSSPropertyCustom, *initialValue, document.getCSSRegisteredCustomPropertySet(), renderStyle);
+        if (!primitiveVal || !primitiveVal->isPrimitiveValue())
+            return Exception { SyntaxError, "The given initial value does not parse for the given syntax." };
+
+        initialValue->setResolvedTypedValue(StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));
+    }
 
-    CSSRegisteredCustomProperty property { descriptor.name, WTFMove(initialValue) };
+    CSSRegisteredCustomProperty property { descriptor.name, descriptor.inherits, WTFMove(initialValue) };
     if (!document.registerCSSProperty(WTFMove(property)))
         return Exception { InvalidModificationError, "This property has already been registered." };
 
index 88a2392..551e2fa 100644 (file)
@@ -35,7 +35,7 @@ class StyleResolver;
 
 class StyleBuilder {
 public:
-    static void applyProperty(CSSPropertyID, StyleResolver&, CSSValue&, bool isInitial, bool isInherit);
+    static void applyProperty(CSSPropertyID, StyleResolver&, CSSValue&, bool isInitial, bool isInherit, const CSSRegisteredCustomProperty*);
 };
 
 } // namespace WebCore
index f478304..b2480e6 100644 (file)
@@ -60,10 +60,10 @@ namespace WebCore {
 // Note that we assume the CSS parser only allows valid CSSValue types.
 class StyleBuilderConverter {
 public:
-    static Length convertLength(StyleResolver&, const CSSValue&);
-    static Length convertLengthOrAuto(StyleResolver&, const CSSValue&);
-    static Length convertLengthSizing(StyleResolver&, const CSSValue&);
-    static Length convertLengthMaxSizing(StyleResolver&, const CSSValue&);
+    static Length convertLength(const StyleResolver&, const CSSValue&);
+    static Length convertLengthOrAuto(const StyleResolver&, const CSSValue&);
+    static Length convertLengthSizing(const StyleResolver&, const CSSValue&);
+    static Length convertLengthMaxSizing(const StyleResolver&, const CSSValue&);
     template<typename T> static T convertComputedLength(StyleResolver&, const CSSValue&);
     template<typename T> static T convertLineWidth(StyleResolver&, const CSSValue&);
     static float convertSpacing(StyleResolver&, const CSSValue&);
@@ -175,7 +175,7 @@ private:
     static CSSToLengthConversionData csstoLengthConversionDataWithTextZoomFactor(StyleResolver&);
 };
 
-inline Length StyleBuilderConverter::convertLength(StyleResolver& styleResolver, const CSSValue& value)
+inline Length StyleBuilderConverter::convertLength(const StyleResolver& styleResolver, const CSSValue& value)
 {
     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
     CSSToLengthConversionData conversionData = styleResolver.useSVGZoomRulesForLength() ?
@@ -198,14 +198,14 @@ inline Length StyleBuilderConverter::convertLength(StyleResolver& styleResolver,
     return Length(0, Fixed);
 }
 
-inline Length StyleBuilderConverter::convertLengthOrAuto(StyleResolver& styleResolver, const CSSValue& value)
+inline Length StyleBuilderConverter::convertLengthOrAuto(const StyleResolver& styleResolver, const CSSValue& value)
 {
     if (downcast<CSSPrimitiveValue>(value).valueID() == CSSValueAuto)
         return Length(Auto);
     return convertLength(styleResolver, value);
 }
 
-inline Length StyleBuilderConverter::convertLengthSizing(StyleResolver& styleResolver, const CSSValue& value)
+inline Length StyleBuilderConverter::convertLengthSizing(const StyleResolver& styleResolver, const CSSValue& value)
 {
     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
     switch (primitiveValue.valueID()) {
@@ -234,7 +234,7 @@ inline Length StyleBuilderConverter::convertLengthSizing(StyleResolver& styleRes
     }
 }
 
-inline Length StyleBuilderConverter::convertLengthMaxSizing(StyleResolver& styleResolver, const CSSValue& value)
+inline Length StyleBuilderConverter::convertLengthMaxSizing(const StyleResolver& styleResolver, const CSSValue& value)
 {
     if (downcast<CSSPrimitiveValue>(value).valueID() == CSSValueNone)
         return Length(Undefined);
index 7508b9f..0c47da2 100644 (file)
@@ -32,6 +32,7 @@
 #include "CSSFontValue.h"
 #include "CSSGradientValue.h"
 #include "CSSGridTemplateAreasValue.h"
+#include "CSSRegisteredCustomProperty.h"
 #include "CSSShadowValue.h"
 #include "Counter.h"
 #include "CounterContent.h"
@@ -145,6 +146,10 @@ public:
     static void applyValueStrokeWidth(StyleResolver&, CSSValue&);
     static void applyValueStrokeColor(StyleResolver&, CSSValue&);
 
+    static void applyInitialCustomProperty(StyleResolver&, const CSSRegisteredCustomProperty*, const AtomicString& name);
+    static void applyInheritCustomProperty(StyleResolver&, const CSSRegisteredCustomProperty*, const AtomicString& name);
+    static void applyValueCustomProperty(StyleResolver&, const CSSRegisteredCustomProperty*, CSSCustomPropertyValue&);
+
 private:
     static void resetEffectiveZoom(StyleResolver&);
 
@@ -1872,4 +1877,35 @@ inline void StyleBuilderCustom::applyValueStrokeColor(StyleResolver& styleResolv
     styleResolver.style()->setHasExplicitlySetStrokeColor(true);
 }
 
+inline void StyleBuilderCustom::applyInitialCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, const AtomicString& name)
+{
+    if (registered) {
+        auto initialValue = registered->initialValueCopy();
+        applyValueCustomProperty(styleResolver, registered, *initialValue);
+        return;
+    }
+
+    auto invalid = CSSCustomPropertyValue::createWithID(name, CSSValueInvalid);
+    applyValueCustomProperty(styleResolver, registered, invalid.get());
+}
+
+inline void StyleBuilderCustom::applyInheritCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, const AtomicString& name)
+{
+    auto* parentValue = styleResolver.parentStyle() ? styleResolver.parentStyle()->inheritedCustomProperties().get(name) : nullptr;
+    if (parentValue && !(registered && !registered->inherits))
+        applyValueCustomProperty(styleResolver, registered, *parentValue);
+    else
+        applyInitialCustomProperty(styleResolver, registered, name);
+}
+
+inline void StyleBuilderCustom::applyValueCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, CSSCustomPropertyValue& value)
+{
+    const auto& name = value.name();
+
+    if (!registered || registered->inherits)
+        styleResolver.style()->setInheritedCustomPropertyValue(name, makeRef(value), registered);
+    else
+        styleResolver.style()->setNonInheritedCustomPropertyValue(name, makeRef(value), registered);
+}
+
 } // namespace WebCore
index 4e011bf..d4e06bc 100644 (file)
@@ -1555,13 +1555,13 @@ static inline bool isValidCueStyleProperty(CSSPropertyID id)
 // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale,
 // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific
 // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size).
-bool StyleResolver::useSVGZoomRules()
+bool StyleResolver::useSVGZoomRules() const
 {
     return m_state.element() && m_state.element()->isSVGElement();
 }
 
 // Scale with/height properties on inline SVG root.
-bool StyleResolver::useSVGZoomRulesForLength()
+bool StyleResolver::useSVGZoomRulesForLength() const
 {
     return is<SVGElement>(m_state.element()) && !(is<SVGSVGElement>(*m_state.element()) && m_state.element()->parentNode());
 }
@@ -1636,9 +1636,13 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, SelectorChe
     CSSCustomPropertyValue* customPropertyValue = nullptr;
     CSSValueID customPropertyValueID = CSSValueInvalid;
 
+    CSSRegisteredCustomProperty* customPropertyRegistered = nullptr;
+
     if (id == CSSPropertyCustom) {
         customPropertyValue = &downcast<CSSCustomPropertyValue>(*valueToApply);
         customPropertyValueID = customPropertyValue->valueID();
+        auto& name = customPropertyValue->name();
+        customPropertyRegistered = document().getCSSRegisteredCustomPropertySet().get(name);
     }
 
     bool isInherit = state.parentStyle() ? valueToCheckForInheritInitial->isInheritedValue() || customPropertyValueID == CSSValueInherit : false;
@@ -1660,7 +1664,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, SelectorChe
             // not present, then we behave like "unset." Otherwise we apply the property instead of
             // our own.
             if (customPropertyValue) {
-                if (rollback->hasCustomProperty(customPropertyValue->name())) {
+                if (customPropertyRegistered && customPropertyRegistered->inherits && rollback->hasCustomProperty(customPropertyValue->name())) {
                     auto property = rollback->customProperty(customPropertyValue->name());
                     if (property.cssValue[linkMatchMask])
                         applyProperty(property.id, property.cssValue[linkMatchMask], linkMatchMask, matchResult);
@@ -1694,21 +1698,14 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, SelectorChe
     if (isInherit && !CSSProperty::isInheritedProperty(id))
         state.style()->setHasExplicitlyInheritedProperties();
 
-    if (customPropertyValue) {
-        auto& name = customPropertyValue->name();
-        auto* value = isInitial ? nullptr : isInherit ? state.parentStyle()->customProperties().get(name) : customPropertyValue;
-        state.style()->setCustomPropertyValue(name, value ? makeRef(*value) : CSSCustomPropertyValue::createInvalid());
-        return;
-    }
-
     // Use the generated StyleBuilder.
-    StyleBuilder::applyProperty(id, *this, *valueToApply, isInitial, isInherit);
+    StyleBuilder::applyProperty(id, *this, *valueToApply, isInitial, isInherit, customPropertyRegistered);
 }
 
-RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value)
+RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value) const
 {
     CSSParser parser(document());
-    return parser.parseValueWithVariableReferences(propID, value, m_state.style()->customProperties(), document().getCSSRegisteredCustomPropertySet(), m_state.style()->direction(), m_state.style()->writingMode());
+    return parser.parseValueWithVariableReferences(propID, value, document().getCSSRegisteredCustomPropertySet(), *m_state.style());
 }
 
 RefPtr<StyleImage> StyleResolver::styleImage(CSSValue& value)
@@ -2274,18 +2271,24 @@ void StyleResolver::applyCascadedProperties(CascadedProperties& cascade, int fir
         if (!cascade.hasProperty(propertyID))
             continue;
         if (propertyID == CSSPropertyCustom) {
+            // Apply font size first, since custom properties may rely on it for relative unit calculations
+            // Once it is applied and the custom property values are set, it will be applied again, which should
+            // handle any font-size properties that rely on registered custom properties.
+            // FIXME cycles should be detected.
+            if (cascade.hasProperty(CSSPropertyFontSize))
+                cascade.property(CSSPropertyFontSize).apply(*this, matchResult);
+            updateFont();
+
             HashMap<AtomicString, CascadedProperties::Property>::iterator end = cascade.customProperties().end();
             for (HashMap<AtomicString, CascadedProperties::Property>::iterator it = cascade.customProperties().begin(); it != end; ++it)
                 it->value.apply(*this, matchResult);
+            m_state.style()->checkVariablesInCustomProperties(document().getCSSRegisteredCustomPropertySet(), m_state.parentStyle(), *this);
             continue;
         }
         auto& property = cascade.property(propertyID);
         ASSERT(!shouldApplyPropertyInParseOrder(propertyID));
         property.apply(*this, matchResult);
     }
-
-    if (firstProperty == CSSPropertyCustom)
-        m_state.style()->checkVariablesInCustomProperties(document().getCSSRegisteredCustomPropertySet());
 }
 
 } // namespace WebCore
index 4e48c30..4703cef 100644 (file)
@@ -187,8 +187,8 @@ public:
     void setFontSize(FontCascadeDescription&, float size);
 
 public:
-    bool useSVGZoomRules();
-    bool useSVGZoomRulesForLength();
+    bool useSVGZoomRules() const;
+    bool useSVGZoomRulesForLength() const;
 
     static bool colorFromPrimitiveValueIsDerivedFromElement(const CSSPrimitiveValue&);
     Color colorFromPrimitiveValue(const CSSPrimitiveValue&, bool forVisitedLink = false) const;
@@ -455,11 +455,12 @@ public:
     void setWritingMode(WritingMode writingMode) { m_state.setWritingMode(writingMode); }
     void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); }
 
+    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&) const;
+
 private:
     void cacheBorderAndBackground();
 
     void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr);
-    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&);
 
     void applySVGProperty(CSSPropertyID, CSSValue*);
 
index 29244fc..c05944c 100755 (executable)
@@ -1027,12 +1027,21 @@ foreach my $name (@names) {
 print STYLEBUILDER << "EOF";
 };
 
-void StyleBuilder::applyProperty(CSSPropertyID property, StyleResolver& styleResolver, CSSValue& value, bool isInitial, bool isInherit)
+void StyleBuilder::applyProperty(CSSPropertyID property, StyleResolver& styleResolver, CSSValue& value, bool isInitial, bool isInherit, const CSSRegisteredCustomProperty* registered)
 {
     switch (property) {
     case CSSPropertyInvalid:
-    case CSSPropertyCustom:
         break;
+    case CSSPropertyCustom: {
+        auto& customProperty = downcast<CSSCustomPropertyValue>(value);
+        if (isInitial)
+            StyleBuilderCustom::applyInitialCustomProperty(styleResolver, registered, customProperty.name());
+        else if (isInherit)
+            StyleBuilderCustom::applyInheritCustomProperty(styleResolver, registered, customProperty.name());
+        else
+            StyleBuilderCustom::applyValueCustomProperty(styleResolver, registered, customProperty);
+        break;
+    }
 EOF
 
 foreach my $name (@names) {
index dd6e4bd..9df0fd4 100644 (file)
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "CSSParser.h"
 
+#include "CSSCustomPropertyValue.h"
 #include "CSSKeyframeRule.h"
 #include "CSSParserFastPaths.h"
 #include "CSSParserImpl.h"
@@ -41,6 +42,7 @@
 #include "Document.h"
 #include "Element.h"
 #include "Page.h"
+#include "RenderStyle.h"
 #include "RenderTheme.h"
 #include "RuntimeEnabledFeatures.h"
 #include "Settings.h"
@@ -175,8 +177,11 @@ void CSSParser::parseDeclarationForInspector(const CSSParserContext& context, co
     CSSParserImpl::parseDeclarationListForInspector(string, context, observer);
 }
 
-RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, const CustomPropertyValueMap& customProperties, const CSSRegisteredCustomPropertySet& registeredProperties, TextDirection direction, WritingMode writingMode)
+RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style)
 {
+    auto direction = style.direction();
+    auto writingMode = style.writingMode();
+
     if (value.isPendingSubstitutionValue()) {
         // FIXME: Should have a resolvedShorthands cache to stop this from being done
         // over and over for each longhand value.
@@ -189,7 +194,7 @@ RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propI
         ASSERT(variableData);
         
         Vector<CSSParserToken> resolvedTokens;
-        if (!variableData->resolveTokenRange(customProperties, registeredProperties, variableData->tokens(), resolvedTokens))
+        if (!variableData->resolveTokenRange(registeredProperties, variableData->tokens(), resolvedTokens, style))
             return nullptr;
         
         ParsedPropertyVector parsedProperties;
@@ -204,19 +209,31 @@ RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propI
         return nullptr;
     }
 
+    const CSSVariableData* variableData = nullptr;
+
     if (value.isVariableReferenceValue()) {
         const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value);
-        const CSSVariableData* variableData = valueWithReferences.variableDataValue();
+        variableData = valueWithReferences.variableDataValue();
         ASSERT(variableData);
-        
-        Vector<CSSParserToken> resolvedTokens;
-        if (!variableData->resolveTokenRange(customProperties, registeredProperties, variableData->tokens(), resolvedTokens))
-            return nullptr;
-        
-        return CSSPropertyParser::parseSingleValue(propID, resolvedTokens, m_context);
     }
-    
-    return nullptr;
+
+    if (value.isCustomPropertyValue()) {
+        const CSSCustomPropertyValue& customPropValue = downcast<CSSCustomPropertyValue>(value);
+
+        if (customPropValue.resolvedTypedValue())
+            return CSSPrimitiveValue::create(*customPropValue.resolvedTypedValue(), style);
+
+        variableData = customPropValue.value();
+    }
+
+    if (!variableData)
+        return nullptr;
+
+    Vector<CSSParserToken> resolvedTokens;
+    if (!variableData->resolveTokenRange(registeredProperties, variableData->tokens(), resolvedTokens, style))
+        return nullptr;
+
+    return CSSPropertyParser::parseSingleValue(propID, resolvedTokens, m_context);
 }
 
 std::unique_ptr<Vector<double>> CSSParser::parseKeyframeKeyList(const String& selector)
index f74fb48..09ba4b0 100644 (file)
@@ -39,6 +39,7 @@ class MutableStyleProperties;
 class StyleRuleBase;
 class StyleRuleKeyframe;
 class StyleSheetContents;
+class RenderStyle;
 
 class CSSParser {
 public:
@@ -76,7 +77,7 @@ public:
 
     void parseSelector(const String&, CSSSelectorList&);
 
-    RefPtr<CSSValue> parseValueWithVariableReferences(CSSPropertyID, const CSSValue&, const CustomPropertyValueMap&, const CSSRegisteredCustomPropertySet&, TextDirection, WritingMode);
+    RefPtr<CSSValue> parseValueWithVariableReferences(CSSPropertyID, const CSSValue&, const CSSRegisteredCustomPropertySet&, const RenderStyle&);
 
     static Color parseColor(const String&, bool strict = false);
     static Color parseSystemColor(const String&, const CSSParserContext*);
index e3e7f9c..9a52555 100644 (file)
@@ -51,7 +51,7 @@ CSSParserContext::CSSParserContext(CSSParserMode mode, const URL& baseURL)
 #endif
 }
 
-CSSParserContext::CSSParserContext(Document& document, const URL& sheetBaseURL, const String& charset)
+CSSParserContext::CSSParserContext(const Document& document, const URL& sheetBaseURL, const String& charset)
     : baseURL(sheetBaseURL.isNull() ? document.baseURL() : sheetBaseURL)
     , charset(charset)
     , mode(document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode)
index 1ef7711..2289866 100644 (file)
@@ -40,7 +40,7 @@ struct CSSParserContext {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     CSSParserContext(CSSParserMode, const URL& baseURL = URL());
-    WEBCORE_EXPORT CSSParserContext(Document&, const URL& baseURL = URL(), const String& charset = emptyString());
+    WEBCORE_EXPORT CSSParserContext(const Document&, const URL& baseURL = URL(), const String& charset = emptyString());
 
     URL baseURL;
     String charset;
index 33d1632..5f21463 100644 (file)
@@ -3909,6 +3909,7 @@ RefPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID property, CSS
     case CSSPropertyMinHeight:
     case CSSPropertyWidth:
     case CSSPropertyHeight:
+    case CSSPropertyCustom: // FIXME: parsing a registered custom property should be based on its syntax.
         return consumeWidthOrHeight(m_range, m_context, UnitlessQuirk::Allow);
     case CSSPropertyMinInlineSize:
     case CSSPropertyMinBlockSize:
index 10fd625..db85d7d 100644 (file)
@@ -39,6 +39,7 @@
 #include "RuntimeEnabledFeatures.h"
 #include "ScaleTransformOperation.h"
 #include "ShadowData.h"
+#include "StyleBuilderConverter.h"
 #include "StyleImage.h"
 #include "StyleInheritedData.h"
 #include "StyleResolver.h"
@@ -2298,46 +2299,87 @@ bool RenderStyle::hasReferenceFilterOnly() const
     return filterOperations.size() == 1 && filterOperations.at(0)->type() == FilterOperation::REFERENCE;
 }
 
-void RenderStyle::checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet& registeredProperties)
+void RenderStyle::checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle* parentStyle, const StyleResolver& styleResolver)
 {
-    if (!m_rareInheritedData->customProperties->containsVariables)
-        return;
-
-    auto& customPropertyData = m_rareInheritedData.access().customProperties.access();
+    bool shouldUpdateInherited = m_rareInheritedData->customProperties->containsVariables || m_rareInheritedData->customProperties->containsUnresolvedRegisteredProperties;
+    bool shouldUpdateNonInherited = m_rareNonInheritedData->customProperties->containsVariables || m_rareNonInheritedData->customProperties->containsUnresolvedRegisteredProperties;
+    auto* inheritedPropertyData = shouldUpdateInherited ? &m_rareInheritedData.access().customProperties.access() : nullptr;
+    auto* nonInheritedPropertyData = shouldUpdateNonInherited ? &m_rareNonInheritedData.access().customProperties.access() : nullptr;
 
-    // Our first pass checks the variables for validity and replaces any properties that became
-    // invalid with empty values.
-    auto& customProperties = customPropertyData.values;
     HashSet<AtomicString> invalidProperties;
-    for (auto entry : customProperties) {
-        if (!entry.value->containsVariables())
+
+    for (auto* customPropertyData : { inheritedPropertyData, nonInheritedPropertyData }) {
+        if (!customPropertyData)
             continue;
-        HashSet<AtomicString> seenProperties;
-        entry.value->checkVariablesForCycles(entry.key, customProperties, seenProperties, invalidProperties);
-    }
-    
-    // Now insert invalid values.
-    if (!invalidProperties.isEmpty()) {
+
+        // Our first pass checks the variables for validity and replaces any properties that became
+        // invalid with empty values.
+        auto& customProperties = customPropertyData->values;
+        for (auto& entry : customProperties) {
+            if (!entry.value->containsVariables())
+                continue;
+            HashSet<AtomicString> seenProperties;
+            entry.value->checkVariablesForCycles(entry.key, *this, seenProperties, invalidProperties);
+        }
+
         auto invalidValue = CSSCustomPropertyValue::createInvalid();
-        for (auto& property : invalidProperties)
-            customProperties.set(property, invalidValue.copyRef());
-    }
 
-    // Now that all of the properties have been tested for validity and replaced with
-    // invalid values if they failed, we can perform variable substitution on the valid values.
-    Vector<Ref<CSSCustomPropertyValue>> resolvedValues;
-    for (auto entry : customProperties) {
-        if (!entry.value->containsVariables())
-            continue;
-        entry.value->resolveVariableReferences(customProperties, registeredProperties, resolvedValues);
-    }
-    
-    // With all results computed, we can now mutate our table to eliminate the variables and
-    // hold the final values. This way when we inherit, we don't end up resubstituting variables, etc.
-    for (auto& resolvedValue : resolvedValues)
-        customProperties.set(resolvedValue->name(), resolvedValue.copyRef());
+        // Now insert invalid values, or defaults if the property is registered.
+        if (!invalidProperties.isEmpty()) {
+            for (auto& property : invalidProperties) {
+                if (!customProperties.contains(property))
+                    continue;
+                
+                const RefPtr<CSSCustomPropertyValue>* parentProperty = nullptr;
+                if (parentStyle) {
+                    auto iterator = parentStyle->inheritedCustomProperties().find(property);
+                    if (iterator != parentStyle->inheritedCustomProperties().end() && iterator.get() && iterator.get()->value)
+                        parentProperty = &iterator.get()->value;
+                }
+
+                auto* registered = registeredProperties.get(property);
+
+                if (registered && registered->inherits && parentProperty)
+                    customProperties.set(property, parentProperty->copyRef());
+                else if (registered && registered->initialValue())
+                    customProperties.set(property, registered->initialValueCopy());
+                else
+                    customProperties.set(property, invalidValue.copyRef());
+            }
+        }
+
+        // Now that all of the properties have been tested for validity and replaced with
+        // invalid values if they failed, we can perform variable substitution on the valid values.
+        Vector<Ref<CSSCustomPropertyValue>> resolvedValues;
+        for (auto entry : customProperties) {
+            if (!entry.value->containsVariables())
+                continue;
+            entry.value->resolveVariableReferences(registeredProperties, resolvedValues, *this);
+        }
+
+        // With all results computed, we can now mutate our table to eliminate the variables and
+        // hold the final values. This way when we inherit, we don't end up resubstituting variables, etc.
+        for (auto& resolvedValue : resolvedValues)
+            customProperties.set(resolvedValue->name(), resolvedValue.copyRef());
 
-    customPropertyData.containsVariables = false;
+        // Finally we can resolve registered custom properties to their typed values.
+        for (auto& entry : customProperties) {
+            auto& name = entry.value->name();
+            auto* registered = registeredProperties.get(name);
+
+            if (!registered)
+                continue;
+
+            auto primitiveVal = styleResolver.resolvedVariableValue(CSSPropertyCustom, *entry.value);
+            if (!primitiveVal || !primitiveVal->isPrimitiveValue())
+                entry.value = invalidValue.copyRef();
+            else
+                entry.value->setResolvedTypedValue(StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));
+        }
+
+        customPropertyData->containsVariables = false;
+        customPropertyData->containsUnresolvedRegisteredProperties = false;
+    }
 }
 
 float RenderStyle::outlineWidth() const
index dcd025f..724f910 100644 (file)
@@ -183,8 +183,11 @@ public:
 
     const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
 
-    const CustomPropertyValueMap& customProperties() const { return m_rareInheritedData->customProperties->values; }
-    void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) { return m_rareInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value)); }
+    const CustomPropertyValueMap& inheritedCustomProperties() const { return m_rareInheritedData->customProperties->values; }
+    const CustomPropertyValueMap& nonInheritedCustomProperties() const { return m_rareNonInheritedData->customProperties->values; }
+    const CSSCustomPropertyValue* getCustomProperty(const AtomicString&) const;
+    void setInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value, bool isRegistered = false) { return m_rareInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value), isRegistered); }
+    void setNonInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value, bool isRegistered = false) { return m_rareNonInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value), isRegistered); }
 
     void setHasViewportUnits(bool v = true) { m_nonInheritedFlags.hasViewportUnits = v; }
     bool hasViewportUnits() const { return m_nonInheritedFlags.hasViewportUnits; }
@@ -792,7 +795,7 @@ public:
     ApplePayButtonType applePayButtonType() const { return static_cast<ApplePayButtonType>(m_rareNonInheritedData->applePayButtonType); }
 #endif
 
-    void checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet&);
+    void checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet&, const RenderStyle* parentStyle, const StyleResolver&);
 
 // attribute setter methods
 
@@ -1998,6 +2001,15 @@ inline BorderStyle collapsedBorderStyle(BorderStyle style)
     return style;
 }
 
+inline const CSSCustomPropertyValue* RenderStyle::getCustomProperty(const AtomicString& name) const
+{
+    for (auto* map : { &nonInheritedCustomProperties(), &inheritedCustomProperties() }) {
+        if (auto* val = map->get(name))
+            return val;
+    }
+    return nullptr;
+}
+
 inline bool RenderStyle::hasBackground() const
 {
     return visitedDependentColor(CSSPropertyBackgroundColor).isVisible() ||  hasBackgroundImage();
index 88f1831..1bcdb22 100644 (file)
@@ -54,15 +54,18 @@ public:
 
     bool operator!=(const StyleCustomPropertyData& other) const { return !(*this == other); }
     
-    void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value)
+    void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value, bool isRegistered)
     {
         if (value->containsVariables())
             containsVariables = true;
+        if (isRegistered)
+            containsUnresolvedRegisteredProperties = true;
         values.set(name, WTFMove(value));
     }
 
     CustomPropertyValueMap values;
     bool containsVariables { false };
+    bool containsUnresolvedRegisteredProperties { false };
 
 private:
     StyleCustomPropertyData() = default;
@@ -70,6 +73,7 @@ private:
         : RefCounted<StyleCustomPropertyData>()
         , values(other.values)
         , containsVariables(other.containsVariables)
+        , containsUnresolvedRegisteredProperties(other.containsUnresolvedRegisteredProperties)
     { }
 };
 
index 0aeac97..080667b 100644 (file)
@@ -75,6 +75,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData()
     , justifyContent(RenderStyle::initialContentAlignment())
     , justifyItems(RenderStyle::initialJustifyItems())
     , justifySelf(RenderStyle::initialSelfAlignment())
+    , customProperties(StyleCustomPropertyData::create())
 #if ENABLE(TOUCH_EVENTS)
     , touchAction(static_cast<unsigned>(RenderStyle::initialTouchAction()))
 #endif
@@ -167,6 +168,7 @@ inline StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonIn
     , justifyContent(o.justifyContent)
     , justifyItems(o.justifyItems)
     , justifySelf(o.justifySelf)
+    , customProperties(o.customProperties)
 #if ENABLE(TOUCH_EVENTS)
     , touchAction(o.touchAction)
 #endif
@@ -268,6 +270,7 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
         && justifyContent == o.justifyContent
         && justifyItems == o.justifyItems
         && justifySelf == o.justifySelf
+        && customProperties == o.customProperties
         && pageSizeType == o.pageSizeType
         && transformStyle3D == o.transformStyle3D
         && backfaceVisibility == o.backfaceVisibility
index 089ccfa..d411cb2 100644 (file)
@@ -171,6 +171,8 @@ public:
     StyleSelfAlignmentData justifyItems;
     StyleSelfAlignmentData justifySelf;
 
+    DataRef<StyleCustomPropertyData> customProperties;
+
 #if ENABLE(TOUCH_EVENTS)
     unsigned touchAction : 1; // TouchAction
 #endif
index 1fdb16e..81f7e87 100644 (file)
@@ -128,7 +128,7 @@ RenderStyle resolveForDocument(const Document& document)
     documentStyle.fontCascade().update(&const_cast<Document&>(document).fontSelector());
 
     for (auto& it : document.constantProperties().values())
-        documentStyle.setCustomPropertyValue(it.key, makeRef(it.value.get()));
+        documentStyle.setInheritedCustomPropertyValue(it.key, makeRef(it.value.get()));
 
     return documentStyle;
 }