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 171269f4704087fde1e30b4b2bd7421fe71b7abd..3f9cbe99f4d7fb398b61a2956a6cbcbf2c919367 100644 |
| --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| @@ -1483,7 +1483,38 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeFilter(CSSParserTokenRange& range |
| } |
| list->append(filterValue.release()); |
| } while (!range.atEnd()); |
| + return list.release(); |
| +} |
| + |
| +static bool matchKeywords(CSSValueID target, const HashSet<int>& ids) |
| +{ |
| + for (const auto& id : ids) { |
| + if (id == target) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeTextDecorationLine(CSSParserTokenRange& range) |
| +{ |
| + CSSValueID id = range.peek().id(); |
| + if (id == CSSValueNone) |
| + return consumeIdent(range); |
| + |
| + RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); |
| + HashSet<int> ids; |
| + ids.add(CSSValueUnderline); |
| + ids.add(CSSValueOverline); |
| + ids.add(CSSValueLineThrough); |
| + ids.add(CSSValueBlink); |
| + while (matchKeywords(id, ids)) { |
|
Timothy Loh
2015/11/04 00:03:02
just use ids.contains(id)
|
| + list->append(consumeIdent(range)); |
| + ids.remove(id); |
| + id = range.peek().id(); |
| + } |
| + if (!list->length()) |
| + return nullptr; |
| return list.release(); |
| } |
| @@ -1584,6 +1615,8 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
| case CSSPropertyOrphans: |
| case CSSPropertyWidows: |
| return consumeWidowsOrOrphans(m_range); |
| + case CSSPropertyTextDecorationColor: |
| + ASSERT(RuntimeEnabledFeatures::css3TextDecorationsEnabled()); |
|
Timothy Loh
2015/11/04 00:03:02
I'd prefer if it didn't fall-through (it's a singl
|
| case CSSPropertyWebkitTextFillColor: |
| case CSSPropertyWebkitTapHighlightColor: |
| return consumeColor(m_range, m_context); |
| @@ -1597,6 +1630,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 +1995,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 +2093,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; |