Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Unified Diff: Source/core/css/parser/CSSParserValues.cpp

Issue 1192983003: CSS Custom Properties (Variables) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: ToT-ed again... Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/css/parser/CSSParserValues.cpp
diff --git a/Source/core/css/parser/CSSParserValues.cpp b/Source/core/css/parser/CSSParserValues.cpp
index 039e70bc66c8316a9d6b117e5f21abdc72476df7..3392bc709aea306138dc2fa08862c1ca52ac17fa 100644
--- a/Source/core/css/parser/CSSParserValues.cpp
+++ b/Source/core/css/parser/CSSParserValues.cpp
@@ -23,19 +23,48 @@
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSSelectorList.h"
+#include "core/css/CSSVariableData.h"
#include "core/css/parser/CSSParserToken.h"
#include "core/css/parser/CSSParserTokenRange.h"
#include "core/css/parser/CSSPropertyParser.h"
+#include "core/css/parser/CSSTokenizer.h"
+#include "core/css/parser/CSSVariableParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "wtf/text/StringBuilder.h"
namespace blink {
using namespace WTF;
+struct SameSizeAsCSSParserValue {
+ CSSValueID id;
+ CSSParserString valueUnion;
+ int unit;
+};
+
+static_assert(sizeof(CSSParserValue) == sizeof(SameSizeAsCSSParserValue), "CSSParserValue should stay small");
+
CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, bool& usesRemUnits)
: m_current(0)
{
+ init(range, usesRemUnits);
+}
+
+CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, const String& string, bool& usesRemUnits, bool& usesVariables)
+: m_current(0)
+{
+ init(range, usesRemUnits, &usesVariables, &string);
+}
+
+void CSSParserValueList::init(CSSParserTokenRange range, bool& usesRemUnits, bool* usesVariables, const String* string)
+{
+ CSSParserTokenRange originalRangeForVariables = range;
+
usesRemUnits = false;
+ if (usesVariables) {
+ ASSERT(string);
+ *usesVariables = false;
+ }
Vector<CSSParserValueList*> stack;
Vector<int> bracketCounts;
stack.append(this);
@@ -51,7 +80,8 @@ CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, bool& usesRemU
if (token.valueEqualsIgnoringCase("url")) {
const CSSParserToken& next = range.consumeIncludingWhitespace();
if (next.type() == BadStringToken || range.consume().type() != RightParenthesisToken) {
- destroyAndClear();
+ if (usesVariables)
+ checkForVariableReferencesOrDestroyAndClear(originalRangeForVariables, *string);
return;
}
ASSERT(next.type() == StringToken);
@@ -60,6 +90,10 @@ CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, bool& usesRemU
value.unit = CSSPrimitiveValue::CSS_URI;
value.string = next.value();
break;
+ } else if (token.valueEqualsIgnoringCase("var")) {
+ if (usesVariables)
+ checkForVariableReferencesOrDestroyAndClear(originalRangeForVariables, *string);
+ return;
}
CSSParserFunction* function = new CSSParserFunction;
@@ -76,6 +110,8 @@ CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, bool& usesRemU
stack.append(list);
bracketCounts.append(0);
calcDepth += (function->id == CSSValueCalc || function->id == CSSValueWebkitCalc);
+ if (function->id == CSSValueVar && usesVariables)
+ *usesVariables = true;
continue;
}
case LeftParenthesisToken: {
@@ -96,7 +132,8 @@ CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, bool& usesRemU
stack.removeLast();
bracketCounts.removeLast();
if (bracketCounts.isEmpty()) {
- destroyAndClear();
+ if (usesVariables)
+ checkForVariableReferencesOrDestroyAndClear(originalRangeForVariables, *string);
return;
}
CSSParserValueList* currentList = stack.last();
@@ -181,7 +218,8 @@ CSSParserValueList::CSSParserValueList(CSSParserTokenRange range, bool& usesRemU
value.setFromOperator(token.delimiter());
if (calcDepth && token.delimiter() == '+' && (&token - 1)->type() != WhitespaceToken) {
// calc(1px+ 2px) is invalid
- destroyAndClear();
+ if (usesVariables)
+ checkForVariableReferencesOrDestroyAndClear(originalRangeForVariables, *string);
return;
}
break;
@@ -245,9 +283,30 @@ static void destroy(Vector<CSSParserValue, 4>& values)
else if (values[i].unit == CSSParserValue::ValueList
|| values[i].unit == CSSParserValue::DimensionList)
delete values[i].valueList;
+ else if (values[i].unit == CSSParserValue::VariableValue)
+ values[i].variableData->deref();
}
}
+void CSSParserValueList::checkForVariableReferencesOrDestroyAndClear(const CSSParserTokenRange& originalRange, const String& string)
+{
+ // We have to clear any state that may have been previously loaded
+ destroyAndClear();
+ if (CSSVariableParser::containsValidVariableReferences(originalRange))
+ consumeVariableValue(originalRange, string);
+}
+
+void CSSParserValueList::consumeVariableValue(const CSSParserTokenRange& originalRange, const String& string)
+{
+ ASSERT(m_values.isEmpty());
+ CSSParserValue variableValue;
+ variableValue.id = CSSValueInternalVariableValue;
+ variableValue.isInt = false;
+ variableValue.unit = CSSParserValue::VariableValue;
+ variableValue.variableData = CSSVariableData::create(originalRange, string).leakRef();
+ addValue(variableValue);
+}
+
void CSSParserValueList::destroyAndClear()
{
destroy(m_values);

Powered by Google App Engine
This is Rietveld 408576698