Title: [208006] trunk/Source/WebCore
Revision
208006
Author
[email protected]
Date
2016-10-27 15:05:01 -0700 (Thu, 27 Oct 2016)

Log Message

[CSS Parser] Implement CSS variables
https://bugs.webkit.org/show_bug.cgi?id=164075

Reviewed by Dean Jackson.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
Add CSSCustomPropertyValue.cpp to the project.

* css/CSSCustomPropertyValue.cpp: Added.
(WebCore::CSSCustomPropertyValue::checkVariablesForCycles):
(WebCore::CSSCustomPropertyValue::resolveVariableReferences):
* css/CSSCustomPropertyValue.h:
These functions abstract the old and new implementations of CSS
variables so that the callers don't have to worry about it.

* css/CSSValue.cpp:
(WebCore::CSSValue::equals):
Make sure CSSVariableReferenceValue and CSSPendingSubstitutionValue
have equals implemented.

(WebCore::CSSValue::isInvalidCustomPropertyValue): Deleted.
This code was dead and never called.

* css/CSSValue.h:
(WebCore::CSSValue::isCustomPropertyValue):
(WebCore::CSSValue::hasVariableReferences):
Add a helper function for asking if a CSSValue has variable references.
This abstracts the old and new implementations so that callers can
ask if the value has variables without caring which implementation is
being used.

* css/CSSValueList.cpp:
(WebCore::CSSValueList::checkVariablesForCycles):
* css/CSSValueList.h:
In order to abstract the old and new variables implementations, custom
properties now store CSSCustomPropertyValue as their values instead of
raw values. The old implementation needs to be patched to deal with this
wrapper being present now.

* css/CSSVariableData.cpp:
(WebCore::CSSVariableData::checkVariablesForCycles):
(WebCore::CSSVariableData::checkVariablesForCyclesWithRange):
(WebCore::CSSVariableData::resolveVariableFallback):
(WebCore::CSSVariableData::resolveVariableReference):
(WebCore::CSSVariableData::resolveVariableReferences):
(WebCore::CSSVariableData::resolveTokenRange):
* css/CSSVariableData.h:
Implementation of cycle checking and variable resolution. The logic of
this implementation is the same as the old. It walks CSSParserTokens
instead of the old CSSParser structures.

* css/CSSVariableReferenceValue.cpp:
(WebCore::CSSVariableReferenceValue::customCSSText):
Add support for serialization caching, just like the old implementation
had in CSSVariableDependentValue.

(WebCore::CSSVariableReferenceValue::checkVariablesForCycles):
* css/CSSVariableReferenceValue.h:
Add cycle checking and variable resolution helper functions.

* css/CSSVariableValue.cpp:
(WebCore::CSSVariableValue::buildParserValueListSubstitutingVariables):
Patched to account for the change in storage of custom properties to
have custom property value wrappers.

* css/StyleProperties.cpp:
(WebCore::StyleProperties::getPropertyValue):
(WebCore::StyleProperties::borderSpacingValue):
(WebCore::StyleProperties::getLayeredShorthandValue):
(WebCore::StyleProperties::getShorthandValue):
(WebCore::StyleProperties::getCommonValue):
(WebCore::StyleProperties::getPropertyCSSValue):
(WebCore::StyleProperties::asText):
Clean up the resolution of pending substitution values. Instead of hacking
it into every possible StyleShorthandProperty crawling function, obtain
the shorthand for the property up front, access the first longhand, and
if we see a pending substitution value, perform the substitution.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::MatchResult::addMatchedProperties):
(WebCore::StyleResolver::applyProperty):
(WebCore::StyleResolver::resolvedVariableValue):
* css/StyleResolver.h:
Add support for the new implementation in all the same places as the old.

* css/parser/CSSParser.cpp:
(WebCore::CSSParser::parseInlineStyleDeclaration):
(WebCore::CSSParser::parseValueWithVariableReferences):
(WebCore::CSSParser::parseVariableDependentValue): Deleted.
* css/parser/CSSParser.h:
Rename parseVariableDependentValue to parseValueWithVariableReferences,
since it is operating on three distinct value types now. Turn on new
parser support for parseInlineStyleDeclaration.

* css/parser/CSSParserImpl.cpp:
(WebCore::filterProperties):
(WebCore::CSSParserImpl::parseVariableValue): Deleted.
(WebCore::CSSParserImpl::parseCustomPropertySet): Deleted.
* css/parser/CSSParserImpl.h:
Remove parser functions that aren't relevant to our implementation
of CSS variables.

* css/parser/CSSVariableParser.cpp:
(WebCore::classifyVariableRange):
Add support for the CSS4 'revert' keyword to the new variable parser.

* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::checkVariablesInCustomProperties):
Modified to store CSSCustomPropertyValues as the values always now and
to use the method abstractions on CSSCustomPropertyValue to resolve
cycles and perform substitutions.

* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::setCustomPropertyValue):
(WebCore::RenderStyle::getCustomPropertyValue):
* rendering/style/StyleCustomPropertyData.h:
(WebCore::StyleCustomPropertyData::operator==):
(WebCore::StyleCustomPropertyData::setCustomPropertyValue):
(WebCore::StyleCustomPropertyData::getCustomPropertyValue):
Tighten up the map to store CSSCustomPropertyValue instead of just
CSSValue.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/CMakeLists.txt (208005 => 208006)


--- trunk/Source/WebCore/CMakeLists.txt	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/CMakeLists.txt	2016-10-27 22:05:01 UTC (rev 208006)
@@ -1271,6 +1271,7 @@
     css/CSSCrossfadeValue.cpp
     css/CSSCursorImageValue.cpp
     css/CSSCustomIdentValue.cpp
+    css/CSSCustomPropertyValue.cpp
     css/CSSDefaultStyleSheets.cpp
     css/CSSFilterImageValue.cpp
     css/FontFaceSet.cpp

Modified: trunk/Source/WebCore/ChangeLog (208005 => 208006)


--- trunk/Source/WebCore/ChangeLog	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/ChangeLog	2016-10-27 22:05:01 UTC (rev 208006)
@@ -1,3 +1,128 @@
+2016-10-27  Dave Hyatt  <[email protected]>
+
+        [CSS Parser] Implement CSS variables
+        https://bugs.webkit.org/show_bug.cgi?id=164075
+
+        Reviewed by Dean Jackson.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        Add CSSCustomPropertyValue.cpp to the project.
+
+        * css/CSSCustomPropertyValue.cpp: Added.
+        (WebCore::CSSCustomPropertyValue::checkVariablesForCycles):
+        (WebCore::CSSCustomPropertyValue::resolveVariableReferences):
+        * css/CSSCustomPropertyValue.h:
+        These functions abstract the old and new implementations of CSS
+        variables so that the callers don't have to worry about it.
+
+        * css/CSSValue.cpp:
+        (WebCore::CSSValue::equals):
+        Make sure CSSVariableReferenceValue and CSSPendingSubstitutionValue
+        have equals implemented.
+
+        (WebCore::CSSValue::isInvalidCustomPropertyValue): Deleted.
+        This code was dead and never called.
+
+        * css/CSSValue.h:
+        (WebCore::CSSValue::isCustomPropertyValue):
+        (WebCore::CSSValue::hasVariableReferences):
+        Add a helper function for asking if a CSSValue has variable references.
+        This abstracts the old and new implementations so that callers can
+        ask if the value has variables without caring which implementation is
+        being used.
+
+        * css/CSSValueList.cpp:
+        (WebCore::CSSValueList::checkVariablesForCycles):
+        * css/CSSValueList.h:
+        In order to abstract the old and new variables implementations, custom
+        properties now store CSSCustomPropertyValue as their values instead of
+        raw values. The old implementation needs to be patched to deal with this
+        wrapper being present now.
+
+        * css/CSSVariableData.cpp:
+        (WebCore::CSSVariableData::checkVariablesForCycles):
+        (WebCore::CSSVariableData::checkVariablesForCyclesWithRange):
+        (WebCore::CSSVariableData::resolveVariableFallback):
+        (WebCore::CSSVariableData::resolveVariableReference):
+        (WebCore::CSSVariableData::resolveVariableReferences):
+        (WebCore::CSSVariableData::resolveTokenRange):
+        * css/CSSVariableData.h:
+        Implementation of cycle checking and variable resolution. The logic of
+        this implementation is the same as the old. It walks CSSParserTokens
+        instead of the old CSSParser structures.
+
+        * css/CSSVariableReferenceValue.cpp:
+        (WebCore::CSSVariableReferenceValue::customCSSText):
+        Add support for serialization caching, just like the old implementation
+        had in CSSVariableDependentValue.
+
+        (WebCore::CSSVariableReferenceValue::checkVariablesForCycles):
+        * css/CSSVariableReferenceValue.h:
+        Add cycle checking and variable resolution helper functions.
+
+        * css/CSSVariableValue.cpp:
+        (WebCore::CSSVariableValue::buildParserValueListSubstitutingVariables):
+        Patched to account for the change in storage of custom properties to
+        have custom property value wrappers.
+
+        * css/StyleProperties.cpp:
+        (WebCore::StyleProperties::getPropertyValue):
+        (WebCore::StyleProperties::borderSpacingValue):
+        (WebCore::StyleProperties::getLayeredShorthandValue):
+        (WebCore::StyleProperties::getShorthandValue):
+        (WebCore::StyleProperties::getCommonValue):
+        (WebCore::StyleProperties::getPropertyCSSValue):
+        (WebCore::StyleProperties::asText):
+        Clean up the resolution of pending substitution values. Instead of hacking
+        it into every possible StyleShorthandProperty crawling function, obtain
+        the shorthand for the property up front, access the first longhand, and
+        if we see a pending substitution value, perform the substitution.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::MatchResult::addMatchedProperties):
+        (WebCore::StyleResolver::applyProperty):
+        (WebCore::StyleResolver::resolvedVariableValue):
+        * css/StyleResolver.h:
+        Add support for the new implementation in all the same places as the old.
+
+        * css/parser/CSSParser.cpp:
+        (WebCore::CSSParser::parseInlineStyleDeclaration):
+        (WebCore::CSSParser::parseValueWithVariableReferences):
+        (WebCore::CSSParser::parseVariableDependentValue): Deleted.
+        * css/parser/CSSParser.h:
+        Rename parseVariableDependentValue to parseValueWithVariableReferences,
+        since it is operating on three distinct value types now. Turn on new
+        parser support for parseInlineStyleDeclaration.
+
+        * css/parser/CSSParserImpl.cpp:
+        (WebCore::filterProperties):
+        (WebCore::CSSParserImpl::parseVariableValue): Deleted.
+        (WebCore::CSSParserImpl::parseCustomPropertySet): Deleted.
+        * css/parser/CSSParserImpl.h:
+        Remove parser functions that aren't relevant to our implementation
+        of CSS variables.
+
+        * css/parser/CSSVariableParser.cpp:
+        (WebCore::classifyVariableRange):
+        Add support for the CSS4 'revert' keyword to the new variable parser.
+
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::checkVariablesInCustomProperties):
+        Modified to store CSSCustomPropertyValues as the values always now and
+        to use the method abstractions on CSSCustomPropertyValue to resolve
+        cycles and perform substitutions.
+
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyle::setCustomPropertyValue):
+        (WebCore::RenderStyle::getCustomPropertyValue):
+        * rendering/style/StyleCustomPropertyData.h:
+        (WebCore::StyleCustomPropertyData::operator==):
+        (WebCore::StyleCustomPropertyData::setCustomPropertyValue):
+        (WebCore::StyleCustomPropertyData::getCustomPropertyValue):
+        Tighten up the map to store CSSCustomPropertyValue instead of just
+        CSSValue.
+
 2016-10-27  Zalan Bujtas  <[email protected]>
 
         RenderMultiColumnFlowThread::processPossibleSpannerDescendant should take RenderObject& instead of RenderObject*

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (208005 => 208006)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2016-10-27 22:05:01 UTC (rev 208006)
@@ -3428,9 +3428,9 @@
 		9444CBE31D8861980073A074 /* CSSCustomIdentValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9444CBE21D8861580073A074 /* CSSCustomIdentValue.cpp */; };
 		9444CBE41D8861990073A074 /* CSSCustomIdentValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9444CBE11D8861580073A074 /* CSSCustomIdentValue.h */; };
 		9444CBE71D8861C20073A074 /* CSSVariableData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9444CBDE1D8861580073A074 /* CSSVariableData.cpp */; };
-		9444CBE81D8861C20073A074 /* CSSVariableData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9444CBDD1D8861580073A074 /* CSSVariableData.h */; };
+		9444CBE81D8861C20073A074 /* CSSVariableData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9444CBDD1D8861580073A074 /* CSSVariableData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		9444CBE91D8861CA0073A074 /* CSSVariableReferenceValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9444CBDC1D8861580073A074 /* CSSVariableReferenceValue.cpp */; };
-		9444CBEA1D8861CA0073A074 /* CSSVariableReferenceValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9444CBDB1D8861580073A074 /* CSSVariableReferenceValue.h */; };
+		9444CBEA1D8861CA0073A074 /* CSSVariableReferenceValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9444CBDB1D8861580073A074 /* CSSVariableReferenceValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		946D372D1D6CB2940077084F /* CSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D37281D6CB28B0077084F /* CSSParser.cpp */; };
 		946D372E1D6CB2940077084F /* CSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37291D6CB28B0077084F /* CSSParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		946D372F1D6CB2940077084F /* CSSParserMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D372A1D6CB28B0077084F /* CSSParserMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3449,7 +3449,7 @@
 		946D37491D6D06280077084F /* CSSMarkup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D37471D6D060C0077084F /* CSSMarkup.cpp */; };
 		946D374A1D6D06280077084F /* CSSMarkup.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37481D6D060C0077084F /* CSSMarkup.h */; };
 		946D374D1D6D08A60077084F /* CSSParserTokenRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D374B1D6D07F50077084F /* CSSParserTokenRange.cpp */; };
-		946D374E1D6D08AA0077084F /* CSSParserTokenRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D374C1D6D07F50077084F /* CSSParserTokenRange.h */; };
+		946D374E1D6D08AA0077084F /* CSSParserTokenRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D374C1D6D07F50077084F /* CSSParserTokenRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		9493B6BE1D74B4120088E780 /* MediaQueryBlockWatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9493B6B61D74B3950088E780 /* MediaQueryBlockWatcher.cpp */; };
 		9493B6BF1D74B4120088E780 /* MediaQueryBlockWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 9493B6B71D74B3950088E780 /* MediaQueryBlockWatcher.h */; };
 		9493B6C01D74B4120088E780 /* MediaQueryParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9493B6B81D74B3950088E780 /* MediaQueryParser.cpp */; };
@@ -3461,6 +3461,7 @@
 		949C77081D6E498700C0DE4F /* CSSParserObserverWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949C77061D6E48ED00C0DE4F /* CSSParserObserverWrapper.cpp */; };
 		949C77091D6E498700C0DE4F /* CSSParserObserverWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 949C77071D6E48ED00C0DE4F /* CSSParserObserverWrapper.h */; };
 		949C770B1D6E49ED00C0DE4F /* CSSParserObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 949C770A1D6E49C300C0DE4F /* CSSParserObserver.h */; };
+		94D4AC621DC24C8E0080F02D /* CSSCustomPropertyValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D4AC611DC24C810080F02D /* CSSCustomPropertyValue.cpp */; };
 		94DE5C7E1D78CB2E00164F2A /* CSSParserIdioms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */; };
 		94DE5C811D7F3A1400164F2A /* CSSAtRuleID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C7F1D7F39D000164F2A /* CSSAtRuleID.cpp */; };
 		94DE5C821D7F3A1400164F2A /* CSSAtRuleID.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C801D7F39D000164F2A /* CSSAtRuleID.h */; };
@@ -5090,7 +5091,7 @@
 		BC128B01137C8D4600CAC845 /* RenderGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC128B00137C8D4600CAC845 /* RenderGrid.cpp */; };
 		BC14028A0E83680800319717 /* ScrollbarThemeComposite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC1402880E83680800319717 /* ScrollbarThemeComposite.cpp */; };
 		BC14028B0E83680800319717 /* ScrollbarThemeComposite.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1402890E83680800319717 /* ScrollbarThemeComposite.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		BC1790BB1BB5AB3F0006D13E /* CSSVariableDependentValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1790BA1BB5AB3F0006D13E /* CSSVariableDependentValue.h */; };
+		BC1790BB1BB5AB3F0006D13E /* CSSVariableDependentValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1790BA1BB5AB3F0006D13E /* CSSVariableDependentValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BC1790BD1BBB36A80006D13E /* CSSVariableDependentValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC1790BC1BBB36A80006D13E /* CSSVariableDependentValue.cpp */; };
 		BC1790C01BBF2C430006D13E /* CSSVariableValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC1790BE1BBF2C430006D13E /* CSSVariableValue.cpp */; };
 		BC1790C11BBF2C430006D13E /* CSSVariableValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1790BF1BBF2C430006D13E /* CSSVariableValue.h */; };
@@ -10861,6 +10862,7 @@
 		949C77061D6E48ED00C0DE4F /* CSSParserObserverWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserObserverWrapper.cpp; path = parser/CSSParserObserverWrapper.cpp; sourceTree = "<group>"; };
 		949C77071D6E48ED00C0DE4F /* CSSParserObserverWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserObserverWrapper.h; path = parser/CSSParserObserverWrapper.h; sourceTree = "<group>"; };
 		949C770A1D6E49C300C0DE4F /* CSSParserObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserObserver.h; path = parser/CSSParserObserver.h; sourceTree = "<group>"; };
+		94D4AC611DC24C810080F02D /* CSSCustomPropertyValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCustomPropertyValue.cpp; sourceTree = "<group>"; };
 		94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserIdioms.cpp; path = parser/CSSParserIdioms.cpp; sourceTree = "<group>"; };
 		94DE5C7F1D7F39D000164F2A /* CSSAtRuleID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSAtRuleID.cpp; path = parser/CSSAtRuleID.cpp; sourceTree = "<group>"; };
 		94DE5C801D7F39D000164F2A /* CSSAtRuleID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSAtRuleID.h; path = parser/CSSAtRuleID.h; sourceTree = "<group>"; };
@@ -22885,6 +22887,7 @@
 				AA0978EE0ABAA6E100874480 /* CSSCursorImageValue.h */,
 				9444CBE21D8861580073A074 /* CSSCustomIdentValue.cpp */,
 				9444CBE11D8861580073A074 /* CSSCustomIdentValue.h */,
+				94D4AC611DC24C810080F02D /* CSSCustomPropertyValue.cpp */,
 				BC779E131BB215BB00CAA8BF /* CSSCustomPropertyValue.h */,
 				4A9CC81516BB9AC600EC645A /* CSSDefaultStyleSheets.cpp */,
 				4A9CC81616BB9AC600EC645A /* CSSDefaultStyleSheets.h */,
@@ -29690,6 +29693,7 @@
 				B2FA3D5A0AB75A6F000E5AC4 /* JSSVGClipPathElement.cpp in Sources */,
 				B2FA3D5C0AB75A6F000E5AC4 /* JSSVGColor.cpp in Sources */,
 				B2FA3D5E0AB75A6F000E5AC4 /* JSSVGComponentTransferFunctionElement.cpp in Sources */,
+				94D4AC621DC24C8E0080F02D /* CSSCustomPropertyValue.cpp in Sources */,
 				B2FA3D600AB75A6F000E5AC4 /* JSSVGCursorElement.cpp in Sources */,
 				B2FA3D620AB75A6F000E5AC4 /* JSSVGDefsElement.cpp in Sources */,
 				B2FA3D640AB75A6F000E5AC4 /* JSSVGDescElement.cpp in Sources */,

Added: trunk/Source/WebCore/css/CSSCustomPropertyValue.cpp (0 => 208006)


--- trunk/Source/WebCore/css/CSSCustomPropertyValue.cpp	                        (rev 0)
+++ trunk/Source/WebCore/css/CSSCustomPropertyValue.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSCustomPropertyValue.h"
+
+#include "CSSParserValues.h"
+
+namespace WebCore {
+
+bool CSSCustomPropertyValue::checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+{
+    ASSERT(containsVariables());
+    if (m_deprecatedValue && m_deprecatedValue->isVariableDependentValue())
+        return downcast<CSSVariableDependentValue>(*m_deprecatedValue).checkVariablesForCycles(name, customProperties, seenProperties, invalidProperties);
+    if (m_value)
+        return m_value->checkVariablesForCycles(name, customProperties, seenProperties, invalidProperties);
+    return true;
+}
+
+void CSSCustomPropertyValue::resolveVariableReferences(const CustomPropertyValueMap& customProperties, Vector<Ref<CSSCustomPropertyValue>>& resolvedValues) const
+{
+    ASSERT(containsVariables());
+    if (m_deprecatedValue && m_deprecatedValue->isVariableDependentValue()) {
+        CSSParserValueList parserList;
+        if (!downcast<CSSVariableDependentValue>(*m_deprecatedValue).valueList().buildParserValueListSubstitutingVariables(&parserList, customProperties))
+            resolvedValues.append(CSSCustomPropertyValue::create(m_name, CSSCustomPropertyValue::createInvalid()));
+        else
+            resolvedValues.append(CSSCustomPropertyValue::create(m_name, CSSValueList::createFromParserValueList(parserList)));
+        return;
+    }
+    
+    if (!m_value)
+        return;
+    
+    ASSERT(m_value->needsVariableResolution());
+    RefPtr<CSSVariableData> resolvedData = m_value->resolveVariableReferences(customProperties);
+    if (resolvedData)
+        resolvedValues.append(CSSCustomPropertyValue::createWithVariableData(m_name, resolvedData.releaseNonNull()));
+    else
+        resolvedValues.append(CSSCustomPropertyValue::create(m_name, CSSCustomPropertyValue::createInvalid()));
+}
+
+}

Modified: trunk/Source/WebCore/css/CSSCustomPropertyValue.h (208005 => 208006)


--- trunk/Source/WebCore/css/CSSCustomPropertyValue.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSCustomPropertyValue.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -28,6 +28,7 @@
 
 #include "CSSValue.h"
 #include "CSSVariableData.h"
+#include "CSSVariableDependentValue.h"
 #include <wtf/RefPtr.h>
 #include <wtf/text/WTFString.h>
 
@@ -73,13 +74,17 @@
 
     const AtomicString& name() const { return m_name; }
     
-    // FIXME: Should arguably implement equals on our internal values, but serialization to compare is probably fine.
-    bool equals(const CSSCustomPropertyValue& other) const { return m_name == other.m_name && customCSSText() == other.customCSSText(); }
+    bool equals(const CSSCustomPropertyValue& other) const { return m_name == other.m_name && m_deprecatedValue == other.m_deprecatedValue && m_value == other.m_value && m_valueId == other.m_valueId; }
 
-    bool isInvalid() const { return !m_value; }
     bool containsVariables() const { return m_containsVariables; }
+    bool checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
 
+    void resolveVariableReferences(const CustomPropertyValueMap&, Vector<Ref<CSSCustomPropertyValue>>&) const;
+
     const RefPtr<CSSValue> deprecatedValue() const { return m_deprecatedValue.get(); }
+    
+    CSSValueID valueID() const { return m_valueId; }
+    CSSVariableData* value() const { return m_value.get(); }
 
 private:
     CSSCustomPropertyValue(const AtomicString& name, Ref<CSSValue>&& value)
@@ -87,7 +92,6 @@
         , m_name(name)
         , m_deprecatedValue(WTFMove(value))
         , m_containsVariables(m_deprecatedValue->isVariableDependentValue())
-        , m_serialized(false)
     {
     }
     
@@ -124,7 +128,7 @@
     
     mutable String m_stringValue;
     bool m_containsVariables { false };
-    mutable bool m_serialized;
+    mutable bool m_serialized { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSValue.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/CSSValue.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSValue.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -245,6 +245,10 @@
             return compareCSSValues<CSSContentDistributionValue>(*this, other);
         case CustomPropertyClass:
             return compareCSSValues<CSSCustomPropertyValue>(*this, other);
+        case VariableReferenceClass:
+            return compareCSSValues<CSSVariableReferenceValue>(*this, other);
+        case PendingSubstitutionValueClass:
+            return compareCSSValues<CSSPendingSubstitutionValue>(*this, other);
         case VariableDependentClass:
             return compareCSSValues<CSSVariableDependentValue>(*this, other);
         case VariableClass:
@@ -552,11 +556,6 @@
     }
 }
 
-bool CSSValue::isInvalidCustomPropertyValue() const
-{
-    return isCustomPropertyValue() && downcast<CSSCustomPropertyValue>(*this).isInvalid();
-}
-
 bool CSSValue::treatAsInheritedValue(CSSPropertyID propertyID) const
 {
     return classType() == InheritedClass || (classType() == UnsetClass && CSSProperty::isInheritedProperty(propertyID));

Modified: trunk/Source/WebCore/css/CSSValue.h (208005 => 208006)


--- trunk/Source/WebCore/css/CSSValue.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSValue.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -30,6 +30,7 @@
 
 namespace WebCore {
 
+class CSSCustomPropertyValue;
 class CachedResource;
 class StyleSheetContents;
 
@@ -78,7 +79,6 @@
     bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
     bool isCursorImageValue() const { return m_classType == CursorImageClass; }
     bool isCustomPropertyValue() const { return m_classType == CustomPropertyClass; }
-    bool isInvalidCustomPropertyValue() const;
     bool isVariableDependentValue() const { return m_classType == VariableDependentClass; }
     bool isVariableValue() const { return m_classType == VariableClass; }
     bool isFunctionValue() const { return m_classType == FunctionClass; }
@@ -129,6 +129,8 @@
     bool isCustomIdentValue() const { return m_classType == CustomIdentClass; }
     bool isVariableReferenceValue() const { return m_classType == VariableReferenceClass; }
     bool isPendingSubstitutionValue() const { return m_classType == PendingSubstitutionValueClass; }
+    
+    bool hasVariableReferences() const { return isVariableDependentValue() || isVariableReferenceValue() || isPendingSubstitutionValue(); }
 
     bool isCSSOMSafe() const { return m_isCSSOMSafe; }
     bool isSubtypeExposedToCSSOM() const
@@ -300,7 +302,7 @@
     return first.get().equals(second);
 }
 
-typedef HashMap<AtomicString, RefPtr<CSSValue>> CustomPropertyValueMap;
+typedef HashMap<AtomicString, RefPtr<CSSCustomPropertyValue>> CustomPropertyValueMap;
 
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/css/CSSValueList.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/CSSValueList.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSValueList.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "CSSValueList.h"
 
+#include "CSSCustomPropertyValue.h"
 #include "CSSFunctionValue.h"
 #include "CSSParserValues.h"
 #include "CSSPrimitiveValue.h"
@@ -206,8 +207,8 @@
             auto& variableValue = downcast<CSSVariableValue>(*value);
             if (seenProperties.contains(variableValue.name()))
                 return false;
-            RefPtr<CSSValue> value = customProperties.get(variableValue.name());
-            if (value && value->isVariableDependentValue() && !downcast<CSSVariableDependentValue>(*value).checkVariablesForCycles(variableValue.name(), customProperties, seenProperties, invalidProperties))
+            RefPtr<CSSCustomPropertyValue> value = customProperties.get(variableValue.name());
+            if (value && value->containsVariables() && !downcast<CSSVariableDependentValue>(*(value->deprecatedValue())).checkVariablesForCycles(variableValue.name(), customProperties, seenProperties, invalidProperties))
                 return false;
 
             // Have to check the fallback values.

Modified: trunk/Source/WebCore/css/CSSValueList.h (208005 => 208006)


--- trunk/Source/WebCore/css/CSSValueList.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSValueList.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -26,6 +26,7 @@
 
 namespace WebCore {
 
+class CSSCustomPropertyValue;
 struct CSSParserValue;
 class CSSParserValueList;
 

Modified: trunk/Source/WebCore/css/CSSVariableData.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/CSSVariableData.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSVariableData.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "CSSVariableData.h"
 
+#include "CSSCustomPropertyValue.h"
 #include "CSSParser.h"
 #include "CSSParserTokenRange.h"
 #include <wtf/text/StringBuilder.h>
@@ -81,4 +82,100 @@
     consumeAndUpdateTokens(range);
 }
 
+bool CSSVariableData::checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap& customProperties, 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, customProperties, newSeenProperties, invalidProperties);
+    if (!valid)
+        invalidProperties.add(name);
+    
+    return valid;
+}
+    
+bool CSSVariableData::checkVariablesForCyclesWithRange(CSSParserTokenRange range, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+{
+    while (!range.atEnd()) {
+        if (range.peek().functionId() == CSSValueVar) {
+            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;
+
+            RefPtr<CSSCustomPropertyValue> value = customProperties.get(variableName);
+            if (value && value->containsVariables() && !value->checkVariablesForCycles(variableName, customProperties, seenProperties, invalidProperties))
+                return false;
+
+            if (range.peek().type() == CommaToken) {
+                // Fallback.
+                range.consume();
+                return checkVariablesForCyclesWithRange(block, customProperties, seenProperties, invalidProperties);
+            }
+        } else
+            range.consume();
+    }
+    return true;
+}
+
+bool CSSVariableData::resolveVariableFallback(const CustomPropertyValueMap& customProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result) const
+{
+    if (range.atEnd())
+        return false;
+    ASSERT(range.peek().type() == CommaToken);
+    range.consume();
+    return resolveTokenRange(customProperties, range, result);
+}
+    
+bool CSSVariableData::resolveVariableReference(const CustomPropertyValueMap& customProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result) const
+{
+    range.consumeWhitespace();
+    ASSERT(range.peek().type() == IdentToken);
+    AtomicString variableName = range.consumeIncludingWhitespace().value().toAtomicString();
+    ASSERT(range.atEnd() || (range.peek().type() == CommaToken));
+    
+    RefPtr<CSSCustomPropertyValue> property = customProperties.get(variableName);
+    if (!property || !property->value())
+        return resolveVariableFallback(customProperties, range, result);
+    
+    if (property->containsVariables()) {
+        // FIXME: Avoid doing this work more than once.
+        RefPtr<CSSVariableData> resolvedData = property->value()->resolveVariableReferences(customProperties);
+        if (!resolvedData)
+            return false;
+        result.appendVector(resolvedData->tokens());
+    } else
+        result.appendVector(property->value()->tokens());
+    
+    return true;
+}
+
+RefPtr<CSSVariableData> CSSVariableData::resolveVariableReferences(const CustomPropertyValueMap& customProperties) const
+{
+    Vector<CSSParserToken> resolvedTokens;
+    CSSParserTokenRange range = m_tokens;
+    if (!resolveTokenRange(customProperties, range, resolvedTokens))
+        return nullptr;
+    return CSSVariableData::createResolved(resolvedTokens, *this);
+}
+    
+bool CSSVariableData::resolveTokenRange(const CustomPropertyValueMap& customProperties, CSSParserTokenRange range, Vector<CSSParserToken>& result) const
+{
+    bool success = true;
+    while (!range.atEnd()) {
+        if (range.peek().functionId() == CSSValueVar)
+            success &= resolveVariableReference(customProperties, range.consumeBlock(), result);
+        else
+            result.append(range.consume());
+    }
+    return success;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSVariableData.h (208005 => 208006)


--- trunk/Source/WebCore/css/CSSVariableData.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSVariableData.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -59,6 +59,11 @@
 
     bool needsVariableResolution() const { return m_needsVariableResolution; }
 
+    bool checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+
+    RefPtr<CSSVariableData> resolveVariableReferences(const CustomPropertyValueMap& customProperties) const;
+    bool resolveTokenRange(const CustomPropertyValueMap&, CSSParserTokenRange, Vector<CSSParserToken>&) const;
+
 private:
     CSSVariableData(const CSSParserTokenRange&, bool needsVariableResolution);
 
@@ -74,6 +79,10 @@
 
     void consumeAndUpdateTokens(const CSSParserTokenRange&);
     template<typename CharacterType> void updateTokens(const CSSParserTokenRange&);
+    
+    bool checkVariablesForCyclesWithRange(CSSParserTokenRange, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+    bool resolveVariableReference(const CustomPropertyValueMap&, CSSParserTokenRange, Vector<CSSParserToken>&) const;
+    bool resolveVariableFallback(const CustomPropertyValueMap&, CSSParserTokenRange, Vector<CSSParserToken>&) const;
 
     String m_backingString;
     Vector<CSSParserToken> m_tokens;

Modified: trunk/Source/WebCore/css/CSSVariableReferenceValue.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/CSSVariableReferenceValue.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSVariableReferenceValue.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -34,8 +34,17 @@
 
 String CSSVariableReferenceValue::customCSSText() const
 {
-    // We may want to consider caching this value.
-    return m_data->tokenRange().serialize();
+    if (!m_serialized) {
+        m_serialized = true;
+        m_stringValue = m_data->tokenRange().serialize();
+    }
+    return m_stringValue;
 }
+    
+bool CSSVariableReferenceValue::checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap& customProperties, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const
+{
+    ASSERT(m_data);
+    return m_data->checkVariablesForCycles(name, customProperties, seenProperties, invalidProperties);
+}
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSVariableReferenceValue.h (208005 => 208006)


--- trunk/Source/WebCore/css/CSSVariableReferenceValue.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSVariableReferenceValue.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -50,6 +50,8 @@
     bool equals(const CSSVariableReferenceValue& other) const { return m_data == other.m_data; }
     String customCSSText() const;
 
+    bool checkVariablesForCycles(const AtomicString& name, CustomPropertyValueMap&, HashSet<AtomicString>& seenProperties, HashSet<AtomicString>& invalidProperties) const;
+
 private:
     CSSVariableReferenceValue(Ref<CSSVariableData>&& data)
         : CSSValue(VariableReferenceClass)
@@ -58,6 +60,8 @@
     }
 
     RefPtr<CSSVariableData> m_data;
+    mutable String m_stringValue;
+    mutable bool m_serialized { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSVariableValue.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/CSSVariableValue.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/CSSVariableValue.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -69,10 +69,11 @@
 
 bool CSSVariableValue::buildParserValueListSubstitutingVariables(CSSParserValueList* resultList, const CustomPropertyValueMap& customProperties) const
 {
-    if (RefPtr<CSSValue> value = customProperties.get(m_name)) {
-        if (value->isValueList())
+    if (RefPtr<CSSCustomPropertyValue> customPropertyValue = customProperties.get(m_name)) {
+        auto value = customPropertyValue->deprecatedValue();
+        if (value && value->isValueList())
             return downcast<CSSValueList>(*value).buildParserValueListSubstitutingVariables(resultList, customProperties);
-        if (value->isVariableDependentValue())
+        if (value && value->isVariableDependentValue())
             return downcast<CSSVariableDependentValue>(*value).valueList().buildParserValueListSubstitutingVariables(resultList, customProperties);
     }
 

Modified: trunk/Source/WebCore/css/StyleProperties.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/StyleProperties.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/StyleProperties.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -26,6 +26,7 @@
 #include "CSSComputedStyleDeclaration.h"
 #include "CSSCustomPropertyValue.h"
 #include "CSSParser.h"
+#include "CSSPendingSubstitutionValue.h"
 #include "CSSValueKeywords.h"
 #include "CSSValueList.h"
 #include "CSSValuePool.h"
@@ -126,6 +127,17 @@
     if (value)
         return value->cssText();
 
+    const StylePropertyShorthand& shorthand = shorthandForProperty(propertyID);
+    if (shorthand.length()) {
+        RefPtr<CSSValue> value = getPropertyCSSValueInternal(shorthand.properties()[0]);
+        if (!value)
+            return String();
+        if (value->isVariableDependentValue())
+            return value->cssText();
+        if (value->isPendingSubstitutionValue())
+            return downcast<CSSPendingSubstitutionValue>(*value).shorthandValue()->cssText();
+    }
+
     // Shorthand and 4-values properties
     switch (propertyID) {
     case CSSPropertyAll:
@@ -232,9 +244,6 @@
 String StyleProperties::borderSpacingValue(const StylePropertyShorthand& shorthand) const
 {
     RefPtr<CSSValue> horizontalValue = getPropertyCSSValueInternal(shorthand.properties()[0]);
-    if (horizontalValue && horizontalValue->isVariableDependentValue())
-        return horizontalValue->cssText();
-    
     RefPtr<CSSValue> verticalValue = getPropertyCSSValueInternal(shorthand.properties()[1]);
 
     // While standard border-spacing property does not allow specifying border-spacing-vertical without
@@ -385,8 +394,6 @@
             // http://www.w3.org/TR/cssom-1/#serialize-a-css-declaration-block.
             return String();
         }
-        if (values[i]->isVariableDependentValue())
-            return values[i]->cssText();
         if (values[i]->isBaseValueList())
             numLayers = std::max(downcast<CSSValueList>(*values[i]).length(), numLayers);
         else
@@ -525,8 +532,6 @@
             RefPtr<CSSValue> value = getPropertyCSSValueInternal(shorthand.properties()[i]);
             if (!value)
                 return String();
-            if (value->isVariableDependentValue())
-                return value->cssText();
             String valueText = value->cssText();
             if (!i)
                 commonValue = valueText;
@@ -554,11 +559,9 @@
     bool lastPropertyWasImportant = false;
     for (unsigned i = 0; i < shorthand.length(); ++i) {
         RefPtr<CSSValue> value = getPropertyCSSValueInternal(shorthand.properties()[i]);
-        // FIXME: CSSInitialValue::cssText should generate the right value.
         if (!value)
             return String();
-        if (value->isVariableDependentValue())
-            return value->cssText();
+        // FIXME: CSSInitialValue::cssText should generate the right value.
         String text = value->cssText();
         if (text.isNull())
             return String();
@@ -611,6 +614,7 @@
         if (dependentValue.propertyID() != propertyID)
             return CSSCustomPropertyValue::createInvalid(); // Have to return special "pending-substitution" value.
     }
+
     return value;
 }
 
@@ -868,6 +872,10 @@
             auto& dependentValue = downcast<CSSVariableDependentValue>(*property.value());
             if (dependentValue.propertyID() != propertyID)
                 shorthandPropertyID = dependentValue.propertyID();
+        } else if (property.value() && property.value()->isPendingSubstitutionValue()) {
+            auto& substitutionValue = downcast<CSSPendingSubstitutionValue>(*property.value());
+            shorthandPropertyID = substitutionValue.shorthandPropertyId();
+            value = substitutionValue.shorthandValue()->cssText();
         } else {
             switch (propertyID) {
             case CSSPropertyAnimationName:

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -233,7 +233,7 @@
                     break;
                 }
 
-                if (value.isVariableDependentValue()) {
+                if (value.hasVariableReferences()) {
                     isCacheable = false;
                     break;
                 }
@@ -1586,8 +1586,8 @@
     State& state = m_state;
     
     RefPtr<CSSValue> valueToApply = value;
-    if (value->isVariableDependentValue()) {
-        valueToApply = resolvedVariableValue(id, *downcast<CSSVariableDependentValue>(value));
+    if (value->hasVariableReferences()) {
+        valueToApply = resolvedVariableValue(id, *value);
         if (!valueToApply) {
             if (CSSProperty::isInheritedProperty(id))
                 valueToApply = CSSValuePool::singleton().createInheritedValue();
@@ -1604,17 +1604,23 @@
     
     CSSValue* valueToCheckForInheritInitial = valueToApply.get();
     CSSCustomPropertyValue* customPropertyValue = nullptr;
+    CSSValueID customPropertyValueID = CSSValueInvalid;
     
     if (id == CSSPropertyCustom) {
+        // FIXME-NEWPARSER: Can clean this up once old parser is gone and remove
+        // the deprecatedValue call and the valueToCheckForInheritInitial variable.
         customPropertyValue = &downcast<CSSCustomPropertyValue>(*valueToApply);
         valueToCheckForInheritInitial = customPropertyValue->deprecatedValue().get();
+        customPropertyValueID = customPropertyValue->valueID();
+        if (customPropertyValueID != CSSValueInvalid)
+            valueToCheckForInheritInitial = valueToApply.get();
     }
 
-    bool isInherit = state.parentStyle() && valueToCheckForInheritInitial->isInheritedValue();
-    bool isInitial = valueToCheckForInheritInitial->isInitialValue() || (!state.parentStyle() && valueToCheckForInheritInitial->isInheritedValue());
+    bool isInherit = state.parentStyle() ? valueToCheckForInheritInitial->isInheritedValue() || customPropertyValueID == CSSValueInherit : false;
+    bool isInitial = valueToCheckForInheritInitial->isInitialValue() || customPropertyValueID == CSSValueInitial || (!state.parentStyle() && (valueToCheckForInheritInitial->isInheritedValue() || customPropertyValueID == CSSValueInherit));
     
-    bool isUnset = valueToCheckForInheritInitial->isUnsetValue();
-    bool isRevert = valueToCheckForInheritInitial->isRevertValue();
+    bool isUnset = valueToCheckForInheritInitial->isUnsetValue() || customPropertyValueID == CSSValueUnset;
+    bool isRevert = valueToCheckForInheritInitial->isRevertValue() || customPropertyValueID == CSSValueRevert;
 
     if (isRevert) {
         if (cascadeLevel() == UserAgentLevel || !matchResult)
@@ -1666,7 +1672,7 @@
     if (id == CSSPropertyCustom) {
         CSSCustomPropertyValue* customProperty = &downcast<CSSCustomPropertyValue>(*valueToApply);
         if (isInherit) {
-            RefPtr<CSSValue> customVal = state.parentStyle()->getCustomPropertyValue(customProperty->name());
+            RefPtr<CSSCustomPropertyValue> customVal = state.parentStyle()->getCustomPropertyValue(customProperty->name());
             if (!customVal)
                 customVal = CSSCustomPropertyValue::createInvalid();
             state.style()->setCustomPropertyValue(customProperty->name(), customVal);
@@ -1673,7 +1679,7 @@
         } else if (isInitial)
             state.style()->setCustomPropertyValue(customProperty->name(), CSSCustomPropertyValue::createInvalid());
         else
-            state.style()->setCustomPropertyValue(customProperty->name(), customProperty->deprecatedValue());
+            state.style()->setCustomPropertyValue(customProperty->name(), customProperty);
         return;
     }
 
@@ -1681,10 +1687,10 @@
     StyleBuilder::applyProperty(id, *this, *valueToApply, isInitial, isInherit);
 }
 
-RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSVariableDependentValue& value)
+RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value)
 {
     CSSParser parser(m_state.document());
-    return parser.parseVariableDependentValue(propID, value, m_state.style()->customProperties(), m_state.style()->direction(), m_state.style()->writingMode());
+    return parser.parseValueWithVariableReferences(propID, value, m_state.style()->customProperties(), m_state.style()->direction(), m_state.style()->writingMode());
 }
 
 RefPtr<StyleImage> StyleResolver::styleImage(CSSValue& value)

Modified: trunk/Source/WebCore/css/StyleResolver.h (208005 => 208006)


--- trunk/Source/WebCore/css/StyleResolver.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/StyleResolver.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -469,7 +469,7 @@
     void cacheBorderAndBackground();
 
     void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr);
-    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSVariableDependentValue&);
+    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&);
 
     void applySVGProperty(CSSPropertyID, CSSValue*);
 

Modified: trunk/Source/WebCore/css/parser/CSSParser.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/parser/CSSParser.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/parser/CSSParser.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -58,8 +58,10 @@
 #include "CSSPageRule.h"
 #include "CSSParserFastPaths.h"
 #include "CSSParserImpl.h"
+#include "CSSPendingSubstitutionValue.h"
 #include "CSSPrimitiveValue.h"
 #include "CSSPrimitiveValueMappings.h"
+#include "CSSPropertyParser.h"
 #include "CSSPropertySourceData.h"
 #include "CSSReflectValue.h"
 #include "CSSRevertValue.h"
@@ -75,6 +77,7 @@
 #include "CSSValueList.h"
 #include "CSSValuePool.h"
 #include "CSSVariableDependentValue.h"
+#include "CSSVariableReferenceValue.h"
 #include "Counter.h"
 #include "Document.h"
 #include "FloatConversion.h"
@@ -1432,6 +1435,10 @@
 {
     CSSParserContext context(element->document());
     context.mode = strictToCSSParserMode(element->isHTMLElement() && !element->document().inQuirksMode());
+
+    if (context.useNewParser)
+        return CSSParserImpl::parseInlineStyleDeclaration(string, element);
+
     return CSSParser(context).parseDeclaration(string, nullptr);
 }
 
@@ -1796,23 +1803,68 @@
         addProperty(longhands[i], value.copyRef(), important);
 }
 
-RefPtr<CSSValue> CSSParser::parseVariableDependentValue(CSSPropertyID propID, const CSSVariableDependentValue& dependentValue, const CustomPropertyValueMap& customProperties, TextDirection direction, WritingMode writingMode)
+RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, const CustomPropertyValueMap& customProperties, TextDirection direction, WritingMode writingMode)
 {
-    m_valueList.reset(new CSSParserValueList());
-    if (!dependentValue.valueList().buildParserValueListSubstitutingVariables(m_valueList.get(), customProperties))
-        return nullptr;
+    if (value.isVariableDependentValue()) {
+        const CSSVariableDependentValue& dependentValue = downcast<CSSVariableDependentValue>(value);
+        m_valueList.reset(new CSSParserValueList());
+        if (!dependentValue.valueList().buildParserValueListSubstitutingVariables(m_valueList.get(), customProperties))
+            return nullptr;
 
-    CSSPropertyID dependentValuePropertyID = dependentValue.propertyID();
-    if (CSSProperty::isDirectionAwareProperty(dependentValuePropertyID))
-        dependentValuePropertyID = CSSProperty::resolveDirectionAwareProperty(dependentValuePropertyID, direction, writingMode);
+        CSSPropertyID dependentValuePropertyID = dependentValue.propertyID();
+        if (CSSProperty::isDirectionAwareProperty(dependentValuePropertyID))
+            dependentValuePropertyID = CSSProperty::resolveDirectionAwareProperty(dependentValuePropertyID, direction, writingMode);
 
-    if (!parseValue(dependentValuePropertyID, false))
+        if (!parseValue(dependentValuePropertyID, false))
+            return nullptr;
+
+        for (auto& property : m_parsedProperties) {
+            if (property.id() == propID)
+                return property.value();
+        }
+        
         return nullptr;
+    }
+    
+    if (value.isPendingSubstitutionValue()) {
+        // FIXME: Should have a resolvedShorthands cache to stop this from being done
+        // over and over for each longhand value.
+        const CSSPendingSubstitutionValue& pendingSubstitution = downcast<CSSPendingSubstitutionValue>(value);
+        CSSPropertyID shorthandID = pendingSubstitution.shorthandPropertyId();
+        if (CSSProperty::isDirectionAwareProperty(shorthandID))
+            shorthandID = CSSProperty::resolveDirectionAwareProperty(shorthandID, direction, writingMode);
+        CSSVariableReferenceValue* shorthandValue = pendingSubstitution.shorthandValue();
+        const CSSVariableData* variableData = shorthandValue->variableDataValue();
+        ASSERT(variableData);
+        
+        Vector<CSSParserToken> resolvedTokens;
+        if (!variableData->resolveTokenRange(customProperties, variableData->tokens(), resolvedTokens))
+            return nullptr;
+        
+        ParsedPropertyVector parsedProperties;
+        if (!CSSPropertyParser::parseValue(shorthandID, false, resolvedTokens, m_context, parsedProperties, StyleRule::Style))
+            return nullptr;
+        
+        for (auto& property : parsedProperties) {
+            if (property.id() == propID)
+                return property.value();
+        }
+        
+        return nullptr;
+    }
 
-    for (auto& property : m_parsedProperties) {
-        if (property.id() == propID)
-            return property.value();
+    if (value.isVariableReferenceValue()) {
+        const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value);
+        const CSSVariableData* variableData = valueWithReferences.variableDataValue();
+        ASSERT(variableData);
+        
+        Vector<CSSParserToken> resolvedTokens;
+        if (!variableData->resolveTokenRange(customProperties, variableData->tokens(), resolvedTokens))
+            return nullptr;
+        
+        return CSSPropertyParser::parseSingleValue(propID, resolvedTokens, m_context);
     }
+    
     return nullptr;
 }
 

Modified: trunk/Source/WebCore/css/parser/CSSParser.h (208005 => 208006)


--- trunk/Source/WebCore/css/parser/CSSParser.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/parser/CSSParser.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -494,7 +494,7 @@
 
     void setCustomPropertyName(const AtomicString& propertyName) { m_customPropertyName = propertyName; }
 
-    RefPtr<CSSValue> parseVariableDependentValue(CSSPropertyID, const CSSVariableDependentValue&, const CustomPropertyValueMap& customProperties, TextDirection, WritingMode);
+    RefPtr<CSSValue> parseValueWithVariableReferences(CSSPropertyID, const CSSValue&, const CustomPropertyValueMap& customProperties, TextDirection, WritingMode);
 
 private:
     bool is8BitSource() { return m_is8BitSource; }

Modified: trunk/Source/WebCore/css/parser/CSSParserImpl.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/parser/CSSParserImpl.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/parser/CSSParserImpl.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -77,16 +77,6 @@
     return declaration->addParsedProperties(parser.m_parsedProperties);
 }
 
-bool CSSParserImpl::parseVariableValue(MutableStyleProperties* declaration, const AtomicString& propertyName, const String& value, bool important, const CSSParserContext& context)
-{
-    CSSParserImpl parser(context);
-    CSSTokenizer::Scope scope(value);
-    parser.consumeVariableValue(scope.tokenRange(), propertyName, important);
-    if (parser.m_parsedProperties.isEmpty())
-        return false;
-    return declaration->addParsedProperties(parser.m_parsedProperties);
-}
-
 static inline void filterProperties(bool important, const ParsedPropertyVector& input, ParsedPropertyVector& output, size_t& unusedEntries, std::bitset<numCSSProperties>& seenProperties, HashSet<AtomicString>& seenCustomProperties)
 {
     // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
@@ -97,11 +87,10 @@
         const unsigned propertyIDIndex = property.id() - firstCSSProperty;
         
         if (property.id() == CSSPropertyCustom) {
-            CSSCustomPropertyValue* customValue = downcast<CSSCustomPropertyValue>(property.value());
-            const AtomicString& name = customValue->name();
-            if (seenCustomProperties.contains(name))
+            auto& name = downcast<CSSCustomPropertyValue>(*property.value()).name();
+            if (!seenCustomProperties.add(name).isNewEntry)
                 continue;
-            seenCustomProperties.add(name);
+            output[--unusedEntries] = property;
             continue;
         }
         
@@ -243,29 +232,6 @@
     return selectorList;
 }
 
-RefPtr<ImmutableStyleProperties> CSSParserImpl::parseCustomPropertySet(CSSParserTokenRange range)
-{
-    range.consumeWhitespace();
-    if (range.peek().type() != LeftBraceToken)
-        return nullptr;
-    CSSParserTokenRange block = range.consumeBlock();
-    range.consumeWhitespace();
-    if (!range.atEnd())
-        return nullptr;
-    CSSParserImpl parser(strictCSSParserContext());
-    parser.consumeDeclarationList(block, StyleRule::Style);
-
-    // FIXME-NEWPARSER: We dont support @apply yet.
-    // Drop nested @apply rules. Seems nicer to do this here instead of making
-    // a different StyleRule type
-    /*for (size_t i = parser.m_parsedProperties.size(); i--; ) {
-        if (parser.m_parsedProperties[i].id() == CSSPropertyApplyAtRule)
-            parser.m_parsedProperties.remove(i);
-    }*/
-
-    return createStyleProperties(parser.m_parsedProperties, HTMLStandardMode);
-}
-
 std::unique_ptr<Vector<double>> CSSParserImpl::parseKeyframeKeyList(const String& keyList)
 {
     return consumeKeyframeKeyList(CSSTokenizer::Scope(keyList).tokenRange());

Modified: trunk/Source/WebCore/css/parser/CSSParserImpl.h (208005 => 208006)


--- trunk/Source/WebCore/css/parser/CSSParserImpl.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/parser/CSSParserImpl.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -83,7 +83,6 @@
     };
 
     static bool parseValue(MutableStyleProperties*, CSSPropertyID, const String&, bool important, const CSSParserContext&);
-    static bool parseVariableValue(MutableStyleProperties*, const AtomicString& propertyName, const String&, bool important, const CSSParserContext&);
     static Ref<ImmutableStyleProperties> parseInlineStyleDeclaration(const String&, Element*);
     static bool parseDeclarationList(MutableStyleProperties*, const String&, const CSSParserContext&);
     static RefPtr<StyleRuleBase> parseRule(const String&, const CSSParserContext&, StyleSheetContents*, AllowedRulesType);
@@ -90,8 +89,6 @@
     static void parseStyleSheet(const String&, const CSSParserContext&, StyleSheetContents*);
     static CSSSelectorList parsePageSelector(CSSParserTokenRange, StyleSheetContents*);
 
-    static RefPtr<ImmutableStyleProperties> parseCustomPropertySet(CSSParserTokenRange);
-
     static std::unique_ptr<Vector<double>> parseKeyframeKeyList(const String&);
 
     bool supportsDeclaration(CSSParserTokenRange&);

Modified: trunk/Source/WebCore/css/parser/CSSVariableParser.cpp (208005 => 208006)


--- trunk/Source/WebCore/css/parser/CSSVariableParser.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/css/parser/CSSVariableParser.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -130,7 +130,7 @@
     range.consumeWhitespace();
     if (range.peek().type() == IdentToken) {
         CSSValueID id = range.consumeIncludingWhitespace().id();
-        if (range.atEnd() && (id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset))
+        if (range.atEnd() && (id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset || id == CSSValueRevert))
             return id;
     }
 

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (208005 => 208006)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2016-10-27 22:05:01 UTC (rev 208006)
@@ -2036,10 +2036,10 @@
     auto& customProperties = rareInheritedData.access()->m_customProperties.access()->values();
     HashSet<AtomicString> invalidProperties;
     for (auto entry : customProperties) {
-        if (!entry.value->isVariableDependentValue())
+        if (!entry.value->containsVariables())
             continue;
         HashSet<AtomicString> seenProperties;
-        downcast<CSSVariableDependentValue>(*entry.value).checkVariablesForCycles(entry.key, customProperties, seenProperties, invalidProperties);
+        entry.value->checkVariablesForCycles(entry.key, customProperties, seenProperties, invalidProperties);
     }
     
     // Now insert invalid values.
@@ -2053,20 +2053,15 @@
     // 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->isVariableDependentValue())
+        if (!entry.value->containsVariables())
             continue;
-        
-        CSSParserValueList parserList;
-        if (!downcast<CSSVariableDependentValue>(*entry.value).valueList().buildParserValueListSubstitutingVariables(&parserList, customProperties))
-            resolvedValues.append(CSSCustomPropertyValue::create(entry.key, CSSCustomPropertyValue::createInvalid()));
-        else
-            resolvedValues.append(CSSCustomPropertyValue::create(entry.key, CSSValueList::createFromParserValueList(parserList)));
+        entry.value->resolveVariableReferences(customProperties, resolvedValues);
     }
     
     // With all results computed, we can now mutate our table to eliminate the variables and
     // hold the final values. This way when we inherit, we don't end up resubstituting variables, etc.
     for (auto& resolvedValue : resolvedValues)
-        customProperties.set(resolvedValue->name(), resolvedValue->deprecatedValue());
+        customProperties.set(resolvedValue->name(), resolvedValue.copyRef());
 
     rareInheritedData.access()->m_customProperties.access()->setContainsVariables(false);
 }

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (208005 => 208006)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -527,8 +527,8 @@
 
     const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
 
-    void setCustomPropertyValue(const AtomicString& name, const RefPtr<CSSValue>& value) { rareInheritedData.access()->m_customProperties.access()->setCustomPropertyValue(name, value); }
-    RefPtr<CSSValue> getCustomPropertyValue(const AtomicString& name) const { return rareInheritedData->m_customProperties->getCustomPropertyValue(name); }
+    void setCustomPropertyValue(const AtomicString& name, const RefPtr<CSSCustomPropertyValue>& value) { rareInheritedData.access()->m_customProperties.access()->setCustomPropertyValue(name, value); }
+    RefPtr<CSSCustomPropertyValue> getCustomPropertyValue(const AtomicString& name) const { return rareInheritedData->m_customProperties->getCustomPropertyValue(name); }
     bool hasCustomProperty(const AtomicString& name) const { return rareInheritedData->m_customProperties->hasCustomProperty(name); }
     const CustomPropertyValueMap& customProperties() const { return rareInheritedData->m_customProperties->m_values; }
 

Modified: trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h (208005 => 208006)


--- trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h	2016-10-27 21:19:34 UTC (rev 208005)
+++ trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h	2016-10-27 22:05:01 UTC (rev 208006)
@@ -22,7 +22,7 @@
 #ifndef StyleCustomPropertyData_h
 #define StyleCustomPropertyData_h
 
-#include "CSSValue.h"
+#include "CSSCustomPropertyValue.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
@@ -44,8 +44,8 @@
         if (m_values.size() != o.m_values.size())
             return false;
         
-        for (WTF::KeyValuePair<AtomicString, RefPtr<CSSValue>> entry : m_values) {
-            RefPtr<CSSValue> other = o.m_values.get(entry.key);
+        for (WTF::KeyValuePair<AtomicString, RefPtr<CSSCustomPropertyValue>> entry : m_values) {
+            RefPtr<CSSCustomPropertyValue> other = o.m_values.get(entry.key);
             if (!other || !entry.value->equals(*other))
                 return false;
         }
@@ -54,14 +54,14 @@
 
     bool operator!=(const StyleCustomPropertyData &o) const { return !(*this == o); }
     
-    void setCustomPropertyValue(const AtomicString& name, const RefPtr<CSSValue>& value)
+    void setCustomPropertyValue(const AtomicString& name, const RefPtr<CSSCustomPropertyValue>& value)
     {
         m_values.set(name, value);
-        if (value->isVariableDependentValue())
+        if (value->containsVariables())
             m_containsVariables = true;
     }
 
-    RefPtr<CSSValue> getCustomPropertyValue(const AtomicString& name) const { return m_values.get(name); }
+    RefPtr<CSSCustomPropertyValue> getCustomPropertyValue(const AtomicString& name) const { return m_values.get(name); }
     CustomPropertyValueMap& values() { return m_values; }
     
     bool hasCustomProperty(const AtomicString& name) const { return m_values.contains(name); }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to