| 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;
 | 
| 
 |