Index: Source/core/css/parser/CSSPropertyParserNew.cpp |
diff --git a/Source/core/css/parser/CSSPropertyParserNew.cpp b/Source/core/css/parser/CSSPropertyParserNew.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0201df875ee016235cdf8d51af680cdf887b8fcf |
--- /dev/null |
+++ b/Source/core/css/parser/CSSPropertyParserNew.cpp |
@@ -0,0 +1,147 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+namespace blink { |
+ |
+static bool consumeCommaIncludingWhitespace(CSSParserTokenRange& valueList) |
+{ |
+ CSSParserToken value = valueList.peek(); |
+ if (value.type() != CommaToken) |
+ return false; |
+ valueList.consumeIncludingWhitespace(); |
+ return true; |
+} |
+ |
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range) |
+{ |
+ ASSERT(range.peek().type() == IdentToken); |
+ return cssValuePool().createIdentifierValue(range.consumeIncludingWhitespace().id()); |
+} |
+ |
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumePrimitiveCustomIdentValue(CSSParserTokenRange& range) |
+{ |
+ ASSERT(range.peek().unitType() == CSSPrimitiveValue::UnitType::String || range.peek().type() == IdentToken); |
+ return cssValuePool().createValue(range.consumeIncludingWhitespace().value(), CSSPrimitiveValue::UnitType::CustomIdentifier); |
+} |
+ |
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID propId) |
+{ |
+ m_range.consumeWhitespace(); |
+ switch (propId) { |
+ case CSSPropertyWillChange: |
+ return parseWillChange(); |
+ case CSSPropertyPage: |
+ return parsePage(); |
+ default: |
+ return nullptr; |
+ } |
+} |
+ |
+bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, bool important) |
+{ |
+ m_range.consumeWhitespace(); |
+ switch (propId) { |
+ case CSSPropertyWebkitMarginCollapse: { |
+ CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
+ if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(webkitMarginCollapseShorthand().properties()[0], id)) |
+ return false; |
+ addProperty(webkitMarginCollapseShorthand().properties()[0], cssValuePool().createIdentifierValue(id), important); |
+ if (m_range.atEnd()) { |
+ CSSValue* value = m_parsedProperties.last().value(); |
+ addProperty(webkitMarginCollapseShorthand().properties()[1], value, important); |
+ return true; |
+ } |
+ id = m_range.consumeIncludingWhitespace().id(); |
+ if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(webkitMarginCollapseShorthand().properties()[1], id)) |
+ return false; |
+ addProperty(webkitMarginCollapseShorthand().properties()[1], cssValuePool().createIdentifierValue(id), important); |
+ return true; |
+ } |
+ case CSSPropertyOverflow: { |
+ CSSValueID id = m_range.consumeIncludingWhitespace().id(); |
+ if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyOverflowY, id)) |
+ return false; |
+ if (!m_range.atEnd()) |
+ return false; |
+ addProperty(CSSPropertyOverflowY, cssValuePool().createIdentifierValue(id), important); |
+ |
+ RefPtrWillBeRawPtr<CSSValue> overflowXValue = nullptr; |
+ |
+ // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been |
+ // set using the shorthand, then for now overflow-x will default to auto, but once we implement |
+ // pagination controls, it should default to hidden. If the overflow-y value is anything but |
+ // paged-x or paged-y, then overflow-x and overflow-y should have the same value. |
+ if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY) |
+ overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto); |
+ else |
+ overflowXValue = m_parsedProperties.last().value(); |
+ addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); |
+ return true; |
+ } |
+ default: |
+ return false; |
+ } |
+} |
+ |
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseWillChange() |
+{ |
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); |
+ if (m_range.peek().id() == CSSValueAuto) { |
+ values->append(consumeIdent(m_range)); |
+ return values.release(); |
+ } |
+ |
+ // Every comma-separated list of identifiers is a valid will-change value, |
+ // unless the list includes an explicitly disallowed identifier. |
+ while (true) { |
+ if (m_range.peek().type() != IdentToken) |
+ return nullptr; |
+ CSSPropertyID unresolvedProperty = unresolvedCSSPropertyID(m_range.peek().value()); |
+ if (unresolvedProperty) { |
+ ASSERT(CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); |
+ // Now "all" is used by both CSSValue and CSSPropertyValue. |
+ // Need to return nullptr when currentValue is CSSPropertyAll. |
+ if (unresolvedProperty == CSSPropertyWillChange || unresolvedProperty == CSSPropertyAll) |
+ return nullptr; |
+ values->append(cssValuePool().createIdentifierValue(unresolvedProperty)); |
+ m_range.consumeIncludingWhitespace(); |
+ } else { |
+ switch (m_range.peek().id()) { |
+ case CSSValueNone: |
+ case CSSValueAll: |
+ case CSSValueAuto: |
+ case CSSValueDefault: |
+ case CSSValueInitial: |
+ case CSSValueInherit: |
+ return nullptr; |
+ case CSSValueContents: |
+ case CSSValueScrollPosition: |
+ values->append(consumeIdent(m_range)); |
+ break; |
+ default: |
+ m_range.consumeIncludingWhitespace(); |
+ break; |
+ } |
+ } |
+ |
+ if (m_range.atEnd()) |
+ break; |
+ if (!consumeCommaIncludingWhitespace(m_range)) |
+ return nullptr; |
+ } |
+ |
+ return values.release(); |
+} |
+ |
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parsePage() |
+{ |
+ CSSParserToken token = m_range.peek(); |
+ if (token.id() == CSSValueAuto) |
+ return consumeIdent(m_range); |
+ if (token.type() == IdentToken) |
+ return consumePrimitiveCustomIdentValue(m_range); |
+ return nullptr; |
+} |
+ |
+} // namespace blink |