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 e5286c36554fdd73b7078ca7bb4ff55115c2e03c..6b1e6437bf8e1d31db47ade3a2562086ef6134e2 100644 |
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
@@ -1415,6 +1415,30 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeShadow(CSSParserTokenRange& range |
return shadowValueList; |
} |
+static PassRefPtrWillBeRawPtr<CSSValue> consumeTextDecorationLine(CSSParserTokenRange& range) |
+{ |
+ CSSValueID id = range.peek().id(); |
+ if (id == CSSValueNone) |
+ return consumeIdent(range); |
+ |
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); |
+ ListHashSet<int> ids; |
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> ident; |
+ CSSParserTokenRange textDecorationRange = range; |
+ while ((ident = consumeIdent<CSSValueBlink, CSSValueUnderline, CSSValueOverline, CSSValueLineThrough>(textDecorationRange))) { |
+ ListHashSet<int>::AddResult result = ids.add(ident->getValueID()); |
Timothy Loh
2015/11/02 03:36:28
I guess we can just use list->hasValue(ident.get()
rwlbuis
2015/11/03 20:53:15
Good idea, however I think HashSet solution is bet
|
+ if (!result.isNewEntry) |
+ return nullptr; |
+ list->append(ident.release()); |
+ } |
+ |
+ // Values are either valid or in shorthand scope. |
Timothy Loh
2015/11/02 03:36:28
I don't understand this comment :\
rwlbuis
2015/11/03 20:53:15
Probably outdated, I removed it.
|
+ if (!list->length()) |
+ return nullptr; |
+ range = textDecorationRange; |
+ return list.release(); |
+} |
+ |
PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty) |
{ |
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
@@ -1514,6 +1538,8 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
return consumeWidowsOrOrphans(m_range); |
case CSSPropertyWebkitTextFillColor: |
case CSSPropertyWebkitTapHighlightColor: |
+ case CSSPropertyTextDecorationColor: |
+ ASSERT(property != CSSPropertyTextDecorationColor || RuntimeEnabledFeatures::css3TextDecorationsEnabled()); |
Timothy Loh
2015/11/02 03:36:28
Might as well just put the text-decoration-color c
rwlbuis
2015/11/03 20:53:15
Done.
|
return consumeColor(m_range, m_context); |
case CSSPropertyColor: |
return consumeColor(m_range, m_context, inQuirksMode()); |
@@ -1522,6 +1548,9 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3 |
case CSSPropertyBoxShadow: |
return consumeShadow(m_range, m_context, property == CSSPropertyBoxShadow); |
+ case CSSPropertyWebkitTextDecorationsInEffect: |
+ case CSSPropertyTextDecorationLine: |
+ return consumeTextDecorationLine(m_range); |
default: |
return nullptr; |
} |
@@ -1884,6 +1913,49 @@ bool CSSPropertyParser::consumeColumns(bool important) |
return true; |
} |
+bool CSSPropertyParser::consumeShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important) |
+{ |
+ // We try to greedily match as many properties as possible. |
+ RefPtrWillBeRawPtr<CSSValue> propertyFound[6] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; // 6 is enough size. |
+ while (!m_range.atEnd()) { |
+ bool found = false; |
+ for (unsigned propertyIndex = 0; !found && propertyIndex < shorthand.length(); ++propertyIndex) { |
+ if (!propertyFound[propertyIndex]) { |
+ if (CSSParserFastPaths::isKeywordPropertyID(shorthand.properties()[propertyIndex])) { |
+ if (CSSParserFastPaths::isValidKeywordPropertyAndValue(shorthand.properties()[propertyIndex], m_range.peek().id())) |
+ propertyFound[propertyIndex] = consumeIdent(m_range); |
+ } else { |
+ propertyFound[propertyIndex] = parseSingleValue(shorthand.properties()[propertyIndex]); |
+ } |
+ if (propertyFound[propertyIndex]) |
+ found = true; |
+ } |
+ } |
+ |
+ // If we didn't find at least one match, this is an invalid shorthand and we have to ignore it. |
+ if (!found) |
+ return false; |
+ } |
+ |
+ // Fill in any remaining properties with the initial value. |
+ ImplicitScope implicitScope(this); |
+ const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization(); |
+ for (unsigned i = 0; i < shorthand.length(); ++i) { |
+ if (propertyFound[i]) { |
+ addProperty(shorthand.properties()[i], propertyFound[i].release(), important); |
+ } else { |
+ if (propertiesForInitialization) { |
+ const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]); |
+ for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex) |
+ addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important); |
+ } else { |
+ addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important); |
+ } |
+ } |
+ } |
+ return true; |
+} |
+ |
bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important) |
{ |
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
@@ -1948,6 +2020,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 consumeShorthand(CSSPropertyTextDecoration, 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; |