Revert r237347 registered custom properties... https://bugs.webkit.org/show_bug.cgi...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Oct 2018 21:48:51 +0000 (21:48 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Oct 2018 21:48:51 +0000 (21:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190919

Patch by Justin Michaud <justin_michaud@apple.com> on 2018-10-29
Reviewed by Michael Saboff.

LayoutTests/imported/w3c:

* web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt:
* web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt:
* web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt:
* web-platform-tests/css/css-properties-values-api/typedom.tentative-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:

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::customPropertyValue):
* css/CSSCustomPropertyValue.cpp:
(WebCore::CSSCustomPropertyValue::customCSSText const):
(WebCore::CSSCustomPropertyValue::tokens const):
(WebCore::CSSCustomPropertyValue::checkVariablesForCycles const):
(WebCore::CSSCustomPropertyValue::resolveVariableReferences const):
(WebCore::CSSCustomPropertyValue::setResolvedTypedValue):
(WebCore::CSSCustomPropertyValue::equals const): Deleted.
* css/CSSCustomPropertyValue.h:
* css/CSSRegisteredCustomProperty.cpp:
(WebCore::CSSRegisteredCustomProperty::CSSRegisteredCustomProperty):
* css/CSSRegisteredCustomProperty.h:
* css/CSSVariableData.cpp:
(WebCore::CSSVariableData::consumeAndUpdateTokens):
(WebCore::CSSVariableData::CSSVariableData):
(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:
(WebCore::CSSVariableData::create):
(WebCore::CSSVariableData::createResolved):
(WebCore::CSSVariableData::needsVariableResolution const):
(WebCore::CSSVariableData::CSSVariableData):
* css/CSSVariableReferenceValue.cpp:
(WebCore::CSSVariableReferenceValue::checkVariablesForCycles const):
(WebCore::resolveVariableFallback): Deleted.
(WebCore::resolveVariableReference): Deleted.
(WebCore::resolveTokenRange): Deleted.
(WebCore::CSSVariableReferenceValue::resolveVariableReferences const): Deleted.
* css/CSSVariableReferenceValue.h:
(WebCore::CSSVariableReferenceValue::create):
(WebCore::CSSVariableReferenceValue::variableDataValue const):
(WebCore::CSSVariableReferenceValue::equals const):
* css/DOMCSSRegisterCustomProperty.cpp:
(WebCore::DOMCSSRegisterCustomProperty::registerProperty):
* css/PropertySetCSSStyleDeclaration.cpp:
(WebCore::PropertySetCSSStyleDeclaration::setProperty):
* css/StyleBuilderCustom.h:
(WebCore::StyleBuilderCustom::applyInitialCustomProperty):
(WebCore::StyleBuilderCustom::applyValueCustomProperty):
* css/StyleProperties.cpp:
(WebCore::MutableStyleProperties::setCustomProperty):
* css/StyleProperties.h:
* css/StyleResolver.cpp:
(WebCore::StyleResolver::State::setStyle):
(WebCore::StyleResolver::styleForKeyframe):
(WebCore::StyleResolver::styleForPage):
(WebCore::StyleResolver::applyMatchedProperties):
(WebCore::StyleResolver::applyPropertyToCurrentStyle):
(WebCore::StyleResolver::applyProperty):
(WebCore::StyleResolver::resolvedVariableValue const):
(WebCore::StyleResolver::CascadedProperties::applyDeferredProperties):
(WebCore::StyleResolver::CascadedProperties::Property::apply):
(WebCore::StyleResolver::applyCascadedProperties):
(WebCore::StyleResolver::applyCascadedCustomProperty): Deleted.
* css/StyleResolver.h:
* css/parser/CSSParser.cpp:
(WebCore::CSSParser::parseValueWithVariableReferences):
* css/parser/CSSParser.h:
* css/parser/CSSPropertyParser.cpp:
(WebCore::CSSPropertyParser::CSSPropertyParser):
(WebCore::CSSPropertyParser::parseValueStart):
(WebCore::CSSPropertyParser::parseSingleValue):
(WebCore::CSSPropertyParser::canParseTypedCustomPropertyValue): Deleted.
(WebCore::CSSPropertyParser::parseTypedCustomPropertyValue): Deleted.
(WebCore::CSSPropertyParser::collectParsedCustomPropertyValueDependencies): Deleted.
* css/parser/CSSPropertyParser.h:
* css/parser/CSSVariableParser.cpp:
(WebCore::CSSVariableParser::parseDeclarationValue):
* dom/ConstantPropertyMap.cpp:
(WebCore::ConstantPropertyMap::setValueForProperty):
(WebCore::variableDataForPositivePixelLength):
(WebCore::variableDataForPositiveDuration):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::checkVariablesInCustomProperties):
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::setInheritedCustomPropertyValue):
(WebCore::RenderStyle::setNonInheritedCustomPropertyValue):
* rendering/style/StyleCustomPropertyData.h:
(WebCore::StyleCustomPropertyData::operator== const):
(WebCore::StyleCustomPropertyData::setCustomPropertyValue):
(WebCore::StyleCustomPropertyData::StyleCustomPropertyData):

LayoutTests:

* css-custom-properties-api/crash-expected.txt: Removed.
* css-custom-properties-api/crash.html: Removed.
* css-custom-properties-api/cycles-expected.txt: Removed.
* css-custom-properties-api/cycles.html: Removed.
* css-custom-properties-api/inline-expected.txt: Removed.
* css-custom-properties-api/inline.html: Removed.

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

40 files changed:
LayoutTests/ChangeLog
LayoutTests/css-custom-properties-api/crash-expected.txt [deleted file]
LayoutTests/css-custom-properties-api/crash.html [deleted file]
LayoutTests/css-custom-properties-api/cycles-expected.txt [deleted file]
LayoutTests/css-custom-properties-api/cycles.html [deleted file]
LayoutTests/css-custom-properties-api/inline-expected.txt [deleted file]
LayoutTests/css-custom-properties-api/inline.html [deleted file]
LayoutTests/imported/w3c/ChangeLog
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-cssom-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/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/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSCustomPropertyValue.cpp
Source/WebCore/css/CSSCustomPropertyValue.h
Source/WebCore/css/CSSRegisteredCustomProperty.cpp
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/PropertySetCSSStyleDeclaration.cpp
Source/WebCore/css/StyleBuilderCustom.h
Source/WebCore/css/StyleProperties.cpp
Source/WebCore/css/StyleProperties.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/css/parser/CSSParser.cpp
Source/WebCore/css/parser/CSSParser.h
Source/WebCore/css/parser/CSSPropertyParser.cpp
Source/WebCore/css/parser/CSSPropertyParser.h
Source/WebCore/css/parser/CSSVariableParser.cpp
Source/WebCore/dom/ConstantPropertyMap.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/StyleCustomPropertyData.h

index 69f1a5c..09852f5 100644 (file)
@@ -1,3 +1,17 @@
+2018-10-29  Justin Michaud  <justin_michaud@apple.com>
+
+        Revert r237347 registered custom properties... https://bugs.webkit.org/show_bug.cgi?id=190039
+        https://bugs.webkit.org/show_bug.cgi?id=190919
+
+        Reviewed by Michael Saboff.
+
+        * css-custom-properties-api/crash-expected.txt: Removed.
+        * css-custom-properties-api/crash.html: Removed.
+        * css-custom-properties-api/cycles-expected.txt: Removed.
+        * css-custom-properties-api/cycles.html: Removed.
+        * css-custom-properties-api/inline-expected.txt: Removed.
+        * css-custom-properties-api/inline.html: Removed.
+
 2018-10-29  Matt Lewis  <jlewis3@apple.com>
 
         Marked http/tests/misc/large-js-program.php as a flaky timeout.
diff --git a/LayoutTests/css-custom-properties-api/crash-expected.txt b/LayoutTests/css-custom-properties-api/crash-expected.txt
deleted file mode 100644 (file)
index 8af0ff5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-This is text
-
-
-PASS Fallback is handled correctly, and we don't crash 
-PASS Setting the inline style is handled correctly 
-PASS CSS.registerProperty 
-PASS Setting the inline style is handled correctly when registered 
-
diff --git a/LayoutTests/css-custom-properties-api/crash.html b/LayoutTests/css-custom-properties-api/crash.html
deleted file mode 100644 (file)
index 7f2cd70..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSCustomPropertiesAndValuesEnabled=true ] -->
-<!-- https://chromium.googlesource.com/chromium/src/+/01ce431409e3a019858677626a983c55168da6dc/third_party/WebKit/LayoutTests/custom-properties/register-property.html -->
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<style>
-  #test1 {
-    font-size: var(--foo, 30px);
-    --foo: var(--bar, 20px);
-    --bar: var(--baz, var(--foo));
-  }
-</style>
-<div>
-  <h2 id=test1>This is text</h2>
-</div>
-<script>
-var computedStyle = getComputedStyle(test1);
-var inlineStyle = test1.style;
-
-test(function() {
-  assert_equals(computedStyle.getPropertyValue('--baz'), '');
-  assert_equals(computedStyle.getPropertyValue('--foo'), '');
-  assert_equals(computedStyle.getPropertyValue('--bar'), '');
-  assert_equals(computedStyle.getPropertyValue('font-size'), '30px');
-}, "Fallback is handled correctly, and we don't crash");
-
-test(function() {
-  inlineStyle.setProperty('--baz', '   40px');
-  assert_equals(computedStyle.getPropertyValue('--baz'), ' 40px');
-  assert_equals(computedStyle.getPropertyValue('--foo'), '');
-  assert_equals(computedStyle.getPropertyValue('--bar'), '');
-  assert_equals(computedStyle.getPropertyValue('--baz'), ' 40px');
-  assert_equals(computedStyle.getPropertyValue('font-size'), '30px');
-  inlineStyle.removeProperty('--baz');
-  assert_equals(computedStyle.getPropertyValue('--baz'), '');
-  assert_equals(computedStyle.getPropertyValue('--foo'), '');
-  assert_equals(computedStyle.getPropertyValue('--bar'), '');
-  assert_equals(computedStyle.getPropertyValue('font-size'), '30px');
-  assert_equals(computedStyle.getPropertyValue('--baz'), '');
-}, "Setting the inline style is handled correctly");
-
-test(function() {
-  CSS.registerProperty({name: '--foo', syntax: '<length>', initialValue: '200px', inherits: true});
-  CSS.registerProperty({name: '--bar', syntax: '<length>', initialValue: '200px', inherits: true});
-  CSS.registerProperty({name: '--baz', syntax: '<length>', initialValue: '200px', inherits: true});
-}, "CSS.registerProperty");
-
-test(function() {
-  inlineStyle.setProperty('--baz', '   40px');
-  assert_equals(computedStyle.getPropertyValue('--baz'), '40px');
-  assert_equals(computedStyle.getPropertyValue('--foo'), '200px');
-  assert_equals(computedStyle.getPropertyValue('--bar'), '200px');
-  assert_equals(computedStyle.getPropertyValue('--baz'), '40px');
-  assert_equals(computedStyle.getPropertyValue('font-size'), '200px');
-  inlineStyle.removeProperty('--baz');
-  assert_equals(computedStyle.getPropertyValue('--baz'), '200px');
-  assert_equals(computedStyle.getPropertyValue('--foo'), '200px');
-  assert_equals(computedStyle.getPropertyValue('--bar'), '200px');
-  assert_equals(computedStyle.getPropertyValue('font-size'), '200px');
-  assert_equals(computedStyle.getPropertyValue('--baz'), '200px');
-}, "Setting the inline style is handled correctly when registered");
-
-</script>
diff --git a/LayoutTests/css-custom-properties-api/cycles-expected.txt b/LayoutTests/css-custom-properties-api/cycles-expected.txt
deleted file mode 100644 (file)
index 7d486eb..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-test
-
-test
-
-test
-
-test
-
-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 JS Attributes are valid for element 4 
-PASS JS Attributes are valid for element 5 
-
diff --git a/LayoutTests/css-custom-properties-api/cycles.html b/LayoutTests/css-custom-properties-api/cycles.html
deleted file mode 100644 (file)
index 6ec24c8..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSCustomPropertiesAndValuesEnabled=true ] -->
-<!-- https://chromium.googlesource.com/chromium/src/+/01ce431409e3a019858677626a983c55168da6dc/third_party/WebKit/LayoutTests/custom-properties/register-property.html -->
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<style>
-  #parent1 {
-    width: 500px;
-    background: blue;
-  }
-  #child1 {
-    background: green;
-    font-size: 10px;
-    --a: 10em;
-    width: var(--a);
-  }
-
-  #parent2 {
-    width: 500px;
-    background: blue;
-    --a: 10em;
-    font-size: calc( var(--a) + -150px);
-  }
-  #child2 {
-    background: green;
-    width: var(--a);
-  }
-
-  #parent3 {
-    width: 500px;
-    background: blue;
-    --b: 10em;
-    font-size: calc( var(--b) + -150px);
-  }
-  #child3 {
-    background: green;
-    width: var(--b);
-  }
-
-  #parent4 {
-    width: 500px;
-    background: blue;
-    --b: 10em;
-    font-size: calc( var(--b) + -150px);
-  }
-  #child4 {
-    background: green;
-    --a: var(--b);
-    font-size: var(--a);
-    width: var(--a);
-  }
-
-  #parent5 {
-    width: 500px;
-    background: blue;
-    --b: 5em;
-    font-size: calc( var(--b) + -70px);
-  }
-  #child5 {
-    background: green;
-    --c: var(--b);
-    font-size: var(--c);
-    width: var(--c);
-  }
-</style>
-<div>
-  <div id="parent1"><div id="child1"><p>test</p></div></div>
-  <div id="parent2"><div id="child2"><p>test</p></div></div>
-  <div id="parent3"><div id="child3"><p>test</p></div></div>
-  <div id="parent4"><div id="child4"><p>test</p></div></div>
-  <div id="parent5"><div id="child5"><p>test</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: '--a',
-    syntax: '<length>',
-    inherits: true,
-    initialValue: '200px'
-  })
-}, "Registration is successful");
-test(function() {
-  test_prop('child1', 'width', '100px');
-  test_prop('child1', '--a', '100px');
-  test_prop('child1', '--b', '');
-  test_prop('parent1', '--a', '200px');
-  test_prop('parent1', '--b', '');
-}, "JS Attributes are valid for element 1");
-test(function() {
-  test_prop('child2', 'width', '160px');
-  test_prop('child2', '--a', '160px');
-  test_prop('child2', '--b', '');
-  test_prop('child2', 'font-size', '16px');
-  test_prop('parent2', '--a', '160px');
-  test_prop('parent2', '--b', '');
-  test_prop('parent2', 'font-size', '16px');
-}, "JS Attributes are valid for element 2");
-test(function() {
-  test_prop('child3', 'width', '100px');
-  test_prop('child3', '--a', '200px');
-  test_prop('child3', '--b', '10em');
-  test_prop('child3', 'font-size', '10px');
-  test_prop('parent3', '--a', '200px');
-  test_prop('parent3', '--b', '10em');
-  test_prop('parent3', 'font-size', '10px');
-}, "JS Attributes are valid for element 3");
-test(function() {
-  test_prop('child4', 'width', '100px');
-  test_prop('child4', '--a', '100px');
-  test_prop('child4', '--b', '10em');
-  test_prop('child4', 'font-size', '10px');
-  test_prop('parent4', '--a', '200px');
-  test_prop('parent4', '--b', '10em');
-  test_prop('parent4', 'font-size', '10px');
-}, "JS Attributes are valid for element 4");
-test(function() {
-  test_prop('child5', 'width', '250px');
-  test_prop('child5', '--c', '5em');
-  test_prop('child5', '--b', '5em');
-  test_prop('child5', 'font-size', '50px');
-  test_prop('parent5', '--a', '200px');
-  test_prop('parent5', '--b', '5em');
-  test_prop('parent5', 'font-size', '10px');
-}, "JS Attributes are valid for element 5");
-</script>
diff --git a/LayoutTests/css-custom-properties-api/inline-expected.txt b/LayoutTests/css-custom-properties-api/inline-expected.txt
deleted file mode 100644 (file)
index e568162..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-test
-
-
-PASS CSSOM setters function as expected for unregistered properties 
-PASS CSS.registerProperty 
-PASS Formerly valid values are still readable from inline styles but are computed as the unset value 
-PASS Values not matching the registered type can't be set 
-PASS Values can be removed from inline styles 
-PASS Stylesheets can be modified by CSSOM 
-PASS Valid values can be set on inline styles 
-PASS Var values are accepted 
-PASS Var values are accepted without validation 
-PASS Var values are accepted without validation, even when it is obvious they will not parse 
-PASS Var values are accepted without validation, even when it is obvious they will not parse (typed) 
-
diff --git a/LayoutTests/css-custom-properties-api/inline.html b/LayoutTests/css-custom-properties-api/inline.html
deleted file mode 100644 (file)
index 51ba7fe..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE html><!-- webkit-test-runner [ experimental:CSSCustomPropertiesAndValuesEnabled=true ] -->
-<!-- https://chromium.googlesource.com/chromium/src/+/01ce431409e3a019858677626a983c55168da6dc/third_party/WebKit/LayoutTests/custom-properties/register-property.html -->
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-
-<style>
-  #test1 {
-    --a: 10em;
-    --b: 10em;
-  }
-</style>
-<div>
-  <div id=test1><p>test</p></div>
-</div>
-<script>
-
-var computedStyle = getComputedStyle(test1);
-var inlineStyle = test1.style;
-var sheetStyle = document.styleSheets[0].cssRules[0].style;
-
-test(function() {
-  // Nothing registered yet, whatever you specify works
-  assert_equals(computedStyle.getPropertyValue('--a'), ' 10em');
-  assert_equals(computedStyle.getPropertyValue('--b'), ' 10em');
-
-  inlineStyle.setProperty('--a', 'hello');
-  inlineStyle.setProperty('--b', 'bonjour');
-
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'hello');
-  assert_equals(inlineStyle.getPropertyValue('--b'), 'bonjour');
-  assert_equals(computedStyle.getPropertyValue('--a'), 'hello');
-  assert_equals(computedStyle.getPropertyValue('--b'), 'bonjour');
-}, "CSSOM setters function as expected for unregistered properties");
-
-test(function() {
-  CSS.registerProperty({name: '--a', syntax: '<length>', initialValue: '0px', inherits: false});
-  CSS.registerProperty({name: '--registered', syntax: '<length>', initialValue: '0px', inherits: false});
-}, "CSS.registerProperty");
-
-test(function() {
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'hello');
-  assert_equals(inlineStyle.getPropertyValue('--b'), 'bonjour');
-  assert_equals(computedStyle.getPropertyValue('--a'), '0px');
-  assert_equals(computedStyle.getPropertyValue('--b'), 'bonjour');
-}, "Formerly valid values are still readable from inline styles but are computed as the unset value");
-
-test(function() {
-  inlineStyle.setProperty('--a', 'hi');
-  inlineStyle.setProperty('--b', 'hi');
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'hello');
-  assert_equals(inlineStyle.getPropertyValue('--b'), 'hi');
-}, "Values not matching the registered type can't be set");
-
-test(function() {
-  inlineStyle.removeProperty('--a');
-  inlineStyle.setProperty('--b', '');
-  assert_equals(inlineStyle.getPropertyValue('--a'), '');
-  assert_equals(inlineStyle.getPropertyValue('--b'), '');
-  assert_equals(computedStyle.getPropertyValue('--a'), '160px');
-  assert_equals(computedStyle.getPropertyValue('--b'), ' 10em');
-}, "Values can be removed from inline styles");
-
-test(function() {
-  sheetStyle.setProperty('--a', 'banana'); // Invalid, no change
-  assert_equals(computedStyle.getPropertyValue('--a'), '160px');
-  sheetStyle.setProperty('--a', '20px');
-  assert_equals(computedStyle.getPropertyValue('--a'), '20px');
-  sheetStyle.setProperty('--a', 'initial');
-  assert_equals(computedStyle.getPropertyValue('--a'), '0px');
-}, "Stylesheets can be modified by CSSOM");
-
-test(function() {
-  inlineStyle.setProperty('--a', '30em');
-  inlineStyle.setProperty('--b', '20em');
-  assert_equals(inlineStyle.getPropertyValue('--a'), '30em');
-  assert_equals(inlineStyle.getPropertyValue('--b'), '20em');
-  assert_equals(computedStyle.getPropertyValue('--a'), '480px');
-  assert_equals(computedStyle.getPropertyValue('--b'), '20em');
-  inlineStyle.setProperty('--a', 'inherit');
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'inherit');
-  assert_equals(computedStyle.getPropertyValue('--a'), '0px');
-}, "Valid values can be set on inline styles");
-
-test(function() {
-  inlineStyle.setProperty('--b', ' 20px');
-  inlineStyle.setProperty('--a', 'calc(var(--b) + 10px)');
-  assert_equals(inlineStyle.getPropertyValue('--b'), ' 20px');
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'calc(var(--b) + 10px)');
-  assert_equals(computedStyle.getPropertyValue('--b'), ' 20px');
-  assert_equals(computedStyle.getPropertyValue('--a'), '30px');
-}, "Var values are accepted");
-
-test(function() {
-  inlineStyle.setProperty('--b', 'hello');
-  inlineStyle.setProperty('--a', 'calc(var(--b) + 15px)');
-  assert_equals(inlineStyle.getPropertyValue('--b'), 'hello');
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'calc(var(--b) + 15px)');
-  assert_equals(computedStyle.getPropertyValue('--b'), 'hello');
-  assert_equals(computedStyle.getPropertyValue('--a'), '0px');
-}, "Var values are accepted without validation");
-
-test(function() {
-  inlineStyle.setProperty('--b', 'hello');
-  inlineStyle.setProperty('--a', 'calc(var(--b) 15px)');
-  assert_equals(inlineStyle.getPropertyValue('--b'), 'hello');
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'calc(var(--b) 15px)');
-  assert_equals(computedStyle.getPropertyValue('--b'), 'hello');
-  assert_equals(computedStyle.getPropertyValue('--a'), '0px');
-}, "Var values are accepted without validation, even when it is obvious they will not parse");
-
-test(function() {
-  inlineStyle.setProperty('--b', 'hello');
-  inlineStyle.setProperty('--a', 'calc(var(--registered) 15px)');
-  assert_equals(inlineStyle.getPropertyValue('--b'), 'hello');
-  assert_equals(inlineStyle.getPropertyValue('--a'), 'calc(var(--registered) 15px)');
-  assert_equals(computedStyle.getPropertyValue('--b'), 'hello');
-  assert_equals(computedStyle.getPropertyValue('--a'), '0px');
-}, "Var values are accepted without validation, even when it is obvious they will not parse (typed)");
-
-</script>
index c216a75..985c1fa 100644 (file)
@@ -1,3 +1,17 @@
+2018-10-29  Justin Michaud  <justin_michaud@apple.com>
+
+        Revert r237347 registered custom properties... https://bugs.webkit.org/show_bug.cgi?id=190039
+        https://bugs.webkit.org/show_bug.cgi?id=190919
+
+        Reviewed by Michael Saboff.
+
+        * web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt:
+        * web-platform-tests/css/css-properties-values-api/typedom.tentative-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-28  Andy Estes  <aestes@apple.com>
 
         [Payment Request] Implement MerchantValidationEvent.methodName
index 2ea78e2..e9e2fe7 100644 (file)
@@ -1,5 +1,5 @@
 
-PASS syntax:'*', initialValue:'a' 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 
 FAIL syntax:' <number>', initialValue:'5' is valid The given initial value does not parse for the given syntax.
@@ -9,11 +9,11 @@ FAIL syntax:' <length>+ | <percentage>', initialValue:'2px 8px' is valid The giv
 PASS syntax:'<length>|<percentage>|<length-percentage>', initialValue:'2px' 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.
-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:'*', 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 does not parse for the given syntax.
+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 
@@ -63,7 +63,7 @@ banana\r
 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.
-PASS syntax:'undefined', initialValue:'undefined' is valid 
+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 
@@ -85,36 +85,36 @@ 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
+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 
-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
+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
 PASS syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is invalid 
-FAIL syntax:'<length>', initialValue:'10em' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+PASS syntax:'<length>', initialValue:'10em' is invalid 
 FAIL syntax:'<length>', initialValue:'10vmin' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
-FAIL syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+PASS syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid 
+PASS syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid 
+PASS syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid 
 PASS syntax:'<length>+', initialValue:'10px calc(20px + 4rem)' is invalid 
 PASS syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid 
 PASS syntax:'<length>', initialValue:'10px;' is invalid 
-FAIL syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
+PASS syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid 
 FAIL syntax:'<percentage>', initialValue:'0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
 PASS syntax:'<integer>', initialValue:'1.0' is invalid 
 PASS syntax:'<integer>', initialValue:'1e0' is invalid 
index 5654e82..fc27b0d 100644 (file)
@@ -2,6 +2,6 @@
 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. 
-PASS Reference to undefined variable results in inherited value 
-PASS Reference to syntax-incompatible variable results in inherited 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 efcc5c2..0d5561f 100644 (file)
@@ -2,8 +2,8 @@
 PASS CSSOM setters function as expected for unregistered properties 
 FAIL CSS.registerProperty The given initial value does not parse for the given syntax.
 FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "blue" but got "hello"
-FAIL Values not matching the registered type can't be set assert_equals: expected "hello" but got "20"
+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 "red" but got " red"
-PASS Stylesheets can be modified by CSSOM 
+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 66fbbca..1e4d270 100644 (file)
@@ -2,7 +2,7 @@ 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 * 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.
index 9314512..2bedf68 100644 (file)
@@ -1,6 +1,6 @@
 
-PASS A var() cycle between two registered properties is handled correctly. 
-PASS A var() cycle between a registered properties and an unregistered property is handled correctly. 
+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. 
-PASS A var() cycle between a syntax:'*' property and an unregistered property 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 39e675d..db535e4 100644 (file)
@@ -1,5 +1,5 @@
 
-FAIL var() references work with registered properties assert_equals: expected "  10px" but got " 10px"
+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 8a4d6d9..6d64558 100644 (file)
@@ -1,3 +1,97 @@
+2018-10-29  Justin Michaud  <justin_michaud@apple.com>
+
+        Revert r237347 registered custom properties... https://bugs.webkit.org/show_bug.cgi?id=190039
+        https://bugs.webkit.org/show_bug.cgi?id=190919
+
+        Reviewed by Michael Saboff.
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::customPropertyValue):
+        * css/CSSCustomPropertyValue.cpp:
+        (WebCore::CSSCustomPropertyValue::customCSSText const):
+        (WebCore::CSSCustomPropertyValue::tokens const):
+        (WebCore::CSSCustomPropertyValue::checkVariablesForCycles const):
+        (WebCore::CSSCustomPropertyValue::resolveVariableReferences const):
+        (WebCore::CSSCustomPropertyValue::setResolvedTypedValue):
+        (WebCore::CSSCustomPropertyValue::equals const): Deleted.
+        * css/CSSCustomPropertyValue.h:
+        * css/CSSRegisteredCustomProperty.cpp:
+        (WebCore::CSSRegisteredCustomProperty::CSSRegisteredCustomProperty):
+        * css/CSSRegisteredCustomProperty.h:
+        * css/CSSVariableData.cpp:
+        (WebCore::CSSVariableData::consumeAndUpdateTokens):
+        (WebCore::CSSVariableData::CSSVariableData):
+        (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:
+        (WebCore::CSSVariableData::create):
+        (WebCore::CSSVariableData::createResolved):
+        (WebCore::CSSVariableData::needsVariableResolution const):
+        (WebCore::CSSVariableData::CSSVariableData):
+        * css/CSSVariableReferenceValue.cpp:
+        (WebCore::CSSVariableReferenceValue::checkVariablesForCycles const):
+        (WebCore::resolveVariableFallback): Deleted.
+        (WebCore::resolveVariableReference): Deleted.
+        (WebCore::resolveTokenRange): Deleted.
+        (WebCore::CSSVariableReferenceValue::resolveVariableReferences const): Deleted.
+        * css/CSSVariableReferenceValue.h:
+        (WebCore::CSSVariableReferenceValue::create):
+        (WebCore::CSSVariableReferenceValue::variableDataValue const):
+        (WebCore::CSSVariableReferenceValue::equals const):
+        * css/DOMCSSRegisterCustomProperty.cpp:
+        (WebCore::DOMCSSRegisterCustomProperty::registerProperty):
+        * css/PropertySetCSSStyleDeclaration.cpp:
+        (WebCore::PropertySetCSSStyleDeclaration::setProperty):
+        * css/StyleBuilderCustom.h:
+        (WebCore::StyleBuilderCustom::applyInitialCustomProperty):
+        (WebCore::StyleBuilderCustom::applyValueCustomProperty):
+        * css/StyleProperties.cpp:
+        (WebCore::MutableStyleProperties::setCustomProperty):
+        * css/StyleProperties.h:
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::State::setStyle):
+        (WebCore::StyleResolver::styleForKeyframe):
+        (WebCore::StyleResolver::styleForPage):
+        (WebCore::StyleResolver::applyMatchedProperties):
+        (WebCore::StyleResolver::applyPropertyToCurrentStyle):
+        (WebCore::StyleResolver::applyProperty):
+        (WebCore::StyleResolver::resolvedVariableValue const):
+        (WebCore::StyleResolver::CascadedProperties::applyDeferredProperties):
+        (WebCore::StyleResolver::CascadedProperties::Property::apply):
+        (WebCore::StyleResolver::applyCascadedProperties):
+        (WebCore::StyleResolver::applyCascadedCustomProperty): Deleted.
+        * css/StyleResolver.h:
+        * css/parser/CSSParser.cpp:
+        (WebCore::CSSParser::parseValueWithVariableReferences):
+        * css/parser/CSSParser.h:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::CSSPropertyParser::CSSPropertyParser):
+        (WebCore::CSSPropertyParser::parseValueStart):
+        (WebCore::CSSPropertyParser::parseSingleValue):
+        (WebCore::CSSPropertyParser::canParseTypedCustomPropertyValue): Deleted.
+        (WebCore::CSSPropertyParser::parseTypedCustomPropertyValue): Deleted.
+        (WebCore::CSSPropertyParser::collectParsedCustomPropertyValueDependencies): Deleted.
+        * css/parser/CSSPropertyParser.h:
+        * css/parser/CSSVariableParser.cpp:
+        (WebCore::CSSVariableParser::parseDeclarationValue):
+        * dom/ConstantPropertyMap.cpp:
+        (WebCore::ConstantPropertyMap::setValueForProperty):
+        (WebCore::variableDataForPositivePixelLength):
+        (WebCore::variableDataForPositiveDuration):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::checkVariablesInCustomProperties):
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::setInheritedCustomPropertyValue):
+        (WebCore::RenderStyle::setNonInheritedCustomPropertyValue):
+        * rendering/style/StyleCustomPropertyData.h:
+        (WebCore::StyleCustomPropertyData::operator== const):
+        (WebCore::StyleCustomPropertyData::setCustomPropertyValue):
+        (WebCore::StyleCustomPropertyData::StyleCustomPropertyData):
+
 2018-10-29  Youenn Fablet  <youenn@apple.com>
 
         Handle MDNS resolution of candidates through libwebrtc directly
index 0749d9a..c77648e 100644 (file)
@@ -2612,23 +2612,21 @@ RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& prope
     auto* registered = styledElement->document().getCSSRegisteredCustomPropertySet().get(propertyName);
     auto* value = style->getCustomProperty(propertyName);
 
-    if (registered && !value)
-        return registered->initialValueCopy();
+    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);
 
-    if (!value)
         return nullptr;
+    }
 
-    auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>&) {
-        ASSERT_NOT_REACHED();
-        return RefPtr<CSSValue>();
-    }, [&](const CSSValueID&) {
+    if (value)
         return CSSCustomPropertyValue::create(*value);
-    }, [&](const Ref<CSSVariableData>&) {
-        return CSSCustomPropertyValue::create(*value);
-    }, [&](const Length& value) {
-        return zoomAdjustedPixelValueForLength(value, *style);
-    });
-    return WTF::visit(visitor, value->value());
+
+    return nullptr;
 }
 
 String ComputedStyleExtractor::customPropertyText(const String& propertyName)
index e6966ff..7c16e84 100644 (file)
 #include "CSSCustomPropertyValue.h"
 #include "CSSTokenizer.h"
 
-namespace WebCore {
 
-bool CSSCustomPropertyValue::equals(const CSSCustomPropertyValue& other) const
-{
-    if (m_name != other.m_name || m_value.index() != other.m_value.index())
-        return false;
-    auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) {
-        return value.get() == WTF::get<Ref<CSSVariableReferenceValue>>(other.m_value).get();
-    }, [&](const CSSValueID& value) {
-        return value == WTF::get<CSSValueID>(other.m_value);
-    }, [&](const Ref<CSSVariableData>& value) {
-        return value.get() == WTF::get<Ref<CSSVariableData>>(other.m_value).get();
-    }, [&](const Length& value) {
-        return value == WTF::get<Length>(other.m_value);
-    });
-    return WTF::visit(visitor, m_value);
-}
+namespace WebCore {
 
 String CSSCustomPropertyValue::customCSSText() const
 {
     if (!m_serialized) {
         m_serialized = true;
-
-        auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) {
-            m_stringValue = value->cssText();
-        }, [&](const CSSValueID& value) {
-            m_stringValue = getValueName(value);
-        }, [&](const Ref<CSSVariableData>& value) {
-            m_stringValue = value->tokenRange().serialize();
-        }, [&](const Length& value) {
-            m_stringValue = CSSPrimitiveValue::create(value.value(), CSSPrimitiveValue::CSS_PX)->cssText();
-        });
-        WTF::visit(visitor, m_value);
+        if (m_resolvedTypedValue) // FIXME: Unit should be based on syntax.
+            m_stringValue = CSSPrimitiveValue::create(m_resolvedTypedValue->value(), CSSPrimitiveValue::CSS_PX)->cssText();
+        else if (m_value)
+            m_stringValue = m_value->tokenRange().serialize();
+        else if (m_valueId != CSSValueInvalid)
+            m_stringValue = getValueName(m_valueId);
+        else
+            m_stringValue = emptyString();
     }
     return m_stringValue;
 }
 
-Vector<CSSParserToken> CSSCustomPropertyValue::tokens() const
+Vector<CSSParserToken> CSSCustomPropertyValue::tokens(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style) const
 {
-    Vector<CSSParserToken> result;
-
-    auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>&) {
-        ASSERT_NOT_REACHED();
-    }, [&](const CSSValueID&) {
-        // Do nothing
-    }, [&](const Ref<CSSVariableData>& value) {
-        result.appendVector(value->tokens());
-    }, [&](const Length&) {
+    if (m_resolvedTypedValue) {
+        Vector<CSSParserToken> result;
         CSSTokenizer tokenizer(cssText());
 
         auto tokenizerRange = tokenizer.tokenRange();
         while (!tokenizerRange.atEnd())
             result.append(tokenizerRange.consume());
-    });
-    WTF::visit(visitor, m_value);
 
-    return result;
+        return result;
+    }
+
+    if (!m_value)
+        return { };
+
+    if (m_containsVariables) {
+        Vector<CSSParserToken> result;
+        // FIXME: Avoid doing this work more than once.
+        RefPtr<CSSVariableData> resolvedData = m_value->resolveVariableReferences(registeredProperties, style);
+        if (resolvedData)
+            result.appendVector(resolvedData->tokens());
+
+        return result;
+    }
+
+    return m_value->tokens();
+}
+
+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, style, seenProperties, invalidProperties);
+    return true;
+}
+
+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(registeredProperties, style);
+    if (resolvedData)
+        resolvedValues.append(CSSCustomPropertyValue::createWithVariableData(m_name, resolvedData.releaseNonNull()));
+    else
+        resolvedValues.append(CSSCustomPropertyValue::createWithID(m_name, CSSValueInvalid));
+}
+
+void CSSCustomPropertyValue::setResolvedTypedValue(Length length)
+{
+    ASSERT(length.isSpecified());
+    m_resolvedTypedValue = WTFMove(length);
 }
 
 }
index 625e195..bb09214 100644 (file)
 
 #include "CSSRegisteredCustomProperty.h"
 #include "CSSValue.h"
-#include "CSSVariableReferenceValue.h"
+#include "CSSVariableData.h"
 #include "Length.h"
 #include <wtf/RefPtr.h>
-#include <wtf/Variant.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
 class CSSParserToken;
-class CSSVariableReferenceValue;
 class RenderStyle;
 
 class CSSCustomPropertyValue final : public CSSValue {
 public:
-    using VariantValue = Variant<Ref<CSSVariableReferenceValue>, CSSValueID, Ref<CSSVariableData>, Length>;
-
-    static Ref<CSSCustomPropertyValue> createUnresolved(const AtomicString& name, Ref<CSSVariableReferenceValue>&& value)
-    {
-        return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
-    }
-
-    static Ref<CSSCustomPropertyValue> createUnresolved(const AtomicString& name, CSSValueID value)
+    static Ref<CSSCustomPropertyValue> createWithVariableData(const AtomicString& name, Ref<CSSVariableData>&& value)
     {
-        return adoptRef(*new CSSCustomPropertyValue(name, { value }));
+        return adoptRef(*new CSSCustomPropertyValue(name, WTFMove(value)));
     }
-
-    static Ref<CSSCustomPropertyValue> createWithID(const AtomicString& name, CSSValueID id)
-    {
-        ASSERT(id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset || id == CSSValueRevert || id == CSSValueInvalid);
-        return adoptRef(*new CSSCustomPropertyValue(name, { id }));
-    }
-
-    static Ref<CSSCustomPropertyValue> createSyntaxAll(const AtomicString& name, Ref<CSSVariableData>&& value)
+    
+    static Ref<CSSCustomPropertyValue> createWithID(const AtomicString& name, CSSValueID value)
     {
-        return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
+        return adoptRef(*new CSSCustomPropertyValue(name, value));
     }
     
-    static Ref<CSSCustomPropertyValue> createSyntaxLength(const AtomicString& name, Length value)
+    static Ref<CSSCustomPropertyValue> createInvalid()
     {
-        return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
+        return adoptRef(*new CSSCustomPropertyValue(emptyString(), emptyString()));
     }
 
     static Ref<CSSCustomPropertyValue> create(const CSSCustomPropertyValue& other)
@@ -77,49 +62,70 @@ public:
     String customCSSText() const;
 
     const AtomicString& name() const { return m_name; }
-    bool isResolved() const  { return !WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(m_value); }
-    bool isUnset() const  { return WTF::holds_alternative<CSSValueID>(m_value) && WTF::get<CSSValueID>(m_value) == CSSValueUnset; }
-    bool isInvalid() const  { return WTF::holds_alternative<CSSValueID>(m_value) && WTF::get<CSSValueID>(m_value) == CSSValueInvalid; }
+    
+    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 { ASSERT(!m_containsVariables || !m_resolvedTypedValue); return m_containsVariables; }
+    bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+
+    void resolveVariableReferences(const CSSRegisteredCustomPropertySet&, Vector<Ref<CSSCustomPropertyValue>>&, const RenderStyle&) const;
 
-    const VariantValue& value() const { return m_value; }
+    CSSValueID valueID() const { return m_valueId; }
+    CSSVariableData* value() const { return m_value.get(); }
+    Vector<CSSParserToken> tokens(const CSSRegisteredCustomPropertySet&, const RenderStyle&) const;
 
-    Vector<CSSParserToken> tokens() const;
-    bool equals(const CSSCustomPropertyValue& other) const;
+    const std::optional<Length>& resolvedTypedValue() const { return m_resolvedTypedValue; }
+    void setResolvedTypedValue(Length);
 
 private:
-    CSSCustomPropertyValue(const AtomicString& name, VariantValue&& value)
+    CSSCustomPropertyValue(const AtomicString& name, const String& serializedValue)
+        : CSSValue(CustomPropertyClass)
+        , m_name(name)
+        , m_stringValue(serializedValue)
+        , m_serialized(true)
+    {
+    }
+
+    CSSCustomPropertyValue(const AtomicString& name, CSSValueID id)
+        : CSSValue(CustomPropertyClass)
+        , m_name(name)
+        , m_valueId(id)
+    {
+        ASSERT(id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset || id == CSSValueRevert || id == CSSValueInvalid);
+    }
+    
+    CSSCustomPropertyValue(const AtomicString& name, Ref<CSSVariableData>&& value)
         : CSSValue(CustomPropertyClass)
         , m_name(name)
         , m_value(WTFMove(value))
-        , m_serialized(false)
+        , m_valueId(CSSValueInternalVariableValue)
+        , m_containsVariables(m_value->needsVariableResolution())
     {
     }
 
     CSSCustomPropertyValue(const CSSCustomPropertyValue& other)
         : CSSValue(CustomPropertyClass)
         , m_name(other.m_name)
-        , m_value(CSSValueUnset)
+        , 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)
     {
-        // No copy constructor for Ref<CSSVariableData>, so we have to do this ourselves
-        auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) {
-            m_value = value.copyRef();
-        }, [&](const CSSValueID& value) {
-            m_value = value;
-        }, [&](const Ref<CSSVariableData>& value) {
-            m_value = value.copyRef();
-        }, [&](const Length& value) {
-            m_value = value;
-        });
-        WTF::visit(visitor, other.m_value);
     }
     
     const AtomicString m_name;
-    VariantValue m_value;
+    
+    RefPtr<CSSVariableData> m_value;
+    CSSValueID m_valueId { CSSValueInvalid };
     
     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
index 79ef7fe..3ea7b92 100644 (file)
@@ -30,9 +30,8 @@
 
 namespace WebCore {
 
-CSSRegisteredCustomProperty::CSSRegisteredCustomProperty(const String& name, const String& syntax, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue)
+CSSRegisteredCustomProperty::CSSRegisteredCustomProperty(const String& name, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue)
     : name(name)
-    , syntax(syntax)
     , inherits(inherits)
     , m_initialValue(WTFMove(initialValue))
 {
index dfcf0bd..3427eaa 100644 (file)
@@ -33,10 +33,10 @@ class CSSCustomPropertyValue;
 
 struct CSSRegisteredCustomProperty {
     const String name;
-    const String syntax;
+    /* TODO syntax */
     const bool inherits;
 
-    CSSRegisteredCustomProperty(const String& name, const String& syntax, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue);
+    CSSRegisteredCustomProperty(const String& name, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue);
 
     const CSSCustomPropertyValue* initialValue() const { return m_initialValue.get(); }
     RefPtr<CSSCustomPropertyValue> initialValueCopy() const;
index 604ca18..9899353 100644 (file)
@@ -60,7 +60,7 @@ bool CSSVariableData::operator==(const CSSVariableData& other) const
     return tokens() == other.tokens();
 }
 
-CSSVariableData::CSSVariableData(const CSSParserTokenRange& range)
+void CSSVariableData::consumeAndUpdateTokens(const CSSParserTokenRange& range)
 {
     StringBuilder stringBuilder;
     CSSParserTokenRange localRange = range;
@@ -77,4 +77,109 @@ CSSVariableData::CSSVariableData(const CSSParserTokenRange& range)
         updateTokens<UChar>(range);
 }
 
+CSSVariableData::CSSVariableData(const CSSParserTokenRange& range, bool needsVariableResolution)
+    : m_needsVariableResolution(needsVariableResolution)
+{
+    consumeAndUpdateTokens(range);
+}
+
+bool CSSVariableData::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+{
+    if (invalidProperties.contains(name))
+        return false;
+    
+    HashSet<AtomicString> newSeenProperties = seenProperties;
+    newSeenProperties.add(name);
+    
+    bool valid = checkVariablesForCyclesWithRange(m_tokens, style, newSeenProperties, invalidProperties);
+    if (!valid)
+        invalidProperties.add(name);
+    
+    return valid;
+}
+    
+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) {
+            CSSParserTokenRange block = range.consumeBlock();
+            
+            block.consumeWhitespace();
+            ASSERT(block.peek().type() == IdentToken);
+            AtomicString variableName = block.consumeIncludingWhitespace().value().toAtomicString();
+            ASSERT(block.atEnd() || block.peek().type() == CommaToken);
+            if (seenProperties.contains(variableName))
+                return false;
+
+            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, style, seenProperties, invalidProperties);
+            }
+        } else
+            range.consume();
+    }
+    return true;
+}
+
+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(registeredProperties, range, result, style);
+}
+
+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));
+    
+    auto* property = style.getCustomProperty(variableName);
+    if (property && property->resolvedTypedValue()) {
+        result.appendVector(property->tokens(registeredProperties, style));
+        return true;
+    }
+
+    if (!property || !property->value()) {
+        auto* registered = registeredProperties.get(variableName);
+        if (registered && registered->initialValue())
+            property = registered->initialValue();
+        else
+            return resolveVariableFallback(registeredProperties, range, result, style);
+    }
+    ASSERT(property);
+    result.appendVector(property->tokens(registeredProperties, style));
+    
+    return true;
+}
+
+RefPtr<CSSVariableData> CSSVariableData::resolveVariableReferences(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style) const
+{
+    Vector<CSSParserToken> resolvedTokens;
+    CSSParserTokenRange range = m_tokens;
+    if (!resolveTokenRange(registeredProperties, range, resolvedTokens, style))
+        return nullptr;
+    return CSSVariableData::createResolved(resolvedTokens, *this);
+}
+    
+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(registeredProperties, range.consumeBlock(), result, style);
+        else
+            result.append(range.consume());
+    }
+    return success;
+}
+
 } // namespace WebCore
index 396e069..008a6fa 100644 (file)
@@ -43,9 +43,14 @@ class CSSVariableData : public RefCounted<CSSVariableData> {
     WTF_MAKE_NONCOPYABLE(CSSVariableData);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static Ref<CSSVariableData> create(const CSSParserTokenRange& range)
+    static Ref<CSSVariableData> create(const CSSParserTokenRange& range, bool needsVariableResolution = true)
     {
-        return adoptRef(*new CSSVariableData(range));
+        return adoptRef(*new CSSVariableData(range, needsVariableResolution));
+    }
+
+    static Ref<CSSVariableData> createResolved(const Vector<CSSParserToken>& resolvedTokens, const CSSVariableData& unresolvedData)
+    {
+        return adoptRef(*new CSSVariableData(resolvedTokens, unresolvedData.m_backingString));
     }
 
     CSSParserTokenRange tokenRange() { return m_tokens; }
@@ -54,12 +59,36 @@ public:
 
     bool operator==(const CSSVariableData& other) const;
 
+    bool needsVariableResolution() const { return m_needsVariableResolution; }
+
+    bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+
+    RefPtr<CSSVariableData> resolveVariableReferences(const CSSRegisteredCustomPropertySet&, const RenderStyle&) const;
+    bool resolveTokenRange(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;
+
 private:
-    CSSVariableData(const CSSParserTokenRange&);
+    CSSVariableData(const CSSParserTokenRange&, bool needsVariableResolution);
+
+    // We can safely copy the tokens (which have raw pointers to substrings) because
+    // StylePropertySets contain references to CSSCustomPropertyValues, which
+    // point to the unresolved CSSVariableData values that own the backing strings
+    // this will potentially reference.
+    CSSVariableData(const Vector<CSSParserToken>& resolvedTokens, String backingString)
+        : m_backingString(backingString)
+        , m_tokens(resolvedTokens)
+        , m_needsVariableResolution(false)
+    { }
+
+    void consumeAndUpdateTokens(const CSSParserTokenRange&);
     template<typename CharacterType> void updateTokens(const CSSParserTokenRange&);
+    
+    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;
+    const bool m_needsVariableResolution;
 
     // FIXME-NEWPARSER: We want to cache StyleProperties once we support @apply.
 };
index 77a523e..38957e4 100644 (file)
@@ -30,9 +30,6 @@
 #include "config.h"
 #include "CSSVariableReferenceValue.h"
 
-#include "RenderStyle.h"
-#include "StyleResolver.h"
-
 namespace WebCore {
 
 String CSSVariableReferenceValue::customCSSText() const
@@ -43,72 +40,11 @@ String CSSVariableReferenceValue::customCSSText() const
     }
     return m_stringValue;
 }
-
-static bool resolveTokenRange(CSSParserTokenRange, Vector<CSSParserToken>&, ApplyCascadedPropertyState&);
-
-static bool resolveVariableFallback(CSSParserTokenRange range, Vector<CSSParserToken>& result, ApplyCascadedPropertyState& state)
-{
-    if (range.atEnd())
-        return false;
-    ASSERT(range.peek().type() == CommaToken);
-    range.consume();
-    return resolveTokenRange(range, result, state);
-}
-
-static bool resolveVariableReference(CSSParserTokenRange range, Vector<CSSParserToken>& result, ApplyCascadedPropertyState& state)
+    
+bool CSSVariableReferenceValue::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
 {
-    auto& registeredProperties = state.styleResolver->document().getCSSRegisteredCustomPropertySet();
-    auto& style = *state.styleResolver->style();
-
-    range.consumeWhitespace();
-    ASSERT(range.peek().type() == IdentToken);
-    String variableName = range.consumeIncludingWhitespace().value().toString();
-    ASSERT(range.atEnd() || (range.peek().type() == CommaToken));
-
-    // Apply this variable first, in case it is still unresolved
-    state.styleResolver->applyCascadedCustomProperty(variableName, state);
-
-    // Apply fallback to detect cycles
-    Vector<CSSParserToken> fallbackResult;
-    resolveVariableFallback(CSSParserTokenRange(range), fallbackResult, state);
-
-    auto* property = style.getCustomProperty(variableName);
-
-    if (!property || property->isUnset() || property->isInvalid()) {
-        auto* registered = registeredProperties.get(variableName);
-        if (registered && registered->initialValue())
-            property = registered->initialValue();
-        else
-            return resolveVariableFallback(range, result, state);
-    }
-
-    ASSERT(property->isResolved());
-    result.appendVector(property->tokens());
-
-    return true;
-}
-
-static bool resolveTokenRange(CSSParserTokenRange range, Vector<CSSParserToken>& result, ApplyCascadedPropertyState& state)
-{
-    bool success = true;
-    while (!range.atEnd()) {
-        if (range.peek().functionId() == CSSValueVar || range.peek().functionId() == CSSValueEnv)
-            success &= resolveVariableReference(range.consumeBlock(), result, state);
-        else
-            result.append(range.consume());
-    }
-    return success;
-}
-
-RefPtr<CSSVariableData> CSSVariableReferenceValue::resolveVariableReferences(ApplyCascadedPropertyState& state) const
-{
-    Vector<CSSParserToken> resolvedTokens;
-    CSSParserTokenRange range = m_data->tokenRange();
-
-    if (!resolveTokenRange(range, resolvedTokens, state))
-        return nullptr;
-
-    return CSSVariableData::create(resolvedTokens);
+    ASSERT(m_data);
+    return m_data->checkVariablesForCycles(name, style, seenProperties, invalidProperties);
 }
 
 } // namespace WebCore
index d70e327..228964e 100644 (file)
 
 #pragma once
 
-#include "CSSParserToken.h"
-#include "CSSParserTokenRange.h"
 #include "CSSValue.h"
 #include "CSSVariableData.h"
-#include <wtf/HashSet.h>
 #include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-struct ApplyCascadedPropertyState;
-class CSSParserTokenRange;
-
 class CSSVariableReferenceValue : public CSSValue {
 public:
-    static Ref<CSSVariableReferenceValue> create(const CSSParserTokenRange& range)
+    static Ref<CSSVariableReferenceValue> create(Ref<CSSVariableData>&& data)
+    {
+        return adoptRef(*new CSSVariableReferenceValue(WTFMove(data)));
+    }
+
+    CSSVariableData* variableDataValue() const
     {
-        return adoptRef(*new CSSVariableReferenceValue(CSSVariableData::create(range)));
+        return m_data.get();
     }
 
-    bool equals(const CSSVariableReferenceValue& other) const { return m_data.get() == other.m_data.get(); }
+    bool equals(const CSSVariableReferenceValue& other) const { return m_data == other.m_data; }
     String customCSSText() const;
 
-    RefPtr<CSSVariableData> resolveVariableReferences(ApplyCascadedPropertyState&) const;
+    bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
 
 private:
     CSSVariableReferenceValue(Ref<CSSVariableData>&& data)
@@ -61,7 +59,7 @@ private:
     {
     }
 
-    Ref<CSSVariableData> m_data;
+    RefPtr<CSSVariableData> m_data;
     mutable String m_stringValue;
     mutable bool m_serialized { false };
 };
index b8ef6a9..37318da 100644 (file)
 
 #include "CSSCustomPropertyValue.h"
 #include "CSSPropertyNames.h"
-#include "CSSPropertyParser.h"
 #include "CSSRegisteredCustomProperty.h"
 #include "CSSTokenizer.h"
 #include "DOMCSSNamespace.h"
 #include "Document.h"
 #include "StyleBuilderConverter.h"
+#include "StyleResolver.h"
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -42,33 +42,28 @@ ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& docum
 {
     RefPtr<CSSCustomPropertyValue> initialValue;
     if (!descriptor.initialValue.isEmpty()) {
-        CSSTokenizer tokenizer(descriptor.initialValue);
+        initialValue = CSSCustomPropertyValue::createWithVariableData(descriptor.name, CSSVariableData::create(CSSParserTokenRange(Vector<CSSParserToken>()), false));
+        CSSParser parser(document);
         StyleResolver styleResolver(document);
 
-        // We need to initialize this so that we can successfully parse computationally dependent values (like em units).
-        // We don't actually need the values to be accurate, since they will be rejected later anyway
-        styleResolver.state().setStyle(styleResolver.defaultStyleForElement());
-        styleResolver.updateFont();
-
-        initialValue = CSSPropertyParser::parseTypedCustomPropertyValue(descriptor.name, descriptor.syntax, tokenizer.tokenRange(), styleResolver, strictCSSParserContext());
-
-        if (!initialValue || !initialValue->isResolved())
+        auto primitiveVal = parser.parseSingleValue(CSSPropertyCustom, descriptor.initialValue);
+        if (!primitiveVal || !primitiveVal->isPrimitiveValue())
             return Exception { SyntaxError, "The given initial value does not parse for the given syntax." };
 
         HashSet<CSSPropertyID> dependencies;
-        initialValue->collectDirectComputationalDependencies(dependencies);
-        initialValue->collectDirectRootComputationalDependencies(dependencies);
+        primitiveVal->collectDirectComputationalDependencies(dependencies);
+        primitiveVal->collectDirectRootComputationalDependencies(dependencies);
 
         if (!dependencies.isEmpty())
             return Exception { SyntaxError, "The given initial value must be computationally independent." };
+
+        initialValue->setResolvedTypedValue(StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));
     }
 
-    CSSRegisteredCustomProperty property { descriptor.name, descriptor.syntax, descriptor.inherits, WTFMove(initialValue) };
+    CSSRegisteredCustomProperty property { descriptor.name, descriptor.inherits, WTFMove(initialValue) };
     if (!document.registerCSSProperty(WTFMove(property)))
         return Exception { InvalidModificationError, "This property has already been registered." };
 
-    document.styleScope().didChangeStyleSheetEnvironment();
-
     return { };
 }
 
index 383ac8e..e28b34c 100644 (file)
@@ -226,16 +226,6 @@ bool PropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyNa
 ExceptionOr<void> PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority)
 {
     StyleAttributeMutationScope mutationScope(this);
-
-    if (!willMutate())
-        return { };
-
-    Document* document = nullptr;
-
-    if (parentElement())
-        document = &parentElement()->document();
-    else
-        document = parentStyleSheet()->ownerDocument();
     
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (isCustomPropertyName(propertyName))
@@ -243,13 +233,16 @@ ExceptionOr<void> PropertySetCSSStyleDeclaration::setProperty(const String& prop
     if (!propertyID)
         return { };
 
+    if (!willMutate())
+        return { };
+
     bool important = equalIgnoringASCIICase(priority, "important");
     if (!important && !priority.isEmpty())
         return { };
 
     bool changed;
     if (propertyID == CSSPropertyCustom)
-        changed = m_propertySet->setCustomProperty(document, propertyName, value, important, cssParserContext());
+        changed = m_propertySet->setCustomProperty(propertyName, value, important, cssParserContext());
     else
         changed = m_propertySet->setProperty(propertyID, value, important, cssParserContext());
 
index 2000fdc..0c47da2 100644 (file)
@@ -1879,13 +1879,13 @@ inline void StyleBuilderCustom::applyValueStrokeColor(StyleResolver& styleResolv
 
 inline void StyleBuilderCustom::applyInitialCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, const AtomicString& name)
 {
-    if (registered && registered->initialValue()) {
+    if (registered) {
         auto initialValue = registered->initialValueCopy();
         applyValueCustomProperty(styleResolver, registered, *initialValue);
         return;
     }
 
-    auto invalid = CSSCustomPropertyValue::createUnresolved(name, CSSValueInvalid);
+    auto invalid = CSSCustomPropertyValue::createWithID(name, CSSValueInvalid);
     applyValueCustomProperty(styleResolver, registered, invalid.get());
 }
 
@@ -1900,13 +1900,12 @@ inline void StyleBuilderCustom::applyInheritCustomProperty(StyleResolver& styleR
 
 inline void StyleBuilderCustom::applyValueCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, CSSCustomPropertyValue& value)
 {
-    ASSERT(value.isResolved());
     const auto& name = value.name();
 
     if (!registered || registered->inherits)
-        styleResolver.style()->setInheritedCustomPropertyValue(name, makeRef(value));
+        styleResolver.style()->setInheritedCustomPropertyValue(name, makeRef(value), registered);
     else
-        styleResolver.style()->setNonInheritedCustomPropertyValue(name, makeRef(value));
+        styleResolver.style()->setNonInheritedCustomPropertyValue(name, makeRef(value), registered);
 }
 
 } // namespace WebCore
index 5acb48f..5d78f8c 100644 (file)
@@ -28,8 +28,6 @@
 #include "CSSDeferredParser.h"
 #include "CSSParser.h"
 #include "CSSPendingSubstitutionValue.h"
-#include "CSSPropertyParser.h"
-#include "CSSTokenizer.h"
 #include "CSSValueKeywords.h"
 #include "CSSValueList.h"
 #include "CSSValuePool.h"
@@ -781,7 +779,7 @@ bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, const String&
     return setProperty(propertyID, value, important, parserContext);
 }
 
-bool MutableStyleProperties::setCustomProperty(const Document* document, const String& propertyName, const String& value, bool important, CSSParserContext parserContext)
+bool MutableStyleProperties::setCustomProperty(const String& propertyName, const String& value, bool important, CSSParserContext parserContext)
 {
     // Setting the value to an empty string just removes the property in both IE and Gecko.
     // Setting it to null seems to produce less consistent results, but we treat it just the same.
@@ -789,17 +787,6 @@ bool MutableStyleProperties::setCustomProperty(const Document* document, const S
         return removeCustomProperty(propertyName);
 
     parserContext.mode = cssParserMode();
-
-    String syntax = "*";
-    auto* registered = document ? document->getCSSRegisteredCustomPropertySet().get(propertyName) : nullptr;
-
-    if (registered)
-        syntax = registered->syntax;
-
-    CSSTokenizer tokenizer(value);
-    if (!CSSPropertyParser::canParseTypedCustomPropertyValue(syntax, tokenizer.tokenRange(), parserContext))
-        return false;
-
     // When replacing an existing property value, this moves the property to the end of the list.
     // Firefox preserves the position, and MSIE moves the property to the beginning.
     return CSSParser::parseCustomPropertyValue(*this, propertyName, value, important, parserContext) == CSSParser::ParseResult::Changed;
index 839a544..3f4b65a 100644 (file)
@@ -249,7 +249,7 @@ public:
     Vector<CSSProperty, 4> m_propertyVector;
 
     // Methods for querying and altering CSS custom properties.
-    bool setCustomProperty(const Document*, const String& propertyName, const String& value, bool important, CSSParserContext);
+    bool setCustomProperty(const String& propertyName, const String& value, bool important, CSSParserContext);
     bool removeCustomProperty(const String& propertyName, String* returnText = nullptr);
 
 private:
index 20f5b2e..d4e06bc 100644 (file)
@@ -321,7 +321,7 @@ inline void StyleResolver::State::updateConversionData()
     m_cssToLengthConversionData = CSSToLengthConversionData(m_style.get(), m_rootElementStyle, m_element ? m_element->document().renderView() : nullptr);
 }
 
-void StyleResolver::State::setStyle(std::unique_ptr<RenderStyle> style)
+inline void StyleResolver::State::setStyle(std::unique_ptr<RenderStyle> style)
 {
     m_style = WTFMove(style);
     updateConversionData();
@@ -429,21 +429,21 @@ std::unique_ptr<RenderStyle> StyleResolver::styleForKeyframe(const RenderStyle*
     CascadedProperties cascade(direction, writingMode);
     cascade.addNormalMatches(result, 0, result.matchedProperties().size() - 1);
 
-    ApplyCascadedPropertyState applyState { this, &cascade, &result };
-    applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState);
+    // Resolve custom properties first.
+    applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &result);
+
+    applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &result);
 
     // If our font got dirtied, update it now.
     updateFont();
 
-    // Now resolve remaining custom properties and the rest, in any order
-    for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it)
-        applyCascadedCustomProperty(it->key, applyState);
-    applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState);
+    // Now do rest of the properties.
+    applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &result);
 
     // If our font got dirtied by one of the non-essential font props, update it a second time.
     updateFont();
 
-    cascade.applyDeferredProperties(*this, applyState);
+    cascade.applyDeferredProperties(*this, &result);
 
     adjustRenderStyle(*state.style(), *state.parentStyle(), nullptr, nullptr);
 
@@ -635,18 +635,17 @@ std::unique_ptr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
     CascadedProperties cascade(direction, writingMode);
     cascade.addNormalMatches(result, 0, result.matchedProperties().size() - 1);
 
-    ApplyCascadedPropertyState applyState { this, &cascade, &result };
-    applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState);
+    // Resolve custom properties first.
+    applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &result);
+
+    applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &result);
 
     // If our font got dirtied, update it now.
     updateFont();
 
-    // Now resolve remaining custom properties and the rest, in any order
-    for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it)
-        applyCascadedCustomProperty(it->key, applyState);
-    applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState);
+    applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &result);
 
-    cascade.applyDeferredProperties(*this, applyState);
+    cascade.applyDeferredProperties(*this, &result);
 
     // Now return the style.
     return m_state.takeStyle();
@@ -1372,20 +1371,17 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
         cascade.addNormalMatches(matchResult, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
         cascade.addImportantMatches(matchResult, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
 
-        ApplyCascadedPropertyState applyState { this, &cascade, &matchResult };
-
-        applyCascadedProperties(CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, applyState);
+        applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, &matchResult);
         adjustStyleForInterCharacterRuby();
 
-        applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState);
+        // Resolve custom variables first.
+        applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &matchResult);
 
-        // If our font got dirtied, update it now.
-        updateFont();
+        // Start by applying properties that other properties may depend on.
+        applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &matchResult);
 
-        // Now resolve remaining custom properties and the rest, in any order
-        for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it)
-            applyCascadedCustomProperty(it->key, applyState);
-        applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState);
+        updateFont();
+        applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &matchResult);
 
         state.cacheBorderAndBackground();
     }
@@ -1396,13 +1392,16 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
     cascade.addImportantMatches(matchResult, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
     cascade.addImportantMatches(matchResult, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
 
+    // Resolve custom properties first.
+    applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &matchResult);
 
-    ApplyCascadedPropertyState applyState { this, &cascade, &matchResult };
+    applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, &matchResult);
 
-    applyCascadedProperties(CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, applyState);
+    // Adjust the font size to be smaller if ruby-position is inter-character.
     adjustStyleForInterCharacterRuby();
 
-    applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState);
+    // Start by applying properties that other properties may depend on.
+    applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &matchResult);
 
     // If the effective zoom value changes, we can't use the matched properties cache. Start over.
     if (cacheItem && cacheItem->renderStyle->effectiveZoom() != state.style()->effectiveZoom())
@@ -1415,15 +1414,13 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
     if (cacheItem && cacheItem->renderStyle->fontDescription() != state.style()->fontDescription())
         return applyMatchedProperties(matchResult, element, DoNotUseMatchedPropertiesCache);
 
-    // Now resolve remaining custom properties and the rest, in any order
-    for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it)
-        applyCascadedCustomProperty(it->key, applyState);
-    applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState);
+    // Apply properties that no other properties depend on.
+    applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &matchResult);
 
     // Finally, some properties must be applied in the order they were parsed.
     // There are some CSS properties that affect the same RenderStyle values,
     // so to preserve behavior, we queue them up during cascade and flush here.
-    cascade.applyDeferredProperties(*this, applyState);
+    cascade.applyDeferredProperties(*this, &matchResult);
 
     ASSERT(!state.fontDirty());
 
@@ -1444,9 +1441,8 @@ void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, std:
 
 void StyleResolver::applyPropertyToCurrentStyle(CSSPropertyID id, CSSValue* value)
 {
-    ApplyCascadedPropertyState applyState { this, nullptr, nullptr };
     if (value)
-        applyProperty(id, value, applyState);
+        applyProperty(id, value);
 }
 
 inline bool isValidVisitedLinkProperty(CSSPropertyID id)
@@ -1613,18 +1609,16 @@ StyleResolver::CascadedProperties* StyleResolver::cascadedPropertiesForRollback(
     return nullptr;
 }
 
-void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, ApplyCascadedPropertyState& applyState, SelectorChecker::LinkMatchMask linkMatchMask)
+void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, SelectorChecker::LinkMatchMask linkMatchMask, const MatchResult* matchResult)
 {
-    auto* matchResult = applyState.matchResult;
     ASSERT_WITH_MESSAGE(!isShorthandCSSProperty(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
 
     State& state = m_state;
 
     RefPtr<CSSValue> valueToApply = value;
     if (value->hasVariableReferences()) {
-        valueToApply = resolvedVariableValue(id, *value, applyState);
-        // If appliedProperties already has this id, then we detected a cycle, and this value should be unset.
-        if (!valueToApply || applyState.appliedProperties.contains(id)) {
+        valueToApply = resolvedVariableValue(id, *value);
+        if (!valueToApply) {
             if (CSSProperty::isInheritedProperty(id))
                 valueToApply = CSSValuePool::singleton().createInheritedValue();
             else
@@ -1635,7 +1629,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, ApplyCascad
     if (CSSProperty::isDirectionAwareProperty(id)) {
         CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode());
         ASSERT(newId != id);
-        return applyProperty(newId, valueToApply.get(), applyState, linkMatchMask);
+        return applyProperty(newId, valueToApply.get(), linkMatchMask, matchResult);
     }
 
     CSSValue* valueToCheckForInheritInitial = valueToApply.get();
@@ -1646,9 +1640,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, ApplyCascad
 
     if (id == CSSPropertyCustom) {
         customPropertyValue = &downcast<CSSCustomPropertyValue>(*valueToApply);
-        ASSERT(customPropertyValue->isResolved());
-        if (WTF::holds_alternative<CSSValueID>(customPropertyValue->value()))
-            customPropertyValueID = WTF::get<CSSValueID>(customPropertyValue->value());
+        customPropertyValueID = customPropertyValue->valueID();
         auto& name = customPropertyValue->name();
         customPropertyRegistered = document().getCSSRegisteredCustomPropertySet().get(name);
     }
@@ -1675,13 +1667,13 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, ApplyCascad
                 if (customPropertyRegistered && customPropertyRegistered->inherits && rollback->hasCustomProperty(customPropertyValue->name())) {
                     auto property = rollback->customProperty(customPropertyValue->name());
                     if (property.cssValue[linkMatchMask])
-                        applyProperty(property.id, property.cssValue[linkMatchMask], applyState, linkMatchMask);
+                        applyProperty(property.id, property.cssValue[linkMatchMask], linkMatchMask, matchResult);
                     return;
                 }
             } else if (rollback->hasProperty(id)) {
                 auto& property = rollback->property(id);
                 if (property.cssValue[linkMatchMask])
-                    applyProperty(property.id, property.cssValue[linkMatchMask], applyState, linkMatchMask);
+                    applyProperty(property.id, property.cssValue[linkMatchMask], linkMatchMask, matchResult);
                 return;
             }
 
@@ -1710,10 +1702,10 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, ApplyCascad
     StyleBuilder::applyProperty(id, *this, *valueToApply, isInitial, isInherit, customPropertyRegistered);
 }
 
-RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value, ApplyCascadedPropertyState& state) const
+RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value) const
 {
     CSSParser parser(document());
-    return parser.parseValueWithVariableReferences(propID, value, state);
+    return parser.parseValueWithVariableReferences(propID, value, document().getCSSRegisteredCustomPropertySet(), *m_state.style());
 }
 
 RefPtr<StyleImage> StyleResolver::styleImage(CSSValue& value)
@@ -2235,13 +2227,13 @@ void StyleResolver::CascadedProperties::addImportantMatches(const MatchResult& m
         addMatch(matchResult, match.index, true, inheritedOnly);
 }
 
-void StyleResolver::CascadedProperties::applyDeferredProperties(StyleResolver& resolver, ApplyCascadedPropertyState& applyState)
+void StyleResolver::CascadedProperties::applyDeferredProperties(StyleResolver& resolver, const MatchResult* matchResult)
 {
     for (auto& property : m_deferredProperties)
-        property.apply(resolver, applyState);
+        property.apply(resolver, matchResult);
 }
 
-void StyleResolver::CascadedProperties::Property::apply(StyleResolver& resolver, ApplyCascadedPropertyState& applyState)
+void StyleResolver::CascadedProperties::Property::apply(StyleResolver& resolver, const MatchResult* matchResult)
 {
     State& state = resolver.state();
     state.setCascadeLevel(level);
@@ -2250,7 +2242,7 @@ void StyleResolver::CascadedProperties::Property::apply(StyleResolver& resolver,
     if (cssValue[SelectorChecker::MatchDefault]) {
         state.setApplyPropertyToRegularStyle(true);
         state.setApplyPropertyToVisitedLinkStyle(false);
-        resolver.applyProperty(id, cssValue[SelectorChecker::MatchDefault], applyState, SelectorChecker::MatchDefault);
+        resolver.applyProperty(id, cssValue[SelectorChecker::MatchDefault], SelectorChecker::MatchDefault, matchResult);
     }
 
     if (state.style()->insideLink() == InsideLink::NotInside)
@@ -2259,99 +2251,43 @@ void StyleResolver::CascadedProperties::Property::apply(StyleResolver& resolver,
     if (cssValue[SelectorChecker::MatchLink]) {
         state.setApplyPropertyToRegularStyle(true);
         state.setApplyPropertyToVisitedLinkStyle(false);
-        resolver.applyProperty(id, cssValue[SelectorChecker::MatchLink], applyState, SelectorChecker::MatchLink);
+        resolver.applyProperty(id, cssValue[SelectorChecker::MatchLink], SelectorChecker::MatchLink, matchResult);
     }
 
     if (cssValue[SelectorChecker::MatchVisited]) {
         state.setApplyPropertyToRegularStyle(false);
         state.setApplyPropertyToVisitedLinkStyle(true);
-        resolver.applyProperty(id, cssValue[SelectorChecker::MatchVisited], applyState, SelectorChecker::MatchVisited);
+        resolver.applyProperty(id, cssValue[SelectorChecker::MatchVisited], SelectorChecker::MatchVisited, matchResult);
     }
 
     state.setApplyPropertyToRegularStyle(true);
     state.setApplyPropertyToVisitedLinkStyle(false);
 }
 
-void StyleResolver::applyCascadedCustomProperty(const String& name, ApplyCascadedPropertyState& state)
-{
-    if (state.appliedCustomProperties.contains(name) || !state.cascade->customProperties().contains(name))
-        return;
-
-    auto property = state.cascade->customProperties().get(name);
-
-    for (auto index : { SelectorChecker::MatchDefault, SelectorChecker::MatchLink, SelectorChecker::MatchVisited }) {
-        if (!property.cssValue[index])
-            continue;
-        if (index != SelectorChecker::MatchDefault && this->state().style()->insideLink() == InsideLink::NotInside)
-            continue;
-
-        Ref<CSSCustomPropertyValue> valueToApply = CSSCustomPropertyValue::create(downcast<CSSCustomPropertyValue>(*property.cssValue[index]));
-
-        if (state.inProgressPropertiesCustom.contains(name)) {
-            // We are in a cycle, so reset the value.
-            state.appliedCustomProperties.add(name);
-            // Resolve this value so that we reset its dependencies
-            if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value()))
-                resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state);
-            valueToApply = CSSCustomPropertyValue::createWithID(name, CSSValueUnset);
-        }
-
-        state.inProgressPropertiesCustom.add(name);
-
-        if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) {
-            RefPtr<CSSValue> parsedValue = resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state);
-
-            if (!parsedValue)
-                parsedValue = CSSCustomPropertyValue::createWithID(name, CSSValueUnset);
-
-            valueToApply = downcast<CSSCustomPropertyValue>(*parsedValue);
-        }
-
-        if (state.inProgressPropertiesCustom.contains(name)) {
-            if (index == SelectorChecker::MatchDefault) {
-                this->state().setApplyPropertyToRegularStyle(true);
-                this->state().setApplyPropertyToVisitedLinkStyle(false);
-            }
-
-            if (index == SelectorChecker::MatchLink) {
-                this->state().setApplyPropertyToRegularStyle(true);
-                this->state().setApplyPropertyToVisitedLinkStyle(false);
-            }
-
-            if (index == SelectorChecker::MatchVisited) {
-                this->state().setApplyPropertyToRegularStyle(false);
-                this->state().setApplyPropertyToVisitedLinkStyle(true);
-            }
-            applyProperty(CSSPropertyCustom, valueToApply.ptr(), state, index);
-        }
-        state.inProgressPropertiesCustom.remove(name);
-        state.appliedCustomProperties.add(name);
-    }
-}
-
-void StyleResolver::applyCascadedProperties(int firstProperty, int lastProperty, ApplyCascadedPropertyState& state)
+void StyleResolver::applyCascadedProperties(CascadedProperties& cascade, int firstProperty, int lastProperty, const MatchResult* matchResult)
 {
     for (int id = firstProperty; id <= lastProperty; ++id) {
         CSSPropertyID propertyID = static_cast<CSSPropertyID>(id);
-        if (!state.cascade->hasProperty(propertyID))
+        if (!cascade.hasProperty(propertyID))
             continue;
-        ASSERT(propertyID != CSSPropertyCustom);
-        auto& property = state.cascade->property(propertyID);
-        ASSERT(!shouldApplyPropertyInParseOrder(propertyID));
-
-        if (state.inProgressProperties.contains(propertyID)) {
-            // We are in a cycle (eg. setting font size using registered custom property value containing em)
-            // So this value should be unset
-            state.appliedProperties.add(propertyID);
-            // This property is in a cycle, and only the root of the call stack will have firstProperty != lastProperty.
-            ASSERT(firstProperty == lastProperty);
+        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;
         }
-
-        state.inProgressProperties.add(propertyID);
-        property.apply(*this, state);
-        state.appliedProperties.add(propertyID);
-        state.inProgressProperties.remove(propertyID);
+        auto& property = cascade.property(propertyID);
+        ASSERT(!shouldApplyPropertyInParseOrder(propertyID));
+        property.apply(*this, matchResult);
     }
 }
 
index 6d88f60..4703cef 100644 (file)
@@ -267,7 +267,7 @@ public:
         CascadedProperties(TextDirection, WritingMode);
 
         struct Property {
-            void apply(StyleResolver&, ApplyCascadedPropertyState&);
+            void apply(StyleResolver&, const MatchResult*);
 
             CSSPropertyID id;
             CascadeLevel level;
@@ -281,7 +281,7 @@ public:
         void addNormalMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false);
         void addImportantMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false);
 
-        void applyDeferredProperties(StyleResolver&, ApplyCascadedPropertyState&);
+        void applyDeferredProperties(StyleResolver&, const MatchResult*);
 
         HashMap<AtomicString, Property>& customProperties() { return m_customProperties; }
         bool hasCustomProperty(const String&) const;
@@ -302,10 +302,7 @@ public:
         TextDirection m_direction;
         WritingMode m_writingMode;
     };
-
-    void applyCascadedProperties(int firstProperty, int lastProperty, ApplyCascadedPropertyState&);
-    void applyCascadedCustomProperty(const String& name, ApplyCascadedPropertyState&);
-
+    
 private:
     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
     void checkForGenericFamilyChange(RenderStyle*, const RenderStyle* parentStyle);
@@ -324,6 +321,7 @@ private:
     enum ShouldUseMatchedPropertiesCache { DoNotUseMatchedPropertiesCache = 0, UseMatchedPropertiesCache };
     void applyMatchedProperties(const MatchResult&, const Element&, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache);
 
+    void applyCascadedProperties(CascadedProperties&, int firstProperty, int lastProperty, const MatchResult*);
     void cascadeMatches(CascadedProperties&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
 
     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
@@ -457,12 +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&, ApplyCascadedPropertyState&) const;
+    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&) const;
 
 private:
     void cacheBorderAndBackground();
 
-    void applyProperty(CSSPropertyID, CSSValue*, ApplyCascadedPropertyState&, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault);
+    void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr);
 
     void applySVGProperty(CSSPropertyID, CSSValue*);
 
@@ -526,19 +524,6 @@ private:
     friend bool operator!=(const MatchRanges&, const MatchRanges&);
 };
 
-// State to use when applying properties, to keep track of which custom and high-priority
-// properties have been resolved.
-struct ApplyCascadedPropertyState {
-    StyleResolver* styleResolver;
-    StyleResolver::CascadedProperties* cascade;
-    const StyleResolver::MatchResult* matchResult;
-    HashSet<CSSPropertyID> appliedProperties = { };
-    HashSet<String> appliedCustomProperties = { };
-    HashSet<CSSPropertyID> inProgressProperties = { };
-    HashSet<String> inProgressPropertiesCustom = { };
-};
-
-
 inline bool StyleResolver::hasSelectorForAttribute(const Element& element, const AtomicString &attributeName) const
 {
     ASSERT(!attributeName.isEmpty());
index 0d6aef0..9df0fd4 100644 (file)
@@ -47,7 +47,6 @@
 #include "RuntimeEnabledFeatures.h"
 #include "Settings.h"
 #include "StyleColor.h"
-#include "StyleResolver.h"
 #include "StyleRule.h"
 #include "StyleSheetContents.h"
 #include <wtf/NeverDestroyed.h>
@@ -178,10 +177,8 @@ void CSSParser::parseDeclarationForInspector(const CSSParserContext& context, co
     CSSParserImpl::parseDeclarationListForInspector(string, context, observer);
 }
 
-RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, ApplyCascadedPropertyState& state)
+RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style)
 {
-    ASSERT((propID == CSSPropertyCustom && value.isCustomPropertyValue()) || (propID != CSSPropertyCustom && !value.isCustomPropertyValue()));
-    auto& style = *state.styleResolver->style();
     auto direction = style.direction();
     auto writingMode = style.writingMode();
 
@@ -193,11 +190,12 @@ RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propI
         if (CSSProperty::isDirectionAwareProperty(shorthandID))
             shorthandID = CSSProperty::resolveDirectionAwareProperty(shorthandID, direction, writingMode);
         CSSVariableReferenceValue* shorthandValue = pendingSubstitution.shorthandValue();
-
-        auto resolvedData = shorthandValue->resolveVariableReferences(state);
-        if (!resolvedData)
+        const CSSVariableData* variableData = shorthandValue->variableDataValue();
+        ASSERT(variableData);
+        
+        Vector<CSSParserToken> resolvedTokens;
+        if (!variableData->resolveTokenRange(registeredProperties, variableData->tokens(), resolvedTokens, style))
             return nullptr;
-        Vector<CSSParserToken> resolvedTokens = resolvedData->tokens();
         
         ParsedPropertyVector parsedProperties;
         if (!CSSPropertyParser::parseValue(shorthandID, false, resolvedTokens, m_context, parsedProperties, StyleRule::Style))
@@ -211,33 +209,31 @@ RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propI
         return nullptr;
     }
 
+    const CSSVariableData* variableData = nullptr;
+
     if (value.isVariableReferenceValue()) {
         const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value);
-        auto resolvedData = valueWithReferences.resolveVariableReferences(state);
-        if (!resolvedData)
-            return nullptr;
-        return CSSPropertyParser::parseSingleValue(propID, resolvedData->tokens(), m_context);
+        variableData = valueWithReferences.variableDataValue();
+        ASSERT(variableData);
     }
 
-    const auto& customPropValue = downcast<CSSCustomPropertyValue>(value);
-    const auto& valueWithReferences = WTF::get<Ref<CSSVariableReferenceValue>>(customPropValue.value()).get();
+    if (value.isCustomPropertyValue()) {
+        const CSSCustomPropertyValue& customPropValue = downcast<CSSCustomPropertyValue>(value);
 
-    auto& name = downcast<CSSCustomPropertyValue>(value).name();
-    auto* registered = state.styleResolver->document().getCSSRegisteredCustomPropertySet().get(name);
-    auto& syntax = registered ? registered->syntax : "*";
-    auto resolvedData = valueWithReferences.resolveVariableReferences(state);
+        if (customPropValue.resolvedTypedValue())
+            return CSSPrimitiveValue::create(*customPropValue.resolvedTypedValue(), style);
 
-    if (!resolvedData)
-        return nullptr;
+        variableData = customPropValue.value();
+    }
 
-    // FIXME handle REM cycles.
-    HashSet<CSSPropertyID> dependencies;
-    CSSPropertyParser::collectParsedCustomPropertyValueDependencies(syntax, false, dependencies, resolvedData->tokens(), m_context);
+    if (!variableData)
+        return nullptr;
 
-    for (auto id : dependencies)
-        state.styleResolver->applyCascadedProperties(id, id, state);
+    Vector<CSSParserToken> resolvedTokens;
+    if (!variableData->resolveTokenRange(registeredProperties, variableData->tokens(), resolvedTokens, style))
+        return nullptr;
 
-    return CSSPropertyParser::parseTypedCustomPropertyValue(name, syntax, resolvedData->tokens(), *state.styleResolver, m_context);
+    return CSSPropertyParser::parseSingleValue(propID, resolvedTokens, m_context);
 }
 
 std::unique_ptr<Vector<double>> CSSParser::parseKeyframeKeyList(const String& selector)
index 47063cd..09ba4b0 100644 (file)
@@ -30,7 +30,6 @@
 
 namespace WebCore {
 
-struct ApplyCascadedPropertyState;
 class CSSParserObserver;
 class CSSSelectorList;
 class Color;
@@ -78,7 +77,7 @@ public:
 
     void parseSelector(const String&, CSSSelectorList&);
 
-    RefPtr<CSSValue> parseValueWithVariableReferences(CSSPropertyID, const CSSValue&, ApplyCascadedPropertyState&);
+    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 c3a23b5..21febac 100644 (file)
@@ -37,7 +37,6 @@
 #include "CSSContentDistributionValue.h"
 #include "CSSCursorImageValue.h"
 #include "CSSCustomIdentValue.h"
-#include "CSSCustomPropertyValue.h"
 #include "CSSFontFaceSrcValue.h"
 #include "CSSFontFeatureValue.h"
 #if ENABLE(VARIATION_FONTS)
 #include "RuntimeEnabledFeatures.h"
 #include "SVGPathByteStream.h"
 #include "SVGPathUtilities.h"
-#include "StyleBuilderConverter.h"
 #include "StylePropertyShorthand.h"
 #include "StylePropertyShorthandFunctions.h"
-#include "StyleResolver.h"
 #include <bitset>
 #include <memory>
 #include <wtf/text/StringBuilder.h>
@@ -216,13 +213,12 @@ CSSPropertyID cssPropertyID(StringView string)
     
 using namespace CSSPropertyParserHelpers;
 
-CSSPropertyParser::CSSPropertyParser(const CSSParserTokenRange& range, const CSSParserContext& context, Vector<CSSProperty, 256>* parsedProperties, bool consumeWhitespace)
+CSSPropertyParser::CSSPropertyParser(const CSSParserTokenRange& range, const CSSParserContext& context, Vector<CSSProperty, 256>* parsedProperties)
     : m_range(range)
     , m_context(context)
     , m_parsedProperties(parsedProperties)
 {
-    if (consumeWhitespace)
-        m_range.consumeWhitespace();
+    m_range.consumeWhitespace();
 }
 
 void CSSPropertyParser::addProperty(CSSPropertyID property, CSSPropertyID currentShorthand, Ref<CSSValue>&& value, bool important, bool implicit)
@@ -282,27 +278,6 @@ RefPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID property, con
     return value;
 }
 
-bool CSSPropertyParser::canParseTypedCustomPropertyValue(const String& syntax, const CSSParserTokenRange& tokens, const CSSParserContext& context)
-{
-    CSSPropertyParser parser(tokens, context, nullptr);
-    return parser.canParseTypedCustomPropertyValue(syntax);
-}
-
-RefPtr<CSSCustomPropertyValue> CSSPropertyParser::parseTypedCustomPropertyValue(const String& name, const String& syntax, const CSSParserTokenRange& tokens, const StyleResolver& styleResolver, const CSSParserContext& context)
-{
-    CSSPropertyParser parser(tokens, context, nullptr, false);
-    RefPtr<CSSCustomPropertyValue> value = parser.parseTypedCustomPropertyValue(name, syntax, styleResolver);
-    if (!value || !parser.m_range.atEnd())
-        return nullptr;
-    return value;
-}
-
-void CSSPropertyParser::collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies, const CSSParserTokenRange& tokens, const CSSParserContext& context)
-{
-    CSSPropertyParser parser(tokens, context, nullptr);
-    parser.collectParsedCustomPropertyValueDependencies(syntax, isRoot, dependencies);
-}
-
 static bool isLegacyBreakProperty(CSSPropertyID propertyID)
 {
     switch (propertyID) {
@@ -345,7 +320,7 @@ bool CSSPropertyParser::parseValueStart(CSSPropertyID propertyID, bool important
     }
 
     if (CSSVariableParser::containsValidVariableReferences(originalRange, m_context)) {
-        RefPtr<CSSVariableReferenceValue> variable = CSSVariableReferenceValue::create(originalRange);
+        RefPtr<CSSVariableReferenceValue> variable = CSSVariableReferenceValue::create(CSSVariableData::create(originalRange));
 
         if (isShorthand) {
             RefPtr<CSSPendingSubstitutionValue> pendingValue = CSSPendingSubstitutionValue::create(propertyID, variable.releaseNonNull());
@@ -3911,6 +3886,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:
@@ -4280,64 +4256,6 @@ RefPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID property, CSS
     }
 }
 
-bool CSSPropertyParser::canParseTypedCustomPropertyValue(const String& syntax)
-{
-    if (syntax != "*") {
-        m_range.consumeWhitespace();
-
-        // First check for keywords
-        CSSValueID id = m_range.peek().id();
-        if (id == CSSValueInherit || id == CSSValueInitial || id == CSSValueRevert)
-            return true;
-
-        auto localRange = m_range;
-        while (!localRange.atEnd()) {
-            auto id = localRange.consume().functionId();
-            if (id == CSSValueVar || id == CSSValueEnv)
-                return true; // For variables, we just permit everything
-        }
-
-        auto primitiveVal = consumeWidthOrHeight(m_range, m_context);
-        if (primitiveVal && primitiveVal->isPrimitiveValue() && m_range.atEnd())
-            return true;
-        return false;
-    }
-
-    return true;
-}
-
-void CSSPropertyParser::collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies)
-{
-    if (syntax != "*") {
-        m_range.consumeWhitespace();
-        auto primitiveVal = consumeWidthOrHeight(m_range, m_context);
-        if (!m_range.atEnd())
-            return;
-        if (primitiveVal && primitiveVal->isPrimitiveValue()) {
-            primitiveVal->collectDirectComputationalDependencies(dependencies);
-            if (isRoot)
-                primitiveVal->collectDirectRootComputationalDependencies(dependencies);
-        }
-    }
-}
-
-RefPtr<CSSCustomPropertyValue> CSSPropertyParser::parseTypedCustomPropertyValue(const String& name, const String& syntax, const StyleResolver& styleResolver)
-{
-    if (syntax != "*") {
-        m_range.consumeWhitespace();
-        auto primitiveVal = consumeWidthOrHeight(m_range, m_context);
-        if (primitiveVal && primitiveVal->isPrimitiveValue())
-            return CSSCustomPropertyValue::createSyntaxLength(name, StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));
-    } else {
-        auto propertyValue = CSSCustomPropertyValue::createSyntaxAll(name, CSSVariableData::create(m_range));
-        while (!m_range.atEnd())
-            m_range.consume();
-        return { WTFMove(propertyValue) };
-    }
-
-    return nullptr;
-}
-
 static RefPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParserTokenRange& range)
 {
     RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
index 1dc05ef..7db7453 100644 (file)
@@ -32,7 +32,6 @@ class CSSProperty;
 class CSSValue;
 class StylePropertyShorthand;
 class StyleSheetContents;
-class StyleResolver;
     
 // Inputs: PropertyID, isImportant bool, CSSParserTokenRange.
 // Outputs: Vector of CSSProperties
@@ -46,20 +45,14 @@ public:
 
     // Parses a non-shorthand CSS property
     static RefPtr<CSSValue> parseSingleValue(CSSPropertyID, const CSSParserTokenRange&, const CSSParserContext&);
-    static bool canParseTypedCustomPropertyValue(const String& syntax, const CSSParserTokenRange&, const CSSParserContext&);
-    static RefPtr<CSSCustomPropertyValue> parseTypedCustomPropertyValue(const String& name, const String& syntax, const CSSParserTokenRange&, const StyleResolver&, const CSSParserContext&);
-    static void collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies, const CSSParserTokenRange&, const CSSParserContext&);
 
 private:
-    CSSPropertyParser(const CSSParserTokenRange&, const CSSParserContext&, Vector<CSSProperty, 256>*, bool consumeWhitespace = true);
+    CSSPropertyParser(const CSSParserTokenRange&, const CSSParserContext&, Vector<CSSProperty, 256>*);
 
     // FIXME: Rename once the CSSParserValue-based parseValue is removed
     bool parseValueStart(CSSPropertyID, bool important);
     bool consumeCSSWideKeyword(CSSPropertyID, bool important);
     RefPtr<CSSValue> parseSingleValue(CSSPropertyID, CSSPropertyID = CSSPropertyInvalid);
-    bool canParseTypedCustomPropertyValue(const String& syntax);
-    RefPtr<CSSCustomPropertyValue> parseTypedCustomPropertyValue(const String& name, const String& syntax, const StyleResolver&);
-    void collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies);
 
     bool inQuirksMode() const { return m_context.mode == HTMLQuirksMode; }
 
index 1be23b9..87086e3 100644 (file)
@@ -189,8 +189,8 @@ RefPtr<CSSCustomPropertyValue> CSSVariableParser::parseDeclarationValue(const At
     if (type == CSSValueInvalid)
         return nullptr;
     if (type == CSSValueInternalVariableValue)
-        return CSSCustomPropertyValue::createUnresolved(variableName, CSSVariableReferenceValue::create(range));
-    return CSSCustomPropertyValue::createUnresolved(variableName, type);
+        return CSSCustomPropertyValue::createWithVariableData(variableName, CSSVariableData::create(range, hasReferences || hasAtApplyRule));
+    return CSSCustomPropertyValue::createWithID(variableName, type);
 }
 
 } // namespace WebCore
index 6c108c8..90fd139 100644 (file)
@@ -90,7 +90,7 @@ void ConstantPropertyMap::setValueForProperty(ConstantProperty property, Ref<CSS
         buildValues();
 
     auto& name = nameForProperty(property);
-    m_values->set(name, CSSCustomPropertyValue::createSyntaxAll(name, WTFMove(data)));
+    m_values->set(name, CSSCustomPropertyValue::createWithVariableData(name, WTFMove(data)));
 }
 
 void ConstantPropertyMap::buildValues()
@@ -110,7 +110,7 @@ static Ref<CSSVariableData> variableDataForPositivePixelLength(float lengthInPx)
 
     Vector<CSSParserToken> tokens { token };
     CSSParserTokenRange tokenRange(tokens);
-    return CSSVariableData::create(tokenRange);
+    return CSSVariableData::create(tokenRange, false);
 }
 
 static Ref<CSSVariableData> variableDataForPositiveDuration(Seconds durationInSeconds)
@@ -122,7 +122,7 @@ static Ref<CSSVariableData> variableDataForPositiveDuration(Seconds durationInSe
 
     Vector<CSSParserToken> tokens { token };
     CSSParserTokenRange tokenRange(tokens);
-    return CSSVariableData::create(tokenRange);
+    return CSSVariableData::create(tokenRange, false);
 }
 
 void ConstantPropertyMap::updateConstantsForSafeAreaInsets()
index c852588..db85d7d 100644 (file)
@@ -2299,6 +2299,89 @@ bool RenderStyle::hasReferenceFilterOnly() const
     return filterOperations.size() == 1 && filterOperations.at(0)->type() == FilterOperation::REFERENCE;
 }
 
+void RenderStyle::checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle* parentStyle, const StyleResolver& styleResolver)
+{
+    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;
+
+    HashSet<AtomicString> invalidProperties;
+
+    for (auto* customPropertyData : { inheritedPropertyData, nonInheritedPropertyData }) {
+        if (!customPropertyData)
+            continue;
+
+        // 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();
+
+        // 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());
+
+        // 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
 {
     if (m_backgroundData->outline.style() == BorderStyle::None)
index 708e6bf..dd242e7 100644 (file)
@@ -186,8 +186,8 @@ public:
     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) { return m_rareInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value)); }
-    void setNonInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) { return m_rareNonInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value)); }
+    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; }
@@ -795,6 +795,8 @@ public:
     ApplePayButtonType applePayButtonType() const { return static_cast<ApplePayButtonType>(m_rareNonInheritedData->applePayButtonType); }
 #endif
 
+    void checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet&, const RenderStyle* parentStyle, const StyleResolver&);
+
 // attribute setter methods
 
     void setDisplay(DisplayType v) { m_nonInheritedFlags.effectiveDisplay = static_cast<unsigned>(v); }
index 132e6f5..1bcdb22 100644 (file)
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "CSSCustomPropertyValue.h"
-#include "CSSVariableReferenceValue.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
@@ -38,6 +37,9 @@ public:
     
     bool operator==(const StyleCustomPropertyData& other) const
     {
+        if (containsVariables != other.containsVariables)
+            return false;
+
         if (values.size() != other.values.size())
             return false;
 
@@ -52,18 +54,26 @@ 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;
     StyleCustomPropertyData(const StyleCustomPropertyData& other)
         : RefCounted<StyleCustomPropertyData>()
         , values(other.values)
+        , containsVariables(other.containsVariables)
+        , containsUnresolvedRegisteredProperties(other.containsUnresolvedRegisteredProperties)
     { }
 };