Changeset 237347 in webkit
- Timestamp:
- Oct 22, 2018 11:10:59 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 34 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r237345 r237347 1 2018-10-22 Justin Michaud <justin_michaud@apple.com> 2 3 Registered custom properties should support syntax parameter for <length> and * 4 https://bugs.webkit.org/show_bug.cgi?id=190039 5 6 Reviewed by Antti Koivisto. 7 8 Add tests for inline styles, font-size cycles with custom properties, and a crash that was reported. 9 10 * css-custom-properties-api/crash-expected.txt: Added. 11 * css-custom-properties-api/crash.html: Added. 12 * css-custom-properties-api/cycles-expected.txt: Added. 13 * css-custom-properties-api/cycles.html: Added. 14 * css-custom-properties-api/inline-expected.txt: Added. 15 * css-custom-properties-api/inline.html: Added. 16 1 17 2018-10-22 Ryan Haddad <ryanhaddad@apple.com> 2 18 -
trunk/LayoutTests/imported/w3c/ChangeLog
r237341 r237347 1 2018-10-22 Justin Michaud <justin_michaud@apple.com> 2 3 Registered custom properties should support syntax parameter for <length> and * 4 https://bugs.webkit.org/show_bug.cgi?id=190039 5 6 Reviewed by Antti Koivisto. 7 8 Update WPT test results to fail in a new way. 9 10 * web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt: 11 * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt: 12 * web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt: 13 * web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt: 14 * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles-expected.txt: 15 * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt: 16 1 17 2018-10-12 Jiewen Tan <jiewen_tan@apple.com> 2 18 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt
r236895 r237347 1 1 2 FAIL syntax:'*', initialValue:'a' is valid The given initial value does not parse for the given syntax. 2 PASS syntax:'*', initialValue:'a' is valid 3 3 FAIL syntax:' * ', initialValue:'b' is valid The given initial value does not parse for the given syntax. 4 4 PASS syntax:'<length>', initialValue:'2px' is valid … … 10 10 FAIL syntax:'<color> | <image> | <url> | <integer> | <angle>', initialValue:'red' is valid The given initial value does not parse for the given syntax. 11 11 FAIL syntax:'<time> | <resolution> | <transform-list> | <custom-ident>', initialValue:'red' is valid The given initial value does not parse for the given syntax. 12 FAIL syntax:'*', initialValue:':> hello' is valid The given initial value does not parse for the given syntax. 13 FAIL syntax:'*', initialValue:'([ brackets ]) { yay (??)}' is valid The given initial value does not parse for the given syntax. 14 FAIL syntax:'*', initialValue:'yep 'this is valid too'' is valid The given initial value does not parse for the given syntax. 15 FAIL syntax:'*', initialValue:'unmatched opening bracket is valid :(' is valid The given initial value does not parse for the given syntax. 16 FAIL syntax:'*', initialValue:'"' is valid The given initial value does not parse for the given syntax. 12 PASS syntax:'*', initialValue:':> hello' is valid 13 PASS syntax:'*', initialValue:'([ brackets ]) { yay (??)}' is valid 14 PASS syntax:'*', initialValue:'yep 'this is valid too'' is valid 15 PASS syntax:'*', initialValue:'unmatched opening bracket is valid :(' is valid 16 PASS syntax:'*', initialValue:'"' is valid 17 17 PASS syntax:'<length>', initialValue:'0' is valid 18 18 PASS syntax:'<length>', initialValue:'10px /*:)*/' is valid … … 65 65 | na\r|nya', initialValue:'nya' is valid The given initial value does not parse for the given syntax. 66 66 FAIL syntax:'null', initialValue:'null' is valid The given initial value does not parse for the given syntax. 67 FAIL syntax:'undefined', initialValue:'undefined' is valid The given initial value does not parse for the given syntax. 67 PASS syntax:'undefined', initialValue:'undefined' is valid 68 68 FAIL syntax:'array', initialValue:'array' is valid The given initial value does not parse for the given syntax. 69 69 PASS syntax:'banana,nya', initialValue:'banana' is invalid … … 87 87 FAIL syntax:'<length>|INHERIT', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 88 88 FAIL syntax:'<percentage>|unsEt', initialValue:'2%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 89 PASS syntax:'*', initialValue:'initial' is invalid 90 PASS syntax:'*', initialValue:'inherit' is invalid 91 PASS syntax:'*', initialValue:'unset' is invalid 92 PASS syntax:'*', initialValue:'revert' is invalid 89 FAIL syntax:'*', initialValue:'initial' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 90 FAIL syntax:'*', initialValue:'inherit' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 91 FAIL syntax:'*', initialValue:'unset' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 92 FAIL syntax:'*', initialValue:'revert' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 93 93 PASS syntax:'<custom-ident>', initialValue:'initial' is invalid 94 94 PASS syntax:'<custom-ident>+', initialValue:'foo inherit bar' is invalid 95 PASS syntax:'*', initialValue:')' is invalid 96 PASS syntax:'*', initialValue:'([)]' is invalid 97 PASS syntax:'*', initialValue:'whee!' is invalid 98 PASSsyntax:'*', initialValue:'"99 ' is invalid 100 PASS syntax:'*', initialValue:'url(moo '')' is invalid 101 PASS syntax:'*', initialValue:'semi;colon' is invalid 102 PASS syntax:'*', initialValue:'var(invalid var ref)' is invalid 103 PASS syntax:'*', initialValue:'var(--foo)' is invalid 95 FAIL syntax:'*', initialValue:')' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 96 FAIL syntax:'*', initialValue:'([)]' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 97 FAIL syntax:'*', initialValue:'whee!' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 98 FAIL syntax:'*', initialValue:'" 99 ' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 100 FAIL syntax:'*', initialValue:'url(moo '')' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 101 FAIL syntax:'*', initialValue:'semi;colon' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 102 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 103 FAIL syntax:'*', initialValue:'var(--foo)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 104 104 PASS syntax:'banana', initialValue:'bAnAnA' is invalid 105 105 PASS syntax:'<length>', initialValue:'var(--moo)' is invalid … … 108 108 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 109 109 PASS syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is invalid 110 PASS syntax:'<length>', initialValue:'10em' is invalid 110 FAIL syntax:'<length>', initialValue:'10em' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 111 111 FAIL syntax:'<length>', initialValue:'10vmin' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 112 PASS syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid 113 PASS syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid 114 PASS syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid 112 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 113 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 114 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 115 115 PASS syntax:'<length>+', initialValue:'10px calc(20px + 4rem)' is invalid 116 116 PASS syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid 117 117 PASS syntax:'<length>', initialValue:'10px;' is invalid 118 PASS syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid 118 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 119 119 FAIL syntax:'<percentage>', initialValue:'0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw 120 120 PASS syntax:'<integer>', initialValue:'1.0' is invalid -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt
r236828 r237347 3 3 PASS Explicitly inheriting from a parent with an invalid value results in initial value. 4 4 PASS Explicitly inheriting from a parent with no value results in initial value. 5 FAIL Reference to undefined variable results in inherited value assert_equals: expected "42px" but got "0px" 6 FAIL Reference to syntax-incompatible variable results in inherited value assert_equals: expected "42px" but got "0px" 5 PASS Reference to undefined variable results in inherited value 6 PASS Reference to syntax-incompatible variable results in inherited value 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt
r236828 r237347 3 3 FAIL CSS.registerProperty The given initial value does not parse for the given syntax. 4 4 FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "blue" but got "hello" 5 FAIL Values not matching the registered type can't be set assert_equals: expected " 5" but got "hi"5 FAIL Values not matching the registered type can't be set assert_equals: expected "hello" but got "20" 6 6 FAIL Values can be removed from inline styles assert_equals: expected "red" but got " red" 7 FAIL Stylesheets can be modified by CSSOM assert_equals: expected "10px" but got "0px" 7 PASS Stylesheets can be modified by CSSOM 8 8 FAIL Valid values can be set on inline styles assert_equals: expected "blue" but got " blue" 9 9 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt
r236828 r237347 3 3 Harness Error (FAIL), message = ReferenceError: Can't find variable: CSSUnparsedValue 4 4 5 FAIL Computed * is reified as CSSUnparsedValue The given initial value does not parse for the given syntax.5 FAIL Computed * is reified as CSSUnparsedValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined) 6 6 FAIL Computed <angle> is reified as CSSUnitValue The given initial value does not parse for the given syntax. 7 7 FAIL Computed <color> is reified as CSSStyleValue The given initial value does not parse for the given syntax. -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles-expected.txt
r236828 r237347 1 1 2 FAIL A var() cycle between two registered properties is handled correctly. assert_equals: expected "2px" but got "3px" 3 FAIL A var() cycle between a registered properties and an unregistered property is handled correctly. assert_equals: expected "1px" but got "2px" 2 PASS A var() cycle between two registered properties is handled correctly. 3 PASS A var() cycle between a registered properties and an unregistered property is handled correctly. 4 4 PASS A var() cycle between a two unregistered properties is handled correctly. 5 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. 5 PASS A var() cycle between a syntax:'*' property and an unregistered property is handled correctly. 6 6 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt
r236828 r237347 1 1 2 FAIL var() references work with registered properties assert_equals: expected " 15px" but got "10%"2 FAIL var() references work with registered properties assert_equals: expected " 10px" but got " 10px" 3 3 FAIL References to registered var()-properties work in registered lists assert_equals: expected "1px, 10px, 2px" but got "0px" 4 4 FAIL References to mixed registered and unregistered var()-properties work in registered lists assert_equals: expected "1px, 20px, 10px, 2px" but got "0px" -
trunk/Source/WebCore/ChangeLog
r237344 r237347 1 2018-10-22 Justin Michaud <justin_michaud@apple.com> 2 3 Registered custom properties should support syntax parameter for <length> and * 4 https://bugs.webkit.org/show_bug.cgi?id=190039 5 6 Reviewed by Antti Koivisto. 7 8 Refactor code so that: 9 - All properties applied in StyleResolver::applyMatchedProperties are only applied once. 10 - Custom properties are only resolved once, in StyleResolver, when they are applied to the RenderStyle. They were previously resolved 11 every time they were referenced, and again in RenderStyle. 12 - The font-size property is applied after its variable references, but before custom properties that depend on it. 13 - Cycles are detected at the same time as resolution. 14 - MutableStyleProperties' custom properties cannot be set from Javascript or WebKitLegacy if they do not parse for the property's type. 15 If they contain var(--...) references, however, then they can be set because we cannot check if the references are valid from setProperty. 16 This behaviour matches chrome, but is not documented in the spec. 17 - Custom property values have more explicit resolved/unresolved state. 18 - RenderStyle only ever holds resolved custom properties, and StyleResolver::CascadedProperties only holds unresolved properties. 19 20 Tests: css-custom-properties-api/crash.html 21 css-custom-properties-api/cycles.html 22 css-custom-properties-api/inline.html 23 24 * css/CSSComputedStyleDeclaration.cpp: 25 (WebCore::ComputedStyleExtractor::customPropertyValue): 26 * css/CSSCustomPropertyValue.cpp: 27 (WebCore::CSSCustomPropertyValue::equals const): 28 (WebCore::CSSCustomPropertyValue::customCSSText const): 29 (WebCore::CSSCustomPropertyValue::tokens const): 30 (WebCore::CSSCustomPropertyValue::checkVariablesForCycles const): Deleted. 31 (WebCore::CSSCustomPropertyValue::resolveVariableReferences const): Deleted. 32 (WebCore::CSSCustomPropertyValue::setResolvedTypedValue): Deleted. 33 * css/CSSCustomPropertyValue.h: 34 * css/CSSRegisteredCustomProperty.cpp: 35 (WebCore::CSSRegisteredCustomProperty::CSSRegisteredCustomProperty): 36 * css/CSSRegisteredCustomProperty.h: 37 * css/CSSStyleSheet.h: 38 * css/CSSVariableData.cpp: 39 (WebCore::CSSVariableData::CSSVariableData): 40 (WebCore::CSSVariableData::consumeAndUpdateTokens): Deleted. 41 (WebCore::CSSVariableData::checkVariablesForCycles const): Deleted. 42 (WebCore::CSSVariableData::checkVariablesForCyclesWithRange const): Deleted. 43 (WebCore::CSSVariableData::resolveVariableFallback const): Deleted. 44 (WebCore::CSSVariableData::resolveVariableReference const): Deleted. 45 (WebCore::CSSVariableData::resolveVariableReferences const): Deleted. 46 (WebCore::CSSVariableData::resolveTokenRange const): Deleted. 47 * css/CSSVariableData.h: 48 (WebCore::CSSVariableData::create): 49 (WebCore::CSSVariableData::createResolved): Deleted. 50 (WebCore::CSSVariableData::needsVariableResolution const): Deleted. 51 (WebCore::CSSVariableData::CSSVariableData): Deleted. 52 * css/CSSVariableReferenceValue.cpp: 53 (WebCore::resolveVariableFallback): 54 (WebCore::resolveVariableReference): 55 (WebCore::resolveTokenRange): 56 (WebCore::CSSVariableReferenceValue::resolveVariableReferences const): 57 (WebCore::CSSVariableReferenceValue::checkVariablesForCycles const): Deleted. 58 * css/CSSVariableReferenceValue.h: 59 (WebCore::CSSVariableReferenceValue::create): 60 (WebCore::CSSVariableReferenceValue::equals const): 61 (WebCore::CSSVariableReferenceValue::variableDataValue const): Deleted. 62 * css/DOMCSSRegisterCustomProperty.cpp: 63 (WebCore::DOMCSSRegisterCustomProperty::registerProperty): 64 * css/PropertySetCSSStyleDeclaration.cpp: 65 (WebCore::PropertySetCSSStyleDeclaration::setProperty): 66 * css/StyleBuilderCustom.h: 67 (WebCore::StyleBuilderCustom::applyInitialCustomProperty): 68 (WebCore::StyleBuilderCustom::applyValueCustomProperty): 69 * css/StyleProperties.cpp: 70 (WebCore::MutableStyleProperties::setCustomProperty): 71 * css/StyleProperties.h: 72 * css/StyleResolver.cpp: 73 (WebCore::StyleResolver::State::setStyle): 74 (WebCore::StyleResolver::styleForKeyframe): 75 (WebCore::StyleResolver::styleForPage): 76 (WebCore::StyleResolver::applyMatchedProperties): 77 (WebCore::StyleResolver::applyPropertyToCurrentStyle): 78 (WebCore::StyleResolver::applyProperty): 79 (WebCore::StyleResolver::resolvedVariableValue const): 80 (WebCore::StyleResolver::CascadedProperties::applyDeferredProperties): 81 (WebCore::StyleResolver::CascadedProperties::Property::apply): 82 (WebCore::StyleResolver::applyCascadedCustomProperty): 83 (WebCore::StyleResolver::applyCascadedProperties): 84 * css/StyleResolver.h: 85 * css/parser/CSSParser.cpp: 86 (WebCore::CSSParser::parseValueWithVariableReferences): 87 * css/parser/CSSParser.h: 88 * css/parser/CSSPropertyParser.cpp: 89 (WebCore::CSSPropertyParser::CSSPropertyParser): 90 (WebCore::CSSPropertyParser::canParseTypedCustomPropertyValue): 91 (WebCore::CSSPropertyParser::parseTypedCustomPropertyValue): 92 (WebCore::CSSPropertyParser::collectParsedCustomPropertyValueDependencies): 93 (WebCore::CSSPropertyParser::parseValueStart): 94 (WebCore::CSSPropertyParser::parseSingleValue): 95 * css/parser/CSSPropertyParser.h: 96 * css/parser/CSSVariableParser.cpp: 97 (WebCore::CSSVariableParser::parseDeclarationValue): 98 * dom/ConstantPropertyMap.cpp: 99 (WebCore::ConstantPropertyMap::setValueForProperty): 100 (WebCore::variableDataForPositivePixelLength): 101 (WebCore::variableDataForPositiveDuration): 102 * rendering/style/RenderStyle.cpp: 103 (WebCore::RenderStyle::checkVariablesInCustomProperties): Deleted. 104 * rendering/style/RenderStyle.h: 105 (WebCore::RenderStyle::setInheritedCustomPropertyValue): 106 (WebCore::RenderStyle::setNonInheritedCustomPropertyValue): 107 * rendering/style/StyleCustomPropertyData.h: 108 (WebCore::StyleCustomPropertyData::operator== const): 109 (WebCore::StyleCustomPropertyData::setCustomPropertyValue): 110 (WebCore::StyleCustomPropertyData::StyleCustomPropertyData): 111 (): Deleted. 112 1 113 2018-10-22 Justin Michaud <justin_michaud@apple.com> 2 114 -
trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
r237266 r237347 2613 2613 auto* value = style->getCustomProperty(propertyName); 2614 2614 2615 if (registered) { 2616 // TODO this should be done based on the syntax 2617 if (value && value->resolvedTypedValue()) 2618 return zoomAdjustedPixelValueForLength(*value->resolvedTypedValue(), *style); 2619 2620 if (registered->initialValue() && registered->initialValue()->resolvedTypedValue()) 2621 return zoomAdjustedPixelValueForLength(*registered->initialValue()->resolvedTypedValue(), *style); 2622 2615 if (registered && !value) 2616 return registered->initialValueCopy(); 2617 2618 if (!value) 2623 2619 return nullptr; 2624 } 2625 2626 if (value) 2620 2621 auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>&) { 2622 ASSERT_NOT_REACHED(); 2623 return RefPtr<CSSValue>(); 2624 }, [&](const CSSValueID&) { 2627 2625 return CSSCustomPropertyValue::create(*value); 2628 2629 return nullptr; 2626 }, [&](const Ref<CSSVariableData>&) { 2627 return CSSCustomPropertyValue::create(*value); 2628 }, [&](const Length& value) { 2629 return zoomAdjustedPixelValueForLength(value, *style); 2630 }); 2631 return WTF::visit(visitor, value->value()); 2630 2632 } 2631 2633 -
trunk/Source/WebCore/css/CSSCustomPropertyValue.cpp
r236895 r237347 28 28 #include "CSSTokenizer.h" 29 29 30 namespace WebCore { 30 31 31 namespace WebCore { 32 bool CSSCustomPropertyValue::equals(const CSSCustomPropertyValue& other) const 33 { 34 if (m_name != other.m_name || m_value.index() != other.m_value.index()) 35 return false; 36 auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) { 37 return value.get() == WTF::get<Ref<CSSVariableReferenceValue>>(other.m_value).get(); 38 }, [&](const CSSValueID& value) { 39 return value == WTF::get<CSSValueID>(other.m_value); 40 }, [&](const Ref<CSSVariableData>& value) { 41 return value.get() == WTF::get<Ref<CSSVariableData>>(other.m_value).get(); 42 }, [&](const Length& value) { 43 return value == WTF::get<Length>(other.m_value); 44 }); 45 return WTF::visit(visitor, m_value); 46 } 32 47 33 48 String CSSCustomPropertyValue::customCSSText() const … … 35 50 if (!m_serialized) { 36 51 m_serialized = true; 37 if (m_resolvedTypedValue) // FIXME: Unit should be based on syntax. 38 m_stringValue = CSSPrimitiveValue::create(m_resolvedTypedValue->value(), CSSPrimitiveValue::CSS_PX)->cssText(); 39 else if (m_value) 40 m_stringValue = m_value->tokenRange().serialize(); 41 else if (m_valueId != CSSValueInvalid) 42 m_stringValue = getValueName(m_valueId); 43 else 44 m_stringValue = emptyString(); 52 53 auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) { 54 m_stringValue = value->cssText(); 55 }, [&](const CSSValueID& value) { 56 m_stringValue = getValueName(value); 57 }, [&](const Ref<CSSVariableData>& value) { 58 m_stringValue = value->tokenRange().serialize(); 59 }, [&](const Length& value) { 60 m_stringValue = CSSPrimitiveValue::create(value.value(), CSSPrimitiveValue::CSS_PX)->cssText(); 61 }); 62 WTF::visit(visitor, m_value); 45 63 } 46 64 return m_stringValue; 47 65 } 48 66 49 Vector<CSSParserToken> CSSCustomPropertyValue::tokens( const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style) const67 Vector<CSSParserToken> CSSCustomPropertyValue::tokens() const 50 68 { 51 if (m_resolvedTypedValue) { 52 Vector<CSSParserToken> result; 69 Vector<CSSParserToken> result; 70 71 auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>&) { 72 ASSERT_NOT_REACHED(); 73 }, [&](const CSSValueID&) { 74 // Do nothing 75 }, [&](const Ref<CSSVariableData>& value) { 76 result.appendVector(value->tokens()); 77 }, [&](const Length&) { 53 78 CSSTokenizer tokenizer(cssText()); 54 79 … … 56 81 while (!tokenizerRange.atEnd()) 57 82 result.append(tokenizerRange.consume()); 83 }); 84 WTF::visit(visitor, m_value); 58 85 59 return result; 60 } 61 62 if (!m_value) 63 return { }; 64 65 if (m_containsVariables) { 66 Vector<CSSParserToken> result; 67 // FIXME: Avoid doing this work more than once. 68 RefPtr<CSSVariableData> resolvedData = m_value->resolveVariableReferences(registeredProperties, style); 69 if (resolvedData) 70 result.appendVector(resolvedData->tokens()); 71 72 return result; 73 } 74 75 return m_value->tokens(); 76 } 77 78 bool CSSCustomPropertyValue::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const 79 { 80 ASSERT(containsVariables()); 81 if (m_value) 82 return m_value->checkVariablesForCycles(name, style, seenProperties, invalidProperties); 83 return true; 84 } 85 86 void CSSCustomPropertyValue::resolveVariableReferences(const CSSRegisteredCustomPropertySet& registeredProperties, Vector<Ref<CSSCustomPropertyValue>>& resolvedValues, const RenderStyle& style) const 87 { 88 ASSERT(containsVariables()); 89 if (!m_value) 90 return; 91 92 ASSERT(m_value->needsVariableResolution()); 93 RefPtr<CSSVariableData> resolvedData = m_value->resolveVariableReferences(registeredProperties, style); 94 if (resolvedData) 95 resolvedValues.append(CSSCustomPropertyValue::createWithVariableData(m_name, resolvedData.releaseNonNull())); 96 else 97 resolvedValues.append(CSSCustomPropertyValue::createWithID(m_name, CSSValueInvalid)); 98 } 99 100 void CSSCustomPropertyValue::setResolvedTypedValue(Length length) 101 { 102 ASSERT(length.isSpecified()); 103 m_resolvedTypedValue = WTFMove(length); 86 return result; 104 87 } 105 88 -
trunk/Source/WebCore/css/CSSCustomPropertyValue.h
r236895 r237347 28 28 #include "CSSRegisteredCustomProperty.h" 29 29 #include "CSSValue.h" 30 #include "CSSVariable Data.h"30 #include "CSSVariableReferenceValue.h" 31 31 #include "Length.h" 32 32 #include <wtf/RefPtr.h> 33 #include <wtf/Variant.h> 33 34 #include <wtf/text/WTFString.h> 34 35 … … 36 37 37 38 class CSSParserToken; 39 class CSSVariableReferenceValue; 38 40 class RenderStyle; 39 41 40 42 class CSSCustomPropertyValue final : public CSSValue { 41 43 public: 42 static Ref<CSSCustomPropertyValue> createWithVariableData(const AtomicString& name, Ref<CSSVariableData>&& value) 44 using VariantValue = Variant<Ref<CSSVariableReferenceValue>, CSSValueID, Ref<CSSVariableData>, Length>; 45 46 static Ref<CSSCustomPropertyValue> createUnresolved(const AtomicString& name, Ref<CSSVariableReferenceValue>&& value) 43 47 { 44 return adoptRef(*new CSSCustomPropertyValue(name, WTFMove(value))); 48 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) })); 49 } 50 51 static Ref<CSSCustomPropertyValue> createUnresolved(const AtomicString& name, CSSValueID value) 52 { 53 return adoptRef(*new CSSCustomPropertyValue(name, { value })); 54 } 55 56 static Ref<CSSCustomPropertyValue> createWithID(const AtomicString& name, CSSValueID id) 57 { 58 ASSERT(id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset || id == CSSValueRevert || id == CSSValueInvalid); 59 return adoptRef(*new CSSCustomPropertyValue(name, { id })); 60 } 61 62 static Ref<CSSCustomPropertyValue> createSyntaxAll(const AtomicString& name, Ref<CSSVariableData>&& value) 63 { 64 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) })); 45 65 } 46 66 47 static Ref<CSSCustomPropertyValue> create WithID(const AtomicString& name, CSSValueIDvalue)67 static Ref<CSSCustomPropertyValue> createSyntaxLength(const AtomicString& name, Length value) 48 68 { 49 return adoptRef(*new CSSCustomPropertyValue(name, value)); 50 } 51 52 static Ref<CSSCustomPropertyValue> createInvalid() 53 { 54 return adoptRef(*new CSSCustomPropertyValue(emptyString(), emptyString())); 69 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) })); 55 70 } 56 71 … … 63 78 64 79 const AtomicString& name() const { return m_name; } 65 66 bool equals(const CSSCustomPropertyValue& other) const { return m_name == other.m_name && m_value == other.m_value && m_valueId == other.m_valueId; } 80 bool isResolved() const { return !WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(m_value); } 81 bool isUnset() const { return WTF::holds_alternative<CSSValueID>(m_value) && WTF::get<CSSValueID>(m_value) == CSSValueUnset; } 82 bool isInvalid() const { return WTF::holds_alternative<CSSValueID>(m_value) && WTF::get<CSSValueID>(m_value) == CSSValueInvalid; } 67 83 68 bool containsVariables() const { ASSERT(!m_containsVariables || !m_resolvedTypedValue); return m_containsVariables; } 69 bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const; 84 const VariantValue& value() const { return m_value; } 70 85 71 void resolveVariableReferences(const CSSRegisteredCustomPropertySet&, Vector<Ref<CSSCustomPropertyValue>>&, const RenderStyle&) const; 72 73 CSSValueID valueID() const { return m_valueId; } 74 CSSVariableData* value() const { return m_value.get(); } 75 Vector<CSSParserToken> tokens(const CSSRegisteredCustomPropertySet&, const RenderStyle&) const; 76 77 const std::optional<Length>& resolvedTypedValue() const { return m_resolvedTypedValue; } 78 void setResolvedTypedValue(Length); 86 Vector<CSSParserToken> tokens() const; 87 bool equals(const CSSCustomPropertyValue& other) const; 79 88 80 89 private: 81 CSSCustomPropertyValue(const AtomicString& name, const String& serializedValue) 82 : CSSValue(CustomPropertyClass) 83 , m_name(name) 84 , m_stringValue(serializedValue) 85 , m_serialized(true) 86 { 87 } 88 89 CSSCustomPropertyValue(const AtomicString& name, CSSValueID id) 90 : CSSValue(CustomPropertyClass) 91 , m_name(name) 92 , m_valueId(id) 93 { 94 ASSERT(id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset || id == CSSValueRevert || id == CSSValueInvalid); 95 } 96 97 CSSCustomPropertyValue(const AtomicString& name, Ref<CSSVariableData>&& value) 90 CSSCustomPropertyValue(const AtomicString& name, VariantValue&& value) 98 91 : CSSValue(CustomPropertyClass) 99 92 , m_name(name) 100 93 , m_value(WTFMove(value)) 101 , m_valueId(CSSValueInternalVariableValue) 102 , m_containsVariables(m_value->needsVariableResolution()) 94 , m_serialized(false) 103 95 { 104 96 } … … 107 99 : CSSValue(CustomPropertyClass) 108 100 , m_name(other.m_name) 109 , m_value(other.m_value.copyRef()) 110 , m_valueId(other.m_valueId) 101 , m_value(CSSValueUnset) 111 102 , m_stringValue(other.m_stringValue) 112 , m_containsVariables(other.m_containsVariables)113 103 , m_serialized(other.m_serialized) 114 , m_resolvedTypedValue(other.m_resolvedTypedValue)115 104 { 105 // No copy constructor for Ref<CSSVariableData>, so we have to do this ourselves 106 auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) { 107 m_value = value.copyRef(); 108 }, [&](const CSSValueID& value) { 109 m_value = value; 110 }, [&](const Ref<CSSVariableData>& value) { 111 m_value = value.copyRef(); 112 }, [&](const Length& value) { 113 m_value = value; 114 }); 115 WTF::visit(visitor, other.m_value); 116 116 } 117 117 118 118 const AtomicString m_name; 119 120 RefPtr<CSSVariableData> m_value; 121 CSSValueID m_valueId { CSSValueInvalid }; 119 VariantValue m_value; 122 120 123 121 mutable String m_stringValue; 124 bool m_containsVariables { false };125 122 mutable bool m_serialized { false }; 126 127 // FIXME: It should not be possible to express an invalid state, such as containsVariables() && resolvedTypedValue().128 std::optional<Length> m_resolvedTypedValue;129 123 }; 130 124 -
trunk/Source/WebCore/css/CSSRegisteredCustomProperty.cpp
r236828 r237347 31 31 namespace WebCore { 32 32 33 CSSRegisteredCustomProperty::CSSRegisteredCustomProperty(const String& name, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue)33 CSSRegisteredCustomProperty::CSSRegisteredCustomProperty(const String& name, const String& syntax, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue) 34 34 : name(name) 35 , syntax(syntax) 35 36 , inherits(inherits) 36 37 , m_initialValue(WTFMove(initialValue)) -
trunk/Source/WebCore/css/CSSRegisteredCustomProperty.h
r236828 r237347 34 34 struct CSSRegisteredCustomProperty { 35 35 const String name; 36 /* TODO syntax */36 const String syntax; 37 37 const bool inherits; 38 38 39 CSSRegisteredCustomProperty(const String& name, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue);39 CSSRegisteredCustomProperty(const String& name, const String& syntax, bool inherits, RefPtr<CSSCustomPropertyValue>&& initialValue); 40 40 41 41 const CSSCustomPropertyValue* initialValue() const { return m_initialValue.get(); } -
trunk/Source/WebCore/css/CSSVariableData.cpp
r236895 r237347 61 61 } 62 62 63 void CSSVariableData::consumeAndUpdateTokens(const CSSParserTokenRange& range)63 CSSVariableData::CSSVariableData(const CSSParserTokenRange& range) 64 64 { 65 65 StringBuilder stringBuilder; … … 78 78 } 79 79 80 CSSVariableData::CSSVariableData(const CSSParserTokenRange& range, bool needsVariableResolution)81 : m_needsVariableResolution(needsVariableResolution)82 {83 consumeAndUpdateTokens(range);84 }85 86 bool CSSVariableData::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const87 {88 if (invalidProperties.contains(name))89 return false;90 91 HashSet<AtomicString> newSeenProperties = seenProperties;92 newSeenProperties.add(name);93 94 bool valid = checkVariablesForCyclesWithRange(m_tokens, style, newSeenProperties, invalidProperties);95 if (!valid)96 invalidProperties.add(name);97 98 return valid;99 }100 101 bool CSSVariableData::checkVariablesForCyclesWithRange(CSSParserTokenRange range, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const102 {103 while (!range.atEnd()) {104 if (range.peek().functionId() == CSSValueVar || range.peek().functionId() == CSSValueEnv) {105 CSSParserTokenRange block = range.consumeBlock();106 107 block.consumeWhitespace();108 ASSERT(block.peek().type() == IdentToken);109 AtomicString variableName = block.consumeIncludingWhitespace().value().toAtomicString();110 ASSERT(block.atEnd() || block.peek().type() == CommaToken);111 if (seenProperties.contains(variableName))112 return false;113 114 auto* value = style.getCustomProperty(variableName);115 if (value && value->containsVariables() && !value->checkVariablesForCycles(variableName, style, seenProperties, invalidProperties))116 return false;117 118 if (range.peek().type() == CommaToken) {119 // Fallback.120 range.consume();121 return checkVariablesForCyclesWithRange(block, style, seenProperties, invalidProperties);122 }123 } else124 range.consume();125 }126 return true;127 }128 129 bool CSSVariableData::resolveVariableFallback(const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result, const RenderStyle& style) const130 {131 if (range.atEnd())132 return false;133 ASSERT(range.peek().type() == CommaToken);134 range.consume();135 return resolveTokenRange(registeredProperties, range, result, style);136 }137 138 bool CSSVariableData::resolveVariableReference(const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result, const RenderStyle& style) const139 {140 range.consumeWhitespace();141 ASSERT(range.peek().type() == IdentToken);142 AtomicString variableName = range.consumeIncludingWhitespace().value().toAtomicString();143 ASSERT(range.atEnd() || (range.peek().type() == CommaToken));144 145 auto* property = style.getCustomProperty(variableName);146 if (property && property->resolvedTypedValue()) {147 result.appendVector(property->tokens(registeredProperties, style));148 return true;149 }150 151 if (!property || !property->value()) {152 auto* registered = registeredProperties.get(variableName);153 if (registered && registered->initialValue())154 property = registered->initialValue();155 else156 return resolveVariableFallback(registeredProperties, range, result, style);157 }158 ASSERT(property);159 result.appendVector(property->tokens(registeredProperties, style));160 161 return true;162 }163 164 RefPtr<CSSVariableData> CSSVariableData::resolveVariableReferences(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style) const165 {166 Vector<CSSParserToken> resolvedTokens;167 CSSParserTokenRange range = m_tokens;168 if (!resolveTokenRange(registeredProperties, range, resolvedTokens, style))169 return nullptr;170 return CSSVariableData::createResolved(resolvedTokens, *this);171 }172 173 bool CSSVariableData::resolveTokenRange(const CSSRegisteredCustomPropertySet& registeredProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result, const RenderStyle& style) const174 {175 bool success = true;176 while (!range.atEnd()) {177 if (range.peek().functionId() == CSSValueVar || range.peek().functionId() == CSSValueEnv)178 success &= resolveVariableReference(registeredProperties, range.consumeBlock(), result, style);179 else180 result.append(range.consume());181 }182 return success;183 }184 185 80 } // namespace WebCore -
trunk/Source/WebCore/css/CSSVariableData.h
r236828 r237347 44 44 WTF_MAKE_FAST_ALLOCATED; 45 45 public: 46 static Ref<CSSVariableData> create(const CSSParserTokenRange& range , bool needsVariableResolution = true)46 static Ref<CSSVariableData> create(const CSSParserTokenRange& range) 47 47 { 48 return adoptRef(*new CSSVariableData(range, needsVariableResolution)); 49 } 50 51 static Ref<CSSVariableData> createResolved(const Vector<CSSParserToken>& resolvedTokens, const CSSVariableData& unresolvedData) 52 { 53 return adoptRef(*new CSSVariableData(resolvedTokens, unresolvedData.m_backingString)); 48 return adoptRef(*new CSSVariableData(range)); 54 49 } 55 50 … … 60 55 bool operator==(const CSSVariableData& other) const; 61 56 62 bool needsVariableResolution() const { return m_needsVariableResolution; }63 64 bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;65 66 RefPtr<CSSVariableData> resolveVariableReferences(const CSSRegisteredCustomPropertySet&, const RenderStyle&) const;67 bool resolveTokenRange(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;68 69 57 private: 70 CSSVariableData(const CSSParserTokenRange&, bool needsVariableResolution); 71 72 // We can safely copy the tokens (which have raw pointers to substrings) because 73 // StylePropertySets contain references to CSSCustomPropertyValues, which 74 // point to the unresolved CSSVariableData values that own the backing strings 75 // this will potentially reference. 76 CSSVariableData(const Vector<CSSParserToken>& resolvedTokens, String backingString) 77 : m_backingString(backingString) 78 , m_tokens(resolvedTokens) 79 , m_needsVariableResolution(false) 80 { } 81 82 void consumeAndUpdateTokens(const CSSParserTokenRange&); 58 CSSVariableData(const CSSParserTokenRange&); 83 59 template<typename CharacterType> void updateTokens(const CSSParserTokenRange&); 84 85 bool checkVariablesForCyclesWithRange(CSSParserTokenRange, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;86 bool resolveVariableReference(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;87 bool resolveVariableFallback(const CSSRegisteredCustomPropertySet&, CSSParserTokenRange, Vector<CSSParserToken>&, const RenderStyle&) const;88 60 89 61 String m_backingString; 90 62 Vector<CSSParserToken> m_tokens; 91 const bool m_needsVariableResolution;92 63 93 64 // FIXME-NEWPARSER: We want to cache StyleProperties once we support @apply. -
trunk/Source/WebCore/css/CSSVariableReferenceValue.cpp
r236828 r237347 31 31 #include "CSSVariableReferenceValue.h" 32 32 33 #include "RenderStyle.h" 34 #include "StyleResolver.h" 35 33 36 namespace WebCore { 34 37 … … 41 44 return m_stringValue; 42 45 } 43 44 bool CSSVariableReferenceValue::checkVariablesForCycles(const AtomicString& name, const RenderStyle& style, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const 46 47 static bool resolveTokenRange(CSSParserTokenRange, Vector<CSSParserToken>&, ApplyCascadedPropertyState&); 48 49 static bool resolveVariableFallback(CSSParserTokenRange range, Vector<CSSParserToken>& result, ApplyCascadedPropertyState& state) 45 50 { 46 ASSERT(m_data); 47 return m_data->checkVariablesForCycles(name, style, seenProperties, invalidProperties); 51 if (range.atEnd()) 52 return false; 53 ASSERT(range.peek().type() == CommaToken); 54 range.consume(); 55 return resolveTokenRange(range, result, state); 56 } 57 58 static bool resolveVariableReference(CSSParserTokenRange range, Vector<CSSParserToken>& result, ApplyCascadedPropertyState& state) 59 { 60 auto& registeredProperties = state.styleResolver->document().getCSSRegisteredCustomPropertySet(); 61 auto& style = *state.styleResolver->style(); 62 63 range.consumeWhitespace(); 64 ASSERT(range.peek().type() == IdentToken); 65 String variableName = range.consumeIncludingWhitespace().value().toString(); 66 ASSERT(range.atEnd() || (range.peek().type() == CommaToken)); 67 68 // Apply this variable first, in case it is still unresolved 69 state.styleResolver->applyCascadedCustomProperty(variableName, state); 70 71 // Apply fallback to detect cycles 72 Vector<CSSParserToken> fallbackResult; 73 resolveVariableFallback(CSSParserTokenRange(range), fallbackResult, state); 74 75 auto* property = style.getCustomProperty(variableName); 76 77 if (!property || property->isUnset() || property->isInvalid()) { 78 auto* registered = registeredProperties.get(variableName); 79 if (registered && registered->initialValue()) 80 property = registered->initialValue(); 81 else 82 return resolveVariableFallback(range, result, state); 83 } 84 85 ASSERT(property->isResolved()); 86 result.appendVector(property->tokens()); 87 88 return true; 89 } 90 91 static bool resolveTokenRange(CSSParserTokenRange range, Vector<CSSParserToken>& result, ApplyCascadedPropertyState& state) 92 { 93 bool success = true; 94 while (!range.atEnd()) { 95 if (range.peek().functionId() == CSSValueVar || range.peek().functionId() == CSSValueEnv) 96 success &= resolveVariableReference(range.consumeBlock(), result, state); 97 else 98 result.append(range.consume()); 99 } 100 return success; 101 } 102 103 RefPtr<CSSVariableData> CSSVariableReferenceValue::resolveVariableReferences(ApplyCascadedPropertyState& state) const 104 { 105 Vector<CSSParserToken> resolvedTokens; 106 CSSParserTokenRange range = m_data->tokenRange(); 107 108 if (!resolveTokenRange(range, resolvedTokens, state)) 109 return nullptr; 110 111 return CSSVariableData::create(resolvedTokens); 48 112 } 49 113 -
trunk/Source/WebCore/css/CSSVariableReferenceValue.h
r236828 r237347 30 30 #pragma once 31 31 32 #include "CSSParserToken.h" 33 #include "CSSParserTokenRange.h" 32 34 #include "CSSValue.h" 33 35 #include "CSSVariableData.h" 36 #include <wtf/HashSet.h> 34 37 #include <wtf/RefPtr.h> 38 #include <wtf/text/WTFString.h> 35 39 36 40 namespace WebCore { 37 41 42 struct ApplyCascadedPropertyState; 43 class CSSParserTokenRange; 44 38 45 class CSSVariableReferenceValue : public CSSValue { 39 46 public: 40 static Ref<CSSVariableReferenceValue> create( Ref<CSSVariableData>&& data)47 static Ref<CSSVariableReferenceValue> create(const CSSParserTokenRange& range) 41 48 { 42 return adoptRef(*new CSSVariableReferenceValue( WTFMove(data)));49 return adoptRef(*new CSSVariableReferenceValue(CSSVariableData::create(range))); 43 50 } 44 51 45 CSSVariableData* variableDataValue() const 46 { 47 return m_data.get(); 48 } 49 50 bool equals(const CSSVariableReferenceValue& other) const { return m_data == other.m_data; } 52 bool equals(const CSSVariableReferenceValue& other) const { return m_data.get() == other.m_data.get(); } 51 53 String customCSSText() const; 52 54 53 bool checkVariablesForCycles(const AtomicString& name, const RenderStyle&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;55 RefPtr<CSSVariableData> resolveVariableReferences(ApplyCascadedPropertyState&) const; 54 56 55 57 private: … … 60 62 } 61 63 62 Ref Ptr<CSSVariableData> m_data;64 Ref<CSSVariableData> m_data; 63 65 mutable String m_stringValue; 64 66 mutable bool m_serialized { false }; -
trunk/Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp
r236895 r237347 29 29 #include "CSSCustomPropertyValue.h" 30 30 #include "CSSPropertyNames.h" 31 #include "CSSPropertyParser.h" 31 32 #include "CSSRegisteredCustomProperty.h" 32 33 #include "CSSTokenizer.h" … … 34 35 #include "Document.h" 35 36 #include "StyleBuilderConverter.h" 36 #include "StyleResolver.h"37 37 #include <wtf/text/WTFString.h> 38 38 … … 43 43 RefPtr<CSSCustomPropertyValue> initialValue; 44 44 if (!descriptor.initialValue.isEmpty()) { 45 initialValue = CSSCustomPropertyValue::createWithVariableData(descriptor.name, CSSVariableData::create(CSSParserTokenRange(Vector<CSSParserToken>()), false)); 46 CSSParser parser(document); 45 CSSTokenizer tokenizer(descriptor.initialValue); 47 46 StyleResolver styleResolver(document); 48 47 49 auto primitiveVal = parser.parseSingleValue(CSSPropertyCustom, descriptor.initialValue); 50 if (!primitiveVal || !primitiveVal->isPrimitiveValue()) 48 // We need to initialize this so that we can successfully parse computationally dependent values (like em units). 49 // We don't actually need the values to be accurate, since they will be rejected later anyway 50 styleResolver.state().setStyle(styleResolver.defaultStyleForElement()); 51 styleResolver.updateFont(); 52 53 initialValue = CSSPropertyParser::parseTypedCustomPropertyValue(descriptor.name, descriptor.syntax, tokenizer.tokenRange(), styleResolver, strictCSSParserContext()); 54 55 if (!initialValue || !initialValue->isResolved()) 51 56 return Exception { SyntaxError, "The given initial value does not parse for the given syntax." }; 52 57 53 58 HashSet<CSSPropertyID> dependencies; 54 primitiveVal->collectDirectComputationalDependencies(dependencies);55 primitiveVal->collectDirectRootComputationalDependencies(dependencies);59 initialValue->collectDirectComputationalDependencies(dependencies); 60 initialValue->collectDirectRootComputationalDependencies(dependencies); 56 61 57 62 if (!dependencies.isEmpty()) 58 63 return Exception { SyntaxError, "The given initial value must be computationally independent." }; 59 60 initialValue->setResolvedTypedValue(StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));61 64 } 62 65 63 CSSRegisteredCustomProperty property { descriptor.name, descriptor. inherits, WTFMove(initialValue) };66 CSSRegisteredCustomProperty property { descriptor.name, descriptor.syntax, descriptor.inherits, WTFMove(initialValue) }; 64 67 if (!document.registerCSSProperty(WTFMove(property))) 65 68 return Exception { InvalidModificationError, "This property has already been registered." }; 69 70 document.styleScope().didChangeStyleSheetEnvironment(); 66 71 67 72 return { }; -
trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp
r233122 r237347 227 227 { 228 228 StyleAttributeMutationScope mutationScope(this); 229 230 if (!willMutate()) 231 return { }; 232 233 Document* document = nullptr; 234 235 if (parentElement()) 236 document = &parentElement()->document(); 237 else 238 document = parentStyleSheet()->ownerDocument(); 229 239 230 240 CSSPropertyID propertyID = cssPropertyID(propertyName); … … 232 242 propertyID = CSSPropertyCustom; 233 243 if (!propertyID) 234 return { };235 236 if (!willMutate())237 244 return { }; 238 245 … … 243 250 bool changed; 244 251 if (propertyID == CSSPropertyCustom) 245 changed = m_propertySet->setCustomProperty( propertyName, value, important, cssParserContext());252 changed = m_propertySet->setCustomProperty(document, propertyName, value, important, cssParserContext()); 246 253 else 247 254 changed = m_propertySet->setProperty(propertyID, value, important, cssParserContext()); -
trunk/Source/WebCore/css/StyleBuilderCustom.h
r236828 r237347 1880 1880 inline void StyleBuilderCustom::applyInitialCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, const AtomicString& name) 1881 1881 { 1882 if (registered ) {1882 if (registered && registered->initialValue()) { 1883 1883 auto initialValue = registered->initialValueCopy(); 1884 1884 applyValueCustomProperty(styleResolver, registered, *initialValue); … … 1886 1886 } 1887 1887 1888 auto invalid = CSSCustomPropertyValue::create WithID(name, CSSValueInvalid);1888 auto invalid = CSSCustomPropertyValue::createUnresolved(name, CSSValueInvalid); 1889 1889 applyValueCustomProperty(styleResolver, registered, invalid.get()); 1890 1890 } … … 1901 1901 inline void StyleBuilderCustom::applyValueCustomProperty(StyleResolver& styleResolver, const CSSRegisteredCustomProperty* registered, CSSCustomPropertyValue& value) 1902 1902 { 1903 ASSERT(value.isResolved()); 1903 1904 const auto& name = value.name(); 1904 1905 1905 1906 if (!registered || registered->inherits) 1906 styleResolver.style()->setInheritedCustomPropertyValue(name, makeRef(value) , registered);1907 styleResolver.style()->setInheritedCustomPropertyValue(name, makeRef(value)); 1907 1908 else 1908 styleResolver.style()->setNonInheritedCustomPropertyValue(name, makeRef(value) , registered);1909 styleResolver.style()->setNonInheritedCustomPropertyValue(name, makeRef(value)); 1909 1910 } 1910 1911 -
trunk/Source/WebCore/css/StyleProperties.cpp
r236278 r237347 29 29 #include "CSSParser.h" 30 30 #include "CSSPendingSubstitutionValue.h" 31 #include "CSSPropertyParser.h" 32 #include "CSSTokenizer.h" 31 33 #include "CSSValueKeywords.h" 32 34 #include "CSSValueList.h" … … 780 782 } 781 783 782 bool MutableStyleProperties::setCustomProperty(const String& propertyName, const String& value, bool important, CSSParserContext parserContext)784 bool MutableStyleProperties::setCustomProperty(const Document* document, const String& propertyName, const String& value, bool important, CSSParserContext parserContext) 783 785 { 784 786 // Setting the value to an empty string just removes the property in both IE and Gecko. … … 788 790 789 791 parserContext.mode = cssParserMode(); 792 793 String syntax = "*"; 794 auto* registered = document ? document->getCSSRegisteredCustomPropertySet().get(propertyName) : nullptr; 795 796 if (registered) 797 syntax = registered->syntax; 798 799 CSSTokenizer tokenizer(value); 800 if (!CSSPropertyParser::canParseTypedCustomPropertyValue(syntax, tokenizer.tokenRange(), parserContext)) 801 return false; 802 790 803 // When replacing an existing property value, this moves the property to the end of the list. 791 804 // Firefox preserves the position, and MSIE moves the property to the beginning. -
trunk/Source/WebCore/css/StyleProperties.h
r236278 r237347 250 250 251 251 // Methods for querying and altering CSS custom properties. 252 bool setCustomProperty(const String& propertyName, const String& value, bool important, CSSParserContext);252 bool setCustomProperty(const Document*, const String& propertyName, const String& value, bool important, CSSParserContext); 253 253 bool removeCustomProperty(const String& propertyName, String* returnText = nullptr); 254 254 -
trunk/Source/WebCore/css/StyleResolver.cpp
r236828 r237347 322 322 } 323 323 324 inlinevoid StyleResolver::State::setStyle(std::unique_ptr<RenderStyle> style)324 void StyleResolver::State::setStyle(std::unique_ptr<RenderStyle> style) 325 325 { 326 326 m_style = WTFMove(style); … … 430 430 cascade.addNormalMatches(result, 0, result.matchedProperties().size() - 1); 431 431 432 // Resolve custom properties first. 433 applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &result); 434 435 applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &result); 432 ApplyCascadedPropertyState applyState { this, &cascade, &result }; 433 applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState); 436 434 437 435 // If our font got dirtied, update it now. 438 436 updateFont(); 439 437 440 // Now do rest of the properties. 441 applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &result); 438 // Now resolve remaining custom properties and the rest, in any order 439 for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it) 440 applyCascadedCustomProperty(it->key, applyState); 441 applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState); 442 442 443 443 // If our font got dirtied by one of the non-essential font props, update it a second time. 444 444 updateFont(); 445 445 446 cascade.applyDeferredProperties(*this, &result);446 cascade.applyDeferredProperties(*this, applyState); 447 447 448 448 adjustRenderStyle(*state.style(), *state.parentStyle(), nullptr, nullptr); … … 636 636 cascade.addNormalMatches(result, 0, result.matchedProperties().size() - 1); 637 637 638 // Resolve custom properties first. 639 applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &result); 640 641 applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &result); 638 ApplyCascadedPropertyState applyState { this, &cascade, &result }; 639 applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState); 642 640 643 641 // If our font got dirtied, update it now. 644 642 updateFont(); 645 643 646 applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &result); 647 648 cascade.applyDeferredProperties(*this, &result); 644 // Now resolve remaining custom properties and the rest, in any order 645 for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it) 646 applyCascadedCustomProperty(it->key, applyState); 647 applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState); 648 649 cascade.applyDeferredProperties(*this, applyState); 649 650 650 651 // Now return the style. … … 1372 1373 cascade.addImportantMatches(matchResult, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly); 1373 1374 1374 applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, &matchResult); 1375 ApplyCascadedPropertyState applyState { this, &cascade, &matchResult }; 1376 1377 applyCascadedProperties(CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, applyState); 1375 1378 adjustStyleForInterCharacterRuby(); 1376 1379 1377 // Resolve custom variables first. 1378 applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &matchResult); 1379 1380 // Start by applying properties that other properties may depend on. 1381 applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &matchResult); 1382 1380 applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState); 1381 1382 // If our font got dirtied, update it now. 1383 1383 updateFont(); 1384 applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &matchResult); 1384 1385 // Now resolve remaining custom properties and the rest, in any order 1386 for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it) 1387 applyCascadedCustomProperty(it->key, applyState); 1388 applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState); 1385 1389 1386 1390 state.cacheBorderAndBackground(); … … 1393 1397 cascade.addImportantMatches(matchResult, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly); 1394 1398 1395 // Resolve custom properties first. 1396 applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom, &matchResult); 1397 1398 applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, &matchResult); 1399 1400 // Adjust the font size to be smaller if ruby-position is inter-character. 1399 1400 ApplyCascadedPropertyState applyState { this, &cascade, &matchResult }; 1401 1402 applyCascadedProperties(CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition, applyState); 1401 1403 adjustStyleForInterCharacterRuby(); 1402 1404 1403 // Start by applying properties that other properties may depend on. 1404 applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty, &matchResult); 1405 applyCascadedProperties(firstCSSProperty, lastHighPriorityProperty, applyState); 1405 1406 1406 1407 // If the effective zoom value changes, we can't use the matched properties cache. Start over. … … 1415 1416 return applyMatchedProperties(matchResult, element, DoNotUseMatchedPropertiesCache); 1416 1417 1417 // Apply properties that no other properties depend on. 1418 applyCascadedProperties(cascade, firstLowPriorityProperty, lastCSSProperty, &matchResult); 1418 // Now resolve remaining custom properties and the rest, in any order 1419 for (auto it = cascade.customProperties().begin(); it != cascade.customProperties().end(); ++it) 1420 applyCascadedCustomProperty(it->key, applyState); 1421 applyCascadedProperties(firstLowPriorityProperty, lastCSSProperty, applyState); 1419 1422 1420 1423 // Finally, some properties must be applied in the order they were parsed. 1421 1424 // There are some CSS properties that affect the same RenderStyle values, 1422 1425 // so to preserve behavior, we queue them up during cascade and flush here. 1423 cascade.applyDeferredProperties(*this, &matchResult);1426 cascade.applyDeferredProperties(*this, applyState); 1424 1427 1425 1428 ASSERT(!state.fontDirty()); … … 1442 1445 void StyleResolver::applyPropertyToCurrentStyle(CSSPropertyID id, CSSValue* value) 1443 1446 { 1447 ApplyCascadedPropertyState applyState { this, nullptr, nullptr }; 1444 1448 if (value) 1445 applyProperty(id, value );1449 applyProperty(id, value, applyState); 1446 1450 } 1447 1451 … … 1610 1614 } 1611 1615 1612 void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, SelectorChecker::LinkMatchMask linkMatchMask, const MatchResult* matchResult) 1613 { 1616 void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, ApplyCascadedPropertyState& applyState, SelectorChecker::LinkMatchMask linkMatchMask) 1617 { 1618 auto* matchResult = applyState.matchResult; 1614 1619 ASSERT_WITH_MESSAGE(!isShorthandCSSProperty(id), "Shorthand property id = %d wasn't expanded at parsing time", id); 1615 1620 … … 1618 1623 RefPtr<CSSValue> valueToApply = value; 1619 1624 if (value->hasVariableReferences()) { 1620 valueToApply = resolvedVariableValue(id, *value); 1621 if (!valueToApply) { 1625 valueToApply = resolvedVariableValue(id, *value, applyState); 1626 // If appliedProperties already has this id, then we detected a cycle, and this value should be unset. 1627 if (!valueToApply || applyState.appliedProperties.contains(id)) { 1622 1628 if (CSSProperty::isInheritedProperty(id)) 1623 1629 valueToApply = CSSValuePool::singleton().createInheritedValue(); … … 1630 1636 CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode()); 1631 1637 ASSERT(newId != id); 1632 return applyProperty(newId, valueToApply.get(), linkMatchMask, matchResult);1638 return applyProperty(newId, valueToApply.get(), applyState, linkMatchMask); 1633 1639 } 1634 1640 … … 1641 1647 if (id == CSSPropertyCustom) { 1642 1648 customPropertyValue = &downcast<CSSCustomPropertyValue>(*valueToApply); 1643 customPropertyValueID = customPropertyValue->valueID(); 1649 ASSERT(customPropertyValue->isResolved()); 1650 if (WTF::holds_alternative<CSSValueID>(customPropertyValue->value())) 1651 customPropertyValueID = WTF::get<CSSValueID>(customPropertyValue->value()); 1644 1652 auto& name = customPropertyValue->name(); 1645 1653 customPropertyRegistered = document().getCSSRegisteredCustomPropertySet().get(name); … … 1668 1676 auto property = rollback->customProperty(customPropertyValue->name()); 1669 1677 if (property.cssValue[linkMatchMask]) 1670 applyProperty(property.id, property.cssValue[linkMatchMask], linkMatchMask, matchResult);1678 applyProperty(property.id, property.cssValue[linkMatchMask], applyState, linkMatchMask); 1671 1679 return; 1672 1680 } … … 1674 1682 auto& property = rollback->property(id); 1675 1683 if (property.cssValue[linkMatchMask]) 1676 applyProperty(property.id, property.cssValue[linkMatchMask], linkMatchMask, matchResult);1684 applyProperty(property.id, property.cssValue[linkMatchMask], applyState, linkMatchMask); 1677 1685 return; 1678 1686 } … … 1703 1711 } 1704 1712 1705 RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value ) const1713 RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value, ApplyCascadedPropertyState& state) const 1706 1714 { 1707 1715 CSSParser parser(document()); 1708 return parser.parseValueWithVariableReferences(propID, value, document().getCSSRegisteredCustomPropertySet(), *m_state.style());1716 return parser.parseValueWithVariableReferences(propID, value, state); 1709 1717 } 1710 1718 … … 2228 2236 } 2229 2237 2230 void StyleResolver::CascadedProperties::applyDeferredProperties(StyleResolver& resolver, const MatchResult* matchResult)2238 void StyleResolver::CascadedProperties::applyDeferredProperties(StyleResolver& resolver, ApplyCascadedPropertyState& applyState) 2231 2239 { 2232 2240 for (auto& property : m_deferredProperties) 2233 property.apply(resolver, matchResult);2234 } 2235 2236 void StyleResolver::CascadedProperties::Property::apply(StyleResolver& resolver, const MatchResult* matchResult)2241 property.apply(resolver, applyState); 2242 } 2243 2244 void StyleResolver::CascadedProperties::Property::apply(StyleResolver& resolver, ApplyCascadedPropertyState& applyState) 2237 2245 { 2238 2246 State& state = resolver.state(); … … 2243 2251 state.setApplyPropertyToRegularStyle(true); 2244 2252 state.setApplyPropertyToVisitedLinkStyle(false); 2245 resolver.applyProperty(id, cssValue[SelectorChecker::MatchDefault], SelectorChecker::MatchDefault, matchResult);2253 resolver.applyProperty(id, cssValue[SelectorChecker::MatchDefault], applyState, SelectorChecker::MatchDefault); 2246 2254 } 2247 2255 … … 2252 2260 state.setApplyPropertyToRegularStyle(true); 2253 2261 state.setApplyPropertyToVisitedLinkStyle(false); 2254 resolver.applyProperty(id, cssValue[SelectorChecker::MatchLink], SelectorChecker::MatchLink, matchResult);2262 resolver.applyProperty(id, cssValue[SelectorChecker::MatchLink], applyState, SelectorChecker::MatchLink); 2255 2263 } 2256 2264 … … 2258 2266 state.setApplyPropertyToRegularStyle(false); 2259 2267 state.setApplyPropertyToVisitedLinkStyle(true); 2260 resolver.applyProperty(id, cssValue[SelectorChecker::MatchVisited], SelectorChecker::MatchVisited, matchResult);2268 resolver.applyProperty(id, cssValue[SelectorChecker::MatchVisited], applyState, SelectorChecker::MatchVisited); 2261 2269 } 2262 2270 … … 2265 2273 } 2266 2274 2267 void StyleResolver::applyCascadedProperties(CascadedProperties& cascade, int firstProperty, int lastProperty, const MatchResult* matchResult) 2275 void StyleResolver::applyCascadedCustomProperty(const String& name, ApplyCascadedPropertyState& state) 2276 { 2277 if (state.appliedCustomProperties.contains(name) || !state.cascade->customProperties().contains(name)) 2278 return; 2279 2280 auto property = state.cascade->customProperties().get(name); 2281 2282 for (auto index : { SelectorChecker::MatchDefault, SelectorChecker::MatchLink, SelectorChecker::MatchVisited }) { 2283 if (!property.cssValue[index]) 2284 continue; 2285 if (index != SelectorChecker::MatchDefault && this->state().style()->insideLink() == InsideLink::NotInside) 2286 continue; 2287 2288 Ref<CSSCustomPropertyValue> valueToApply = CSSCustomPropertyValue::create(downcast<CSSCustomPropertyValue>(*property.cssValue[index])); 2289 2290 if (state.inProgressPropertiesCustom.contains(name)) { 2291 // We are in a cycle, so reset the value. 2292 state.appliedCustomProperties.add(name); 2293 // Resolve this value so that we reset its dependencies 2294 if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) 2295 resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state); 2296 valueToApply = CSSCustomPropertyValue::createWithID(name, CSSValueUnset); 2297 } 2298 2299 state.inProgressPropertiesCustom.add(name); 2300 2301 if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) { 2302 RefPtr<CSSValue> parsedValue = resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state); 2303 2304 if (!parsedValue) 2305 parsedValue = CSSCustomPropertyValue::createWithID(name, CSSValueUnset); 2306 2307 valueToApply = downcast<CSSCustomPropertyValue>(*parsedValue); 2308 } 2309 2310 if (state.inProgressPropertiesCustom.contains(name)) { 2311 if (index == SelectorChecker::MatchDefault) { 2312 this->state().setApplyPropertyToRegularStyle(true); 2313 this->state().setApplyPropertyToVisitedLinkStyle(false); 2314 } 2315 2316 if (index == SelectorChecker::MatchLink) { 2317 this->state().setApplyPropertyToRegularStyle(true); 2318 this->state().setApplyPropertyToVisitedLinkStyle(false); 2319 } 2320 2321 if (index == SelectorChecker::MatchVisited) { 2322 this->state().setApplyPropertyToRegularStyle(false); 2323 this->state().setApplyPropertyToVisitedLinkStyle(true); 2324 } 2325 applyProperty(CSSPropertyCustom, valueToApply.ptr(), state, index); 2326 } 2327 state.inProgressPropertiesCustom.remove(name); 2328 state.appliedCustomProperties.add(name); 2329 } 2330 } 2331 2332 void StyleResolver::applyCascadedProperties(int firstProperty, int lastProperty, ApplyCascadedPropertyState& state) 2268 2333 { 2269 2334 for (int id = firstProperty; id <= lastProperty; ++id) { 2270 2335 CSSPropertyID propertyID = static_cast<CSSPropertyID>(id); 2271 if (! cascade.hasProperty(propertyID))2336 if (!state.cascade->hasProperty(propertyID)) 2272 2337 continue; 2273 if (propertyID == CSSPropertyCustom) { 2274 // Apply font size first, since custom properties may rely on it for relative unit calculations 2275 // Once it is applied and the custom property values are set, it will be applied again, which should 2276 // handle any font-size properties that rely on registered custom properties. 2277 // FIXME cycles should be detected. 2278 if (cascade.hasProperty(CSSPropertyFontSize)) 2279 cascade.property(CSSPropertyFontSize).apply(*this, matchResult); 2280 updateFont(); 2281 2282 HashMap<AtomicString, CascadedProperties::Property>::iterator end = cascade.customProperties().end(); 2283 for (HashMap<AtomicString, CascadedProperties::Property>::iterator it = cascade.customProperties().begin(); it != end; ++it) 2284 it->value.apply(*this, matchResult); 2285 m_state.style()->checkVariablesInCustomProperties(document().getCSSRegisteredCustomPropertySet(), m_state.parentStyle(), *this); 2338 ASSERT(propertyID != CSSPropertyCustom); 2339 auto& property = state.cascade->property(propertyID); 2340 ASSERT(!shouldApplyPropertyInParseOrder(propertyID)); 2341 2342 if (state.inProgressProperties.contains(propertyID)) { 2343 // We are in a cycle (eg. setting font size using registered custom property value containing em) 2344 // So this value should be unset 2345 state.appliedProperties.add(propertyID); 2346 // This property is in a cycle, and only the root of the call stack will have firstProperty != lastProperty. 2347 ASSERT(firstProperty == lastProperty); 2286 2348 continue; 2287 2349 } 2288 auto& property = cascade.property(propertyID); 2289 ASSERT(!shouldApplyPropertyInParseOrder(propertyID)); 2290 property.apply(*this, matchResult); 2350 2351 state.inProgressProperties.add(propertyID); 2352 property.apply(*this, state); 2353 state.appliedProperties.add(propertyID); 2354 state.inProgressProperties.remove(propertyID); 2291 2355 } 2292 2356 } -
trunk/Source/WebCore/css/StyleResolver.h
r236828 r237347 268 268 269 269 struct Property { 270 void apply(StyleResolver&, const MatchResult*);270 void apply(StyleResolver&, ApplyCascadedPropertyState&); 271 271 272 272 CSSPropertyID id; … … 282 282 void addImportantMatches(const MatchResult&, int startIndex, int endIndex, bool inheritedOnly = false); 283 283 284 void applyDeferredProperties(StyleResolver&, const MatchResult*);284 void applyDeferredProperties(StyleResolver&, ApplyCascadedPropertyState&); 285 285 286 286 HashMap<AtomicString, Property>& customProperties() { return m_customProperties; } … … 303 303 WritingMode m_writingMode; 304 304 }; 305 305 306 void applyCascadedProperties(int firstProperty, int lastProperty, ApplyCascadedPropertyState&); 307 void applyCascadedCustomProperty(const String& name, ApplyCascadedPropertyState&); 308 306 309 private: 307 310 // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh … … 322 325 void applyMatchedProperties(const MatchResult&, const Element&, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache); 323 326 324 void applyCascadedProperties(CascadedProperties&, int firstProperty, int lastProperty, const MatchResult*);325 327 void cascadeMatches(CascadedProperties&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly); 326 328 … … 456 458 void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); } 457 459 458 RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue& ) const;460 RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&, ApplyCascadedPropertyState&) const; 459 461 460 462 private: 461 463 void cacheBorderAndBackground(); 462 464 463 void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr);465 void applyProperty(CSSPropertyID, CSSValue*, ApplyCascadedPropertyState&, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault); 464 466 465 467 void applySVGProperty(CSSPropertyID, CSSValue*); … … 525 527 }; 526 528 529 // State to use when applying properties, to keep track of which custom and high-priority 530 // properties have been resolved. 531 struct ApplyCascadedPropertyState { 532 StyleResolver* styleResolver; 533 StyleResolver::CascadedProperties* cascade; 534 const StyleResolver::MatchResult* matchResult; 535 HashSet<CSSPropertyID> appliedProperties = { }; 536 HashSet<String> appliedCustomProperties = { }; 537 HashSet<CSSPropertyID> inProgressProperties = { }; 538 HashSet<String> inProgressPropertiesCustom = { }; 539 }; 540 541 527 542 inline bool StyleResolver::hasSelectorForAttribute(const Element& element, const AtomicString &attributeName) const 528 543 { -
trunk/Source/WebCore/css/parser/CSSParser.cpp
r236828 r237347 48 48 #include "Settings.h" 49 49 #include "StyleColor.h" 50 #include "StyleResolver.h" 50 51 #include "StyleRule.h" 51 52 #include "StyleSheetContents.h" … … 178 179 } 179 180 180 RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle& style) 181 { 181 RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, ApplyCascadedPropertyState& state) 182 { 183 ASSERT((propID == CSSPropertyCustom && value.isCustomPropertyValue()) || (propID != CSSPropertyCustom && !value.isCustomPropertyValue())); 184 auto& style = *state.styleResolver->style(); 182 185 auto direction = style.direction(); 183 186 auto writingMode = style.writingMode(); … … 191 194 shorthandID = CSSProperty::resolveDirectionAwareProperty(shorthandID, direction, writingMode); 192 195 CSSVariableReferenceValue* shorthandValue = pendingSubstitution.shorthandValue(); 193 const CSSVariableData* variableData = shorthandValue->variableDataValue(); 194 ASSERT(variableData); 195 196 Vector<CSSParserToken> resolvedTokens; 197 if (!variableData->resolveTokenRange(registeredProperties, variableData->tokens(), resolvedTokens, style)) 196 197 auto resolvedData = shorthandValue->resolveVariableReferences(state); 198 if (!resolvedData) 198 199 return nullptr; 200 Vector<CSSParserToken> resolvedTokens = resolvedData->tokens(); 199 201 200 202 ParsedPropertyVector parsedProperties; … … 210 212 } 211 213 212 const CSSVariableData* variableData = nullptr;213 214 214 if (value.isVariableReferenceValue()) { 215 215 const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value); 216 variableData = valueWithReferences.variableDataValue(); 217 ASSERT(variableData); 216 auto resolvedData = valueWithReferences.resolveVariableReferences(state); 217 if (!resolvedData) 218 return nullptr; 219 return CSSPropertyParser::parseSingleValue(propID, resolvedData->tokens(), m_context); 218 220 } 219 221 220 if (value.isCustomPropertyValue()) { 221 const CSSCustomPropertyValue& customPropValue = downcast<CSSCustomPropertyValue>(value); 222 223 if (customPropValue.resolvedTypedValue()) 224 return CSSPrimitiveValue::create(*customPropValue.resolvedTypedValue(), style); 225 226 variableData = customPropValue.value(); 227 } 228 229 if (!variableData) 230 return nullptr; 231 232 Vector<CSSParserToken> resolvedTokens; 233 if (!variableData->resolveTokenRange(registeredProperties, variableData->tokens(), resolvedTokens, style)) 234 return nullptr; 235 236 return CSSPropertyParser::parseSingleValue(propID, resolvedTokens, m_context); 222 const auto& customPropValue = downcast<CSSCustomPropertyValue>(value); 223 const auto& valueWithReferences = WTF::get<Ref<CSSVariableReferenceValue>>(customPropValue.value()).get(); 224 225 auto& name = downcast<CSSCustomPropertyValue>(value).name(); 226 auto* registered = state.styleResolver->document().getCSSRegisteredCustomPropertySet().get(name); 227 auto& syntax = registered ? registered->syntax : "*"; 228 auto resolvedData = valueWithReferences.resolveVariableReferences(state); 229 230 if (!resolvedData) 231 return nullptr; 232 233 // FIXME handle REM cycles. 234 HashSet<CSSPropertyID> dependencies; 235 CSSPropertyParser::collectParsedCustomPropertyValueDependencies(syntax, false, dependencies, resolvedData->tokens(), m_context); 236 237 for (auto id : dependencies) 238 state.styleResolver->applyCascadedProperties(id, id, state); 239 240 return CSSPropertyParser::parseTypedCustomPropertyValue(name, syntax, resolvedData->tokens(), *state.styleResolver, m_context); 237 241 } 238 242 -
trunk/Source/WebCore/css/parser/CSSParser.h
r236828 r237347 31 31 namespace WebCore { 32 32 33 struct ApplyCascadedPropertyState; 33 34 class CSSParserObserver; 34 35 class CSSSelectorList; … … 78 79 void parseSelector(const String&, CSSSelectorList&); 79 80 80 RefPtr<CSSValue> parseValueWithVariableReferences(CSSPropertyID, const CSSValue&, const CSSRegisteredCustomPropertySet&, const RenderStyle&);81 RefPtr<CSSValue> parseValueWithVariableReferences(CSSPropertyID, const CSSValue&, ApplyCascadedPropertyState&); 81 82 82 83 static Color parseColor(const String&, bool strict = false); -
trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp
r237266 r237347 38 38 #include "CSSCursorImageValue.h" 39 39 #include "CSSCustomIdentValue.h" 40 #include "CSSCustomPropertyValue.h" 40 41 #include "CSSFontFaceSrcValue.h" 41 42 #include "CSSFontFeatureValue.h" … … 74 75 #include "SVGPathByteStream.h" 75 76 #include "SVGPathUtilities.h" 77 #include "StyleBuilderConverter.h" 76 78 #include "StylePropertyShorthand.h" 77 79 #include "StylePropertyShorthandFunctions.h" 80 #include "StyleResolver.h" 78 81 #include <bitset> 79 82 #include <memory> … … 214 217 using namespace CSSPropertyParserHelpers; 215 218 216 CSSPropertyParser::CSSPropertyParser(const CSSParserTokenRange& range, const CSSParserContext& context, Vector<CSSProperty, 256>* parsedProperties )219 CSSPropertyParser::CSSPropertyParser(const CSSParserTokenRange& range, const CSSParserContext& context, Vector<CSSProperty, 256>* parsedProperties, bool consumeWhitespace) 217 220 : m_range(range) 218 221 , m_context(context) 219 222 , m_parsedProperties(parsedProperties) 220 223 { 221 m_range.consumeWhitespace(); 224 if (consumeWhitespace) 225 m_range.consumeWhitespace(); 222 226 } 223 227 … … 277 281 return nullptr; 278 282 return value; 283 } 284 285 bool CSSPropertyParser::canParseTypedCustomPropertyValue(const String& syntax, const CSSParserTokenRange& tokens, const CSSParserContext& context) 286 { 287 CSSPropertyParser parser(tokens, context, nullptr); 288 return parser.canParseTypedCustomPropertyValue(syntax); 289 } 290 291 RefPtr<CSSCustomPropertyValue> CSSPropertyParser::parseTypedCustomPropertyValue(const String& name, const String& syntax, const CSSParserTokenRange& tokens, const StyleResolver& styleResolver, const CSSParserContext& context) 292 { 293 CSSPropertyParser parser(tokens, context, nullptr, false); 294 RefPtr<CSSCustomPropertyValue> value = parser.parseTypedCustomPropertyValue(name, syntax, styleResolver); 295 if (!value || !parser.m_range.atEnd()) 296 return nullptr; 297 return value; 298 } 299 300 void CSSPropertyParser::collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies, const CSSParserTokenRange& tokens, const CSSParserContext& context) 301 { 302 CSSPropertyParser parser(tokens, context, nullptr); 303 parser.collectParsedCustomPropertyValueDependencies(syntax, isRoot, dependencies); 279 304 } 280 305 … … 321 346 322 347 if (CSSVariableParser::containsValidVariableReferences(originalRange, m_context)) { 323 RefPtr<CSSVariableReferenceValue> variable = CSSVariableReferenceValue::create( CSSVariableData::create(originalRange));348 RefPtr<CSSVariableReferenceValue> variable = CSSVariableReferenceValue::create(originalRange); 324 349 325 350 if (isShorthand) { … … 3887 3912 case CSSPropertyWidth: 3888 3913 case CSSPropertyHeight: 3889 case CSSPropertyCustom: // FIXME: parsing a registered custom property should be based on its syntax.3890 3914 return consumeWidthOrHeight(m_range, m_context, UnitlessQuirk::Allow); 3891 3915 case CSSPropertyMinInlineSize: … … 4257 4281 } 4258 4282 4283 bool CSSPropertyParser::canParseTypedCustomPropertyValue(const String& syntax) 4284 { 4285 if (syntax != "*") { 4286 m_range.consumeWhitespace(); 4287 4288 // First check for keywords 4289 CSSValueID id = m_range.peek().id(); 4290 if (id == CSSValueInherit || id == CSSValueInitial || id == CSSValueRevert) 4291 return true; 4292 4293 auto localRange = m_range; 4294 while (!localRange.atEnd()) { 4295 auto id = localRange.consume().functionId(); 4296 if (id == CSSValueVar || id == CSSValueEnv) 4297 return true; // For variables, we just permit everything 4298 } 4299 4300 auto primitiveVal = consumeWidthOrHeight(m_range, m_context); 4301 if (primitiveVal && primitiveVal->isPrimitiveValue() && m_range.atEnd()) 4302 return true; 4303 return false; 4304 } 4305 4306 return true; 4307 } 4308 4309 void CSSPropertyParser::collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies) 4310 { 4311 if (syntax != "*") { 4312 m_range.consumeWhitespace(); 4313 auto primitiveVal = consumeWidthOrHeight(m_range, m_context); 4314 if (!m_range.atEnd()) 4315 return; 4316 if (primitiveVal && primitiveVal->isPrimitiveValue()) { 4317 primitiveVal->collectDirectComputationalDependencies(dependencies); 4318 if (isRoot) 4319 primitiveVal->collectDirectRootComputationalDependencies(dependencies); 4320 } 4321 } 4322 } 4323 4324 RefPtr<CSSCustomPropertyValue> CSSPropertyParser::parseTypedCustomPropertyValue(const String& name, const String& syntax, const StyleResolver& styleResolver) 4325 { 4326 if (syntax != "*") { 4327 m_range.consumeWhitespace(); 4328 auto primitiveVal = consumeWidthOrHeight(m_range, m_context); 4329 if (primitiveVal && primitiveVal->isPrimitiveValue()) 4330 return CSSCustomPropertyValue::createSyntaxLength(name, StyleBuilderConverter::convertLength(styleResolver, *primitiveVal)); 4331 } else { 4332 auto propertyValue = CSSCustomPropertyValue::createSyntaxAll(name, CSSVariableData::create(m_range)); 4333 while (!m_range.atEnd()) 4334 m_range.consume(); 4335 return { WTFMove(propertyValue) }; 4336 } 4337 4338 return nullptr; 4339 } 4340 4259 4341 static RefPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParserTokenRange& range) 4260 4342 { -
trunk/Source/WebCore/css/parser/CSSPropertyParser.h
r237266 r237347 33 33 class StylePropertyShorthand; 34 34 class StyleSheetContents; 35 class StyleResolver; 35 36 36 37 // Inputs: PropertyID, isImportant bool, CSSParserTokenRange. … … 46 47 // Parses a non-shorthand CSS property 47 48 static RefPtr<CSSValue> parseSingleValue(CSSPropertyID, const CSSParserTokenRange&, const CSSParserContext&); 49 static bool canParseTypedCustomPropertyValue(const String& syntax, const CSSParserTokenRange&, const CSSParserContext&); 50 static RefPtr<CSSCustomPropertyValue> parseTypedCustomPropertyValue(const String& name, const String& syntax, const CSSParserTokenRange&, const StyleResolver&, const CSSParserContext&); 51 static void collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies, const CSSParserTokenRange&, const CSSParserContext&); 48 52 49 53 private: 50 CSSPropertyParser(const CSSParserTokenRange&, const CSSParserContext&, Vector<CSSProperty, 256>* );54 CSSPropertyParser(const CSSParserTokenRange&, const CSSParserContext&, Vector<CSSProperty, 256>*, bool consumeWhitespace = true); 51 55 52 56 // FIXME: Rename once the CSSParserValue-based parseValue is removed … … 54 58 bool consumeCSSWideKeyword(CSSPropertyID, bool important); 55 59 RefPtr<CSSValue> parseSingleValue(CSSPropertyID, CSSPropertyID = CSSPropertyInvalid); 60 bool canParseTypedCustomPropertyValue(const String& syntax); 61 RefPtr<CSSCustomPropertyValue> parseTypedCustomPropertyValue(const String& name, const String& syntax, const StyleResolver&); 62 void collectParsedCustomPropertyValueDependencies(const String& syntax, bool isRoot, HashSet<CSSPropertyID>& dependencies); 56 63 57 64 bool inQuirksMode() const { return m_context.mode == HTMLQuirksMode; } -
trunk/Source/WebCore/css/parser/CSSVariableParser.cpp
r233520 r237347 190 190 return nullptr; 191 191 if (type == CSSValueInternalVariableValue) 192 return CSSCustomPropertyValue::create WithVariableData(variableName, CSSVariableData::create(range, hasReferences || hasAtApplyRule));193 return CSSCustomPropertyValue::create WithID(variableName, type);192 return CSSCustomPropertyValue::createUnresolved(variableName, CSSVariableReferenceValue::create(range)); 193 return CSSCustomPropertyValue::createUnresolved(variableName, type); 194 194 } 195 195 -
trunk/Source/WebCore/dom/ConstantPropertyMap.cpp
r234098 r237347 91 91 92 92 auto& name = nameForProperty(property); 93 m_values->set(name, CSSCustomPropertyValue::create WithVariableData(name, WTFMove(data)));93 m_values->set(name, CSSCustomPropertyValue::createSyntaxAll(name, WTFMove(data))); 94 94 } 95 95 … … 111 111 Vector<CSSParserToken> tokens { token }; 112 112 CSSParserTokenRange tokenRange(tokens); 113 return CSSVariableData::create(tokenRange , false);113 return CSSVariableData::create(tokenRange); 114 114 } 115 115 … … 123 123 Vector<CSSParserToken> tokens { token }; 124 124 CSSParserTokenRange tokenRange(tokens); 125 return CSSVariableData::create(tokenRange , false);125 return CSSVariableData::create(tokenRange); 126 126 } 127 127 -
trunk/Source/WebCore/rendering/style/RenderStyle.cpp
r236828 r237347 2300 2300 } 2301 2301 2302 void RenderStyle::checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet& registeredProperties, const RenderStyle* parentStyle, const StyleResolver& styleResolver)2303 {2304 bool shouldUpdateInherited = m_rareInheritedData->customProperties->containsVariables || m_rareInheritedData->customProperties->containsUnresolvedRegisteredProperties;2305 bool shouldUpdateNonInherited = m_rareNonInheritedData->customProperties->containsVariables || m_rareNonInheritedData->customProperties->containsUnresolvedRegisteredProperties;2306 auto* inheritedPropertyData = shouldUpdateInherited ? &m_rareInheritedData.access().customProperties.access() : nullptr;2307 auto* nonInheritedPropertyData = shouldUpdateNonInherited ? &m_rareNonInheritedData.access().customProperties.access() : nullptr;2308 2309 HashSet<AtomicString> invalidProperties;2310 2311 for (auto* customPropertyData : { inheritedPropertyData, nonInheritedPropertyData }) {2312 if (!customPropertyData)2313 continue;2314 2315 // Our first pass checks the variables for validity and replaces any properties that became2316 // invalid with empty values.2317 auto& customProperties = customPropertyData->values;2318 for (auto& entry : customProperties) {2319 if (!entry.value->containsVariables())2320 continue;2321 HashSet<AtomicString> seenProperties;2322 entry.value->checkVariablesForCycles(entry.key, *this, seenProperties, invalidProperties);2323 }2324 2325 auto invalidValue = CSSCustomPropertyValue::createInvalid();2326 2327 // Now insert invalid values, or defaults if the property is registered.2328 if (!invalidProperties.isEmpty()) {2329 for (auto& property : invalidProperties) {2330 if (!customProperties.contains(property))2331 continue;2332 2333 const RefPtr<CSSCustomPropertyValue>* parentProperty = nullptr;2334 if (parentStyle) {2335 auto iterator = parentStyle->inheritedCustomProperties().find(property);2336 if (iterator != parentStyle->inheritedCustomProperties().end() && iterator.get() && iterator.get()->value)2337 parentProperty = &iterator.get()->value;2338 }2339 2340 auto* registered = registeredProperties.get(property);2341 2342 if (registered && registered->inherits && parentProperty)2343 customProperties.set(property, parentProperty->copyRef());2344 else if (registered && registered->initialValue())2345 customProperties.set(property, registered->initialValueCopy());2346 else2347 customProperties.set(property, invalidValue.copyRef());2348 }2349 }2350 2351 // Now that all of the properties have been tested for validity and replaced with2352 // invalid values if they failed, we can perform variable substitution on the valid values.2353 Vector<Ref<CSSCustomPropertyValue>> resolvedValues;2354 for (auto entry : customProperties) {2355 if (!entry.value->containsVariables())2356 continue;2357 entry.value->resolveVariableReferences(registeredProperties, resolvedValues, *this);2358 }2359 2360 // With all results computed, we can now mutate our table to eliminate the variables and2361 // hold the final values. This way when we inherit, we don't end up resubstituting variables, etc.2362 for (auto& resolvedValue : resolvedValues)2363 customProperties.set(resolvedValue->name(), resolvedValue.copyRef());2364 2365 // Finally we can resolve registered custom properties to their typed values.2366 for (auto& entry : customProperties) {2367 auto& name = entry.value->name();2368 auto* registered = registeredProperties.get(name);2369 2370 if (!registered)2371 continue;2372 2373 auto primitiveVal = styleResolver.resolvedVariableValue(CSSPropertyCustom, *entry.value);2374 if (!primitiveVal || !primitiveVal->isPrimitiveValue())2375 entry.value = invalidValue.copyRef();2376 else2377 entry.value->setResolvedTypedValue(StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));2378 }2379 2380 customPropertyData->containsVariables = false;2381 customPropertyData->containsUnresolvedRegisteredProperties = false;2382 }2383 }2384 2385 2302 float RenderStyle::outlineWidth() const 2386 2303 { -
trunk/Source/WebCore/rendering/style/RenderStyle.h
r237266 r237347 187 187 const CustomPropertyValueMap& nonInheritedCustomProperties() const { return m_rareNonInheritedData->customProperties->values; } 188 188 const CSSCustomPropertyValue* getCustomProperty(const AtomicString&) const; 189 void setInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value , bool isRegistered = false) { return m_rareInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value), isRegistered); }190 void setNonInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value , bool isRegistered = false) { return m_rareNonInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value), isRegistered); }189 void setInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) { return m_rareInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value)); } 190 void setNonInheritedCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) { return m_rareNonInheritedData.access().customProperties.access().setCustomPropertyValue(name, WTFMove(value)); } 191 191 192 192 void setHasViewportUnits(bool v = true) { m_nonInheritedFlags.hasViewportUnits = v; } … … 795 795 ApplePayButtonType applePayButtonType() const { return static_cast<ApplePayButtonType>(m_rareNonInheritedData->applePayButtonType); } 796 796 #endif 797 798 void checkVariablesInCustomProperties(const CSSRegisteredCustomPropertySet&, const RenderStyle* parentStyle, const StyleResolver&);799 797 800 798 // attribute setter methods -
trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h
r236828 r237347 23 23 24 24 #include "CSSCustomPropertyValue.h" 25 #include "CSSVariableReferenceValue.h" 25 26 #include <wtf/Forward.h> 26 27 #include <wtf/HashMap.h> … … 38 39 bool operator==(const StyleCustomPropertyData& other) const 39 40 { 40 if (containsVariables != other.containsVariables)41 return false;42 43 41 if (values.size() != other.values.size()) 44 42 return false; … … 55 53 bool operator!=(const StyleCustomPropertyData& other) const { return !(*this == other); } 56 54 57 void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value , bool isRegistered)55 void setCustomPropertyValue(const AtomicString& name, Ref<CSSCustomPropertyValue>&& value) 58 56 { 59 if (value->containsVariables())60 containsVariables = true;61 if (isRegistered)62 containsUnresolvedRegisteredProperties = true;63 57 values.set(name, WTFMove(value)); 64 58 } 65 59 66 60 CustomPropertyValueMap values; 67 bool containsVariables { false };68 bool containsUnresolvedRegisteredProperties { false };69 61 70 62 private: … … 73 65 : RefCounted<StyleCustomPropertyData>() 74 66 , values(other.values) 75 , containsVariables(other.containsVariables)76 , containsUnresolvedRegisteredProperties(other.containsUnresolvedRegisteredProperties)77 67 { } 78 68 };
Note: See TracChangeset
for help on using the changeset viewer.