Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / parser / BisonCSSParser-in.cpp
index adff837..2bae251 100644 (file)
 #include "config.h"
 #include "core/css/parser/BisonCSSParser.h"
 
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
-#include "core/css/CSSArrayFunctionValue.h"
+#include "core/CSSValueKeywords.h"
+#include "core/StylePropertyShorthand.h"
 #include "core/css/CSSAspectRatioValue.h"
 #include "core/css/CSSBasicShapes.h"
 #include "core/css/CSSBorderImage.h"
@@ -53,7 +51,6 @@
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSPropertySourceData.h"
 #include "core/css/CSSReflectValue.h"
-#include "core/css/CSSSVGDocumentValue.h"
 #include "core/css/CSSSelector.h"
 #include "core/css/CSSShadowValue.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/css/parser/CSSParserIdioms.h"
 #include "core/dom/Document.h"
+#include "core/frame/FrameConsole.h"
 #include "core/frame/FrameHost.h"
-#include "core/frame/PageConsole.h"
 #include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/parser/HTMLParserIdioms.h"
+#include "core/inspector/ConsoleMessage.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/rendering/RenderTheme.h"
-#include "core/svg/SVGParserUtilities.h"
 #include "platform/FloatConversion.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "wtf/BitArray.h"
 #include "wtf/HexNumber.h"
 #include "wtf/text/StringBuffer.h"
 extern int cssyydebug;
 #endif
 
-int cssyyparse(WebCore::BisonCSSParser*);
+int cssyyparse(blink::BisonCSSParser*);
 
-using namespace std;
 using namespace WTF;
 
-namespace WebCore {
+namespace blink {
 
 static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
 
@@ -109,11 +107,10 @@ BisonCSSParser::BisonCSSParser(const CSSParserContext& context)
     : m_context(context)
     , m_important(false)
     , m_id(CSSPropertyInvalid)
-    , m_styleSheet(0)
+    , m_styleSheet(nullptr)
     , m_supportsCondition(false)
     , m_selectorListForParseSelector(0)
     , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
-    , m_hasFontFaceOnlyValues(false)
     , m_hadSyntacticallyValidCSSRule(false)
     , m_logErrors(false)
     , m_ignoreErrors(false)
@@ -129,7 +126,6 @@ BisonCSSParser::BisonCSSParser(const CSSParserContext& context)
 #if YYDEBUG > 0
     cssyydebug = 1;
 #endif
-    CSSPropertySourceData::init();
 }
 
 BisonCSSParser::~BisonCSSParser()
@@ -213,9 +209,6 @@ static inline bool isColorPropertyID(CSSPropertyID propertyId)
     case CSSPropertyBorderRightColor:
     case CSSPropertyBorderTopColor:
     case CSSPropertyOutlineColor:
-    case CSSPropertyTextLineThroughColor:
-    case CSSPropertyTextOverlineColor:
-    case CSSPropertyTextUnderlineColor:
     case CSSPropertyWebkitBorderAfterColor:
     case CSSPropertyWebkitBorderBeforeColor:
     case CSSPropertyWebkitBorderEndColor:
@@ -287,9 +280,8 @@ static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acce
         acceptsNegativeNumbers = false;
         return true;
     case CSSPropertyShapeMargin:
-    case CSSPropertyShapePadding:
         acceptsNegativeNumbers = false;
-        return RuntimeEnabledFeatures::cssShapesEnabled();
+        return true;
     case CSSPropertyBottom:
     case CSSPropertyLeft:
     case CSSPropertyMarginBottom:
@@ -310,7 +302,7 @@ static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acce
 }
 
 template <typename CharacterType>
-static inline bool parseSimpleLength(const CharacterType* characters, unsigned length, CSSPrimitiveValue::UnitTypes& unit, double& number)
+static inline bool parseSimpleLength(const CharacterType* characters, unsigned length, CSSPrimitiveValue::UnitType& unit, double& number)
 {
     if (length > 2 && (characters[length - 2] | 0x20) == 'p' && (characters[length - 1] | 0x20) == 'x') {
         length -= 2;
@@ -331,7 +323,7 @@ static inline bool parseSimpleLength(const CharacterType* characters, unsigned l
 static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
 {
     ASSERT(!string.isEmpty());
-    bool acceptsNegativeNumbers;
+    bool acceptsNegativeNumbers = false;
 
     // In @viewport, width and height are shorthands, not simple length values.
     if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
@@ -339,7 +331,7 @@ static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSProp
 
     unsigned length = string.length();
     double number;
-    CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
+    CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::CSS_NUMBER;
 
     if (string.is8Bit()) {
         if (!parseSimpleLength(string.characters8(), length, unit, number))
@@ -363,17 +355,18 @@ static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSProp
     return true;
 }
 
-bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext)
+bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, CSSValueID valueID, const CSSParserContext& parserContext)
 {
-    if (!valueID)
+    if (valueID == CSSValueInvalid)
         return false;
 
     switch (propertyId) {
-    case CSSPropertyBorderCollapse: // collapse | separate | inherit
-        if (valueID == CSSValueCollapse || valueID == CSSValueSeparate)
-            return true;
-        break;
-    case CSSPropertyBorderTopStyle: // <border-style> | inherit
+    case CSSPropertyBackgroundRepeatX: // repeat | no-repeat
+    case CSSPropertyBackgroundRepeatY: // repeat | no-repeat
+        return valueID == CSSValueRepeat || valueID == CSSValueNoRepeat;
+    case CSSPropertyBorderCollapse: // collapse | separate
+        return valueID == CSSValueCollapse || valueID == CSSValueSeparate;
+    case CSSPropertyBorderTopStyle: // <border-style>
     case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed |
     case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset
     case CSSPropertyBorderLeftStyle:
@@ -382,352 +375,185 @@ bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const
     case CSSPropertyWebkitBorderEndStyle:
     case CSSPropertyWebkitBorderStartStyle:
     case CSSPropertyWebkitColumnRuleStyle:
-        if (valueID >= CSSValueNone && valueID <= CSSValueDouble)
-            return true;
-        break;
+        return valueID >= CSSValueNone && valueID <= CSSValueDouble;
     case CSSPropertyBoxSizing:
-         if (valueID == CSSValueBorderBox || valueID == CSSValueContentBox)
-             return true;
-         break;
-    case CSSPropertyCaptionSide: // top | bottom | left | right | inherit
-        if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom)
-            return true;
-        break;
-    case CSSPropertyClear: // none | left | right | both | inherit
-        if (valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth)
-            return true;
-        break;
-    case CSSPropertyDirection: // ltr | rtl | inherit
-        if (valueID == CSSValueLtr || valueID == CSSValueRtl)
-            return true;
-        break;
+        return valueID == CSSValueBorderBox || valueID == CSSValueContentBox;
+    case CSSPropertyCaptionSide: // top | bottom | left | right
+        return valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom;
+    case CSSPropertyClear: // none | left | right | both
+        return valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth;
+    case CSSPropertyDirection: // ltr | rtl
+        return valueID == CSSValueLtr || valueID == CSSValueRtl;
     case CSSPropertyDisplay:
         // inline | block | list-item | inline-block | table |
         // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
-        // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit
-        // flex | inline-flex | -webkit-flex | -webkit-inline-flex | grid | inline-grid | lazy-block
-        if ((valueID >= CSSValueInline && valueID <= CSSValueInlineFlex) || valueID == CSSValueWebkitFlex || valueID == CSSValueWebkitInlineFlex || valueID == CSSValueNone)
-            return true;
-        if (valueID == CSSValueGrid || valueID == CSSValueInlineGrid)
-            return RuntimeEnabledFeatures::cssGridLayoutEnabled();
-        break;
-
-    case CSSPropertyEmptyCells: // show | hide | inherit
-        if (valueID == CSSValueShow || valueID == CSSValueHide)
-            return true;
-        break;
+        // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none
+        // flex | inline-flex | -webkit-flex | -webkit-inline-flex | grid | inline-grid
+        return (valueID >= CSSValueInline && valueID <= CSSValueInlineFlex) || valueID == CSSValueWebkitFlex || valueID == CSSValueWebkitInlineFlex || valueID == CSSValueNone
+            || (RuntimeEnabledFeatures::cssGridLayoutEnabled() && (valueID == CSSValueGrid || valueID == CSSValueInlineGrid));
+    case CSSPropertyEmptyCells: // show | hide
+        return valueID == CSSValueShow || valueID == CSSValueHide;
     case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none)
-        if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter)
-            return true;
-        break;
-    case CSSPropertyFontStyle: // normal | italic | oblique | inherit
-        if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique)
-            return true;
-        break;
-    case CSSPropertyImageRendering: // auto | optimizeContrast
-        if (valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast)
-            return true;
-        break;
+        return valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter;
+    case CSSPropertyFontStyle: // normal | italic | oblique
+        return valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique;
+    case CSSPropertyFontStretch: // normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded
+        return valueID == CSSValueNormal || valueID == CSSValueUltraCondensed || valueID == CSSValueExtraCondensed || valueID == CSSValueCondensed || valueID == CSSValueSemiCondensed || valueID == CSSValueSemiExpanded || valueID == CSSValueExpanded || valueID == CSSValueExtraExpanded || valueID == CSSValueUltraExpanded;
+    case CSSPropertyImageRendering: // auto | optimizeContrast | pixelated
+        return valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast || (RuntimeEnabledFeatures::imageRenderingPixelatedEnabled() && valueID == CSSValuePixelated);
     case CSSPropertyIsolation: // auto | isolate
-        if (valueID == CSSValueAuto || valueID == CSSValueIsolate)
-            return RuntimeEnabledFeatures::cssCompositingEnabled();
-        break;
-    case CSSPropertyListStylePosition: // inside | outside | inherit
-        if (valueID == CSSValueInside || valueID == CSSValueOutside)
-            return true;
-        break;
+        return RuntimeEnabledFeatures::cssCompositingEnabled()
+            && (valueID == CSSValueAuto || valueID == CSSValueIsolate);
+    case CSSPropertyListStylePosition: // inside | outside
+        return valueID == CSSValueInside || valueID == CSSValueOutside;
     case CSSPropertyListStyleType:
         // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
         // for the list of supported list-style-types.
-        if ((valueID >= CSSValueDisc && valueID <= CSSValueKatakanaIroha) || valueID == CSSValueNone)
-            return true;
-        break;
+        return (valueID >= CSSValueDisc && valueID <= CSSValueKatakanaIroha) || valueID == CSSValueNone;
     case CSSPropertyObjectFit:
-        if (RuntimeEnabledFeatures::objectFitPositionEnabled()) {
-            if (valueID == CSSValueFill || valueID == CSSValueContain || valueID == CSSValueCover || valueID == CSSValueNone || valueID == CSSValueScaleDown)
-                return true;
-        }
-        break;
-    case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto | inherit
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || (valueID >= CSSValueInset && valueID <= CSSValueDouble))
-            return true;
-        break;
+        return RuntimeEnabledFeatures::objectFitPositionEnabled()
+            && (valueID == CSSValueFill || valueID == CSSValueContain || valueID == CSSValueCover || valueID == CSSValueNone || valueID == CSSValueScaleDown);
+    case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto
+        return valueID == CSSValueAuto || valueID == CSSValueNone || (valueID >= CSSValueInset && valueID <= CSSValueDouble);
     case CSSPropertyOverflowWrap: // normal | break-word
     case CSSPropertyWordWrap:
-        if (valueID == CSSValueNormal || valueID == CSSValueBreakWord)
-            return true;
-        break;
-    case CSSPropertyOverflowX: // visible | hidden | scroll | auto | overlay | inherit
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay)
-            return true;
-        break;
-    case CSSPropertyOverflowY: // visible | hidden | scroll | auto | overlay | inherit | -webkit-paged-x | -webkit-paged-y
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitPagedX || valueID == CSSValueWebkitPagedY)
-            return true;
-        break;
-    case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit
+        return valueID == CSSValueNormal || valueID == CSSValueBreakWord;
+    case CSSPropertyOverflowX: // visible | hidden | scroll | auto | overlay
+        return valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay;
+    case CSSPropertyOverflowY: // visible | hidden | scroll | auto | overlay | -webkit-paged-x | -webkit-paged-y
+        return valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitPagedX || valueID == CSSValueWebkitPagedY;
+    case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right
     case CSSPropertyPageBreakBefore:
     case CSSPropertyWebkitColumnBreakAfter:
     case CSSPropertyWebkitColumnBreakBefore:
-        if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
-            return true;
-        break;
-    case CSSPropertyPageBreakInside: // avoid | auto | inherit
+        return valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight;
+    case CSSPropertyPageBreakInside: // avoid | auto
     case CSSPropertyWebkitColumnBreakInside:
-        if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueAvoid;
     case CSSPropertyPointerEvents:
         // none | visiblePainted | visibleFill | visibleStroke | visible |
-        // painted | fill | stroke | auto | all | bounding-box | inherit
-        if (valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID >= CSSValueVisiblepainted && valueID <= CSSValueBoundingBox))
-            return true;
-        break;
-    case CSSPropertyPosition: // static | relative | absolute | fixed | sticky | inherit
-        if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed
-            || (RuntimeEnabledFeatures::cssStickyPositionEnabled() && valueID == CSSValueSticky))
-            return true;
-        break;
+        // painted | fill | stroke | auto | all | bounding-box
+        return valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID >= CSSValueVisiblepainted && valueID <= CSSValueBoundingBox);
+    case CSSPropertyPosition: // static | relative | absolute | fixed
+        return valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed;
     case CSSPropertyResize: // none | both | horizontal | vertical | auto
-        if (valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto)
-            return true;
-        break;
+        return valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto;
     case CSSPropertyScrollBehavior: // instant | smooth
-        if (valueID == CSSValueInstant || valueID == CSSValueSmooth)
-            return RuntimeEnabledFeatures::cssomSmoothScrollEnabled();
-    case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit
-        if (valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation)
-            return true;
-        break;
-    case CSSPropertyTableLayout: // auto | fixed | inherit
-        if (valueID == CSSValueAuto || valueID == CSSValueFixed)
-            return true;
-        break;
+        return RuntimeEnabledFeatures::cssomSmoothScrollEnabled()
+            && (valueID == CSSValueInstant || valueID == CSSValueSmooth);
+    case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation
+        return valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation;
+    case CSSPropertyTableLayout: // auto | fixed
+        return valueID == CSSValueAuto || valueID == CSSValueFixed;
     case CSSPropertyTextAlignLast:
         // auto | start | end | left | right | center | justify
-        if (RuntimeEnabledFeatures::css3TextEnabled()
-            && ((valueID >= CSSValueLeft && valueID <= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto))
-            return true;
-        break;
+        return RuntimeEnabledFeatures::css3TextEnabled()
+            && ((valueID >= CSSValueLeft && valueID <= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto);
     case CSSPropertyTextJustify:
         // auto | none | inter-word | distribute
-        if (RuntimeEnabledFeatures::css3TextEnabled()
-            && (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone))
-            return true;
-        break;
-    case CSSPropertyTextLineThroughMode:
-    case CSSPropertyTextOverlineMode:
-    case CSSPropertyTextUnderlineMode:
-        if (valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace)
-            return true;
-        break;
-    case CSSPropertyTextLineThroughStyle:
-    case CSSPropertyTextOverlineStyle:
-    case CSSPropertyTextUnderlineStyle:
-        if (valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave)
-            return true;
-        break;
+        return RuntimeEnabledFeatures::css3TextEnabled()
+            && (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone);
     case CSSPropertyTextOverflow: // clip | ellipsis
-        if (valueID == CSSValueClip || valueID == CSSValueEllipsis)
-            return true;
-        break;
+        return valueID == CSSValueClip || valueID == CSSValueEllipsis;
     case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
-        if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision)
-            return true;
-        break;
-    case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit
-        if ((valueID >= CSSValueCapitalize && valueID <= CSSValueLowercase) || valueID == CSSValueNone)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision;
+    case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none
+        return (valueID >= CSSValueCapitalize && valueID <= CSSValueLowercase) || valueID == CSSValueNone;
     case CSSPropertyTouchActionDelay: // none | script
-        if (RuntimeEnabledFeatures::cssTouchActionDelayEnabled() && (valueID == CSSValueScript || valueID == CSSValueNone))
-            return true;
-        break;
-    case CSSPropertyVisibility: // visible | hidden | collapse | inherit
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse)
-            return true;
-        break;
+        return RuntimeEnabledFeatures::cssTouchActionDelayEnabled()
+            && (valueID == CSSValueScript || valueID == CSSValueNone);
+    case CSSPropertyVisibility: // visible | hidden | collapse
+        return valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse;
     case CSSPropertyWebkitAppearance:
-        if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone)
-            return true;
-        break;
+        return (valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone;
+    case CSSPropertyBackfaceVisibility:
     case CSSPropertyWebkitBackfaceVisibility:
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden)
-            return true;
-        break;
+        return valueID == CSSValueVisible || valueID == CSSValueHidden;
     case CSSPropertyMixBlendMode:
-        if (RuntimeEnabledFeatures::cssCompositingEnabled() && (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen
-            || valueID == CSSValueOverlay || valueID == CSSValueDarken || valueID == CSSValueLighten ||  valueID == CSSValueColorDodge
-            || valueID == CSSValueColorBurn || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference
-            || valueID == CSSValueExclusion || valueID == CSSValueHue || valueID == CSSValueSaturation || valueID == CSSValueColor
-            || valueID == CSSValueLuminosity))
-            return true;
-        break;
+        return RuntimeEnabledFeatures::cssCompositingEnabled()
+            && (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen || valueID == CSSValueOverlay
+            || valueID == CSSValueDarken || valueID == CSSValueLighten || valueID == CSSValueColorDodge || valueID == CSSValueColorBurn
+            || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference || valueID == CSSValueExclusion
+            || valueID == CSSValueHue || valueID == CSSValueSaturation || valueID == CSSValueColor || valueID == CSSValueLuminosity);
     case CSSPropertyWebkitBorderFit:
-        if (valueID == CSSValueBorder || valueID == CSSValueLines)
-            return true;
-        break;
+        return valueID == CSSValueBorder || valueID == CSSValueLines;
     case CSSPropertyWebkitBoxAlign:
-        if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline)
-            return true;
-        break;
+        return valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline;
     case CSSPropertyWebkitBoxDecorationBreak:
-         if (valueID == CSSValueClone || valueID == CSSValueSlice)
-             return true;
-         break;
+        return valueID == CSSValueClone || valueID == CSSValueSlice;
     case CSSPropertyWebkitBoxDirection:
-        if (valueID == CSSValueNormal || valueID == CSSValueReverse)
-            return true;
-        break;
+        return valueID == CSSValueNormal || valueID == CSSValueReverse;
     case CSSPropertyWebkitBoxLines:
-        if (valueID == CSSValueSingle || valueID == CSSValueMultiple)
-                return true;
-        break;
+        return valueID == CSSValueSingle || valueID == CSSValueMultiple;
     case CSSPropertyWebkitBoxOrient:
-        if (valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis)
-            return true;
-        break;
+        return valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis;
     case CSSPropertyWebkitBoxPack:
-        if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify)
-            return true;
-        break;
+        return valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify;
     case CSSPropertyInternalCallback:
         // This property is only injected programmatically, not parsed from stylesheets.
         return false;
     case CSSPropertyColumnFill:
-        if (RuntimeEnabledFeatures::regionBasedColumnsEnabled()) {
-            if (valueID == CSSValueAuto || valueID == CSSValueBalance)
-                return true;
-        }
-        break;
+        return RuntimeEnabledFeatures::regionBasedColumnsEnabled()
+            && (valueID == CSSValueAuto || valueID == CSSValueBalance);
     case CSSPropertyAlignContent:
         // FIXME: Per CSS alignment, this property should accept an optional <overflow-position>. We should share this parsing code with 'justify-self'.
-         if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch)
-             return true;
-         break;
+        return valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch;
     case CSSPropertyAlignItems:
         // FIXME: Per CSS alignment, this property should accept the same arguments as 'justify-self' so we should share its parsing code.
-        if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch)
-            return true;
-        break;
+        return valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch;
     case CSSPropertyAlignSelf:
         // FIXME: Per CSS alignment, this property should accept the same arguments as 'justify-self' so we should share its parsing code.
-        if (valueID == CSSValueAuto || valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch;
     case CSSPropertyFlexDirection:
-        if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse)
-            return true;
-        break;
+        return valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse;
     case CSSPropertyFlexWrap:
-        if (valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse)
-             return true;
-        break;
+        return valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse;
     case CSSPropertyJustifyContent:
         // FIXME: Per CSS alignment, this property should accept an optional <overflow-position>. We should share this parsing code with 'justify-self'.
-        if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround)
-            return true;
-        break;
+        return valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround;
     case CSSPropertyFontKerning:
-        if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone;
     case CSSPropertyWebkitFontSmoothing:
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased)
-            return true;
-        break;
-    case CSSPropertyGridAutoFlow:
-        if (valueID == CSSValueNone || valueID == CSSValueRow || valueID == CSSValueColumn)
-            return RuntimeEnabledFeatures::cssGridLayoutEnabled();
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased;
     case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
-        if (valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace;
     case CSSPropertyWebkitMarginAfterCollapse:
     case CSSPropertyWebkitMarginBeforeCollapse:
     case CSSPropertyWebkitMarginBottomCollapse:
     case CSSPropertyWebkitMarginTopCollapse:
-        if (valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard)
-            return true;
-        break;
+        return valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard;
     case CSSPropertyInternalMarqueeDirection:
-        if (valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
-            || valueID == CSSValueUp || valueID == CSSValueAuto)
-            return true;
-        break;
+        return valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
+            || valueID == CSSValueUp || valueID == CSSValueAuto;
     case CSSPropertyInternalMarqueeStyle:
-        if (valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate)
-            return true;
-        break;
+        return valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate;
     case CSSPropertyWebkitPrintColorAdjust:
-        if (valueID == CSSValueExact || valueID == CSSValueEconomy)
-            return true;
-        break;
+        return valueID == CSSValueExact || valueID == CSSValueEconomy;
     case CSSPropertyWebkitRtlOrdering:
-        if (valueID == CSSValueLogical || valueID == CSSValueVisual)
-            return true;
-        break;
-
+        return valueID == CSSValueLogical || valueID == CSSValueVisual;
     case CSSPropertyWebkitRubyPosition:
-        if (valueID == CSSValueBefore || valueID == CSSValueAfter)
-            return true;
-        break;
-
+        return valueID == CSSValueBefore || valueID == CSSValueAfter;
     case CSSPropertyWebkitTextCombine:
-        if (valueID == CSSValueNone || valueID == CSSValueHorizontal)
-            return true;
-        break;
+        return valueID == CSSValueNone || valueID == CSSValueHorizontal;
     case CSSPropertyWebkitTextEmphasisPosition:
-        if (valueID == CSSValueOver || valueID == CSSValueUnder)
-            return true;
-        break;
-    case CSSPropertyWebkitTextSecurity:
-        // disc | circle | square | none | inherit
-        if (valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone)
-            return true;
-        break;
+        return valueID == CSSValueOver || valueID == CSSValueUnder;
+    case CSSPropertyWebkitTextSecurity: // disc | circle | square | none
+        return valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone;
     case CSSPropertyTransformStyle:
     case CSSPropertyWebkitTransformStyle:
-        if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d)
-            return true;
-        break;
+        return valueID == CSSValueFlat || valueID == CSSValuePreserve3d;
     case CSSPropertyWebkitUserDrag: // auto | none | element
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement;
     case CSSPropertyWebkitUserModify: // read-only | read-write
-        if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly)
-            return true;
-        break;
+        return valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly;
     case CSSPropertyWebkitUserSelect: // auto | none | text | all
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText || valueID == CSSValueAll)
-            return true;
-        break;
-    case CSSPropertyWebkitWrapFlow:
-        if (!RuntimeEnabledFeatures::cssExclusionsEnabled())
-            return false;
-        if (valueID == CSSValueAuto || valueID == CSSValueBoth || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueMaximum || valueID == CSSValueClear)
-            return true;
-        break;
-    case CSSPropertyWebkitWrapThrough:
-        if (!RuntimeEnabledFeatures::cssExclusionsEnabled())
-            return false;
-        if (valueID == CSSValueWrap || valueID == CSSValueNone)
-            return true;
-        break;
+        return valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText || valueID == CSSValueAll;
     case CSSPropertyWebkitWritingMode:
-        if (valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt)
-            return true;
-        break;
-    case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit
-        if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap)
-            return true;
-        break;
+        return valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt;
+    case CSSPropertyWhiteSpace: // normal | pre | nowrap
+        return valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap;
     case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension)
-        if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord)
-            return true;
-        break;
+        return valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord;
     default:
         ASSERT_NOT_REACHED();
         return false;
@@ -740,6 +566,8 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     switch (propertyId) {
     case CSSPropertyMixBlendMode:
     case CSSPropertyIsolation:
+    case CSSPropertyBackgroundRepeatX:
+    case CSSPropertyBackgroundRepeatY:
     case CSSPropertyBorderBottomStyle:
     case CSSPropertyBorderCollapse:
     case CSSPropertyBorderLeftStyle:
@@ -753,6 +581,7 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     case CSSPropertyEmptyCells:
     case CSSPropertyFloat:
     case CSSPropertyFontStyle:
+    case CSSPropertyFontStretch:
     case CSSPropertyImageRendering:
     case CSSPropertyListStylePosition:
     case CSSPropertyListStyleType:
@@ -772,18 +601,13 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     case CSSPropertyTableLayout:
     case CSSPropertyTextAlignLast:
     case CSSPropertyTextJustify:
-    case CSSPropertyTextLineThroughMode:
-    case CSSPropertyTextLineThroughStyle:
     case CSSPropertyTextOverflow:
-    case CSSPropertyTextOverlineMode:
-    case CSSPropertyTextOverlineStyle:
     case CSSPropertyTextRendering:
     case CSSPropertyTextTransform:
-    case CSSPropertyTextUnderlineMode:
-    case CSSPropertyTextUnderlineStyle:
     case CSSPropertyTouchActionDelay:
     case CSSPropertyVisibility:
     case CSSPropertyWebkitAppearance:
+    case CSSPropertyBackfaceVisibility:
     case CSSPropertyWebkitBackfaceVisibility:
     case CSSPropertyWebkitBorderAfterStyle:
     case CSSPropertyWebkitBorderBeforeStyle:
@@ -808,7 +632,6 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     case CSSPropertyJustifyContent:
     case CSSPropertyFontKerning:
     case CSSPropertyWebkitFontSmoothing:
-    case CSSPropertyGridAutoFlow:
     case CSSPropertyWebkitLineBreak:
     case CSSPropertyWebkitMarginAfterCollapse:
     case CSSPropertyWebkitMarginBeforeCollapse:
@@ -827,8 +650,6 @@ bool isKeywordPropertyID(CSSPropertyID propertyId)
     case CSSPropertyWebkitUserDrag:
     case CSSPropertyWebkitUserModify:
     case CSSPropertyWebkitUserSelect:
-    case CSSPropertyWebkitWrapFlow:
-    case CSSPropertyWebkitWrapThrough:
     case CSSPropertyWebkitWritingMode:
     case CSSPropertyWhiteSpace:
     case CSSPropertyWordBreak:
@@ -886,7 +707,7 @@ static bool parseTransformTranslateArguments(CharType*& pos, CharType* end, unsi
         if (delimiter == kNotFound)
             return false;
         unsigned argumentLength = static_cast<unsigned>(delimiter);
-        CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
+        CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::CSS_NUMBER;
         double number;
         if (!parseSimpleLength(pos, argumentLength, unit, number))
             return false;
@@ -900,60 +721,117 @@ static bool parseTransformTranslateArguments(CharType*& pos, CharType* end, unsi
 }
 
 template <typename CharType>
-static PassRefPtrWillBeRawPtr<CSSTransformValue> parseTranslateTransformValue(CharType*& pos, CharType* end)
+static bool parseTransformNumberArguments(CharType*& pos, CharType* end, unsigned expectedCount, CSSTransformValue* transformValue)
+{
+    while (expectedCount) {
+        size_t delimiter = WTF::find(pos, end - pos, expectedCount == 1 ? ')' : ',');
+        if (delimiter == kNotFound)
+            return false;
+        unsigned argumentLength = static_cast<unsigned>(delimiter);
+        bool ok;
+        double number = charactersToDouble(pos, argumentLength, &ok);
+        if (!ok)
+            return false;
+        transformValue->append(cssValuePool().createValue(number, CSSPrimitiveValue::CSS_NUMBER));
+        pos += argumentLength + 1;
+        --expectedCount;
+    }
+    return true;
+}
+
+template <typename CharType>
+static PassRefPtrWillBeRawPtr<CSSTransformValue> parseSimpleTransformValue(CharType*& pos, CharType* end)
 {
     static const int shortestValidTransformStringLength = 12;
 
     if (end - pos < shortestValidTransformStringLength)
         return nullptr;
 
-    if ((pos[0] != 't' && pos[0] != 'T')
-        || (pos[1] != 'r' && pos[1] != 'R')
-        || (pos[2] != 'a' && pos[2] != 'A')
-        || (pos[3] != 'n' && pos[3] != 'N')
-        || (pos[4] != 's' && pos[4] != 'S')
-        || (pos[5] != 'l' && pos[5] != 'L')
-        || (pos[6] != 'a' && pos[6] != 'A')
-        || (pos[7] != 't' && pos[7] != 'T')
-        || (pos[8] != 'e' && pos[8] != 'E'))
-        return nullptr;
+    const bool isTranslate = toASCIILower(pos[0]) == 't'
+        && toASCIILower(pos[1]) == 'r'
+        && toASCIILower(pos[2]) == 'a'
+        && toASCIILower(pos[3]) == 'n'
+        && toASCIILower(pos[4]) == 's'
+        && toASCIILower(pos[5]) == 'l'
+        && toASCIILower(pos[6]) == 'a'
+        && toASCIILower(pos[7]) == 't'
+        && toASCIILower(pos[8]) == 'e';
+
+    if (isTranslate) {
+        CSSTransformValue::TransformOperationType transformType;
+        unsigned expectedArgumentCount = 1;
+        unsigned argumentStart = 11;
+        CharType c9 = toASCIILower(pos[9]);
+        if (c9 == 'x' && pos[10] == '(') {
+            transformType = CSSTransformValue::TranslateXTransformOperation;
+        } else if (c9 == 'y' && pos[10] == '(') {
+            transformType = CSSTransformValue::TranslateYTransformOperation;
+        } else if (c9 == 'z' && pos[10] == '(') {
+            transformType = CSSTransformValue::TranslateZTransformOperation;
+        } else if (c9 == '(') {
+            transformType = CSSTransformValue::TranslateTransformOperation;
+            expectedArgumentCount = 2;
+            argumentStart = 10;
+        } else if (c9 == '3' && toASCIILower(pos[10]) == 'd' && pos[11] == '(') {
+            transformType = CSSTransformValue::Translate3DTransformOperation;
+            expectedArgumentCount = 3;
+            argumentStart = 12;
+        } else {
+            return nullptr;
+        }
+        pos += argumentStart;
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
+        if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
+            return nullptr;
+        return transformValue.release();
+    }
 
-    CSSTransformValue::TransformOperationType transformType;
-    unsigned expectedArgumentCount = 1;
-    unsigned argumentStart = 11;
-    if ((pos[9] == 'x' || pos[9] == 'X') && pos[10] == '(') {
-        transformType = CSSTransformValue::TranslateXTransformOperation;
-    } else if ((pos[9] == 'y' || pos[9] == 'Y') && pos[10] == '(') {
-        transformType = CSSTransformValue::TranslateYTransformOperation;
-    } else if ((pos[9] == 'z' || pos[9] == 'Z') && pos[10] == '(') {
-        transformType = CSSTransformValue::TranslateZTransformOperation;
-    } else if (pos[9] == '(') {
-        transformType = CSSTransformValue::TranslateTransformOperation;
-        expectedArgumentCount = 2;
-        argumentStart = 10;
-    } else if (pos[9] == '3' && (pos[10] == 'd' || pos[10] == 'D') && pos[11] == '(') {
-        transformType = CSSTransformValue::Translate3DTransformOperation;
-        expectedArgumentCount = 3;
-        argumentStart = 12;
-    } else {
-        return nullptr;
+    const bool isMatrix3d = toASCIILower(pos[0]) == 'm'
+        && toASCIILower(pos[1]) == 'a'
+        && toASCIILower(pos[2]) == 't'
+        && toASCIILower(pos[3]) == 'r'
+        && toASCIILower(pos[4]) == 'i'
+        && toASCIILower(pos[5]) == 'x'
+        && pos[6] == '3'
+        && toASCIILower(pos[7]) == 'd'
+        && pos[8] == '(';
+
+    if (isMatrix3d) {
+        pos += 9;
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
+        if (!parseTransformNumberArguments(pos, end, 16, transformValue.get()))
+            return nullptr;
+        return transformValue.release();
     }
-    pos += argumentStart;
 
-    RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
-    if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
-        return nullptr;
-    return transformValue.release();
+    const bool isScale3d = toASCIILower(pos[0]) == 's'
+        && toASCIILower(pos[1]) == 'c'
+        && toASCIILower(pos[2]) == 'a'
+        && toASCIILower(pos[3]) == 'l'
+        && toASCIILower(pos[4]) == 'e'
+        && pos[5] == '3'
+        && toASCIILower(pos[6]) == 'd'
+        && pos[7] == '(';
+
+    if (isScale3d) {
+        pos += 8;
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(CSSTransformValue::Scale3DTransformOperation);
+        if (!parseTransformNumberArguments(pos, end, 3, transformValue.get()))
+            return nullptr;
+        return transformValue.release();
+    }
+
+    return nullptr;
 }
 
 template <typename CharType>
-static PassRefPtrWillBeRawPtr<CSSValueList> parseTranslateTransformList(CharType*& pos, CharType* end)
+static PassRefPtrWillBeRawPtr<CSSValueList> parseSimpleTransformList(CharType*& pos, CharType* end)
 {
     RefPtrWillBeRawPtr<CSSValueList> transformList = nullptr;
     while (pos < end) {
         while (pos < end && isCSSSpace(*pos))
             ++pos;
-        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = parseTranslateTransformValue(pos, end);
+        RefPtrWillBeRawPtr<CSSTransformValue> transformValue = parseSimpleTransformValue(pos, end);
         if (!transformValue)
             return nullptr;
         if (!transformList)
@@ -967,9 +845,9 @@ static PassRefPtrWillBeRawPtr<CSSValueList> parseTranslateTransformList(CharType
     return transformList.release();
 }
 
-static bool parseTranslateTransform(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
+static bool parseSimpleTransform(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
 {
-    if (propertyID != CSSPropertyWebkitTransform)
+    if (propertyID != CSSPropertyTransform && propertyID != CSSPropertyWebkitTransform)
         return false;
     if (string.isEmpty())
         return false;
@@ -977,17 +855,17 @@ static bool parseTranslateTransform(MutableStylePropertySet* properties, CSSProp
     if (string.is8Bit()) {
         const LChar* pos = string.characters8();
         const LChar* end = pos + string.length();
-        transformList = parseTranslateTransformList(pos, end);
+        transformList = parseSimpleTransformList(pos, end);
         if (!transformList)
             return false;
     } else {
         const UChar* pos = string.characters16();
         const UChar* end = pos + string.length();
-        transformList = parseTranslateTransformList(pos, end);
+        transformList = parseSimpleTransformList(pos, end);
         if (!transformList)
             return false;
     }
-    properties->addParsedProperty(CSSProperty(CSSPropertyWebkitTransform, transformList.release(), important));
+    properties->addParsedProperty(CSSProperty(propertyID, transformList.release(), important));
     return true;
 }
 
@@ -1011,10 +889,16 @@ PassRefPtrWillBeRawPtr<CSSValue> BisonCSSParser::parseAnimationTimingFunctionVal
     if (string.isEmpty())
         return nullptr;
     RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
-    if (!parseValue(style.get(), CSSPropertyAnimationTimingFunction, string, false, HTMLStandardMode, 0))
+    if (!parseValue(style.get(), CSSPropertyTransitionTimingFunction, string, false, HTMLStandardMode, 0))
         return nullptr;
 
-    return style->getPropertyCSSValue(CSSPropertyAnimationTimingFunction);
+    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(CSSPropertyTransitionTimingFunction);
+    if (!value || value->isInitialValue() || value->isInheritedValue())
+        return nullptr;
+    CSSValueList* valueList = toCSSValueList(value.get());
+    if (valueList->length() > 1)
+        return nullptr;
+    return valueList->item(0);
 }
 
 bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, const Document& document)
@@ -1050,7 +934,7 @@ bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropert
 
     if (parseKeywordValue(declaration, propertyID, string, important, context))
         return true;
-    if (parseTranslateTransform(declaration, propertyID, string, important))
+    if (parseSimpleTransform(declaration, propertyID, string, important))
         return true;
 
     BisonCSSParser parser(context);
@@ -1080,8 +964,6 @@ bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropert
     m_id = CSSPropertyInvalid;
 
     bool ok = false;
-    if (m_hasFontFaceOnlyValues)
-        deleteFontFaceOnlyValues();
     if (!m_parsedProperties.isEmpty()) {
         ok = true;
         declaration->addParsedProperties(m_parsedProperties);
@@ -1117,6 +999,16 @@ bool BisonCSSParser::parseColor(RGBA32& color, const String& string, bool strict
     return true;
 }
 
+StyleColor BisonCSSParser::colorFromRGBColorString(const String& colorString)
+{
+    // FIXME: Rework css parser so it is more SVG aware.
+    RGBA32 color;
+    if (parseColor(color, colorString.stripWhiteSpace()))
+        return StyleColor(color);
+    // FIXME: This branch catches the string currentColor, but we should error if we have an illegal color value.
+    return StyleColor::currentColor();
+}
+
 bool BisonCSSParser::parseColor(const String& string)
 {
     setupParser("@-internal-decls color:", string, "");
@@ -1150,7 +1042,7 @@ void BisonCSSParser::parseSelector(const String& string, CSSSelectorList& select
     m_selectorListForParseSelector = 0;
 }
 
-PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseInlineStyleDeclaration(const String& string, Element* element)
+PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> BisonCSSParser::parseInlineStyleDeclaration(const String& string, Element* element)
 {
     Document& document = element->document();
     CSSParserContext context = CSSParserContext(document.elementSheet().contents()->parserContext(), UseCounter::getFrom(&document));
@@ -1158,7 +1050,7 @@ PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseInlineStyleDeclaratio
     return BisonCSSParser(context).parseDeclaration(string, document.elementSheet().contents());
 }
 
-PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet)
+PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> BisonCSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet)
 {
     setStyleSheet(contextStyleSheet);
 
@@ -1166,10 +1058,7 @@ PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseDeclaration(const Str
     cssyyparse(this);
     m_rule = nullptr;
 
-    if (m_hasFontFaceOnlyValues)
-        deleteFontFaceOnlyValues();
-
-    RefPtr<ImmutableStylePropertySet> style = createStylePropertySet();
+    RefPtrWillBeRawPtr<ImmutableStylePropertySet> style = createStylePropertySet();
     clearProperties();
     return style.release();
 }
@@ -1196,8 +1085,6 @@ bool BisonCSSParser::parseDeclaration(MutableStylePropertySet* declaration, cons
     m_rule = nullptr;
 
     bool ok = false;
-    if (m_hasFontFaceOnlyValues)
-        deleteFontFaceOnlyValues();
     if (!m_parsedProperties.isEmpty()) {
         ok = true;
         declaration->addParsedProperties(m_parsedProperties);
@@ -1223,6 +1110,17 @@ PassRefPtrWillBeRawPtr<MediaQuerySet> BisonCSSParser::parseMediaQueryList(const
     return m_mediaList.release();
 }
 
+bool BisonCSSParser::parseAttributeMatchType(CSSSelector::AttributeMatchType& matchType, const String& string)
+{
+    if (!RuntimeEnabledFeatures::cssAttributeCaseSensitivityEnabled() && !isUASheetBehavior(m_context.mode()))
+        return false;
+    if (string == "i") {
+        matchType = CSSSelector::CaseInsensitive;
+        return true;
+    }
+    return false;
+}
+
 static inline void filterProperties(bool important, const WillBeHeapVector<CSSProperty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties)
 {
     // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
@@ -1238,7 +1136,7 @@ static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr
     }
 }
 
-PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::createStylePropertySet()
+PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> BisonCSSParser::createStylePropertySet()
 {
     BitArray<numCSSProperties> seenProperties;
     size_t unusedEntries = m_parsedProperties.size();
@@ -1266,7 +1164,6 @@ void BisonCSSParser::clearProperties()
 {
     m_parsedProperties.clear();
     m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
-    m_hasFontFaceOnlyValues = false;
 }
 
 void BisonCSSParser::setCurrentProperty(CSSPropertyID propId)
@@ -1276,7 +1173,7 @@ void BisonCSSParser::setCurrentProperty(CSSPropertyID propId)
 
 bool BisonCSSParser::parseValue(CSSPropertyID propId, bool important)
 {
-    CSSPropertyParser parser(m_valueList, m_context, m_inViewport, m_important, m_parsedProperties, m_hasFontFaceOnlyValues);
+    CSSPropertyParser parser(m_valueList, m_context, m_inViewport, m_important, m_parsedProperties, m_ruleHeaderType);
     return parser.parseValue(propId, important);
 }
 
@@ -1416,14 +1313,14 @@ private:
     CSSPropertyParser::Units m_unit;
 };
 
-PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform()
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform(CSSPropertyID propId)
 {
     if (!m_valueList)
         return nullptr;
 
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
+        RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(propId, value);
         if (!parsedTransformValue)
             return nullptr;
 
@@ -1433,7 +1330,7 @@ PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform()
     return list.release();
 }
 
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSParserValue *value)
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSPropertyID propId, CSSParserValue *value)
 {
     if (value->unit != CSSParserValue::Function || !value->function)
         return nullptr;
@@ -1477,7 +1374,8 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSParse
                 return nullptr;
         } else if (info.type() == CSSTransformValue::PerspectiveTransformOperation && !argNumber) {
             // 1st param of perspective() must be a non-negative number (deprecated) or length.
-            if (!validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+            if ((propId == CSSPropertyWebkitTransform && !validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+                || (propId == CSSPropertyTransform && !validUnit(a, FLength | FNonNeg, HTMLStandardMode)))
                 return nullptr;
         } else if (!validUnit(a, unit, HTMLStandardMode)) {
             return nullptr;
@@ -1693,7 +1591,7 @@ StyleRuleBase* BisonCSSParser::createSupportsRule(bool conditionIsSupported, Rul
 {
     m_allowImportRules = m_allowNamespaceDeclarations = false;
 
-    RefPtr<CSSRuleSourceData> data = popSupportsRuleData();
+    RefPtrWillBeRawPtr<CSSRuleSourceData> data = popSupportsRuleData();
     RefPtrWillBeRawPtr<StyleRuleSupports> rule = nullptr;
     String conditionText;
     unsigned conditionOffset = data->ruleHeaderRange.start + 9;
@@ -1720,9 +1618,9 @@ StyleRuleBase* BisonCSSParser::createSupportsRule(bool conditionIsSupported, Rul
 void BisonCSSParser::markSupportsRuleHeaderStart()
 {
     if (!m_supportsRuleDataStack)
-        m_supportsRuleDataStack = adoptPtr(new RuleSourceDataList());
+        m_supportsRuleDataStack = adoptPtrWillBeNoop(new RuleSourceDataList());
 
-    RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
+    RefPtrWillBeRawPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
     data->ruleHeaderRange.start = m_tokenizer.tokenStartOffset();
     m_supportsRuleDataStack->append(data);
 }
@@ -1737,10 +1635,10 @@ void BisonCSSParser::markSupportsRuleHeaderEnd()
         m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<UChar>() - m_tokenizer.m_dataStart16.get();
 }
 
-PassRefPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
 {
     ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
-    RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
+    RefPtrWillBeRawPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
     m_supportsRuleDataStack->removeLast();
     return data.release();
 }
@@ -1782,15 +1680,16 @@ ALWAYS_INLINE static void makeLower(const CharacterType* input, CharacterType* o
     }
 }
 
-void BisonCSSParser::tokenToLowerCase(const CSSParserString& token)
+void BisonCSSParser::tokenToLowerCase(CSSParserString& token)
 {
+    // Since it's our internal token, we know that we created it out
+    // of our writable work buffers. Therefore the const_cast is just
+    // ugly and not a potential crash.
     size_t length = token.length();
-    if (m_tokenizer.is8BitSource()) {
-        size_t offset = token.characters8() - m_tokenizer.m_dataStart8.get();
-        makeLower(token.characters8(), m_tokenizer.m_dataStart8.get() + offset, length);
+    if (token.is8Bit()) {
+        makeLower(token.characters8(), const_cast<LChar*>(token.characters8()), length);
     } else {
-        size_t offset = token.characters16() - m_tokenizer.m_dataStart16.get();
-        makeLower(token.characters16(), m_tokenizer.m_dataStart16.get() + offset, length);
+        makeLower(token.characters16(), const_cast<UChar*>(token.characters16()), length);
     }
 }
 
@@ -1834,8 +1733,8 @@ void BisonCSSParser::logError(const String& message, const CSSParserLocation& lo
     } else {
         lineNumberInStyleSheet = location.lineNumber;
     }
-    PageConsole& console = m_styleSheet->singleOwnerDocument()->frameHost()->console();
-    console.addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleSheet->baseURL().string(), lineNumberInStyleSheet + m_startPosition.m_line.zeroBasedInt() + 1, columnNumber + 1);
+    FrameConsole& console = m_styleSheet->singleOwnerDocument()->frame()->console();
+    console.addMessage(ConsoleMessage::create(CSSMessageSource, WarningMessageLevel, message, m_styleSheet->baseURL().string(), lineNumberInStyleSheet + m_startPosition.m_line.zeroBasedInt() + 1, columnNumber + 1));
 }
 
 StyleRuleKeyframes* BisonCSSParser::createKeyframesRule(const String& name, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > popKeyframes, bool isPrefixed)
@@ -1852,6 +1751,43 @@ StyleRuleKeyframes* BisonCSSParser::createKeyframesRule(const String& name, Pass
     return rulePtr;
 }
 
+static void recordSelectorStats(const CSSParserContext& context, const CSSSelectorList& selectorList)
+{
+    if (!context.useCounter())
+        return;
+
+    for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
+        for (const CSSSelector* current = selector; current ; current = current->tagHistory()) {
+            UseCounter::Feature feature = UseCounter::NumberOfFeatures;
+            switch (current->pseudoType()) {
+            case CSSSelector::PseudoUnresolved:
+                feature = UseCounter::CSSSelectorPseudoUnresolved;
+                break;
+            case CSSSelector::PseudoShadow:
+                feature = UseCounter::CSSSelectorPseudoShadow;
+                break;
+            case CSSSelector::PseudoContent:
+                feature = UseCounter::CSSSelectorPseudoContent;
+                break;
+            case CSSSelector::PseudoHost:
+                feature = UseCounter::CSSSelectorPseudoHost;
+                break;
+            case CSSSelector::PseudoHostContext:
+                feature = UseCounter::CSSSelectorPseudoHostContext;
+                break;
+            default:
+                break;
+            }
+            if (feature != UseCounter::NumberOfFeatures)
+                context.useCounter()->count(feature);
+            if (current->relation() == CSSSelector::ShadowDeep)
+                context.useCounter()->count(UseCounter::CSSDeepCombinator);
+            if (current->selectorList())
+                recordSelectorStats(context, *current->selectorList());
+        }
+    }
+}
+
 StyleRuleBase* BisonCSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors)
 {
     StyleRule* result = 0;
@@ -1859,11 +1795,10 @@ StyleRuleBase* BisonCSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector>
         m_allowImportRules = m_allowNamespaceDeclarations = false;
         RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create();
         rule->parserAdoptSelectorVector(*selectors);
-        if (m_hasFontFaceOnlyValues)
-            deleteFontFaceOnlyValues();
         rule->setProperties(createStylePropertySet());
         result = rule.get();
         m_parsedRules.append(rule.release());
+        recordSelectorStats(m_context, result->selectorList());
     }
     clearProperties();
     return result;
@@ -2054,19 +1989,6 @@ void BisonCSSParser::endDeclarationsForMarginBox()
     m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
 }
 
-void BisonCSSParser::deleteFontFaceOnlyValues()
-{
-    ASSERT(m_hasFontFaceOnlyValues);
-    for (unsigned i = 0; i < m_parsedProperties.size();) {
-        CSSProperty& property = m_parsedProperties[i];
-        if (property.id() == CSSPropertyFontVariant && property.value()->isValueList()) {
-            m_parsedProperties.remove(i);
-            continue;
-        }
-        ++i;
-    }
-}
-
 StyleKeyframe* BisonCSSParser::createKeyframe(CSSParserValueList* keys)
 {
     OwnPtr<Vector<double> > keyVector = StyleKeyframe::createKeyList(keys);