| 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 6ca22bca6a57d001061fb51cb99bb9db7024c6d1..45ffcb58c7501647e7497c3f7466e4822a37651c 100644
 | 
| --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
 | 
| +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
 | 
| @@ -20,6 +20,7 @@
 | 
|  #include "core/css/CSSPathValue.h"
 | 
|  #include "core/css/CSSPrimitiveValueMappings.h"
 | 
|  #include "core/css/CSSQuadValue.h"
 | 
| +#include "core/css/CSSReflectValue.h"
 | 
|  #include "core/css/CSSSVGDocumentValue.h"
 | 
|  #include "core/css/CSSShadowValue.h"
 | 
|  #include "core/css/CSSStringValue.h"
 | 
| @@ -273,6 +274,15 @@ static bool consumeCommaIncludingWhitespace(CSSParserTokenRange& valueList)
 | 
|      return true;
 | 
|  }
 | 
|  
 | 
| +static bool consumeSlashIncludingWhitespace(CSSParserTokenRange& range)
 | 
| +{
 | 
| +    CSSParserToken value = range.peek();
 | 
| +    if (value.type() != DelimiterToken || value.delimiter() != '/')
 | 
| +        return false;
 | 
| +    range.consumeIncludingWhitespace();
 | 
| +    return true;
 | 
| +}
 | 
| +
 | 
|  static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
 | 
|  {
 | 
|      if (range.peek().type() != IdentToken)
 | 
| @@ -3046,9 +3056,8 @@ static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4
 | 
|              return true;
 | 
|          }
 | 
|      } else {
 | 
| -        if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '/')
 | 
| +        if (!consumeSlashIncludingWhitespace(range))
 | 
|              return false;
 | 
| -        range.consumeIncludingWhitespace();
 | 
|          for (i = 0; i < 4 && !range.atEnd(); ++i) {
 | 
|              verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative);
 | 
|              if (!verticalRadii[i])
 | 
| @@ -3282,6 +3291,69 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeBorderImageWidth(CSSParserTokenRa
 | 
|      return CSSQuadValue::create(widths[0].release(), widths[1].release(), widths[2].release(), widths[3].release(), CSSQuadValue::SerializeAsQuad);
 | 
|  }
 | 
|  
 | 
| +static bool consumeBorderImageComponents(CSSPropertyID property, CSSParserTokenRange& range, const CSSParserContext& context, RefPtrWillBeRawPtr<CSSValue>& source,
 | 
| +    RefPtrWillBeRawPtr<CSSValue>& slice, RefPtrWillBeRawPtr<CSSValue>& width, RefPtrWillBeRawPtr<CSSValue>& outset, RefPtrWillBeRawPtr<CSSValue>& repeat)
 | 
| +{
 | 
| +    do {
 | 
| +        if (!source && (source = consumeImage(range, context)))
 | 
| +            continue;
 | 
| +        if (!repeat && (repeat = consumeBorderImageRepeat(range)))
 | 
| +            continue;
 | 
| +        if (!slice && (slice = consumeBorderImageSlice(property, range, context.mode()))) {
 | 
| +            ASSERT(!width && !outset);
 | 
| +            if (consumeSlashIncludingWhitespace(range)) {
 | 
| +                width = consumeBorderImageWidth(range);
 | 
| +                if (consumeSlashIncludingWhitespace(range)) {
 | 
| +                    outset = consumeBorderImageOutset(range);
 | 
| +                    if (!outset)
 | 
| +                        return false;
 | 
| +                } else if (!width) {
 | 
| +                    return false;
 | 
| +                }
 | 
| +            }
 | 
| +        } else {
 | 
| +            return false;
 | 
| +        }
 | 
| +    } while (!range.atEnd());
 | 
| +    return true;
 | 
| +}
 | 
| +
 | 
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeWebkitBorderImage(CSSPropertyID property, CSSParserTokenRange& range, const CSSParserContext& context)
 | 
| +{
 | 
| +    RefPtrWillBeRawPtr<CSSValue> source = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> slice = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> width = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> outset = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> repeat = nullptr;
 | 
| +    if (consumeBorderImageComponents(property, range, context, source, slice, width, outset, repeat))
 | 
| +        return createBorderImageValue(source, slice, width, outset, repeat);
 | 
| +    return nullptr;
 | 
| +}
 | 
| +
 | 
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeReflect(CSSParserTokenRange& range, const CSSParserContext& context)
 | 
| +{
 | 
| +    RefPtrWillBeRawPtr<CSSPrimitiveValue> direction = consumeIdent<CSSValueAbove, CSSValueBelow, CSSValueLeft, CSSValueRight>(range);
 | 
| +    if (!direction)
 | 
| +        return nullptr;
 | 
| +
 | 
| +    RefPtrWillBeRawPtr<CSSPrimitiveValue> offset = nullptr;
 | 
| +    if (range.atEnd()) {
 | 
| +        offset = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Pixels);
 | 
| +    } else {
 | 
| +        offset = consumeLengthOrPercent(range, context.mode(), ValueRangeAll, UnitlessQuirk::Forbid);
 | 
| +        if (!offset)
 | 
| +            return nullptr;
 | 
| +    }
 | 
| +
 | 
| +    RefPtrWillBeRawPtr<CSSValue> mask = nullptr;
 | 
| +    if (!range.atEnd()) {
 | 
| +        mask = consumeWebkitBorderImage(CSSPropertyWebkitBoxReflect, range, context);
 | 
| +        if (!mask)
 | 
| +            return nullptr;
 | 
| +    }
 | 
| +    return CSSReflectValue::create(direction.release(), offset.release(), mask.release());
 | 
| +}
 | 
| +
 | 
|  PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty)
 | 
|  {
 | 
|      CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
 | 
| @@ -3598,6 +3670,10 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
 | 
|      case CSSPropertyBorderImageWidth:
 | 
|      case CSSPropertyWebkitMaskBoxImageWidth:
 | 
|          return consumeBorderImageWidth(m_range);
 | 
| +    case CSSPropertyWebkitBorderImage:
 | 
| +        return consumeWebkitBorderImage(property, m_range, m_context);
 | 
| +    case CSSPropertyWebkitBoxReflect:
 | 
| +        return consumeReflect(m_range, m_context);
 | 
|      default:
 | 
|          CSSParserValueList valueList(m_range);
 | 
|          if (valueList.size()) {
 | 
| @@ -3812,8 +3888,7 @@ bool CSSPropertyParser::consumeFont(bool important)
 | 
|  
 | 
|      addProperty(CSSPropertyFontSize, fontSize.release(), important);
 | 
|  
 | 
| -    if (m_range.peek().type() == DelimiterToken && m_range.peek().delimiter() == '/') {
 | 
| -        m_range.consumeIncludingWhitespace();
 | 
| +    if (consumeSlashIncludingWhitespace(m_range)) {
 | 
|          RefPtrWillBeRawPtr<CSSPrimitiveValue> lineHeight = consumeLineHeight(m_range, m_context.mode());
 | 
|          if (!lineHeight)
 | 
|              return false;
 | 
| @@ -3935,7 +4010,7 @@ bool CSSPropertyParser::parseViewportDescriptor(CSSPropertyID propId, bool impor
 | 
|      }
 | 
|  }
 | 
|  
 | 
| -static bool consumeColumnWidthOrCount(CSSParserTokenRange& range, CSSParserMode cssParserMode, RefPtrWillBeRawPtr<CSSValue> &columnWidth, RefPtrWillBeRawPtr<CSSValue> &columnCount)
 | 
| +static bool consumeColumnWidthOrCount(CSSParserTokenRange& range, CSSParserMode cssParserMode, RefPtrWillBeRawPtr<CSSValue>& columnWidth, RefPtrWillBeRawPtr<CSSValue>& columnCount)
 | 
|  {
 | 
|      if (range.peek().id() == CSSValueAuto) {
 | 
|          consumeIdent(range);
 | 
| @@ -4116,6 +4191,38 @@ bool CSSPropertyParser::consume4Values(const StylePropertyShorthand& shorthand,
 | 
|      return m_range.atEnd();
 | 
|  }
 | 
|  
 | 
| +bool CSSPropertyParser::consumeBorderImage(CSSPropertyID property, bool important)
 | 
| +{
 | 
| +    RefPtrWillBeRawPtr<CSSValue> source = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> slice = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> width = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> outset = nullptr;
 | 
| +    RefPtrWillBeRawPtr<CSSValue> repeat = nullptr;
 | 
| +    if (consumeBorderImageComponents(property, m_range, m_context, source, slice, width, outset, repeat)) {
 | 
| +        ImplicitScope implicitScope(this);
 | 
| +        switch (property) {
 | 
| +        case CSSPropertyWebkitMaskBoxImage:
 | 
| +            addProperty(CSSPropertyWebkitMaskBoxImageSource, source ? source : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyWebkitMaskBoxImageSlice, slice ? slice : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyWebkitMaskBoxImageWidth, width ? width : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyWebkitMaskBoxImageOutset, outset ? outset : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyWebkitMaskBoxImageRepeat, repeat ? repeat : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            return true;
 | 
| +        case CSSPropertyBorderImage:
 | 
| +            addProperty(CSSPropertyBorderImageSource, source ? source : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyBorderImageSlice, slice ? slice : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyBorderImageWidth, width ? width : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyBorderImageOutset, outset ? outset : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            addProperty(CSSPropertyBorderImageRepeat, repeat ? repeat : cssValuePool().createImplicitInitialValue(), important);
 | 
| +            return true;
 | 
| +        default:
 | 
| +            ASSERT_NOT_REACHED();
 | 
| +            return false;
 | 
| +        }
 | 
| +    }
 | 
| +    return false;
 | 
| +}
 | 
| +
 | 
|  bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important)
 | 
|  {
 | 
|      CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
 | 
| @@ -4247,6 +4354,9 @@ bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im
 | 
|          return consumeShorthandGreedily(borderLeftShorthand(), important);
 | 
|      case CSSPropertyBorder:
 | 
|          return consumeBorder(important);
 | 
| +    case CSSPropertyBorderImage:
 | 
| +    case CSSPropertyWebkitMaskBoxImage:
 | 
| +        return consumeBorderImage(property, important);
 | 
|      default:
 | 
|          m_currentShorthand = oldShorthand;
 | 
|          CSSParserValueList valueList(m_range);
 | 
| 
 |