Chromium Code Reviews| 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; |