Index: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
index 171269f4704087fde1e30b4b2bd7421fe71b7abd..304d82fbd3b8b1c4e6423f95f2c05fca79e6325e 100644 |
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
@@ -1483,7 +1483,25 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeFilter(CSSParserTokenRange& range |
} |
list->append(filterValue.release()); |
} while (!range.atEnd()); |
+ return list.release(); |
+} |
+ |
+static PassRefPtrWillBeRawPtr<CSSValue> consumeTextDecorationLine(CSSParserTokenRange& range) |
+{ |
+ CSSValueID id = range.peek().id(); |
+ if (id == CSSValueNone) |
+ return consumeIdent(range); |
+ |
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); |
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> ident; |
+ while ((ident = consumeIdent<CSSValueBlink, CSSValueUnderline, CSSValueOverline, CSSValueLineThrough>(range))) { |
+ if (list->hasValue(ident.get())) |
+ return nullptr; |
+ list->append(ident.release()); |
+ } |
+ if (!list->length()) |
+ return nullptr; |
return list.release(); |
} |
@@ -1584,6 +1602,9 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
case CSSPropertyOrphans: |
case CSSPropertyWidows: |
return consumeWidowsOrOrphans(m_range); |
+ case CSSPropertyTextDecorationColor: |
+ ASSERT(RuntimeEnabledFeatures::css3TextDecorationsEnabled()); |
+ return consumeColor(m_range, m_context); |
case CSSPropertyWebkitTextFillColor: |
case CSSPropertyWebkitTapHighlightColor: |
return consumeColor(m_range, m_context); |
@@ -1597,6 +1618,9 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
case CSSPropertyWebkitFilter: |
case CSSPropertyBackdropFilter: |
return consumeFilter(m_range, m_context); |
+ case CSSPropertyWebkitTextDecorationsInEffect: |
+ case CSSPropertyTextDecorationLine: |
+ return consumeTextDecorationLine(m_range); |
default: |
return nullptr; |
} |
@@ -1959,6 +1983,40 @@ bool CSSPropertyParser::consumeColumns(bool important) |
return true; |
} |
+bool CSSPropertyParser::consumeShorthandGreedily(const StylePropertyShorthand& shorthand, bool important) |
+{ |
+ ASSERT(shorthand.length() <= 6); // Existing shorthands have at most 6 longhands. |
+ RefPtrWillBeRawPtr<CSSValue> longhands[6] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; |
+ const CSSPropertyID* shorthandProperties = shorthand.properties(); |
+ do { |
+ bool foundLonghand = false; |
+ for (size_t i = 0; !foundLonghand && i < shorthand.length(); ++i) { |
+ if (longhands[i]) |
+ continue; |
+ // TODO: parseSingleValue needs to handle fastpath keywords. |
+ if (CSSParserFastPaths::isKeywordPropertyID(shorthandProperties[i])) { |
+ if (CSSParserFastPaths::isValidKeywordPropertyAndValue(shorthandProperties[i], m_range.peek().id())) |
+ longhands[i] = consumeIdent(m_range); |
+ } else { |
+ longhands[i] = parseSingleValue(shorthandProperties[i]); |
+ } |
+ if (longhands[i]) |
+ foundLonghand = true; |
+ } |
+ if (!foundLonghand) |
+ return false; |
+ } while (!m_range.atEnd()); |
+ |
+ ImplicitScope implicitScope(this); |
+ for (size_t i = 0; i < shorthand.length(); ++i) { |
+ if (longhands[i]) |
+ addProperty(shorthandProperties[i], longhands[i].release(), important); |
+ else |
+ addProperty(shorthandProperties[i], cssValuePool().createImplicitInitialValue(), important); |
+ } |
+ return true; |
+} |
+ |
bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important) |
{ |
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
@@ -2023,6 +2081,17 @@ bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im |
return consumeAnimationShorthand(animationShorthandForParsing(), unresolvedProperty == CSSPropertyAliasWebkitAnimation, important); |
case CSSPropertyTransition: |
return consumeAnimationShorthand(transitionShorthandForParsing(), false, important); |
+ case CSSPropertyTextDecoration: { |
+ // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration |
+ // is disabled to match CSS 2.1 rules for parsing 'text-decoration'. |
+ if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) |
+ return consumeShorthandGreedily(textDecorationShorthand(), important); |
+ RefPtrWillBeRawPtr<CSSValue> textDecoration = consumeTextDecorationLine(m_range); |
+ if (!textDecoration || !m_range.atEnd()) |
+ return false; |
+ addProperty(CSSPropertyTextDecoration, textDecoration.release(), important); |
+ return true; |
+ } |
default: |
m_currentShorthand = oldShorthand; |
return false; |