Merge from Chromium at DEPS revision 228962

This commit was generated by merge_to_master.py.

Change-Id: Ifa868e6d63fe87d2338d9388aa5ea81f746d485f
diff --git a/Source/core/css/BasicShapeFunctions.cpp b/Source/core/css/BasicShapeFunctions.cpp
index e80d033..cc9f57b 100644
--- a/Source/core/css/BasicShapeFunctions.cpp
+++ b/Source/core/css/BasicShapeFunctions.cpp
@@ -35,23 +35,26 @@
 #include "core/css/CSSValuePool.h"
 #include "core/css/resolver/StyleResolverState.h"
 #include "core/rendering/style/BasicShapes.h"
+#include "core/rendering/style/RenderStyle.h"
 
 namespace WebCore {
 
-PassRefPtr<CSSValue> valueForBasicShape(const BasicShape* basicShape)
+PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle* style, const BasicShape* basicShape)
 {
+    CSSValuePool& pool = cssValuePool();
+
     RefPtr<CSSBasicShape> basicShapeValue;
     switch (basicShape->type()) {
     case BasicShape::BasicShapeRectangleType: {
         const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
         RefPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
 
-        rectangleValue->setX(cssValuePool().createValue(rectangle->x()));
-        rectangleValue->setY(cssValuePool().createValue(rectangle->y()));
-        rectangleValue->setWidth(cssValuePool().createValue(rectangle->width()));
-        rectangleValue->setHeight(cssValuePool().createValue(rectangle->height()));
-        rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
-        rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));
+        rectangleValue->setX(pool.createValue(rectangle->x(), style));
+        rectangleValue->setY(pool.createValue(rectangle->y(), style));
+        rectangleValue->setWidth(pool.createValue(rectangle->width(), style));
+        rectangleValue->setHeight(pool.createValue(rectangle->height(), style));
+        rectangleValue->setRadiusX(pool.createValue(rectangle->cornerRadiusX(), style));
+        rectangleValue->setRadiusY(pool.createValue(rectangle->cornerRadiusY(), style));
 
         basicShapeValue = rectangleValue.release();
         break;
@@ -60,9 +63,9 @@
         const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
         RefPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
 
-        circleValue->setCenterX(cssValuePool().createValue(circle->centerX()));
-        circleValue->setCenterY(cssValuePool().createValue(circle->centerY()));
-        circleValue->setRadius(cssValuePool().createValue(circle->radius()));
+        circleValue->setCenterX(pool.createValue(circle->centerX(), style));
+        circleValue->setCenterY(pool.createValue(circle->centerY(), style));
+        circleValue->setRadius(pool.createValue(circle->radius(), style));
 
         basicShapeValue = circleValue.release();
         break;
@@ -71,10 +74,10 @@
         const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
         RefPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
 
-        ellipseValue->setCenterX(cssValuePool().createValue(ellipse->centerX()));
-        ellipseValue->setCenterY(cssValuePool().createValue(ellipse->centerY()));
-        ellipseValue->setRadiusX(cssValuePool().createValue(ellipse->radiusX()));
-        ellipseValue->setRadiusY(cssValuePool().createValue(ellipse->radiusY()));
+        ellipseValue->setCenterX(pool.createValue(ellipse->centerX(), style));
+        ellipseValue->setCenterY(pool.createValue(ellipse->centerY(), style));
+        ellipseValue->setRadiusX(pool.createValue(ellipse->radiusX(), style));
+        ellipseValue->setRadiusY(pool.createValue(ellipse->radiusY(), style));
 
         basicShapeValue = ellipseValue.release();
         break;
@@ -86,7 +89,7 @@
         polygonValue->setWindRule(polygon->windRule());
         const Vector<Length>& values = polygon->values();
         for (unsigned i = 0; i < values.size(); i += 2)
-            polygonValue->appendPoint(cssValuePool().createValue(values.at(i)), cssValuePool().createValue(values.at(i + 1)));
+            polygonValue->appendPoint(pool.createValue(values.at(i), style), pool.createValue(values.at(i + 1), style));
 
         basicShapeValue = polygonValue.release();
         break;
@@ -108,7 +111,7 @@
     default:
         break;
     }
-    return cssValuePool().createValue<PassRefPtr<CSSBasicShape> >(basicShapeValue.release());
+    return pool.createValue(basicShapeValue.release());
 }
 
 static Length convertToLength(const StyleResolverState& state, CSSPrimitiveValue* value)
diff --git a/Source/core/css/BasicShapeFunctions.h b/Source/core/css/BasicShapeFunctions.h
index 4b3d39f..c0cd68a 100644
--- a/Source/core/css/BasicShapeFunctions.h
+++ b/Source/core/css/BasicShapeFunctions.h
@@ -38,8 +38,9 @@
 class CSSBasicShape;
 class CSSValue;
 class StyleResolverState;
+class RenderStyle;
 
-PassRefPtr<CSSValue> valueForBasicShape(const BasicShape*);
+PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle*, const BasicShape*);
 PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState&, const CSSBasicShape*);
 
 }
diff --git a/Source/core/css/CSSArrayFunctionValue.h b/Source/core/css/CSSArrayFunctionValue.h
index 9325207..3de65c7 100644
--- a/Source/core/css/CSSArrayFunctionValue.h
+++ b/Source/core/css/CSSArrayFunctionValue.h
@@ -53,6 +53,8 @@
     explicit CSSArrayFunctionValue(const CSSArrayFunctionValue& cloneFrom);
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(ArrayFunctionValue);
+
 } // namespace WebCore
 
 
diff --git a/Source/core/css/CSSCalculationValue.cpp b/Source/core/css/CSSCalculationValue.cpp
index f2eaae3..493500b 100644
--- a/Source/core/css/CSSCalculationValue.cpp
+++ b/Source/core/css/CSSCalculationValue.cpp
@@ -230,7 +230,7 @@
         case CalcNumber:
             return adoptPtr(new CalcExpressionNumber(m_value->getFloatValue()));
         case CalcLength:
-            return adoptPtr(new CalcExpressionNumber(m_value->computeLength<float>(style, rootStyle, zoom)));
+            return adoptPtr(new CalcExpressionLength(Length(m_value->computeLength<float>(style, rootStyle, zoom), WebCore::Fixed)));
         case CalcPercent:
         case CalcPercentLength: {
             CSSPrimitiveValue* primitiveValue = m_value.get();
@@ -611,8 +611,7 @@
         if (!value || !value->isPrimitiveValue())
             return false;
 
-        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
-        result->value = CSSCalcPrimitiveValue::create(primitiveValue, parserValue->isInt);
+        result->value = CSSCalcPrimitiveValue::create(toCSSPrimitiveValue(value.get()), parserValue->isInt);
 
         ++*index;
         return true;
@@ -707,7 +706,7 @@
     return CSSCalcBinaryOperation::create(leftSide, rightSide, op);
 }
 
-PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const CalcExpressionNode* node, const RenderStyle* style)
+PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const CalcExpressionNode* node, float zoom)
 {
     switch (node->type()) {
     case CalcExpressionNodeNumber: {
@@ -715,10 +714,10 @@
         return createExpressionNode(CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER), value == trunc(value));
     }
     case CalcExpressionNodeLength:
-        return createExpressionNode(toCalcExpressionLength(node)->length(), style);
+        return createExpressionNode(toCalcExpressionLength(node)->length(), zoom);
     case CalcExpressionNodeBinaryOperation: {
         const CalcExpressionBinaryOperation* binaryNode = toCalcExpressionBinaryOperation(node);
-        return createExpressionNode(createExpressionNode(binaryNode->leftSide(), style), createExpressionNode(binaryNode->rightSide(), style), binaryNode->getOperator());
+        return createExpressionNode(createExpressionNode(binaryNode->leftSide(), zoom), createExpressionNode(binaryNode->rightSide(), zoom), binaryNode->getOperator());
     }
     case CalcExpressionNodeBlendLength: {
         // FIXME(crbug.com/269320): Create a CSSCalcExpressionNode equivalent of CalcExpressionBlendLength.
@@ -727,11 +726,11 @@
         const bool isInteger = !progress || (progress == 1);
         return createExpressionNode(
             createExpressionNode(
-                createExpressionNode(blendNode->from(), style),
+                createExpressionNode(blendNode->from(), zoom),
                 createExpressionNode(CSSPrimitiveValue::create(1 - progress, CSSPrimitiveValue::CSS_NUMBER), isInteger),
                 CalcMultiply),
             createExpressionNode(
-                createExpressionNode(blendNode->to(), style),
+                createExpressionNode(blendNode->to(), zoom),
                 createExpressionNode(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER), isInteger),
                 CalcMultiply),
             CalcAdd);
@@ -744,7 +743,7 @@
     return 0;
 }
 
-PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const Length& length, const RenderStyle* style)
+PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const Length& length, float zoom)
 {
     switch (length.type()) {
     case Percent:
@@ -753,9 +752,9 @@
     case ViewportPercentageMin:
     case ViewportPercentageMax:
     case Fixed:
-        return createExpressionNode(CSSPrimitiveValue::create(length, style), length.value() == trunc(length.value()));
+        return createExpressionNode(CSSPrimitiveValue::create(length, zoom), length.value() == trunc(length.value()));
     case Calculated:
-        return createExpressionNode(length.calculationValue()->expression(), style);
+        return createExpressionNode(length.calculationValue()->expression(), zoom);
     case Auto:
     case Intrinsic:
     case MinIntrinsic:
@@ -773,7 +772,7 @@
     return 0;
 }
 
-PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList, CalculationPermittedValueRange range)
+PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList, ValueRange range)
 {
     CSSCalcExpressionNodeParser parser;
     RefPtr<CSSCalcExpressionNode> expression;
@@ -785,7 +784,7 @@
     return expression ? adoptRef(new CSSCalcValue(expression, range)) : 0;
 }
 
-PassRefPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtr<CSSCalcExpressionNode> expression, CalculationPermittedValueRange range)
+PassRefPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtr<CSSCalcExpressionNode> expression, ValueRange range)
 {
     return adoptRef(new CSSCalcValue(expression, range));
 }
diff --git a/Source/core/css/CSSCalculationValue.h b/Source/core/css/CSSCalculationValue.h
index 6bf1ac7..9d0ee82 100644
--- a/Source/core/css/CSSCalculationValue.h
+++ b/Source/core/css/CSSCalculationValue.h
@@ -93,24 +93,24 @@
 
 class CSSCalcValue : public CSSValue {
 public:
-    static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, CalculationPermittedValueRange);
-    static PassRefPtr<CSSCalcValue> create(PassRefPtr<CSSCalcExpressionNode>, CalculationPermittedValueRange = CalculationRangeAll);
-    static PassRefPtr<CSSCalcValue> create(const CalculationValue* value, const RenderStyle* style) { return adoptRef(new CSSCalcValue(value, style)); }
+    static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, ValueRange);
+    static PassRefPtr<CSSCalcValue> create(PassRefPtr<CSSCalcExpressionNode>, ValueRange = ValueRangeAll);
+    static PassRefPtr<CSSCalcValue> create(const CalculationValue* value, float zoom) { return adoptRef(new CSSCalcValue(value, zoom)); }
 
     static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSPrimitiveValue>, bool isInteger = false);
     static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSCalcExpressionNode>, PassRefPtr<CSSCalcExpressionNode>, CalcOperator);
-    static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const CalcExpressionNode*, const RenderStyle*);
-    static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const Length&, const RenderStyle*);
+    static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const CalcExpressionNode*, float zoom);
+    static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const Length&, float zoom);
 
     PassRefPtr<CalculationValue> toCalcValue(const RenderStyle* style, const RenderStyle* rootStyle, double zoom = 1.0) const
     {
-        return CalculationValue::create(m_expression->toCalcValue(style, rootStyle, zoom), m_nonNegative ? CalculationRangeNonNegative : CalculationRangeAll);
+        return CalculationValue::create(m_expression->toCalcValue(style, rootStyle, zoom), m_nonNegative ? ValueRangeNonNegative : ValueRangeAll);
     }
     CalculationCategory category() const { return m_expression->category(); }
     bool isInt() const { return m_expression->isInteger(); }
     double doubleValue() const;
     bool isNegative() const { return m_expression->doubleValue() < 0; }
-    CalculationPermittedValueRange permittedValueRange() { return m_nonNegative ? CalculationRangeNonNegative : CalculationRangeAll; }
+    ValueRange permittedValueRange() { return m_nonNegative ? ValueRangeNonNegative : ValueRangeAll; }
     double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const;
     CSSCalcExpressionNode* expressionNode() const { return m_expression.get(); }
 
@@ -120,15 +120,15 @@
     bool hasVariableReference() const;
 
 private:
-    CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression, CalculationPermittedValueRange range)
+    CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression, ValueRange range)
         : CSSValue(CalculationClass)
         , m_expression(expression)
-        , m_nonNegative(range == CalculationRangeNonNegative)
+        , m_nonNegative(range == ValueRangeNonNegative)
     {
     }
-    CSSCalcValue(const CalculationValue* value, const RenderStyle* style)
+    CSSCalcValue(const CalculationValue* value, float zoom)
         : CSSValue(CalculationClass)
-        , m_expression(createExpressionNode(value->expression(), style))
+        , m_expression(createExpressionNode(value->expression(), zoom))
         , m_nonNegative(value->isNonNegative())
     {
     }
@@ -139,17 +139,7 @@
     const bool m_nonNegative;
 };
 
-inline CSSCalcValue* toCSSCalcValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isCalculationValue());
-    return static_cast<CSSCalcValue*>(value);
-}
-
-inline const CSSCalcValue* toCSSCalcValue(const CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isCalculationValue());
-    return static_cast<const CSSCalcValue*>(value);
-}
+DEFINE_CSS_VALUE_TYPE_CASTS(CalcValue);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSCalculationValueTest.cpp b/Source/core/css/CSSCalculationValueTest.cpp
index bfd0be4..687a3ea 100644
--- a/Source/core/css/CSSCalculationValueTest.cpp
+++ b/Source/core/css/CSSCalculationValueTest.cpp
@@ -41,6 +41,15 @@
 
 namespace {
 
+void testExpression(PassRefPtr<CSSCalcExpressionNode> expression, const RenderStyle* style)
+{
+    EXPECT_TRUE(
+        expression->equals(
+            *CSSCalcValue::createExpressionNode(
+                expression->toCalcValue(style, style, style->effectiveZoom()).get(),
+                style->effectiveZoom()).get()));
+}
+
 TEST(CSSCalculationValue, CreateExpressionNodeFromLength)
 {
     RefPtr<RenderStyle> style = RenderStyle::create();
@@ -48,7 +57,7 @@
     RefPtr<CSSCalcExpressionNode> actual;
 
     expected = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true);
-    actual = CSSCalcValue::createExpressionNode(Length(10, WebCore::Fixed), style.get());
+    actual = CSSCalcValue::createExpressionNode(Length(10, WebCore::Fixed), style->effectiveZoom());
     EXPECT_TRUE(actual->equals(*expected.get()));
 
     expected = CSSCalcValue::createExpressionNode(
@@ -61,8 +70,8 @@
                 adoptPtr(new CalcExpressionLength(Length(10, WebCore::Fixed))),
                 adoptPtr(new CalcExpressionLength(Length(20, WebCore::Fixed))),
                 CalcAdd)),
-            CalculationRangeAll)),
-        style.get());
+            ValueRangeAll)),
+        style->effectiveZoom());
     EXPECT_TRUE(actual->equals(*expected.get()));
 
     expected = CSSCalcValue::createExpressionNode(
@@ -75,8 +84,8 @@
                 adoptPtr(new CalcExpressionLength(Length(30, WebCore::Fixed))),
                 adoptPtr(new CalcExpressionNumber(40)),
                 CalcMultiply)),
-            CalculationRangeAll)),
-        style.get());
+            ValueRangeAll)),
+        style->effectiveZoom());
     EXPECT_TRUE(actual->equals(*expected.get()));
 
     expected = CSSCalcValue::createExpressionNode(
@@ -92,9 +101,47 @@
     actual = CSSCalcValue::createExpressionNode(
         Length(CalculationValue::create(
             adoptPtr(new CalcExpressionBlendLength(Length(50, WebCore::Fixed), Length(60, WebCore::Fixed), 0.75)),
-            CalculationRangeAll)),
-        style.get());
+            ValueRangeAll)),
+        style->effectiveZoom());
     EXPECT_TRUE(actual->equals(*expected.get()));
 }
 
+TEST(CSSCalculationValue, CreateExpressionNodeFromLengthFromExpressionNode)
+{
+    RefPtr<CSSCalcExpressionNode> expression;
+    RefPtr<RenderStyle> style = RenderStyle::createDefaultStyle();
+    style->setEffectiveZoom(5);
+
+    testExpression(
+        CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true),
+        style.get());
+
+    testExpression(
+        CSSCalcValue::createExpressionNode(
+            CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true),
+            CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(20, CSSPrimitiveValue::CSS_PX), true),
+            CalcAdd),
+        style.get());
+
+    testExpression(
+        CSSCalcValue::createExpressionNode(
+            CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(30, CSSPrimitiveValue::CSS_PX), true),
+            CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(40, CSSPrimitiveValue::CSS_NUMBER), true),
+            CalcMultiply),
+        style.get());
+
+    testExpression(
+        CSSCalcValue::createExpressionNode(
+            CSSCalcValue::createExpressionNode(
+                CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PX), true),
+                CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(0.25, CSSPrimitiveValue::CSS_NUMBER), false),
+                CalcMultiply),
+            CSSCalcValue::createExpressionNode(
+                CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(60, CSSPrimitiveValue::CSS_PX), true),
+                CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(0.75, CSSPrimitiveValue::CSS_NUMBER), false),
+                CalcMultiply),
+            CalcAdd),
+        style.get());
+}
+
 }
diff --git a/Source/core/css/CSSCanvasValue.h b/Source/core/css/CSSCanvasValue.h
index 8283adb..7c1476d 100644
--- a/Source/core/css/CSSCanvasValue.h
+++ b/Source/core/css/CSSCanvasValue.h
@@ -94,6 +94,8 @@
     HTMLCanvasElement* m_element;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(CanvasValue);
+
 } // namespace WebCore
 
 #endif // CSSCanvasValue_h
diff --git a/Source/core/css/CSSComputedStyleDeclaration.cpp b/Source/core/css/CSSComputedStyleDeclaration.cpp
index 37ef541..3975865 100644
--- a/Source/core/css/CSSComputedStyleDeclaration.cpp
+++ b/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -34,6 +34,8 @@
 #include "core/css/CSSAspectRatioValue.h"
 #include "core/css/CSSBorderImage.h"
 #include "core/css/CSSFilterValue.h"
+#include "core/css/CSSFontFeatureValue.h"
+#include "core/css/CSSFontValue.h"
 #include "core/css/CSSFunctionValue.h"
 #include "core/css/CSSGridTemplateValue.h"
 #include "core/css/CSSLineBoxContainValue.h"
@@ -43,23 +45,20 @@
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSReflectValue.h"
 #include "core/css/CSSSelector.h"
+#include "core/css/CSSShadowValue.h"
 #include "core/css/CSSTimingFunctionValue.h"
 #include "core/css/CSSTransformValue.h"
 #include "core/css/CSSValueList.h"
 #include "core/css/CSSValuePool.h"
-#include "core/css/FontFeatureValue.h"
-#include "core/css/FontValue.h"
 #include "core/css/Pair.h"
 #include "core/css/Rect.h"
-#include "core/css/ShadowValue.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/PseudoElement.h"
 #include "core/page/RuntimeCSSEnabled.h"
-#include "core/page/animation/AnimationController.h"
-#include "core/platform/graphics/FontFeatureSettings.h"
+#include "core/frame/animation/AnimationController.h"
 #include "core/rendering/RenderBox.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/style/ContentData.h"
@@ -67,6 +66,7 @@
 #include "core/rendering/style/CursorList.h"
 #include "core/rendering/style/RenderStyle.h"
 #include "core/rendering/style/ShapeValue.h"
+#include "platform/fonts/FontFeatureSettings.h"
 #include "wtf/text/StringBuilder.h"
 
 #include "core/platform/graphics/filters/custom/CustomFilterArrayParameter.h"
@@ -188,6 +188,7 @@
     CSSPropertyTextDecorationLine,
     CSSPropertyTextDecorationStyle,
     CSSPropertyTextDecorationColor,
+    CSSPropertyTextJustify,
 #if ENABLE(CSS3_TEXT)
     CSSPropertyWebkitTextUnderlinePosition,
 #endif // CSS3_TEXT
@@ -341,6 +342,7 @@
     CSSPropertyWebkitWrapFlow,
     CSSPropertyWebkitShapeMargin,
     CSSPropertyWebkitShapePadding,
+    CSSPropertyWebkitShapeImageThreshold,
     CSSPropertyWebkitWrapThrough,
     CSSPropertyBufferedRendering,
     CSSPropertyClipPath,
@@ -559,11 +561,11 @@
     return cssValuePool().createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
 }
 
-static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style)
+static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style)
 {
     if (length.isFixed())
         return zoomAdjustedPixelValue(length.value(), style);
-    return cssValuePool().createValue(length);
+    return cssValuePool().createValue(length, style);
 }
 
 static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style)
@@ -693,13 +695,14 @@
 static PassRefPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle* style, RenderObject* renderer, RenderView* renderView)
 {
     RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
+
     bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width();
-    bool showHorizontalBottomRight = style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width();
-    bool showHorizontalTopRight = style->borderTopRightRadius().width() != style->borderTopLeftRadius().width();
+    bool showHorizontalBottomRight = showHorizontalBottomLeft || (style->borderBottomRightRadius().width() != style->borderTopLeftRadius().width());
+    bool showHorizontalTopRight = showHorizontalBottomRight || (style->borderTopRightRadius().width() != style->borderTopLeftRadius().width());
 
     bool showVerticalBottomLeft = style->borderTopRightRadius().height() != style->borderBottomLeftRadius().height();
-    bool showVerticalBottomRight = (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomLeft;
-    bool showVerticalTopRight = (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomRight;
+    bool showVerticalBottomRight = showVerticalBottomLeft || (style->borderBottomRightRadius().height() != style->borderTopLeftRadius().height());
+    bool showVerticalTopRight = showVerticalBottomRight || (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height());
     bool showVerticalTopLeft = (style->borderTopLeftRadius().width() != style->borderTopLeftRadius().height());
 
     RefPtr<CSSValueList> topLeftRadius = valuesForBorderRadiusCorner(style->borderTopLeftRadius(), style, renderer, renderView);
@@ -1323,7 +1326,7 @@
         RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style);
         RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);
         RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(s->color().rgb());
-        list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
+        list->prepend(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
     }
     return list.release();
 }
@@ -1455,7 +1458,7 @@
         } else if (contentData->isText())
             list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
     }
-    if (!style->regionThread().isNull())
+    if (style->hasFlowFrom())
         list->append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
     return list.release();
 }
@@ -1504,7 +1507,7 @@
         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
         // that here either.
         return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style);
-    return zoomAdjustedPixelValue(valueForLength(length, 0, renderView), style);
+    return zoomAdjustedPixelValue(floatValueForLength(length, 0, renderView), style);
 }
 
 static PassRefPtr<CSSPrimitiveValue> valueForFontSize(RenderStyle* style)
@@ -1907,6 +1910,10 @@
             if (style->hasAutoColumnCount())
                 return cssValuePool().createIdentifierValue(CSSValueAuto);
             return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
+        case CSSPropertyColumnFill:
+            if (RuntimeEnabledFeatures::regionBasedColumnsEnabled())
+                return cssValuePool().createValue(style->columnFill());
+            return 0;
         case CSSPropertyWebkitColumnGap:
             if (style->hasNormalColumnGap())
                 return cssValuePool().createIdentifierValue(CSSValueNormal);
@@ -1996,7 +2003,7 @@
                 return cssValuePool().createIdentifierValue(CSSValueNone);
             return cssValuePool().createValue(style->floating());
         case CSSPropertyFont: {
-            RefPtr<FontValue> computedFont = FontValue::create();
+            RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
             computedFont->style = valueForFontStyle(style.get());
             computedFont->variant = valueForFontVariant(style.get());
             computedFont->weight = valueForFontWeight(style.get());
@@ -2028,7 +2035,7 @@
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (unsigned i = 0; i < featureSettings->size(); ++i) {
                 const FontFeature& feature = featureSettings->at(i);
-                RefPtr<FontFeatureValue> featureValue = FontFeatureValue::create(feature.tag(), feature.value());
+                RefPtr<CSSFontFeatureValue> featureValue = CSSFontFeatureValue::create(feature.tag(), feature.value());
                 list->append(featureValue.release());
             }
             return list.release();
@@ -2260,6 +2267,8 @@
             return valueForTextDecorationStyle(style->textDecorationStyle());
         case CSSPropertyTextDecorationColor:
             return currentColorOrValidColor(style.get(), style->textDecorationColor());
+        case CSSPropertyTextJustify:
+            return cssValuePool().createValue(style->textJustify());
 #if ENABLE(CSS3_TEXT)
         case CSSPropertyWebkitTextUnderlinePosition:
             return cssValuePool().createValue(style->textUnderlinePosition());
@@ -2710,7 +2719,7 @@
         case CSSPropertyWebkitClipPath:
             if (ClipPathOperation* operation = style->clipPath()) {
                 if (operation->getOperationType() == ClipPathOperation::SHAPE)
-                    return valueForBasicShape(static_cast<ShapeClipPathOperation*>(operation)->basicShape());
+                    return valueForBasicShape(style.get(), static_cast<ShapeClipPathOperation*>(operation)->basicShape());
                 if (operation->getOperationType() == ClipPathOperation::REFERENCE) {
                     ReferenceClipPathOperation* referenceOperation = static_cast<ReferenceClipPathOperation*>(operation);
                     return CSSPrimitiveValue::create(referenceOperation->url(), CSSPrimitiveValue::CSS_URI);
@@ -2722,7 +2731,7 @@
                 return cssValuePool().createIdentifierValue(CSSValueNone);
             return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
         case CSSPropertyWebkitFlowFrom:
-            if (style->regionThread().isNull())
+            if (!style->hasFlowFrom())
                 return cssValuePool().createIdentifierValue(CSSValueNone);
             return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
         case CSSPropertyWebkitRegionFragment:
@@ -2733,6 +2742,8 @@
             return cssValuePool().createValue(style->shapeMargin());
         case CSSPropertyWebkitShapePadding:
             return cssValuePool().createValue(style->shapePadding());
+        case CSSPropertyWebkitShapeImageThreshold:
+            return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitShapeInside:
             if (!style->shapeInside())
                 return cssValuePool().createIdentifierValue(CSSValueAuto);
@@ -2744,7 +2755,7 @@
                 return cssValuePool().createIdentifierValue(CSSValueNone);
             }
             ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
-            return valueForBasicShape(style->shapeInside()->shape());
+            return valueForBasicShape(style.get(), style->shapeInside()->shape());
         case CSSPropertyWebkitShapeOutside:
             if (!style->shapeOutside())
                 return cssValuePool().createIdentifierValue(CSSValueAuto);
@@ -2754,7 +2765,7 @@
                 return cssValuePool().createIdentifierValue(CSSValueNone);
             }
             ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
-            return valueForBasicShape(style->shapeOutside()->shape());
+            return valueForBasicShape(style.get(), style->shapeOutside()->shape());
         case CSSPropertyWebkitWrapThrough:
             return cssValuePool().createValue(style->wrapThrough());
         case CSSPropertyWebkitFilter:
@@ -2819,6 +2830,9 @@
         case CSSPropertyBackgroundRepeatX:
         case CSSPropertyBackgroundRepeatY:
             break;
+        case CSSPropertyInternalCallback:
+            // This property is hidden from the web.
+            return 0;
 
         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
         case CSSPropertyWebkitTextEmphasis:
@@ -3169,10 +3183,11 @@
     return it->value;
 }
 
-void CSSComputedStyleDeclaration::setVariableValue(const AtomicString& name, const String&, ExceptionState& es)
+bool CSSComputedStyleDeclaration::setVariableValue(const AtomicString& name, const String&, ExceptionState& es)
 {
     ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
     es.throwDOMException(NoModificationAllowedError, "Failed to set the '" + name + "' property on a computed 'CSSStyleDeclaration': computed styles are read-only.");
+    return false;
 }
 
 bool CSSComputedStyleDeclaration::removeVariable(const AtomicString&)
@@ -3181,10 +3196,40 @@
     return false;
 }
 
-void CSSComputedStyleDeclaration::clearVariables(ExceptionState& es)
+bool CSSComputedStyleDeclaration::clearVariables(ExceptionState& es)
 {
     ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
     es.throwDOMException(NoModificationAllowedError, "Failed to clear variables from a computed 'CSSStyleDeclaration': computed styles are read-only.");
+    return false;
+}
+
+CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::ComputedCSSVariablesIterator(const HashMap<AtomicString, String>* variables)
+    : m_active(variables)
+{
+    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
+    if (m_active) {
+        m_it = variables->begin();
+        m_end = variables->end();
+    }
+}
+
+void CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::advance()
+{
+    ASSERT(m_active);
+    ++m_it;
+    m_active = !atEnd();
+}
+
+AtomicString CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::name() const
+{
+    ASSERT(m_active);
+    return m_it->key;
+}
+
+String CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::value() const
+{
+    ASSERT(m_active);
+    return m_it->value;
 }
 
 PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForBackgroundShorthand() const
diff --git a/Source/core/css/CSSComputedStyleDeclaration.h b/Source/core/css/CSSComputedStyleDeclaration.h
index 6116b50..53f10d2 100644
--- a/Source/core/css/CSSComputedStyleDeclaration.h
+++ b/Source/core/css/CSSComputedStyleDeclaration.h
@@ -49,6 +49,23 @@
 enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true };
 
 class CSSComputedStyleDeclaration : public CSSStyleDeclaration {
+private:
+    class ComputedCSSVariablesIterator : public CSSVariablesIterator {
+    public:
+        virtual ~ComputedCSSVariablesIterator() { }
+        static PassRefPtr<ComputedCSSVariablesIterator> create(const HashMap<AtomicString, String>* variableMap) { return adoptRef(new ComputedCSSVariablesIterator(variableMap)); }
+    private:
+        explicit ComputedCSSVariablesIterator(const HashMap<AtomicString, String>* variableMap);
+        virtual void advance() OVERRIDE;
+        virtual bool atEnd() const OVERRIDE { return m_it == m_end; }
+        virtual AtomicString name() const OVERRIDE;
+        virtual String value() const OVERRIDE;
+        bool m_active;
+        typedef HashMap<AtomicString, String>::const_iterator VariablesMapIterator;
+        VariablesMapIterator m_it;
+        VariablesMapIterator m_end;
+    };
+
 public:
     static PassRefPtr<CSSComputedStyleDeclaration> create(PassRefPtr<Node> node, bool allowVisitedStyle = false, const String& pseudoElementName = String())
     {
@@ -103,9 +120,10 @@
     const HashMap<AtomicString, String>* variableMap() const;
     virtual unsigned variableCount() const OVERRIDE;
     virtual String variableValue(const AtomicString& name) const OVERRIDE;
-    virtual void setVariableValue(const AtomicString& name, const String& value, ExceptionState&) OVERRIDE;
+    virtual bool setVariableValue(const AtomicString& name, const String& value, ExceptionState&) OVERRIDE;
     virtual bool removeVariable(const AtomicString& name) OVERRIDE;
-    virtual void clearVariables(ExceptionState&) OVERRIDE;
+    virtual bool clearVariables(ExceptionState&) OVERRIDE;
+    virtual PassRefPtr<CSSVariablesIterator> variablesIterator() const OVERRIDE { return ComputedCSSVariablesIterator::create(variableMap()); }
 
     virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const OVERRIDE;
 
diff --git a/Source/core/css/CSSCrossfadeValue.cpp b/Source/core/css/CSSCrossfadeValue.cpp
index b45f6cc..b547b39 100644
--- a/Source/core/css/CSSCrossfadeValue.cpp
+++ b/Source/core/css/CSSCrossfadeValue.cpp
@@ -41,7 +41,7 @@
         return toCSSImageValue(value)->cachedOrPendingImage()->isPendingImage();
 
     if (value->isImageGeneratorValue())
-        return static_cast<CSSImageGeneratorValue*>(value)->isPending();
+        return toCSSImageGeneratorValue(value)->isPending();
 
     ASSERT_NOT_REACHED();
 
@@ -54,7 +54,7 @@
         return toCSSImageValue(value)->knownToBeOpaque(renderer);
 
     if (value->isImageGeneratorValue())
-        return static_cast<CSSImageGeneratorValue*>(value)->knownToBeOpaque(renderer);
+        return toCSSImageGeneratorValue(value)->knownToBeOpaque(renderer);
 
     ASSERT_NOT_REACHED();
 
@@ -75,7 +75,7 @@
     }
 
     if (value->isImageGeneratorValue()) {
-        static_cast<CSSImageGeneratorValue*>(value)->loadSubimages(fetcher);
+        toCSSImageGeneratorValue(value)->loadSubimages(fetcher);
         // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas).
         return 0;
     }
diff --git a/Source/core/css/CSSCrossfadeValue.h b/Source/core/css/CSSCrossfadeValue.h
index 4df7520..f506651 100644
--- a/Source/core/css/CSSCrossfadeValue.h
+++ b/Source/core/css/CSSCrossfadeValue.h
@@ -104,6 +104,8 @@
     CrossfadeSubimageObserverProxy m_crossfadeSubimageObserver;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(CrossfadeValue);
+
 } // namespace WebCore
 
 #endif // CSSCrossfadeValue_h
diff --git a/Source/core/css/CSSCursorImageValue.h b/Source/core/css/CSSCursorImageValue.h
index c4a895c..b163f41 100644
--- a/Source/core/css/CSSCursorImageValue.h
+++ b/Source/core/css/CSSCursorImageValue.h
@@ -22,7 +22,7 @@
 #define CSSCursorImageValue_h
 
 #include "core/css/CSSImageValue.h"
-#include "core/platform/graphics/IntPoint.h"
+#include "platform/geometry/IntPoint.h"
 #include "wtf/HashSet.h"
 
 namespace WebCore {
@@ -75,6 +75,8 @@
     HashSet<SVGElement*> m_referencedElements;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(CursorImageValue);
+
 } // namespace WebCore
 
 #endif // CSSCursorImageValue_h
diff --git a/Source/core/css/CSSDefaultStyleSheets.cpp b/Source/core/css/CSSDefaultStyleSheets.cpp
index 436ab64..e5fda36 100644
--- a/Source/core/css/CSSDefaultStyleSheets.cpp
+++ b/Source/core/css/CSSDefaultStyleSheets.cpp
@@ -57,7 +57,7 @@
 StyleSheetContents* CSSDefaultStyleSheets::fullscreenStyleSheet;
 
 // FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet.
-static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}head{display:none}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}body:-webkit-seamless-document{margin:0}body:-webkit-full-page-media{background-color:black}";
+static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}head{display:none}body{margin:8px}div:focus,span:focus,a:focus{outline:auto 5px -webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}body:-webkit-seamless-document{margin:0}body:-webkit-full-page-media{background-color:black}@viewport{min-width:980px}@page{size:auto;margin:auto;padding:0;border-width:0}";
 
 static inline bool elementCanUseSimpleDefaultStyle(Element* e)
 {
diff --git a/Source/core/css/CSSFilterValue.h b/Source/core/css/CSSFilterValue.h
index 3398cfa..fcbcf5a 100644
--- a/Source/core/css/CSSFilterValue.h
+++ b/Source/core/css/CSSFilterValue.h
@@ -72,6 +72,8 @@
     FilterOperationType m_type;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(FilterValue);
+
 }
 
 
diff --git a/Source/core/css/CSSFontFace.cpp b/Source/core/css/CSSFontFace.cpp
index c667aaa..ce3d142 100644
--- a/Source/core/css/CSSFontFace.cpp
+++ b/Source/core/css/CSSFontFace.cpp
@@ -31,6 +31,7 @@
 #include "core/css/CSSSegmentedFontFace.h"
 #include "core/css/FontFaceSet.h"
 #include "core/dom/Document.h"
+#include "core/page/UseCounter.h"
 #include "core/platform/graphics/SimpleFontData.h"
 
 namespace WebCore {
@@ -94,8 +95,11 @@
     fontSelector->fontLoaded();
 
     if (fontSelector->document() && loadStatus() == FontFace::Loading) {
-        if (source->ensureFontData())
+        if (source->ensureFontData()) {
             setLoadStatus(FontFace::Loaded);
+            if (source->isSVGFontFaceSource())
+                UseCounter::count(*fontSelector->document(), UseCounter::SVGFontInCSS);
+        }
         else if (!isValid())
             setLoadStatus(FontFace::Error);
     }
@@ -173,16 +177,25 @@
     }
 }
 
-#if ENABLE(SVG_FONTS)
-bool CSSFontFace::hasSVGFontFaceSource() const
+bool CSSFontFace::UnicodeRangeSet::intersectsWith(const String& text) const
 {
-    size_t size = m_sources.size();
-    for (size_t i = 0; i < size; i++) {
-        if (m_sources[i]->isSVGFontFaceSource())
-            return true;
+    if (text.isEmpty())
+        return false;
+    if (m_ranges.isEmpty())
+        return true; // Empty UnicodeRangeSet represents the whole code space.
+
+    // FIXME: This takes O(text.length() * m_ranges.size()) time. It would be
+    // better to make m_ranges sorted and use binary search.
+    unsigned index = 0;
+    while (index < text.length()) {
+        UChar32 c = text.characterStartingAt(index);
+        index += U16_LENGTH(c);
+        for (unsigned i = 0; i < m_ranges.size(); i++) {
+            if (m_ranges[i].contains(c))
+                return true;
+        }
     }
     return false;
 }
-#endif
 
 }
diff --git a/Source/core/css/CSSFontFace.h b/Source/core/css/CSSFontFace.h
index 7ada75e..b547667 100644
--- a/Source/core/css/CSSFontFace.h
+++ b/Source/core/css/CSSFontFace.h
@@ -45,12 +45,11 @@
 public:
     static PassRefPtr<CSSFontFace> create(PassRefPtr<FontFace> fontFace) { return adoptRef(new CSSFontFace(fontFace)); }
 
-    struct UnicodeRange;
+    class UnicodeRangeSet;
 
     FontFace* fontFace() const { return m_fontFace.get(); }
 
-    void addRange(UChar32 from, UChar32 to) { m_ranges.append(UnicodeRange(from, to)); }
-    const Vector<UnicodeRange>& ranges() const { return m_ranges; }
+    UnicodeRangeSet& ranges() { return m_ranges; }
 
     void setSegmentedFontFace(CSSSegmentedFontFace*);
     void clearSegmentedFontFace() { m_segmentedFontFace = 0; }
@@ -74,15 +73,22 @@
 
         UChar32 from() const { return m_from; }
         UChar32 to() const { return m_to; }
+        bool contains(UChar32 c) const { return m_from <= c && c <= m_to; }
 
     private:
         UChar32 m_from;
         UChar32 m_to;
     };
 
-#if ENABLE(SVG_FONTS)
-    bool hasSVGFontFaceSource() const;
-#endif
+    class UnicodeRangeSet {
+    public:
+        void add(UChar32 from, UChar32 to) { m_ranges.append(UnicodeRange(from, to)); }
+        bool intersectsWith(const String&) const;
+        size_t size() const { return m_ranges.size(); }
+        const UnicodeRange& rangeAt(size_t i) const { return m_ranges[i]; }
+    private:
+        Vector<UnicodeRange> m_ranges;
+    };
 
     FontFace::LoadStatus loadStatus() const { return m_fontFace ? m_fontFace->loadStatus() : FontFace::Loaded; }
     void willUseFontData(const FontDescription&);
@@ -96,7 +102,7 @@
     }
     void setLoadStatus(FontFace::LoadStatus);
 
-    Vector<UnicodeRange> m_ranges;
+    UnicodeRangeSet m_ranges;
     CSSSegmentedFontFace* m_segmentedFontFace;
     Vector<OwnPtr<CSSFontFaceSource> > m_sources;
     CSSFontFaceSource* m_activeSource;
diff --git a/Source/core/css/CSSFontFaceLoadEvent.cpp b/Source/core/css/CSSFontFaceLoadEvent.cpp
index 58a5e4f..95aa3b2 100644
--- a/Source/core/css/CSSFontFaceLoadEvent.cpp
+++ b/Source/core/css/CSSFontFaceLoadEvent.cpp
@@ -58,7 +58,7 @@
 
 const AtomicString& CSSFontFaceLoadEvent::interfaceName() const
 {
-    return eventNames().interfaceForCSSFontFaceLoadEvent;
+    return EventNames::CSSFontFaceLoadEvent;
 }
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSFontFaceLoadEvent.h b/Source/core/css/CSSFontFaceLoadEvent.h
index 432dacf..e77ca32 100644
--- a/Source/core/css/CSSFontFaceLoadEvent.h
+++ b/Source/core/css/CSSFontFaceLoadEvent.h
@@ -34,7 +34,7 @@
 #include "core/css/FontFace.h"
 #include "core/dom/DOMError.h"
 #include "core/events/Event.h"
-#include "core/events/EventNames.h"
+#include "core/events/ThreadLocalEventNames.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 
diff --git a/Source/core/css/CSSFontFaceLoadEvent.idl b/Source/core/css/CSSFontFaceLoadEvent.idl
index 7ab2522..b77706c 100644
--- a/Source/core/css/CSSFontFaceLoadEvent.idl
+++ b/Source/core/css/CSSFontFaceLoadEvent.idl
@@ -31,7 +31,7 @@
 // FIXME: Make this constructable from Javascript
 [
     NoInterfaceObject,
-    EnabledAtRuntime=FontLoadEvents,
+    RuntimeEnabled=FontLoadEvents,
 ] interface CSSFontFaceLoadEvent : Event {
     readonly attribute FontFace[] fontfaces;
 };
diff --git a/Source/core/css/CSSFontFaceSource.cpp b/Source/core/css/CSSFontFaceSource.cpp
index 7fe19c9..834f3d1 100644
--- a/Source/core/css/CSSFontFaceSource.cpp
+++ b/Source/core/css/CSSFontFaceSource.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "core/css/CSSFontFaceSource.h"
 
+#include "RuntimeEnabledFeatures.h"
 #include "core/css/CSSFontFace.h"
 #include "core/css/CSSFontSelector.h"
 #include "core/fetch/FontResource.h"
@@ -139,9 +140,18 @@
         return fontData;
     }
 
+    float fontSize;
+    if (RuntimeEnabledFeatures::subpixelFontScalingEnabled())
+        fontSize = fontDescription.computedSize();
+    else
+        fontSize = fontDescription.computedPixelSize();
+
     // See if we have a mapping in our FontData cache.
-    unsigned hashKey = (fontDescription.computedPixelSize() + 1) << 5 | fontDescription.widthVariant() << 3
-                       | (fontDescription.orientation() == Vertical ? 4 : 0) | (syntheticBold ? 2 : 0) | (syntheticItalic ? 1 : 0);
+    unsigned hashKey = (static_cast<unsigned>(fontSize * FontCache::s_fontSizePrecisionMultiplier) + 1) << 5
+        | fontDescription.widthVariant() << 3
+        | (fontDescription.orientation() == Vertical ? 4 : 0)
+        | (syntheticBold ? 2 : 0)
+        | (syntheticItalic ? 1 : 0);
 
     RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(hashKey, 0).iterator->value;
     if (fontData)
@@ -184,7 +194,7 @@
                         m_svgFontFaceElement = fontFaceElement;
                     }
 
-                    fontData = SimpleFontData::create(SVGFontData::create(fontFaceElement), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
+                    fontData = SimpleFontData::create(SVGFontData::create(fontFaceElement), fontSize, syntheticBold, syntheticItalic);
                 }
             } else
 #endif
@@ -193,14 +203,14 @@
                 if (!m_font->ensureCustomFontData())
                     return 0;
 
-                fontData = SimpleFontData::create(m_font->platformDataFromCustomData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic,
+                fontData = SimpleFontData::create(m_font->platformDataFromCustomData(fontSize, syntheticBold, syntheticItalic,
                     fontDescription.orientation(), fontDescription.widthVariant()), true, false);
             }
         } else {
 #if ENABLE(SVG_FONTS)
             // In-Document SVG Fonts
             if (m_svgFontFaceElement)
-                fontData = SimpleFontData::create(SVGFontData::create(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
+                fontData = SimpleFontData::create(SVGFontData::create(m_svgFontFaceElement.get()), fontSize, syntheticBold, syntheticItalic);
 #endif
         }
     } else {
diff --git a/Source/core/css/CSSFontFaceSource.h b/Source/core/css/CSSFontFaceSource.h
index 6cdabfd..a30f994 100644
--- a/Source/core/css/CSSFontFaceSource.h
+++ b/Source/core/css/CSSFontFaceSource.h
@@ -28,7 +28,7 @@
 
 #include "core/fetch/FontResource.h"
 #include "core/fetch/ResourcePtr.h"
-#include "core/platform/Timer.h"
+#include "platform/Timer.h"
 #include "wtf/HashMap.h"
 #include "wtf/text/AtomicString.h"
 
diff --git a/Source/core/css/CSSFontFaceSrcValue.h b/Source/core/css/CSSFontFaceSrcValue.h
index 992448e..db61e61 100644
--- a/Source/core/css/CSSFontFaceSrcValue.h
+++ b/Source/core/css/CSSFontFaceSrcValue.h
@@ -95,11 +95,7 @@
 #endif
 };
 
-inline CSSFontFaceSrcValue* toCSSFontFaceSrcValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isFontFaceSrcValue());
-    return static_cast<CSSFontFaceSrcValue*>(value);
-}
+DEFINE_CSS_VALUE_TYPE_CASTS(FontFaceSrcValue);
 
 }
 
diff --git a/Source/core/css/FontFeatureValue.cpp b/Source/core/css/CSSFontFeatureValue.cpp
similarity index 88%
rename from Source/core/css/FontFeatureValue.cpp
rename to Source/core/css/CSSFontFeatureValue.cpp
index 37c93da..b6cc105 100644
--- a/Source/core/css/FontFeatureValue.cpp
+++ b/Source/core/css/CSSFontFeatureValue.cpp
@@ -24,20 +24,20 @@
  */
 
 #include "config.h"
-#include "core/css/FontFeatureValue.h"
+#include "core/css/CSSFontFeatureValue.h"
 
 #include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
-FontFeatureValue::FontFeatureValue(const String& tag, int value)
+CSSFontFeatureValue::CSSFontFeatureValue(const String& tag, int value)
     : CSSValue(FontFeatureClass)
     , m_tag(tag)
     , m_value(value)
 {
 }
 
-String FontFeatureValue::customCssText() const
+String CSSFontFeatureValue::customCssText() const
 {
     StringBuilder builder;
     builder.append('\'');
@@ -47,7 +47,7 @@
     return builder.toString();
 }
 
-bool FontFeatureValue::equals(const FontFeatureValue& other) const
+bool CSSFontFeatureValue::equals(const CSSFontFeatureValue& other) const
 {
     return m_tag == other.m_tag && m_value == other.m_value;
 }
diff --git a/Source/core/css/FontFeatureValue.h b/Source/core/css/CSSFontFeatureValue.h
similarity index 81%
rename from Source/core/css/FontFeatureValue.h
rename to Source/core/css/CSSFontFeatureValue.h
index 4aa3345..d566a5b 100644
--- a/Source/core/css/FontFeatureValue.h
+++ b/Source/core/css/CSSFontFeatureValue.h
@@ -23,34 +23,36 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef FontFeatureValue_h
-#define FontFeatureValue_h
+#ifndef CSSFontFeatureValue_h
+#define CSSFontFeatureValue_h
 
 #include "core/css/CSSValue.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-class FontFeatureValue : public CSSValue {
+class CSSFontFeatureValue : public CSSValue {
 public:
-    static PassRefPtr<FontFeatureValue> create(const String& tag, int value)
+    static PassRefPtr<CSSFontFeatureValue> create(const String& tag, int value)
     {
-        return adoptRef(new FontFeatureValue(tag, value));
+        return adoptRef(new CSSFontFeatureValue(tag, value));
     }
 
     const String& tag() const { return m_tag; }
     int value() const { return m_value; }
     String customCssText() const;
 
-    bool equals(const FontFeatureValue&) const;
+    bool equals(const CSSFontFeatureValue&) const;
 
 private:
-    FontFeatureValue(const String&, int);
+    CSSFontFeatureValue(const String&, int);
 
     String m_tag;
     const int m_value;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(FontFeatureValue);
+
 } // namespace
 
 #endif
diff --git a/Source/core/css/CSSFontSelector.cpp b/Source/core/css/CSSFontSelector.cpp
index bfe6bfe..3c25503 100644
--- a/Source/core/css/CSSFontSelector.cpp
+++ b/Source/core/css/CSSFontSelector.cpp
@@ -27,7 +27,6 @@
 #include "config.h"
 #include "core/css/CSSFontSelector.h"
 
-#include "FontFamilyNames.h"
 #include "RuntimeEnabledFeatures.h"
 #include "core/css/CSSFontFace.h"
 #include "core/css/CSSFontFaceRule.h"
@@ -39,7 +38,7 @@
 #include "core/fetch/FontResource.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/loader/FrameLoader.h"
-#include "core/page/Frame.h"
+#include "core/frame/Frame.h"
 #include "core/page/Settings.h"
 #include "core/platform/graphics/FontCache.h"
 #include "core/platform/graphics/SimpleFontData.h"
@@ -49,10 +48,61 @@
 
 namespace WebCore {
 
+FontLoader::FontLoader(ResourceFetcher* resourceFetcher)
+    : m_beginLoadingTimer(this, &FontLoader::beginLoadTimerFired)
+    , m_resourceFetcher(resourceFetcher)
+{
+}
+
+void FontLoader::addFontToBeginLoading(FontResource* fontResource)
+{
+    if (!m_resourceFetcher)
+        return;
+
+    m_fontsToBeginLoading.append(fontResource);
+    // FIXME: Use RequestCountTracker??!!
+    // Increment the request count now, in order to prevent didFinishLoad from being dispatched
+    // after this font has been requested but before it began loading. Balanced by
+    // decrementRequestCount() in beginLoadTimerFired() and in clearDocument().
+    m_resourceFetcher->incrementRequestCount(fontResource);
+    m_beginLoadingTimer.startOneShot(0);
+}
+
+void FontLoader::beginLoadTimerFired(Timer<WebCore::FontLoader>*)
+{
+    ASSERT(m_resourceFetcher);
+
+    Vector<ResourcePtr<FontResource> > fontsToBeginLoading;
+    fontsToBeginLoading.swap(m_fontsToBeginLoading);
+
+    for (size_t i = 0; i < fontsToBeginLoading.size(); ++i) {
+        fontsToBeginLoading[i]->beginLoadIfNeeded(m_resourceFetcher);
+        // Balances incrementRequestCount() in beginLoadingFontSoon().
+        m_resourceFetcher->decrementRequestCount(fontsToBeginLoading[i].get());
+    }
+}
+
+void FontLoader::clearResourceFetcher()
+{
+    if (!m_resourceFetcher) {
+        ASSERT(m_fontsToBeginLoading.isEmpty());
+        return;
+    }
+
+    m_beginLoadingTimer.stop();
+
+    for (size_t i = 0; i < m_fontsToBeginLoading.size(); ++i) {
+        // Balances incrementRequestCount() in beginLoadingFontSoon().
+        m_resourceFetcher->decrementRequestCount(m_fontsToBeginLoading[i].get());
+    }
+
+    m_fontsToBeginLoading.clear();
+    m_resourceFetcher = 0;
+}
+
 CSSFontSelector::CSSFontSelector(Document* document)
     : m_document(document)
-    , m_beginLoadingTimer(this, &CSSFontSelector::beginLoadTimerFired)
-    , m_version(0)
+    , m_fontLoader(document->fetcher())
 {
     // FIXME: An old comment used to say there was no need to hold a reference to m_document
     // because "we are guaranteed to be destroyed before the document". But there does not
@@ -68,59 +118,6 @@
     fontCache()->removeClient(this);
 }
 
-bool CSSFontSelector::isEmpty() const
-{
-    return m_fonts.isEmpty();
-}
-
-void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule)
-{
-    RefPtr<FontFace> fontFace = FontFace::create(fontFaceRule);
-    if (!fontFace || fontFace->family().isEmpty())
-        return;
-
-    unsigned traitsMask = fontFace->traitsMask();
-    if (!traitsMask)
-        return;
-
-    RefPtr<CSSFontFace> cssFontFace = fontFace->createCSSFontFace(m_document);
-    if (!cssFontFace || !cssFontFace->isValid())
-        return;
-
-    OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& familyFontFaces = m_fontFaces.add(fontFace->family(), nullptr).iterator->value;
-    if (!familyFontFaces) {
-        familyFontFaces = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >);
-
-        ASSERT(!m_locallyInstalledFontFaces.contains(fontFace->family()));
-
-        Vector<unsigned> locallyInstalledFontsTraitsMasks;
-        fontCache()->getTraitsInFamily(fontFace->family(), locallyInstalledFontsTraitsMasks);
-        if (unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size()) {
-            OwnPtr<Vector<RefPtr<CSSSegmentedFontFace> > > familyLocallyInstalledFaces = adoptPtr(new Vector<RefPtr<CSSSegmentedFontFace> >);
-
-            for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) {
-                RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(0);
-                locallyInstalledFontFace->addSource(adoptPtr(new CSSFontFaceSource(fontFace->family())));
-                ASSERT(locallyInstalledFontFace->isValid());
-
-                RefPtr<CSSSegmentedFontFace> segmentedFontFace = CSSSegmentedFontFace::create(this, static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]), true);
-                segmentedFontFace->appendFontFace(locallyInstalledFontFace.release());
-                familyLocallyInstalledFaces->append(segmentedFontFace);
-            }
-
-            m_locallyInstalledFontFaces.set(fontFace->family(), familyLocallyInstalledFaces.release());
-        }
-    }
-
-    RefPtr<CSSSegmentedFontFace>& segmentedFontFace = familyFontFaces->add(traitsMask, 0).iterator->value;
-    if (!segmentedFontFace)
-        segmentedFontFace = CSSSegmentedFontFace::create(this, static_cast<FontTraitsMask>(traitsMask), false);
-
-    segmentedFontFace->appendFontFace(cssFontFace);
-
-    ++m_version;
-}
-
 void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* client)
 {
     m_clients.add(client);
@@ -137,15 +134,6 @@
     copyToVector(m_clients, clients);
     for (size_t i = 0; i < clients.size(); ++i)
         clients[i]->fontsNeedUpdate(this);
-
-    // FIXME: Make Document a FontSelectorClient so that it can simply register for invalidation callbacks.
-    if (!m_document)
-        return;
-    if (StyleResolver* styleResolver = m_document->styleResolverIfExists())
-        styleResolver->invalidateMatchedPropertiesCache();
-    if (!m_document->renderer())
-        return;
-    m_document->setNeedsStyleRecalc();
 }
 
 void CSSFontSelector::fontLoaded()
@@ -158,189 +146,22 @@
     dispatchInvalidationCallbacks();
 }
 
-static PassRefPtr<FontData> fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName)
+void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule)
 {
-    if (!document || !document->frame())
-        return 0;
-
-    const Settings* settings = document->frame()->settings();
-    if (!settings)
-        return 0;
-
-    AtomicString genericFamily;
-    UScriptCode script = fontDescription.script();
-
-    if (familyName == serifFamily)
-         genericFamily = settings->serifFontFamily(script);
-    else if (familyName == sansSerifFamily)
-         genericFamily = settings->sansSerifFontFamily(script);
-    else if (familyName == cursiveFamily)
-         genericFamily = settings->cursiveFontFamily(script);
-    else if (familyName == fantasyFamily)
-         genericFamily = settings->fantasyFontFamily(script);
-    else if (familyName == monospaceFamily)
-         genericFamily = settings->fixedFontFamily(script);
-    else if (familyName == pictographFamily)
-         genericFamily = settings->pictographFontFamily(script);
-    else if (familyName == standardFamily)
-         genericFamily = settings->standardFontFamily(script);
-
-    if (!genericFamily.isEmpty())
-        return fontCache()->getFontResourceData(fontDescription, genericFamily);
-
-    return 0;
-}
-
-static inline bool compareFontFaces(CSSSegmentedFontFace* first, CSSSegmentedFontFace* second, FontTraitsMask desiredTraitsMask)
-{
-    FontTraitsMask firstTraitsMask = first->traitsMask();
-    FontTraitsMask secondTraitsMask = second->traitsMask();
-
-    bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMask & FontVariantMask;
-    bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMask & FontVariantMask;
-
-    if (firstHasDesiredVariant != secondHasDesiredVariant)
-        return firstHasDesiredVariant;
-
-    // We need to check font-variant css property for CSS2.1 compatibility.
-    if ((desiredTraitsMask & FontVariantSmallCapsMask) && !first->isLocalFallback() && !second->isLocalFallback()) {
-        // Prefer a font that has indicated that it can only support small-caps to a font that claims to support
-        // all variants.  The specialized font is more likely to be true small-caps and not require synthesis.
-        bool firstRequiresSmallCaps = (firstTraitsMask & FontVariantSmallCapsMask) && !(firstTraitsMask & FontVariantNormalMask);
-        bool secondRequiresSmallCaps = (secondTraitsMask & FontVariantSmallCapsMask) && !(secondTraitsMask & FontVariantNormalMask);
-        if (firstRequiresSmallCaps != secondRequiresSmallCaps)
-            return firstRequiresSmallCaps;
-    }
-
-    bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMask & FontStyleMask;
-    bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMask & FontStyleMask;
-
-    if (firstHasDesiredStyle != secondHasDesiredStyle)
-        return firstHasDesiredStyle;
-
-    if ((desiredTraitsMask & FontStyleItalicMask) && !first->isLocalFallback() && !second->isLocalFallback()) {
-        // Prefer a font that has indicated that it can only support italics to a font that claims to support
-        // all styles.  The specialized font is more likely to be the one the author wants used.
-        bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask);
-        bool secondRequiresItalics = (secondTraitsMask & FontStyleItalicMask) && !(secondTraitsMask & FontStyleNormalMask);
-        if (firstRequiresItalics != secondRequiresItalics)
-            return firstRequiresItalics;
-    }
-
-    if (secondTraitsMask & desiredTraitsMask & FontWeightMask)
-        return false;
-    if (firstTraitsMask & desiredTraitsMask & FontWeightMask)
-        return true;
-
-    // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says :
-    //   - If the desired weight is less than 400, weights below the desired weight are checked in descending order followed by weights above the desired weight in ascending order until a match is found.
-    //   - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found.
-    //   - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used.
-    //   - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used.
-
-    static const unsigned fallbackRuleSets = 9;
-    static const unsigned rulesPerSet = 8;
-    static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
-        { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight500Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
-        { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
-        { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
-        { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }
-    };
-
-    unsigned ruleSetIndex = 0;
-    unsigned w = FontWeight100Bit;
-    while (!(desiredTraitsMask & (1 << w))) {
-        w++;
-        ruleSetIndex++;
-    }
-
-    ASSERT(ruleSetIndex < fallbackRuleSets);
-    const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
-    for (unsigned i = 0; i < rulesPerSet; ++i) {
-        if (secondTraitsMask & weightFallbackRule[i])
-            return false;
-        if (firstTraitsMask & weightFallbackRule[i])
-            return true;
-    }
-
-    return false;
+    m_cssSegmentedFontFaceCache.addFontFaceRule(this, fontFaceRule);
 }
 
 PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName)
 {
-    if (m_fontFaces.isEmpty()) {
-        if (familyName.startsWith("-webkit-"))
-            return fontDataForGenericFamily(m_document, fontDescription, familyName);
-        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
-            return fontDataForGenericFamily(m_document, fontDescription, "-webkit-standard");
+    if (!m_document || !m_document->frame())
         return 0;
-    }
 
-    CSSSegmentedFontFace* face = getFontFace(fontDescription, familyName);
-    // If no face was found, then return 0 and let the OS come up with its best match for the name.
-    if (!face) {
-        // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our
-        // settings.
-        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
-            return fontDataForGenericFamily(m_document, fontDescription, "-webkit-standard");
-        return fontDataForGenericFamily(m_document, fontDescription, familyName);
-    }
-
-    // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over.
-    return face->getFontData(fontDescription);
+    return m_cssSegmentedFontFaceCache.getFontData(m_document->frame()->settings(), fontDescription, familyName);
 }
 
-CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& family)
+CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& familyName)
 {
-    HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >* familyFontFaces = m_fontFaces.get(family);
-    if (!familyFontFaces || familyFontFaces->isEmpty())
-        return 0;
-
-    OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value;
-    if (!segmentedFontFaceCache)
-        segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >);
-
-    FontTraitsMask traitsMask = fontDescription.traitsMask();
-
-    RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->value;
-    if (!face) {
-        for (HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >::const_iterator i = familyFontFaces->begin(); i != familyFontFaces->end(); ++i) {
-            CSSSegmentedFontFace* candidate = i->value.get();
-            unsigned candidateTraitsMask = candidate->traitsMask();
-            if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
-                continue;
-            if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
-                continue;
-#if ENABLE(SVG_FONTS)
-            // For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable
-            // of small-caps synthesis and just ignore the font face as a candidate.
-            if (candidate->hasSVGFontFaceSource() && (traitsMask & FontVariantSmallCapsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask))
-                continue;
-#endif
-            if (!face || compareFontFaces(candidate, face.get(), traitsMask))
-                face = candidate;
-        }
-
-        if (Vector<RefPtr<CSSSegmentedFontFace> >* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) {
-            unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size();
-            for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) {
-                CSSSegmentedFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get();
-                unsigned candidateTraitsMask = candidate->traitsMask();
-                if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
-                    continue;
-                if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
-                    continue;
-                if (!face || compareFontFaces(candidate, face.get(), traitsMask))
-                    face = candidate;
-            }
-        }
-    }
-    return face.get();
+    return m_cssSegmentedFontFaceCache.getFontFace(fontDescription, familyName);
 }
 
 void CSSFontSelector::willUseFontData(const FontDescription& fontDescription, const AtomicString& family)
@@ -352,58 +173,13 @@
 
 void CSSFontSelector::clearDocument()
 {
-    if (!m_document) {
-        ASSERT(!m_beginLoadingTimer.isActive());
-        ASSERT(m_fontsToBeginLoading.isEmpty());
-        return;
-    }
-
-    m_beginLoadingTimer.stop();
-
-    ResourceFetcher* fetcher = m_document->fetcher();
-    for (size_t i = 0; i < m_fontsToBeginLoading.size(); ++i) {
-        // Balances incrementRequestCount() in beginLoadingFontSoon().
-        fetcher->decrementRequestCount(m_fontsToBeginLoading[i].get());
-    }
-
-    m_fontsToBeginLoading.clear();
-
+    m_fontLoader.clearResourceFetcher();
     m_document = 0;
 }
 
 void CSSFontSelector::beginLoadingFontSoon(FontResource* font)
 {
-    if (!m_document)
-        return;
-
-    m_fontsToBeginLoading.append(font);
-    // Increment the request count now, in order to prevent didFinishLoad from being dispatched
-    // after this font has been requested but before it began loading. Balanced by
-    // decrementRequestCount() in beginLoadTimerFired() and in clearDocument().
-    m_document->fetcher()->incrementRequestCount(font);
-    m_beginLoadingTimer.startOneShot(0);
-}
-
-void CSSFontSelector::beginLoadTimerFired(Timer<WebCore::CSSFontSelector>*)
-{
-    Vector<ResourcePtr<FontResource> > fontsToBeginLoading;
-    fontsToBeginLoading.swap(m_fontsToBeginLoading);
-
-    // CSSFontSelector could get deleted via beginLoadIfNeeded() or loadDone() unless protected.
-    RefPtr<CSSFontSelector> protect(this);
-
-    ResourceFetcher* fetcher = m_document->fetcher();
-    for (size_t i = 0; i < fontsToBeginLoading.size(); ++i) {
-        fontsToBeginLoading[i]->beginLoadIfNeeded(fetcher);
-        // Balances incrementRequestCount() in beginLoadingFontSoon().
-        fetcher->decrementRequestCount(fontsToBeginLoading[i].get());
-    }
-    // Ensure that if the request count reaches zero, the frame loader will know about it.
-    fetcher->didLoadResource(0);
-    // New font loads may be triggered by layout after the document load is complete but before we have dispatched
-    // didFinishLoading for the frame. Make sure the delegate is always dispatched by checking explicitly.
-    if (m_document && m_document->frame())
-        m_document->frame()->loader()->checkLoadComplete();
+    m_fontLoader.addFontToBeginLoading(font);
 }
 
 }
diff --git a/Source/core/css/CSSFontSelector.h b/Source/core/css/CSSFontSelector.h
index 559fa38..1733964 100644
--- a/Source/core/css/CSSFontSelector.h
+++ b/Source/core/css/CSSFontSelector.h
@@ -26,13 +26,13 @@
 #ifndef CSSFontSelector_h
 #define CSSFontSelector_h
 
+#include "core/css/CSSSegmentedFontFaceCache.h"
 #include "core/fetch/ResourcePtr.h"
-#include "core/platform/Timer.h"
 #include "core/platform/graphics/FontSelector.h"
+#include "platform/Timer.h"
 #include "wtf/Forward.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
-#include "wtf/text/StringHash.h"
 
 namespace WebCore {
 
@@ -44,6 +44,22 @@
 class FontDescription;
 class StyleRuleFontFace;
 
+class FontLoader {
+public:
+    explicit FontLoader(ResourceFetcher*);
+
+    void addFontToBeginLoading(FontResource*);
+
+    void clearResourceFetcher();
+
+private:
+    void beginLoadTimerFired(Timer<FontLoader>*);
+
+    Timer<FontLoader> m_beginLoadingTimer;
+    Vector<ResourcePtr<FontResource> > m_fontsToBeginLoading;
+    ResourceFetcher* m_resourceFetcher;
+};
+
 class CSSFontSelector : public FontSelector {
 public:
     static PassRefPtr<CSSFontSelector> create(Document* document)
@@ -52,7 +68,7 @@
     }
     virtual ~CSSFontSelector();
 
-    virtual unsigned version() const OVERRIDE { return m_version; }
+    virtual unsigned version() const OVERRIDE { return m_cssSegmentedFontFaceCache.version(); }
 
     virtual PassRefPtr<FontData> getFontData(const FontDescription&, const AtomicString&);
     CSSSegmentedFontFace* getFontFace(const FontDescription&, const AtomicString& family);
@@ -65,8 +81,6 @@
     void fontLoaded();
     virtual void fontCacheInvalidated();
 
-    bool isEmpty() const;
-
     virtual void registerForInvalidationCallbacks(FontSelectorClient*);
     virtual void unregisterForInvalidationCallbacks(FontSelectorClient*);
 
@@ -79,18 +93,12 @@
 
     void dispatchInvalidationCallbacks();
 
-    void beginLoadTimerFired(Timer<CSSFontSelector>*);
-
     Document* m_document;
-    HashMap<String, OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >, CaseFoldingHash> m_fontFaces;
-    HashMap<String, OwnPtr<Vector<RefPtr<CSSSegmentedFontFace> > >, CaseFoldingHash> m_locallyInstalledFontFaces;
-    HashMap<String, OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >, CaseFoldingHash> m_fonts;
+    // FIXME: Move to Document or StyleEngine.
+    CSSSegmentedFontFaceCache m_cssSegmentedFontFaceCache;
     HashSet<FontSelectorClient*> m_clients;
 
-    Vector<ResourcePtr<FontResource> > m_fontsToBeginLoading;
-    Timer<CSSFontSelector> m_beginLoadingTimer;
-
-    unsigned m_version;
+    FontLoader m_fontLoader;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/FontValue.cpp b/Source/core/css/CSSFontValue.cpp
similarity index 94%
rename from Source/core/css/FontValue.cpp
rename to Source/core/css/CSSFontValue.cpp
index 5537183..e4eaee5 100644
--- a/Source/core/css/FontValue.cpp
+++ b/Source/core/css/CSSFontValue.cpp
@@ -18,7 +18,7 @@
  * Boston, MA 02110-1301, USA.
  */
 #include "config.h"
-#include "core/css/FontValue.h"
+#include "core/css/CSSFontValue.h"
 
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSValueList.h"
@@ -26,7 +26,7 @@
 
 namespace WebCore {
 
-String FontValue::customCssText() const
+String CSSFontValue::customCssText() const
 {
     // font variant weight size / line-height family
 
@@ -64,7 +64,7 @@
     return result.toString();
 }
 
-bool FontValue::equals(const FontValue& other) const
+bool CSSFontValue::equals(const CSSFontValue& other) const
 {
     return compareCSSValuePtr(style, other.style)
         && compareCSSValuePtr(variant, other.variant)
diff --git a/Source/core/css/FontValue.h b/Source/core/css/CSSFontValue.h
similarity index 83%
rename from Source/core/css/FontValue.h
rename to Source/core/css/CSSFontValue.h
index df8f9a7..5ca4f32 100644
--- a/Source/core/css/FontValue.h
+++ b/Source/core/css/CSSFontValue.h
@@ -18,8 +18,8 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#ifndef FontValue_h
-#define FontValue_h
+#ifndef CSSFontValue_h
+#define CSSFontValue_h
 
 #include "core/css/CSSValue.h"
 #include "wtf/PassRefPtr.h"
@@ -30,16 +30,16 @@
 class CSSPrimitiveValue;
 class CSSValueList;
 
-class FontValue : public CSSValue {
+class CSSFontValue : public CSSValue {
 public:
-    static PassRefPtr<FontValue> create()
+    static PassRefPtr<CSSFontValue> create()
     {
-        return adoptRef(new FontValue);
+        return adoptRef(new CSSFontValue);
     }
 
     String customCssText() const;
 
-    bool equals(const FontValue&) const;
+    bool equals(const CSSFontValue&) const;
 
     RefPtr<CSSPrimitiveValue> style;
     RefPtr<CSSPrimitiveValue> variant;
@@ -49,12 +49,14 @@
     RefPtr<CSSValueList> family;
 
 private:
-    FontValue()
+    CSSFontValue()
         : CSSValue(FontClass)
     {
     }
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(FontValue);
+
 } // namespace
 
 #endif
diff --git a/Source/core/css/CSSFunctionValue.h b/Source/core/css/CSSFunctionValue.h
index d4e7e4d..ee5c5d9 100644
--- a/Source/core/css/CSSFunctionValue.h
+++ b/Source/core/css/CSSFunctionValue.h
@@ -59,20 +59,7 @@
     RefPtr<CSSValueList> m_args;
 };
 
-inline CSSFunctionValue* toCSSFunctionValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(value->isFunctionValue());
-    return static_cast<CSSFunctionValue*>(value);
-}
-
-inline const CSSFunctionValue* toCSSFunctionValue(const CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(value->isFunctionValue());
-    return static_cast<const CSSFunctionValue*>(value);
-}
-
-// Catch any unneeded cast.
-void toCSSFunctionValue(const CSSFunctionValue*);
+DEFINE_CSS_VALUE_TYPE_CASTS(FunctionValue);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSGradientValue.cpp b/Source/core/css/CSSGradientValue.cpp
index 5b7ea0b..32bc0e2 100644
--- a/Source/core/css/CSSGradientValue.cpp
+++ b/Source/core/css/CSSGradientValue.cpp
@@ -33,8 +33,8 @@
 #include "core/platform/graphics/GeneratorGeneratedImage.h"
 #include "core/platform/graphics/Gradient.h"
 #include "core/platform/graphics/Image.h"
-#include "core/platform/graphics/IntSize.h"
 #include "core/rendering/RenderObject.h"
+#include "platform/geometry/IntSize.h"
 #include "wtf/text/StringBuilder.h"
 #include "wtf/text/WTFString.h"
 
@@ -61,12 +61,10 @@
     // We need to create an image.
     RefPtr<Gradient> gradient;
 
-    if (isLinearGradient())
-        gradient = static_cast<CSSLinearGradientValue*>(this)->createGradient(renderer, size);
-    else {
-        ASSERT(isRadialGradient());
-        gradient = static_cast<CSSRadialGradientValue*>(this)->createGradient(renderer, size);
-    }
+    if (isLinearGradientValue())
+        gradient = toCSSLinearGradientValue(this)->createGradient(renderer, size);
+    else
+        gradient = toCSSRadialGradientValue(this)->createGradient(renderer, size);
 
     RefPtr<Image> newImage = GeneratorGeneratedImage::create(gradient, size);
     if (cacheable)
@@ -118,10 +116,10 @@
     RefPtr<CSSGradientValue> result;
     if (!derived)
         result = this;
-    else if (isLinearGradient())
-        result = static_cast<CSSLinearGradientValue*>(this)->clone();
-    else if (isRadialGradient())
-        result = static_cast<CSSRadialGradientValue*>(this)->clone();
+    else if (isLinearGradientValue())
+        result = toCSSLinearGradientValue(this)->clone();
+    else if (isRadialGradientValue())
+        result = toCSSRadialGradientValue(this)->clone();
     else {
         ASSERT_NOT_REACHED();
         return 0;
@@ -166,9 +164,9 @@
 
     FloatPoint gradientStart = gradient->p0();
     FloatPoint gradientEnd;
-    if (isLinearGradient())
+    if (isLinearGradientValue())
         gradientEnd = gradient->p1();
-    else if (isRadialGradient())
+    else if (isRadialGradientValue())
         gradientEnd = gradientStart + FloatSize(gradient->endRadius(), 0);
 
     for (size_t i = 0; i < numStops; ++i) {
@@ -269,7 +267,7 @@
 
             // Radial gradients may need to extend further than the endpoints, because they have
             // to repeat out to the corners of the box.
-            if (isRadialGradient()) {
+            if (isRadialGradientValue()) {
                 if (!computedGradientLength) {
                     FloatSize gradientSize(gradientStart - gradientEnd);
                     gradientLength = gradientSize.diagonalLength();
@@ -327,7 +325,7 @@
 
     // If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and adjusting the stops.
     if (numStops > 1 && (stops[0].offset < 0 || stops[numStops - 1].offset > 1)) {
-        if (isLinearGradient()) {
+        if (isLinearGradientValue()) {
             float firstOffset = stops[0].offset;
             float lastOffset = stops[numStops - 1].offset;
             float scale = lastOffset - firstOffset;
@@ -339,7 +337,7 @@
             FloatPoint p1 = gradient->p1();
             gradient->setP0(FloatPoint(p0.x() + firstOffset * (p1.x() - p0.x()), p0.y() + firstOffset * (p1.y() - p0.y())));
             gradient->setP1(FloatPoint(p1.x() + (lastOffset - 1) * (p1.x() - p0.x()), p1.y() + (lastOffset - 1) * (p1.y() - p0.y())));
-        } else if (isRadialGradient()) {
+        } else if (isRadialGradientValue()) {
             // Rather than scaling the points < 0, we truncate them, so only scale according to the largest point.
             float firstOffset = 0;
             float lastOffset = stops[numStops - 1].offset;
diff --git a/Source/core/css/CSSGradientValue.h b/Source/core/css/CSSGradientValue.h
index 75e5152..1429e50 100644
--- a/Source/core/css/CSSGradientValue.h
+++ b/Source/core/css/CSSGradientValue.h
@@ -75,9 +75,6 @@
 
     void sortStopsIfNeeded();
 
-    bool isLinearGradient() const { return classType() == LinearGradientClass; }
-    bool isRadialGradient() const { return classType() == RadialGradientClass; }
-
     bool isRepeating() const { return m_repeating; }
 
     CSSGradientType gradientType() const { return m_gradientType; }
@@ -134,6 +131,7 @@
     bool m_repeating;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(GradientValue);
 
 class CSSLinearGradientValue : public CSSGradientValue {
 public:
@@ -172,6 +170,8 @@
     RefPtr<CSSPrimitiveValue> m_angle; // may be null.
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(LinearGradientValue);
+
 class CSSRadialGradientValue : public CSSGradientValue {
 public:
     static PassRefPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
@@ -233,6 +233,8 @@
     RefPtr<CSSPrimitiveValue> m_endVerticalSize;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(RadialGradientValue);
+
 } // namespace WebCore
 
 #endif // CSSGradientValue_h
diff --git a/Source/core/css/CSSGrammar.y.in b/Source/core/css/CSSGrammar.y.in
index da016a2..1fc7d7a 100644
--- a/Source/core/css/CSSGrammar.y.in
+++ b/Source/core/css/CSSGrammar.y.in
@@ -170,6 +170,7 @@
 %token MEDIA_ONLY
 %token MEDIA_NOT
 %token MEDIA_AND
+%token MEDIA_OR
 
 %token SUPPORTS_NOT
 %token SUPPORTS_AND
@@ -397,9 +398,14 @@
     }
 ;
 
+space:
+    WHITESPACE
+  | space WHITESPACE
+  ;
+
 maybe_space:
     /* empty */ %prec UNIMPORTANT_TOK
-  | maybe_space WHITESPACE
+  | space
   ;
 
 maybe_sgml:
@@ -598,7 +604,7 @@
     ;
 
 media_query_exp:
-    '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis maybe_space {
+    '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis {
         parser->tokenToLowerCase($3);
         $$ = parser->createFloatingMediaQueryExp($3, $5);
         if (!$$)
@@ -614,18 +620,18 @@
         $$ = parser->createFloatingMediaQueryExpList();
         $$->append(parser->sinkFloatingMediaQueryExp($1));
     }
-    | media_query_exp_list MEDIA_AND maybe_space media_query_exp {
+    | media_query_exp_list space MEDIA_AND space media_query_exp {
         $$ = $1;
-        $$->append(parser->sinkFloatingMediaQueryExp($4));
+        $$->append(parser->sinkFloatingMediaQueryExp($5));
     }
     ;
 
 maybe_and_media_query_exp_list:
-    /*empty*/ {
+    maybe_space {
         $$ = parser->createFloatingMediaQueryExpList();
     }
-    | MEDIA_AND maybe_space media_query_exp_list {
-        $$ = $3;
+    | space MEDIA_AND space media_query_exp_list maybe_space {
+        $$ = $4;
     }
     ;
 
@@ -633,16 +639,16 @@
     /*empty*/ {
         $$ = MediaQuery::None;
     }
-    | MEDIA_ONLY maybe_space {
+    | MEDIA_ONLY space {
         $$ = MediaQuery::Only;
     }
-    | MEDIA_NOT maybe_space {
+    | MEDIA_NOT space {
         $$ = MediaQuery::Not;
     }
     ;
 
 valid_media_query:
-    media_query_exp_list {
+    media_query_exp_list maybe_space {
         $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($1));
     }
     | maybe_media_restrictor medium maybe_and_media_query_exp_list {
@@ -732,7 +738,7 @@
     ;
 
 medium:
-  IDENT maybe_space
+  IDENT
   ;
 
 supports:
@@ -1089,7 +1095,7 @@
     ;
 
 region:
-    before_region_rule WEBKIT_REGION_RULE_SYM WHITESPACE region_selector at_rule_header_end '{' at_rule_body_start maybe_space region_block_rule_body closing_brace {
+    before_region_rule WEBKIT_REGION_RULE_SYM maybe_space region_selector at_rule_header_end '{' at_rule_body_start maybe_space region_block_rule_body closing_brace {
         $$ = parser->createRegionRule($4, $9);
     }
   | before_region_rule WEBKIT_REGION_RULE_SYM at_rule_recovery {
@@ -1106,7 +1112,7 @@
     ;
 
 filter:
-    before_filter_rule WEBKIT_FILTER_RULE_SYM WHITESPACE IDENT at_rule_header_end_maybe_space
+    before_filter_rule WEBKIT_FILTER_RULE_SYM maybe_space IDENT at_rule_header_end_maybe_space
     '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
         parser->m_inFilterRule = false;
         $$ = parser->createFilterRule($4);
@@ -1772,10 +1778,10 @@
   ;
 
 calc_func_operator:
-    WHITESPACE '+' WHITESPACE {
+    space '+' space {
         $$ = '+';
     }
-    | WHITESPACE '-' WHITESPACE {
+    | space '-' space {
         $$ = '-';
     }
     | calc_maybe_space '*' maybe_space {
diff --git a/Source/core/css/CSSGridTemplateValue.h b/Source/core/css/CSSGridTemplateValue.h
index f2b796a..40967ed 100644
--- a/Source/core/css/CSSGridTemplateValue.h
+++ b/Source/core/css/CSSGridTemplateValue.h
@@ -56,20 +56,7 @@
     size_t m_columnCount;
 };
 
-inline CSSGridTemplateValue* toCSSGridTemplateValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(value->isGridTemplateValue());
-    return static_cast<CSSGridTemplateValue*>(value);
-}
-
-inline const CSSGridTemplateValue* toCSSGridTemplateValue(const CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(value->isGridTemplateValue());
-    return static_cast<const CSSGridTemplateValue*>(value);
-}
-
-// Catch unneeded cast.
-void toCSSGridTemplateValue(const CSSGridTemplateValue*);
+DEFINE_CSS_VALUE_TYPE_CASTS(GridTemplateValue);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSImageGeneratorValue.cpp b/Source/core/css/CSSImageGeneratorValue.cpp
index 472c6ee..0fb08b1 100644
--- a/Source/core/css/CSSImageGeneratorValue.cpp
+++ b/Source/core/css/CSSImageGeneratorValue.cpp
@@ -110,13 +110,13 @@
 {
     switch (classType()) {
     case CanvasClass:
-        return static_cast<CSSCanvasValue*>(this)->image(renderer, size);
+        return toCSSCanvasValue(this)->image(renderer, size);
     case CrossfadeClass:
-        return static_cast<CSSCrossfadeValue*>(this)->image(renderer, size);
+        return toCSSCrossfadeValue(this)->image(renderer, size);
     case LinearGradientClass:
-        return static_cast<CSSLinearGradientValue*>(this)->image(renderer, size);
+        return toCSSLinearGradientValue(this)->image(renderer, size);
     case RadialGradientClass:
-        return static_cast<CSSRadialGradientValue*>(this)->image(renderer, size);
+        return toCSSRadialGradientValue(this)->image(renderer, size);
     default:
         ASSERT_NOT_REACHED();
     }
@@ -127,13 +127,13 @@
 {
     switch (classType()) {
     case CanvasClass:
-        return static_cast<const CSSCanvasValue*>(this)->isFixedSize();
+        return toCSSCanvasValue(this)->isFixedSize();
     case CrossfadeClass:
-        return static_cast<const CSSCrossfadeValue*>(this)->isFixedSize();
+        return toCSSCrossfadeValue(this)->isFixedSize();
     case LinearGradientClass:
-        return static_cast<const CSSLinearGradientValue*>(this)->isFixedSize();
+        return toCSSLinearGradientValue(this)->isFixedSize();
     case RadialGradientClass:
-        return static_cast<const CSSRadialGradientValue*>(this)->isFixedSize();
+        return toCSSRadialGradientValue(this)->isFixedSize();
     default:
         ASSERT_NOT_REACHED();
     }
@@ -144,13 +144,13 @@
 {
     switch (classType()) {
     case CanvasClass:
-        return static_cast<CSSCanvasValue*>(this)->fixedSize(renderer);
+        return toCSSCanvasValue(this)->fixedSize(renderer);
     case CrossfadeClass:
-        return static_cast<CSSCrossfadeValue*>(this)->fixedSize(renderer);
+        return toCSSCrossfadeValue(this)->fixedSize(renderer);
     case LinearGradientClass:
-        return static_cast<CSSLinearGradientValue*>(this)->fixedSize(renderer);
+        return toCSSLinearGradientValue(this)->fixedSize(renderer);
     case RadialGradientClass:
-        return static_cast<CSSRadialGradientValue*>(this)->fixedSize(renderer);
+        return toCSSRadialGradientValue(this)->fixedSize(renderer);
     default:
         ASSERT_NOT_REACHED();
     }
@@ -161,13 +161,13 @@
 {
     switch (classType()) {
     case CrossfadeClass:
-        return static_cast<const CSSCrossfadeValue*>(this)->isPending();
+        return toCSSCrossfadeValue(this)->isPending();
     case CanvasClass:
-        return static_cast<const CSSCanvasValue*>(this)->isPending();
+        return toCSSCanvasValue(this)->isPending();
     case LinearGradientClass:
-        return static_cast<const CSSLinearGradientValue*>(this)->isPending();
+        return toCSSLinearGradientValue(this)->isPending();
     case RadialGradientClass:
-        return static_cast<const CSSRadialGradientValue*>(this)->isPending();
+        return toCSSRadialGradientValue(this)->isPending();
     default:
         ASSERT_NOT_REACHED();
     }
@@ -178,13 +178,13 @@
 {
     switch (classType()) {
     case CrossfadeClass:
-        return static_cast<const CSSCrossfadeValue*>(this)->knownToBeOpaque(renderer);
+        return toCSSCrossfadeValue(this)->knownToBeOpaque(renderer);
     case CanvasClass:
         return false;
     case LinearGradientClass:
-        return static_cast<const CSSLinearGradientValue*>(this)->knownToBeOpaque(renderer);
+        return toCSSLinearGradientValue(this)->knownToBeOpaque(renderer);
     case RadialGradientClass:
-        return static_cast<const CSSRadialGradientValue*>(this)->knownToBeOpaque(renderer);
+        return toCSSRadialGradientValue(this)->knownToBeOpaque(renderer);
     default:
         ASSERT_NOT_REACHED();
     }
@@ -195,16 +195,16 @@
 {
     switch (classType()) {
     case CrossfadeClass:
-        static_cast<CSSCrossfadeValue*>(this)->loadSubimages(fetcher);
+        toCSSCrossfadeValue(this)->loadSubimages(fetcher);
         break;
     case CanvasClass:
-        static_cast<CSSCanvasValue*>(this)->loadSubimages(fetcher);
+        toCSSCanvasValue(this)->loadSubimages(fetcher);
         break;
     case LinearGradientClass:
-        static_cast<CSSLinearGradientValue*>(this)->loadSubimages(fetcher);
+        toCSSLinearGradientValue(this)->loadSubimages(fetcher);
         break;
     case RadialGradientClass:
-        static_cast<CSSRadialGradientValue*>(this)->loadSubimages(fetcher);
+        toCSSRadialGradientValue(this)->loadSubimages(fetcher);
         break;
     default:
         ASSERT_NOT_REACHED();
diff --git a/Source/core/css/CSSImageGeneratorValue.h b/Source/core/css/CSSImageGeneratorValue.h
index 4d96768..d00621c 100644
--- a/Source/core/css/CSSImageGeneratorValue.h
+++ b/Source/core/css/CSSImageGeneratorValue.h
@@ -79,6 +79,8 @@
     HashMap<IntSize, RefPtr<Image> > m_images; // A cache of Image objects by image size.
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(ImageGeneratorValue);
+
 } // namespace WebCore
 
 #endif // CSSImageGeneratorValue_h
diff --git a/Source/core/css/CSSImageValue.h b/Source/core/css/CSSImageValue.h
index 0e66982..9046902 100644
--- a/Source/core/css/CSSImageValue.h
+++ b/Source/core/css/CSSImageValue.h
@@ -67,20 +67,7 @@
     AtomicString m_initiatorName;
 };
 
-inline CSSImageValue* toCSSImageValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isImageValue());
-    return static_cast<CSSImageValue*>(value);
-}
-
-inline const CSSImageValue* toCSSImageValue(const CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isImageValue());
-    return static_cast<const CSSImageValue*>(value);
-}
-
-// Catch unneeded cast.
-void toCSSImageValue(const CSSImageValue*);
+DEFINE_CSS_VALUE_TYPE_CASTS(ImageValue);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSInheritedValue.h b/Source/core/css/CSSInheritedValue.h
index 3e346bf..e2ed7a9 100644
--- a/Source/core/css/CSSInheritedValue.h
+++ b/Source/core/css/CSSInheritedValue.h
@@ -44,6 +44,8 @@
     }
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(InheritedValue);
+
 } // namespace WebCore
 
 #endif // CSSInheritedValue_h
diff --git a/Source/core/css/CSSInitialValue.h b/Source/core/css/CSSInitialValue.h
index f2bc029..a82192a 100644
--- a/Source/core/css/CSSInitialValue.h
+++ b/Source/core/css/CSSInitialValue.h
@@ -53,6 +53,8 @@
     bool m_isImplicit;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(InitialValue);
+
 } // namespace WebCore
 
 #endif // CSSInitialValue_h
diff --git a/Source/core/css/CSSLineBoxContainValue.h b/Source/core/css/CSSLineBoxContainValue.h
index 6e5a050..079f815 100644
--- a/Source/core/css/CSSLineBoxContainValue.h
+++ b/Source/core/css/CSSLineBoxContainValue.h
@@ -56,6 +56,8 @@
     explicit CSSLineBoxContainValue(LineBoxContain);
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(LineBoxContainValue);
+
 } // namespace
 
 #endif
diff --git a/Source/core/css/CSSMatrix.h b/Source/core/css/CSSMatrix.h
index 1f3397d..201c234 100644
--- a/Source/core/css/CSSMatrix.h
+++ b/Source/core/css/CSSMatrix.h
@@ -27,7 +27,7 @@
 #define CSSMatrix_h
 
 #include "bindings/v8/ScriptWrappable.h"
-#include "core/platform/graphics/transforms/TransformationMatrix.h"
+#include "platform/transforms/TransformationMatrix.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
diff --git a/Source/core/css/CSSMixFunctionValue.h b/Source/core/css/CSSMixFunctionValue.h
index e91542d..573437d 100644
--- a/Source/core/css/CSSMixFunctionValue.h
+++ b/Source/core/css/CSSMixFunctionValue.h
@@ -53,6 +53,8 @@
     CSSMixFunctionValue(const CSSMixFunctionValue& cloneFrom);
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(MixFunctionValue);
+
 } // namespace WebCore
 
 
diff --git a/Source/core/css/CSSParser-in.cpp b/Source/core/css/CSSParser-in.cpp
index 118d8a1..77fc6cf 100644
--- a/Source/core/css/CSSParser-in.cpp
+++ b/Source/core/css/CSSParser-in.cpp
@@ -38,6 +38,7 @@
 #include "core/css/CSSCrossfadeValue.h"
 #include "core/css/CSSCursorImageValue.h"
 #include "core/css/CSSFontFaceSrcValue.h"
+#include "core/css/CSSFontFeatureValue.h"
 #include "core/css/CSSFunctionValue.h"
 #include "core/css/CSSGradientValue.h"
 #include "core/css/CSSGridTemplateValue.h"
@@ -55,6 +56,7 @@
 #include "core/css/CSSSVGDocumentValue.h"
 #include "core/css/CSSSelector.h"
 #include "core/css/CSSShaderValue.h"
+#include "core/css/CSSShadowValue.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSTimingFunctionValue.h"
 #include "core/css/CSSTransformValue.h"
@@ -63,12 +65,10 @@
 #include "core/css/CSSValuePool.h"
 #include "core/css/CSSVariableValue.h"
 #include "core/css/Counter.h"
-#include "core/css/FontFeatureValue.h"
 #include "core/css/MediaList.h"
 #include "core/css/MediaQueryExp.h"
 #include "core/css/Pair.h"
 #include "core/css/Rect.h"
-#include "core/css/ShadowValue.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/StyleRule.h"
 #include "core/css/StyleRuleImport.h"
@@ -76,13 +76,12 @@
 #include "core/dom/Document.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/Page.h"
 #include "core/page/PageConsole.h"
 #include "core/page/Settings.h"
-#include "core/platform/FloatConversion.h"
 #include "core/platform/HashTools.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/svg/SVGParserUtilities.h"
+#include "platform/FloatConversion.h"
 #include "wtf/BitArray.h"
 #include "wtf/HexNumber.h"
 #include "wtf/text/StringBuffer.h"
@@ -205,8 +204,6 @@
     : baseURL(baseURL)
     , mode(mode)
     , isHTMLDocument(false)
-    , isCSSCustomFilterEnabled(false)
-    , isCSSStickyPositionEnabled(false)
     , needsSiteSpecificQuirks(false)
     , useLegacyBackgroundSizeShorthandBehavior(false)
 {
@@ -217,8 +214,6 @@
     , charset(charset)
     , mode(document.inQuirksMode() ? CSSQuirksMode : CSSStrictMode)
     , isHTMLDocument(document.isHTMLDocument())
-    , isCSSCustomFilterEnabled(document.settings() ? document.settings()->isCSSCustomFilterEnabled() : false)
-    , isCSSStickyPositionEnabled(document.cssStickyPositionEnabled())
     , needsSiteSpecificQuirks(document.settings() ? document.settings()->needsSiteSpecificQuirks() : false)
     , useLegacyBackgroundSizeShorthandBehavior(document.settings() ? document.settings()->useLegacyBackgroundSizeShorthandBehavior() : false)
 {
@@ -230,8 +225,6 @@
         && a.charset == b.charset
         && a.mode == b.mode
         && a.isHTMLDocument == b.isHTMLDocument
-        && a.isCSSCustomFilterEnabled == b.isCSSCustomFilterEnabled
-        && a.isCSSStickyPositionEnabled == b.isCSSStickyPositionEnabled
         && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks
         && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior;
 }
@@ -694,7 +687,7 @@
         break;
     case CSSPropertyPosition: // static | relative | absolute | fixed | sticky | inherit
         if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed
-            || (parserContext.isCSSStickyPositionEnabled && valueID == CSSValueSticky))
+            || (RuntimeEnabledFeatures::cssStickyPositionEnabled() && valueID == CSSValueSticky))
             return true;
         break;
     case CSSPropertyResize: // none | both | horizontal | vertical | auto
@@ -715,6 +708,12 @@
             && ((valueID >= CSSValueLeft && valueID <= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto))
             return true;
         break;
+    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:
@@ -791,6 +790,15 @@
         if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify)
             return true;
         break;
+    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;
     case CSSPropertyAlignContent:
          if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch)
              return true;
@@ -948,8 +956,6 @@
     case CSSPropertyMixBlendMode:
     case CSSPropertyIsolation:
         return RuntimeEnabledFeatures::cssCompositingEnabled();
-    case CSSPropertyTextAlignLast:
-        return RuntimeEnabledFeatures::css3TextEnabled();
     case CSSPropertyBorderBottomStyle:
     case CSSPropertyBorderCollapse:
     case CSSPropertyBorderLeftStyle:
@@ -979,6 +985,8 @@
     case CSSPropertyResize:
     case CSSPropertySpeak:
     case CSSPropertyTableLayout:
+    case CSSPropertyTextAlignLast:
+    case CSSPropertyTextJustify:
     case CSSPropertyTextLineThroughMode:
     case CSSPropertyTextLineThroughStyle:
     case CSSPropertyTextOverflow:
@@ -1003,9 +1011,11 @@
     case CSSPropertyWebkitBoxLines:
     case CSSPropertyWebkitBoxOrient:
     case CSSPropertyWebkitBoxPack:
+    case CSSPropertyInternalCallback:
     case CSSPropertyWebkitColumnBreakAfter:
     case CSSPropertyWebkitColumnBreakBefore:
     case CSSPropertyWebkitColumnBreakInside:
+    case CSSPropertyColumnFill:
     case CSSPropertyWebkitColumnRuleStyle:
     case CSSPropertyAlignContent:
     case CSSPropertyAlignItems:
@@ -1487,7 +1497,7 @@
 {
     bool mustBeNonNegative = unitflags & FNonNeg;
 
-    if (!parseCalculation(value, mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll))
+    if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
         return false;
 
     bool b = false;
@@ -1526,8 +1536,8 @@
 
 inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode)
 {
-    // Qirks mode and svg presentation attributes accept unit less values.
-    return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode);
+    // Quirks mode and presentation attributes accept unit less values.
+    return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode || cssParserMode == CSSAttributeMode);
 }
 
 bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode, ReleaseParsedCalcValueCondition releaseCalc)
@@ -1694,7 +1704,7 @@
 
 bool CSSParser::parseValue(CSSPropertyID propId, bool important)
 {
-    if (m_context.mode != UASheetMode && isInternalProperty(propId))
+    if ((m_context.mode != UASheetMode && m_context.mode != CSSAttributeMode) && isInternalProperty(propId))
         return false;
 
     // We don't count the UA style sheet in our statistics.
@@ -2792,6 +2802,9 @@
     case CSSPropertyWebkitShapePadding:
         validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FLength | FNonNeg));
         break;
+    case CSSPropertyWebkitShapeImageThreshold:
+        validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FNumber));
+        break;
     case CSSPropertyBorderBottomStyle:
     case CSSPropertyBorderCollapse:
     case CSSPropertyBorderLeftStyle:
@@ -2822,6 +2835,7 @@
     case CSSPropertySpeak:
     case CSSPropertyTableLayout:
     case CSSPropertyTextAlignLast:
+    case CSSPropertyTextJustify:
     case CSSPropertyTextLineThroughMode:
     case CSSPropertyTextLineThroughStyle:
     case CSSPropertyTextOverflow:
@@ -2847,9 +2861,11 @@
     case CSSPropertyWebkitBoxLines:
     case CSSPropertyWebkitBoxOrient:
     case CSSPropertyWebkitBoxPack:
+    case CSSPropertyInternalCallback:
     case CSSPropertyWebkitColumnBreakAfter:
     case CSSPropertyWebkitColumnBreakBefore:
     case CSSPropertyWebkitColumnBreakInside:
+    case CSSPropertyColumnFill:
     case CSSPropertyWebkitColumnRuleStyle:
     case CSSPropertyAlignContent:
     case CSSPropertyAlignItems:
@@ -6383,7 +6399,7 @@
                 values = CSSValueList::createCommaSeparated();
 
             // Construct the current shadow value and add it to the list.
-            values->append(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
+            values->append(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
         }
 
         // Now reset for the next shadow value.
@@ -7395,7 +7411,7 @@
         a = args->next();
         if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
             return false;
-        static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(createPrimitiveNumericValue(a));
+        toCSSRadialGradientValue(result.get())->setFirstRadius(createPrimitiveNumericValue(a));
 
         // Comma after the first radius.
         a = args->next();
@@ -7432,7 +7448,7 @@
         a = args->next();
         if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
             return false;
-        static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(createPrimitiveNumericValue(a));
+        toCSSRadialGradientValue(result.get())->setSecondRadius(createPrimitiveNumericValue(a));
     }
 
     // We now will accept any number of stops (0 or more).
@@ -8887,7 +8903,7 @@
 
             if (filterType == CSSFilterValue::CustomFilterOperation) {
                 // Make sure parsing fails if custom filters are disabled.
-                if (!m_context.isCSSCustomFilterEnabled)
+                if (!RuntimeEnabledFeatures::cssCustomFilterEnabled())
                     return 0;
 
                 RefPtr<CSSFilterValue> filterValue = parseCustomFilterFunction(value);
@@ -9320,7 +9336,7 @@
             m_valueList->next();
         }
     }
-    settings->append(FontFeatureValue::create(tag, tagValue));
+    settings->append(CSSFontFeatureValue::create(tag, tagValue));
     return true;
 }
 
@@ -9395,7 +9411,7 @@
     return true;
 }
 
-bool CSSParser::parseCalculation(CSSParserValue* value, CalculationPermittedValueRange range)
+bool CSSParser::parseCalculation(CSSParserValue* value, ValueRange range)
 {
     ASSERT(isCalculation(value));
 
@@ -10174,6 +10190,9 @@
         CASE("only") {
             m_token = MEDIA_ONLY;
         }
+        CASE("or") {
+            m_token = MEDIA_OR;
+        }
     }
 }
 
diff --git a/Source/core/css/CSSParser.h b/Source/core/css/CSSParser.h
index a63df8f..8ca92c9 100644
--- a/Source/core/css/CSSParser.h
+++ b/Source/core/css/CSSParser.h
@@ -38,7 +38,7 @@
 #include "core/page/UseCounter.h"
 #include "core/platform/graphics/Color.h"
 #include "wtf/HashSet.h"
-#include "wtf/OwnArrayPtr.h"
+#include "wtf/OwnPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/TextPosition.h"
@@ -286,7 +286,7 @@
     PassRefPtr<CSSValue> parseTextIndent();
 
     bool parseLineBoxContain(bool important);
-    bool parseCalculation(CSSParserValue*, CalculationPermittedValueRange);
+    bool parseCalculation(CSSParserValue*, ValueRange);
 
     bool parseFontFeatureTag(CSSValueList*);
     bool parseFontFeatureSettings(bool important);
@@ -564,7 +564,7 @@
     void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
 
     inline bool inStrictMode() const { return isStrictParserMode(m_context.mode); }
-    inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
+    inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode || m_context.mode == CSSAttributeMode; }
 
     KURL completeURL(const String& url) const;
 
@@ -614,8 +614,8 @@
 
     ParsingMode m_parsingMode;
     bool m_is8BitSource;
-    OwnArrayPtr<LChar> m_dataStart8;
-    OwnArrayPtr<UChar> m_dataStart16;
+    OwnPtr<LChar[]> m_dataStart8;
+    OwnPtr<UChar[]> m_dataStart16;
     LChar* m_currentCharacter8;
     UChar* m_currentCharacter16;
     const String* m_source;
diff --git a/Source/core/css/CSSParserMode.h b/Source/core/css/CSSParserMode.h
index 6a40a5f..3914554 100644
--- a/Source/core/css/CSSParserMode.h
+++ b/Source/core/css/CSSParserMode.h
@@ -42,6 +42,8 @@
     CSSStrictMode,
     // SVG should always be in strict mode. For SVG attributes, the rules differ to strict sometimes.
     SVGAttributeMode,
+    // CSS attribute are parsed in quirks mode. They also allow internal only properties and values.
+    CSSAttributeMode,
     // User agent style sheet should always be in strict mode. Enables internal
     // only properties and values.
     UASheetMode,
@@ -70,10 +72,6 @@
     String charset;
     CSSParserMode mode;
     bool isHTMLDocument;
-    bool isCSSCustomFilterEnabled;
-    bool isCSSStickyPositionEnabled;
-    bool isCSSCompositingEnabled;
-    bool isCSSTouchActionEnabled;
     bool needsSiteSpecificQuirks;
     // This quirk is to maintain compatibility with Android apps built on
     // the Android SDK prior to and including version 18. Presumably, this
diff --git a/Source/core/css/CSSPrimitiveValue.cpp b/Source/core/css/CSSPrimitiveValue.cpp
index fa13eda..ed807fb 100644
--- a/Source/core/css/CSSPrimitiveValue.cpp
+++ b/Source/core/css/CSSPrimitiveValue.cpp
@@ -35,9 +35,9 @@
 #include "core/css/StyleSheetContents.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/Node.h"
-#include "core/platform/LayoutUnit.h"
 #include "core/platform/graphics/Color.h"
 #include "core/rendering/style/RenderStyle.h"
+#include "platform/LayoutUnit.h"
 #include "wtf/DecimalNumber.h"
 #include "wtf/StdLibExtras.h"
 #include "wtf/text/StringBuffer.h"
@@ -275,7 +275,7 @@
     m_value.rgbcolor = color;
 }
 
-CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle* style)
+CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, float zoom)
     : CSSValue(PrimitiveClass)
 {
     switch (length.type()) {
@@ -296,10 +296,10 @@
         return;
     case Fixed:
         m_primitiveUnitType = CSS_PX;
-        m_value.num = adjustFloatForAbsoluteZoom(length.value(), style);
+        m_value.num = length.value() / zoom;
         return;
     case Calculated:
-        init(CSSCalcValue::create(length.calculationValue().get(), style));
+        init(CSSCalcValue::create(length.calculationValue(), zoom));
         return;
     case Relative:
     case Undefined:
diff --git a/Source/core/css/CSSPrimitiveValue.h b/Source/core/css/CSSPrimitiveValue.h
index 4d2e614..b4ca9d1 100644
--- a/Source/core/css/CSSPrimitiveValue.h
+++ b/Source/core/css/CSSPrimitiveValue.h
@@ -204,7 +204,7 @@
     static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); }
     static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
     static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
-    static PassRefPtr<CSSPrimitiveValue> create(const Length& value, const RenderStyle* style) { return adoptRef(new CSSPrimitiveValue(value, style)); }
+    static PassRefPtr<CSSPrimitiveValue> create(const Length& value, float zoom) { return adoptRef(new CSSPrimitiveValue(value, zoom)); }
 
     template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value)
     {
@@ -337,7 +337,7 @@
     {
         init(length);
     }
-    CSSPrimitiveValue(const Length&, const RenderStyle*);
+    CSSPrimitiveValue(const Length&, float zoom);
     CSSPrimitiveValue(const String&, UnitTypes);
     CSSPrimitiveValue(double, UnitTypes);
 
@@ -385,20 +385,7 @@
     } m_value;
 };
 
-inline CSSPrimitiveValue* toCSSPrimitiveValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isPrimitiveValue());
-    return static_cast<CSSPrimitiveValue*>(value);
-}
-
-inline const CSSPrimitiveValue* toCSSPrimitiveValue(const CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isPrimitiveValue());
-    return static_cast<const CSSPrimitiveValue*>(value);
-}
-
-// Catch unneeded cast.
-void toCSSPrimitiveValue(const CSSPrimitiveValue*);
+DEFINE_CSS_VALUE_TYPE_CASTS(PrimitiveValue);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSPrimitiveValueMappings.h b/Source/core/css/CSSPrimitiveValueMappings.h
index 0de35fd..2778533 100644
--- a/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/Source/core/css/CSSPrimitiveValueMappings.h
@@ -41,12 +41,12 @@
 #include "core/platform/ThemeTypes.h"
 #include "core/platform/graphics/Path.h"
 #include "core/platform/graphics/TextRenderingMode.h"
-#include "core/platform/text/TextDirection.h"
-#include "core/platform/text/UnicodeBidi.h"
-#include "core/platform/text/WritingMode.h"
 #include "core/rendering/style/LineClampValue.h"
 #include "core/rendering/style/RenderStyleConstants.h"
 #include "core/rendering/style/SVGRenderStyleDefs.h"
+#include "platform/text/TextDirection.h"
+#include "platform/text/UnicodeBidi.h"
+#include "platform/text/WritingMode.h"
 #include "wtf/MathExtras.h"
 
 namespace WebCore {
@@ -176,6 +176,32 @@
     return ReflectionBelow;
 }
 
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnFill columnFill)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (columnFill) {
+    case ColumnFillAuto:
+        m_value.valueID = CSSValueAuto;
+        break;
+    case ColumnFillBalance:
+        m_value.valueID = CSSValueBalance;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator ColumnFill() const
+{
+    if (m_primitiveUnitType == CSS_VALUE_ID) {
+        if (m_value.valueID == CSSValueBalance)
+            return ColumnFillBalance;
+        if (m_value.valueID == CSSValueAuto)
+            return ColumnFillAuto;
+    }
+    ASSERT_NOT_REACHED();
+    return ColumnFillBalance;
+}
+
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnSpan columnSpan)
     : CSSValue(PrimitiveClass)
 {
@@ -2394,6 +2420,45 @@
     return TextAlignLastAuto;
 }
 
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextJustify e)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (e) {
+    case TextJustifyAuto:
+        m_value.valueID = CSSValueAuto;
+        break;
+    case TextJustifyNone:
+        m_value.valueID = CSSValueNone;
+        break;
+    case TextJustifyInterWord:
+        m_value.valueID = CSSValueInterWord;
+        break;
+    case TextJustifyDistribute:
+        m_value.valueID = CSSValueDistribute;
+        break;
+    }
+}
+
+template<> inline CSSPrimitiveValue::operator TextJustify() const
+{
+    switch (m_value.valueID) {
+    case CSSValueAuto:
+        return TextJustifyAuto;
+    case CSSValueNone:
+        return TextJustifyNone;
+    case CSSValueInterWord:
+        return TextJustifyInterWord;
+    case CSSValueDistribute:
+        return TextJustifyDistribute;
+    default:
+        break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return TextJustifyAuto;
+}
+
 template<> inline CSSPrimitiveValue::operator TextDecoration() const
 {
     ASSERT(isValueID());
@@ -3398,6 +3463,26 @@
     }
 }
 
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFillSizeType fillSize)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (fillSize) {
+    case Contain:
+        m_value.valueID = CSSValueContain;
+        break;
+    case Cover:
+        m_value.valueID = CSSValueCover;
+        break;
+    case SizeNone:
+        m_value.valueID = CSSValueNone;
+        break;
+    case SizeLength:
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmoothingMode smoothing)
     : CSSValue(PrimitiveClass)
 {
diff --git a/Source/core/css/CSSProperties.in b/Source/core/css/CSSProperties.in
index 4bcc442..67d22c2 100644
--- a/Source/core/css/CSSProperties.in
+++ b/Source/core/css/CSSProperties.in
@@ -116,6 +116,7 @@
 text-decoration-color custom_all
 text-decoration-style type_name=TextDecorationStyle
 text-indent custom_all
+text-justify type_name=TextJustify
 text-overflow type_name=TextOverflow
 text-rendering custom_all
 text-transform
@@ -168,6 +169,7 @@
 -webkit-column-break-before type_name=EPageBreak, initial=initialPageBreak
 -webkit-column-break-inside type_name=EPageBreak, initial=initialPageBreak
 -webkit-column-count type_name=unsigned short, custom_all
+column-fill type_name=ColumnFill
 -webkit-column-gap type_name=float, custom_all
 -webkit-column-progression type_name=ColumnProgression
 -webkit-column-rule-color custom_all
@@ -225,6 +227,7 @@
 -webkit-shape-margin type_name=Length, converter=convertLength
 -webkit-shape-outside type_name=ShapeValue*, custom_value
 -webkit-shape-padding type_name=Length, converter=convertLength
+-webkit-shape-image-threshold type_name=float
 -webkit-text-combine type_name=TextCombine
 -webkit-text-emphasis-color custom_all
 -webkit-text-emphasis-position type_name=TextEmphasisPosition
diff --git a/Source/core/css/CSSProperty.cpp b/Source/core/css/CSSProperty.cpp
index 56e95f1..c3bcb10 100644
--- a/Source/core/css/CSSProperty.cpp
+++ b/Source/core/css/CSSProperty.cpp
@@ -309,6 +309,7 @@
     case CSSPropertyTabSize:
     case CSSPropertyTextAlign:
     case CSSPropertyTextAlignLast:
+    case CSSPropertyTextJustify:
     case CSSPropertyTextAnchor:
     case CSSPropertyTextIndent:
     case CSSPropertyTextRendering:
@@ -557,12 +558,14 @@
     case CSSPropertyWebkitBoxPack:
     case CSSPropertyWebkitBoxReflect:
     case CSSPropertyWebkitBoxShadow:
+    case CSSPropertyInternalCallback:
     case CSSPropertyWebkitClipPath:
     case CSSPropertyWebkitColumnAxis:
     case CSSPropertyWebkitColumnBreakAfter:
     case CSSPropertyWebkitColumnBreakBefore:
     case CSSPropertyWebkitColumnBreakInside:
     case CSSPropertyWebkitColumnCount:
+    case CSSPropertyColumnFill:
     case CSSPropertyWebkitColumnGap:
     case CSSPropertyWebkitColumnProgression:
     case CSSPropertyWebkitColumnRule:
@@ -663,6 +666,7 @@
     case CSSPropertyWebkitRegionFragment:
     case CSSPropertyWebkitWrapFlow:
     case CSSPropertyWebkitShapeMargin:
+    case CSSPropertyWebkitShapeImageThreshold:
     case CSSPropertyWebkitShapePadding:
     case CSSPropertyWebkitShapeInside:
     case CSSPropertyWebkitShapeOutside:
diff --git a/Source/core/css/CSSProperty.h b/Source/core/css/CSSProperty.h
index fd802ec..a0fb377 100644
--- a/Source/core/css/CSSProperty.h
+++ b/Source/core/css/CSSProperty.h
@@ -24,8 +24,8 @@
 #include "CSSPropertyNames.h"
 #include "RuntimeEnabledFeatures.h"
 #include "core/css/CSSValue.h"
-#include "core/platform/text/TextDirection.h"
-#include "core/platform/text/WritingMode.h"
+#include "platform/text/TextDirection.h"
+#include "platform/text/WritingMode.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 
diff --git a/Source/core/css/CSSPropertyNames.in b/Source/core/css/CSSPropertyNames.in
index 2f88d93..3ed1bd4 100644
--- a/Source/core/css/CSSPropertyNames.in
+++ b/Source/core/css/CSSPropertyNames.in
@@ -195,6 +195,7 @@
 text-decoration-style
 text-decoration-color
 text-indent
+text-justify
 text-line-through-color
 text-line-through-mode
 text-line-through-style
@@ -270,11 +271,13 @@
 -webkit-box-pack
 -webkit-box-reflect
 -webkit-box-shadow
+-internal-callback
 -webkit-column-axis
 -webkit-column-break-after
 -webkit-column-break-before
 -webkit-column-break-inside
 -webkit-column-count
+column-fill
 -webkit-column-gap
 -webkit-column-progression
 -webkit-column-rule
@@ -411,6 +414,7 @@
 -webkit-shape-outside
 -webkit-shape-margin
 -webkit-shape-padding
+-webkit-shape-image-threshold
 -webkit-wrap-flow
 -webkit-wrap-through
 max-zoom
diff --git a/Source/core/css/CSSRule.cpp b/Source/core/css/CSSRule.cpp
index d71bee1..8f8e834 100644
--- a/Source/core/css/CSSRule.cpp
+++ b/Source/core/css/CSSRule.cpp
@@ -25,7 +25,7 @@
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/StyleRule.h"
 #include "core/css/StyleSheetContents.h"
-#include "core/platform/NotImplemented.h"
+#include "platform/NotImplemented.h"
 
 namespace WebCore {
 
diff --git a/Source/core/css/CSSRule.idl b/Source/core/css/CSSRule.idl
index 94ce538..2489d2d 100644
--- a/Source/core/css/CSSRule.idl
+++ b/Source/core/css/CSSRule.idl
@@ -37,8 +37,8 @@
     const unsigned short KEYFRAME_RULE = 8;
     const unsigned short WEBKIT_KEYFRAME_RULE = 8;
     const unsigned short SUPPORTS_RULE = 12;
-    [EnabledAtRuntime=CSSViewport] const unsigned short VIEWPORT_RULE = 15;
-    [EnabledAtRuntime=CSSRegions] const unsigned short WEBKIT_REGION_RULE = 16;
+    [RuntimeEnabled=CSSViewport] const unsigned short VIEWPORT_RULE = 15;
+    [RuntimeEnabled=CSSRegions] const unsigned short WEBKIT_REGION_RULE = 16;
     const unsigned short WEBKIT_FILTER_RULE = 17;
     const unsigned short HOST_RULE = 1001;
 
diff --git a/Source/core/css/CSSSVGDocumentValue.h b/Source/core/css/CSSSVGDocumentValue.h
index 7e43406..fad50a6 100644
--- a/Source/core/css/CSSSVGDocumentValue.h
+++ b/Source/core/css/CSSSVGDocumentValue.h
@@ -54,6 +54,8 @@
     bool m_loadRequested;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(SVGDocumentValue);
+
 } // namespace WebCore
 
 #endif // CSSSVGDocumentValue_h
diff --git a/Source/core/css/CSSSegmentedFontFace.cpp b/Source/core/css/CSSSegmentedFontFace.cpp
index 60bc3c5..96c553f 100644
--- a/Source/core/css/CSSSegmentedFontFace.cpp
+++ b/Source/core/css/CSSSegmentedFontFace.cpp
@@ -26,8 +26,9 @@
 #include "config.h"
 #include "core/css/CSSSegmentedFontFace.h"
 
-#include "core/css/CSSFontFace.h"
 #include "RuntimeEnabledFeatures.h"
+#include "core/css/CSSFontFace.h"
+#include "core/platform/graphics/FontCache.h"
 #include "core/platform/graphics/FontDescription.h"
 #include "core/platform/graphics/SegmentedFontData.h"
 #include "core/platform/graphics/SimpleFontData.h"
@@ -77,7 +78,7 @@
         Vector<RefPtr<LoadFontCallback> > callbacks;
         m_callbacks.swap(callbacks);
         for (size_t index = 0; index < callbacks.size(); ++index) {
-            if (checkFont())
+            if (isLoaded())
                 callbacks[index]->notifyLoaded(this);
             else
                 callbacks[index]->notifyError(this);
@@ -92,7 +93,7 @@
     m_fontFaces.append(fontFace);
 }
 
-static void appendFontData(SegmentedFontData* newFontData, PassRefPtr<SimpleFontData> prpFaceFontData, const Vector<CSSFontFace::UnicodeRange>& ranges)
+static void appendFontData(SegmentedFontData* newFontData, PassRefPtr<SimpleFontData> prpFaceFontData, const CSSFontFace::UnicodeRangeSet& ranges)
 {
     RefPtr<SimpleFontData> faceFontData = prpFaceFontData;
     unsigned numRanges = ranges.size();
@@ -102,7 +103,7 @@
     }
 
     for (unsigned j = 0; j < numRanges; ++j)
-        newFontData->appendRange(FontDataRange(ranges[j].from(), ranges[j].to(), faceFontData));
+        newFontData->appendRange(FontDataRange(ranges.rangeAt(j).from(), ranges.rangeAt(j).to(), faceFontData));
 }
 
 PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription)
@@ -110,8 +111,14 @@
     if (!isValid())
         return 0;
 
+    float fontSize;
+    if (RuntimeEnabledFeatures::subpixelFontScalingEnabled())
+        fontSize = fontDescription.computedSize();
+    else
+        fontSize = fontDescription.computedPixelSize();
+
     FontTraitsMask desiredTraitsMask = fontDescription.traitsMask();
-    unsigned hashKey = ((fontDescription.computedPixelSize() + 1) << (FontTraitsMaskWidth + FontWidthVariantWidth + 1))
+    unsigned hashKey = ((static_cast<unsigned>(fontSize * FontCache::s_fontSizePrecisionMultiplier) + 1) << (FontTraitsMaskWidth + FontWidthVariantWidth + 1))
         | ((fontDescription.orientation() == Vertical ? 1 : 0) << (FontTraitsMaskWidth + FontWidthVariantWidth))
         | fontDescription.widthVariant() << FontTraitsMaskWidth
         | desiredTraitsMask;
@@ -131,6 +138,12 @@
             continue;
         if (RefPtr<SimpleFontData> faceFontData = m_fontFaces[i]->getFontData(fontDescription, syntheticBold, syntheticItalic)) {
             ASSERT(!faceFontData->isSegmented());
+#if ENABLE(SVG_FONTS)
+            // For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable
+            // of small-caps synthesis and just ignore the font face.
+            if (faceFontData->isSVGFont() && (desiredTraitsMask & FontVariantSmallCapsMask) && !(m_traitsMask & FontVariantSmallCapsMask))
+                continue;
+#endif
             appendFontData(fontData.get(), faceFontData.release(), m_fontFaces[i]->ranges());
         }
     }
@@ -140,16 +153,6 @@
     return 0;
 }
 
-bool CSSSegmentedFontFace::hasSVGFontFaceSource() const
-{
-    unsigned size = m_fontFaces.size();
-    for (unsigned i = 0; i < size; i++) {
-        if (m_fontFaces[i]->hasSVGFontFaceSource())
-            return true;
-    }
-    return false;
-}
-
 bool CSSSegmentedFontFace::isLoading() const
 {
     unsigned size = m_fontFaces.size();
@@ -160,14 +163,7 @@
     return false;
 }
 
-void CSSSegmentedFontFace::willUseFontData(const FontDescription& fontDescription)
-{
-    unsigned size = m_fontFaces.size();
-    for (unsigned i = 0; i < size; i++)
-        m_fontFaces[i]->willUseFontData(fontDescription);
-}
-
-bool CSSSegmentedFontFace::checkFont() const
+bool CSSSegmentedFontFace::isLoaded() const
 {
     unsigned size = m_fontFaces.size();
     for (unsigned i = 0; i < size; i++) {
@@ -177,30 +173,50 @@
     return true;
 }
 
-void CSSSegmentedFontFace::loadFont(const FontDescription& fontDescription, PassRefPtr<LoadFontCallback> callback)
+void CSSSegmentedFontFace::willUseFontData(const FontDescription& fontDescription)
 {
-    RefPtr<SegmentedFontData> fontData = toSegmentedFontData(getFontData(fontDescription).get());
-    unsigned numRanges = fontData->numRanges();
-    for (unsigned i = 0; i < numRanges; i++)
-        fontData->rangeAt(i).fontData()->beginLoadIfNeeded();
+    unsigned size = m_fontFaces.size();
+    for (unsigned i = 0; i < size; i++)
+        m_fontFaces[i]->willUseFontData(fontDescription);
+}
+
+bool CSSSegmentedFontFace::checkFont(const String& text) const
+{
+    unsigned size = m_fontFaces.size();
+    for (unsigned i = 0; i < size; i++) {
+        if (m_fontFaces[i]->loadStatus() != FontFace::Loaded && m_fontFaces[i]->ranges().intersectsWith(text))
+            return false;
+    }
+    return true;
+}
+
+void CSSSegmentedFontFace::loadFont(const FontDescription& fontDescription, const String& text, PassRefPtr<LoadFontCallback> callback)
+{
+    unsigned size = m_fontFaces.size();
+    for (unsigned i = 0; i < size; i++) {
+        if (m_fontFaces[i]->loadStatus() == FontFace::Unloaded && m_fontFaces[i]->ranges().intersectsWith(text)) {
+            RefPtr<SimpleFontData> fontData = m_fontFaces[i]->getFontData(fontDescription, false, false);
+            fontData->beginLoadIfNeeded();
+        }
+    }
 
     if (callback) {
         if (isLoading())
             m_callbacks.append(callback);
-        else if (checkFont())
+        else if (isLoaded())
             callback->notifyLoaded(this);
         else
             callback->notifyError(this);
     }
 }
 
-Vector<RefPtr<FontFace> > CSSSegmentedFontFace::fontFaces() const
+Vector<RefPtr<FontFace> > CSSSegmentedFontFace::fontFaces(const String& text) const
 {
     Vector<RefPtr<FontFace> > fontFaces;
     unsigned size = m_fontFaces.size();
     for (unsigned i = 0; i < size; i++) {
         RefPtr<FontFace> face = m_fontFaces[i]->fontFace();
-        if (face)
+        if (face && m_fontFaces[i]->ranges().intersectsWith(text))
             fontFaces.append(face);
     }
     return fontFaces;
diff --git a/Source/core/css/CSSSegmentedFontFace.h b/Source/core/css/CSSSegmentedFontFace.h
index a9a624d..7cfa61d 100644
--- a/Source/core/css/CSSSegmentedFontFace.h
+++ b/Source/core/css/CSSSegmentedFontFace.h
@@ -31,6 +31,7 @@
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
@@ -56,10 +57,6 @@
 
     PassRefPtr<FontData> getFontData(const FontDescription&);
 
-#if ENABLE(SVG_FONTS)
-    bool hasSVGFontFaceSource() const;
-#endif
-
     class LoadFontCallback : public RefCounted<LoadFontCallback> {
     public:
         virtual ~LoadFontCallback() { }
@@ -67,9 +64,9 @@
         virtual void notifyError(CSSSegmentedFontFace*) = 0;
     };
 
-    bool checkFont() const;
-    void loadFont(const FontDescription&, PassRefPtr<LoadFontCallback> loadCallback);
-    Vector<RefPtr<FontFace> > fontFaces() const;
+    bool checkFont(const String&) const;
+    void loadFont(const FontDescription&, const String&, PassRefPtr<LoadFontCallback>);
+    Vector<RefPtr<FontFace> > fontFaces(const String& text) const;
     void willUseFontData(const FontDescription&);
 
 private:
@@ -78,6 +75,7 @@
     void pruneTable();
     bool isValid() const;
     bool isLoading() const;
+    bool isLoaded() const;
 
     CSSFontSelector* m_fontSelector;
     FontTraitsMask m_traitsMask;
diff --git a/Source/core/css/CSSSegmentedFontFaceCache.cpp b/Source/core/css/CSSSegmentedFontFaceCache.cpp
new file mode 100644
index 0000000..160bcdf
--- /dev/null
+++ b/Source/core/css/CSSSegmentedFontFaceCache.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "CSSSegmentedFontFaceCache.h"
+
+#include "FontFamilyNames.h"
+#include "core/css/CSSFontFace.h"
+#include "core/css/CSSFontFaceSource.h"
+#include "core/css/CSSFontSelector.h"
+#include "core/css/CSSSegmentedFontFace.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/StyleRule.h"
+#include "core/dom/Document.h"
+#include "core/fetch/FontResource.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/Frame.h"
+#include "core/page/Settings.h"
+#include "core/platform/graphics/FontCache.h"
+#include "core/platform/graphics/FontDescription.h"
+#include "core/platform/graphics/SimpleFontData.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+using namespace FontFamilyNames;
+
+
+CSSSegmentedFontFaceCache::CSSSegmentedFontFaceCache()
+    : m_version(0)
+{
+}
+
+void CSSSegmentedFontFaceCache::addFontFaceRule(CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule)
+{
+    RefPtr<FontFace> fontFace = FontFace::create(fontFaceRule);
+    if (!fontFace || fontFace->family().isEmpty())
+        return;
+
+    unsigned traitsMask = fontFace->traitsMask();
+    if (!traitsMask)
+        return;
+
+    RefPtr<CSSFontFace> cssFontFace = fontFace->createCSSFontFace(cssFontSelector->document());
+    if (!cssFontFace || !cssFontFace->isValid())
+        return;
+
+    OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& familyFontFaces = m_fontFaces.add(fontFace->family(), nullptr).iterator->value;
+    if (!familyFontFaces) {
+        familyFontFaces = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >);
+
+        ASSERT(!m_locallyInstalledFontFaces.contains(fontFace->family()));
+
+        Vector<unsigned> locallyInstalledFontsTraitsMasks;
+        fontCache()->getTraitsInFamily(fontFace->family(), locallyInstalledFontsTraitsMasks);
+        if (unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size()) {
+            OwnPtr<Vector<RefPtr<CSSSegmentedFontFace> > > familyLocallyInstalledFaces = adoptPtr(new Vector<RefPtr<CSSSegmentedFontFace> >);
+
+            for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) {
+                RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(0);
+                locallyInstalledFontFace->addSource(adoptPtr(new CSSFontFaceSource(fontFace->family())));
+                ASSERT(locallyInstalledFontFace->isValid());
+
+                RefPtr<CSSSegmentedFontFace> segmentedFontFace = CSSSegmentedFontFace::create(cssFontSelector, static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]), true);
+                segmentedFontFace->appendFontFace(locallyInstalledFontFace.release());
+                familyLocallyInstalledFaces->append(segmentedFontFace);
+            }
+
+            m_locallyInstalledFontFaces.set(fontFace->family(), familyLocallyInstalledFaces.release());
+        }
+    }
+
+    RefPtr<CSSSegmentedFontFace>& segmentedFontFace = familyFontFaces->add(traitsMask, 0).iterator->value;
+    if (!segmentedFontFace)
+        segmentedFontFace = CSSSegmentedFontFace::create(cssFontSelector, static_cast<FontTraitsMask>(traitsMask), false);
+
+    segmentedFontFace->appendFontFace(cssFontFace);
+
+    ++m_version;
+}
+
+
+static PassRefPtr<FontData> fontDataForGenericFamily(Settings* settings, const FontDescription& fontDescription, const AtomicString& familyName)
+{
+    if (!settings)
+        return 0;
+
+    AtomicString genericFamily;
+    UScriptCode script = fontDescription.script();
+
+#if OS(ANDROID)
+    genericFamily = FontCache::getGenericFamilyNameForScript(familyName, script);
+#else
+    if (familyName == serifFamily)
+        genericFamily = settings->serifFontFamily(script);
+    else if (familyName == sansSerifFamily)
+        genericFamily = settings->sansSerifFontFamily(script);
+    else if (familyName == cursiveFamily)
+        genericFamily = settings->cursiveFontFamily(script);
+    else if (familyName == fantasyFamily)
+        genericFamily = settings->fantasyFontFamily(script);
+    else if (familyName == monospaceFamily)
+        genericFamily = settings->fixedFontFamily(script);
+    else if (familyName == pictographFamily)
+        genericFamily = settings->pictographFontFamily(script);
+    else if (familyName == standardFamily)
+        genericFamily = settings->standardFontFamily(script);
+#endif
+
+    if (!genericFamily.isEmpty())
+        return fontCache()->getFontResourceData(fontDescription, genericFamily);
+
+    return 0;
+}
+
+static inline bool compareFontFaces(CSSSegmentedFontFace* first, CSSSegmentedFontFace* second, FontTraitsMask desiredTraitsMask)
+{
+    FontTraitsMask firstTraitsMask = first->traitsMask();
+    FontTraitsMask secondTraitsMask = second->traitsMask();
+
+    bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMask & FontVariantMask;
+    bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMask & FontVariantMask;
+
+    if (firstHasDesiredVariant != secondHasDesiredVariant)
+        return firstHasDesiredVariant;
+
+    // We need to check font-variant css property for CSS2.1 compatibility.
+    if ((desiredTraitsMask & FontVariantSmallCapsMask) && !first->isLocalFallback() && !second->isLocalFallback()) {
+        // Prefer a font that has indicated that it can only support small-caps to a font that claims to support
+        // all variants. The specialized font is more likely to be true small-caps and not require synthesis.
+        bool firstRequiresSmallCaps = (firstTraitsMask & FontVariantSmallCapsMask) && !(firstTraitsMask & FontVariantNormalMask);
+        bool secondRequiresSmallCaps = (secondTraitsMask & FontVariantSmallCapsMask) && !(secondTraitsMask & FontVariantNormalMask);
+        if (firstRequiresSmallCaps != secondRequiresSmallCaps)
+            return firstRequiresSmallCaps;
+    }
+
+    bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMask & FontStyleMask;
+    bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMask & FontStyleMask;
+
+    if (firstHasDesiredStyle != secondHasDesiredStyle)
+        return firstHasDesiredStyle;
+
+    if ((desiredTraitsMask & FontStyleItalicMask) && !first->isLocalFallback() && !second->isLocalFallback()) {
+        // Prefer a font that has indicated that it can only support italics to a font that claims to support
+        // all styles. The specialized font is more likely to be the one the author wants used.
+        bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask);
+        bool secondRequiresItalics = (secondTraitsMask & FontStyleItalicMask) && !(secondTraitsMask & FontStyleNormalMask);
+        if (firstRequiresItalics != secondRequiresItalics)
+            return firstRequiresItalics;
+    }
+
+    if (secondTraitsMask & desiredTraitsMask & FontWeightMask)
+        return false;
+    if (firstTraitsMask & desiredTraitsMask & FontWeightMask)
+        return true;
+
+    // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says :
+    //   - If the desired weight is less than 400, weights below the desired weight are checked in descending order followed by weights above the desired weight in ascending order until a match is found.
+    //   - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found.
+    //   - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used.
+    //   - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used.
+
+    static const unsigned fallbackRuleSets = 9;
+    static const unsigned rulesPerSet = 8;
+    static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
+        { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
+        { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
+        { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
+        { FontWeight500Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
+        { FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
+        { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
+        { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
+        { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
+        { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }
+    };
+
+    unsigned ruleSetIndex = 0;
+    unsigned w = FontWeight100Bit;
+    while (!(desiredTraitsMask & (1 << w))) {
+        w++;
+        ruleSetIndex++;
+    }
+
+    ASSERT(ruleSetIndex < fallbackRuleSets);
+    const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
+    for (unsigned i = 0; i < rulesPerSet; ++i) {
+        if (secondTraitsMask & weightFallbackRule[i])
+            return false;
+        if (firstTraitsMask & weightFallbackRule[i])
+            return true;
+    }
+
+    return false;
+}
+
+PassRefPtr<FontData> CSSSegmentedFontFaceCache::getFontData(Settings* settings, const FontDescription& fontDescription, const AtomicString& familyName)
+{
+    if (m_fontFaces.isEmpty()) {
+        if (familyName.startsWith("-webkit-"))
+            return fontDataForGenericFamily(settings, fontDescription, familyName);
+        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
+            return fontDataForGenericFamily(settings, fontDescription, "-webkit-standard");
+        return 0;
+    }
+
+    CSSSegmentedFontFace* face = getFontFace(fontDescription, familyName);
+    // If no face was found, then return 0 and let the OS come up with its best match for the name.
+    if (!face) {
+        // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our
+        // settings.
+        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
+            return fontDataForGenericFamily(settings, fontDescription, "-webkit-standard");
+        return fontDataForGenericFamily(settings, fontDescription, familyName);
+    }
+
+    // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over.
+    return face->getFontData(fontDescription);
+}
+
+CSSSegmentedFontFace* CSSSegmentedFontFaceCache::getFontFace(const FontDescription& fontDescription, const AtomicString& family)
+{
+    HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >* familyFontFaces = m_fontFaces.get(family);
+    if (!familyFontFaces || familyFontFaces->isEmpty())
+        return 0;
+
+    OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value;
+    if (!segmentedFontFaceCache)
+        segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >);
+
+    FontTraitsMask traitsMask = fontDescription.traitsMask();
+
+    RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->value;
+    if (!face) {
+        for (HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >::const_iterator i = familyFontFaces->begin(); i != familyFontFaces->end(); ++i) {
+            CSSSegmentedFontFace* candidate = i->value.get();
+            unsigned candidateTraitsMask = candidate->traitsMask();
+            if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
+                continue;
+            if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
+                continue;
+            if (!face || compareFontFaces(candidate, face.get(), traitsMask))
+                face = candidate;
+        }
+
+        if (Vector<RefPtr<CSSSegmentedFontFace> >* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) {
+            unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size();
+            for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) {
+                CSSSegmentedFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get();
+                unsigned candidateTraitsMask = candidate->traitsMask();
+                if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
+                    continue;
+                if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
+                    continue;
+                if (!face || compareFontFaces(candidate, face.get(), traitsMask))
+                    face = candidate;
+            }
+        }
+    }
+    return face.get();
+}
+
+}
diff --git a/Source/core/css/CSSSegmentedFontFaceCache.h b/Source/core/css/CSSSegmentedFontFaceCache.h
new file mode 100644
index 0000000..4b005a9
--- /dev/null
+++ b/Source/core/css/CSSSegmentedFontFaceCache.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSSegmentedFontFaceCache_h
+#define CSSSegmentedFontFaceCache_h
+
+#include "wtf/Forward.h"
+#include "wtf/HashMap.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+class CSSFontSelector;
+class CSSSegmentedFontFace;
+class FontData;
+class FontDescription;
+class StyleRuleFontFace;
+class Settings;
+
+class CSSSegmentedFontFaceCache {
+public:
+    CSSSegmentedFontFaceCache();
+
+    // FIXME: Remove CSSFontSelector as argument. Passing CSSFontSelector here is
+    // a result of egregious spaghettification in CSSFontFace/FontFaceSet.
+    void addFontFaceRule(CSSFontSelector*, const StyleRuleFontFace*);
+    PassRefPtr<FontData> getFontData(Settings*, const FontDescription&, const AtomicString&);
+    CSSSegmentedFontFace* getFontFace(const FontDescription&, const AtomicString& family);
+
+    unsigned version() const { return m_version; }
+
+private:
+    HashMap<String, OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >, CaseFoldingHash> m_fontFaces;
+    HashMap<String, OwnPtr<Vector<RefPtr<CSSSegmentedFontFace> > >, CaseFoldingHash> m_locallyInstalledFontFaces;
+    HashMap<String, OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >, CaseFoldingHash> m_fonts;
+
+    // FIXME: See if this could be ditched
+    // Used to compare Font instances, and the usage seems suspect.
+    unsigned m_version;
+};
+
+}
+
+#endif
diff --git a/Source/core/css/CSSSelector.cpp b/Source/core/css/CSSSelector.cpp
index e970247..b2ea820 100644
--- a/Source/core/css/CSSSelector.cpp
+++ b/Source/core/css/CSSSelector.cpp
@@ -812,6 +812,7 @@
     case CSSSelector::PseudoFirstOfType:
     case CSSSelector::PseudoLastOfType:
     case CSSSelector::PseudoOnlyOfType:
+    case CSSSelector::PseudoHost:
         return true;
     default:
         return false;
diff --git a/Source/core/css/CSSSelector.h b/Source/core/css/CSSSelector.h
index 028e512..3f8b7e8 100644
--- a/Source/core/css/CSSSelector.h
+++ b/Source/core/css/CSSSelector.h
@@ -222,6 +222,7 @@
         bool isAttributeSelector() const;
         bool isDistributedPseudoElement() const;
         bool isContentPseudoElement() const;
+        bool isHostPseudoClass() const;
 
         Relation relation() const { return static_cast<Relation>(m_relation); }
 
@@ -311,6 +312,11 @@
     return m_match == PseudoElement && (m_pseudoType == PseudoUserAgentCustomElement || m_pseudoType == PseudoWebKitCustomElement || m_pseudoType == PseudoPart);
 }
 
+inline bool CSSSelector::isHostPseudoClass() const
+{
+    return m_match == PseudoClass && m_pseudoType == PseudoHost;
+}
+
 inline bool CSSSelector::isSiblingSelector() const
 {
     PseudoType type = pseudoType();
diff --git a/Source/core/css/CSSShaderValue.h b/Source/core/css/CSSShaderValue.h
index 69daf55..94816e8 100644
--- a/Source/core/css/CSSShaderValue.h
+++ b/Source/core/css/CSSShaderValue.h
@@ -64,13 +64,7 @@
     bool m_accessedShader;
 };
 
-// This will catch anyone doing an unnecessary cast.
-CSSShaderValue* toCSSShaderValue(const CSSShaderValue*);
-
-inline CSSShaderValue* toCSSShaderValue(CSSValue* value)
-{
-    return value->isCSSShaderValue() ? static_cast<CSSShaderValue*>(value) : 0;
-}
+DEFINE_CSS_VALUE_TYPE_CASTS(ShaderValue);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/ShadowValue.cpp b/Source/core/css/CSSShadowValue.cpp
similarity index 80%
rename from Source/core/css/ShadowValue.cpp
rename to Source/core/css/CSSShadowValue.cpp
index 1ee8b1d..57cb927 100644
--- a/Source/core/css/ShadowValue.cpp
+++ b/Source/core/css/CSSShadowValue.cpp
@@ -18,7 +18,7 @@
  * Boston, MA 02110-1301, USA.
  */
 #include "config.h"
-#include "core/css/ShadowValue.h"
+#include "core/css/CSSShadowValue.h"
 
 #include "core/css/CSSPrimitiveValue.h"
 #include "wtf/text/StringBuilder.h"
@@ -27,23 +27,23 @@
 namespace WebCore {
 
 // Used for text-shadow and box-shadow
-ShadowValue::ShadowValue(PassRefPtr<CSSPrimitiveValue> _x,
-    PassRefPtr<CSSPrimitiveValue> _y,
-    PassRefPtr<CSSPrimitiveValue> _blur,
-    PassRefPtr<CSSPrimitiveValue> _spread,
-    PassRefPtr<CSSPrimitiveValue> _style,
-    PassRefPtr<CSSPrimitiveValue> _color)
+CSSShadowValue::CSSShadowValue(PassRefPtr<CSSPrimitiveValue> x,
+    PassRefPtr<CSSPrimitiveValue> y,
+    PassRefPtr<CSSPrimitiveValue> blur,
+    PassRefPtr<CSSPrimitiveValue> spread,
+    PassRefPtr<CSSPrimitiveValue> style,
+    PassRefPtr<CSSPrimitiveValue> color)
     : CSSValue(ShadowClass)
-    , x(_x)
-    , y(_y)
-    , blur(_blur)
-    , spread(_spread)
-    , style(_style)
-    , color(_color)
+    , x(x)
+    , y(y)
+    , blur(blur)
+    , spread(spread)
+    , style(style)
+    , color(color)
 {
 }
 
-String ShadowValue::customCssText() const
+String CSSShadowValue::customCssText() const
 {
     StringBuilder text;
 
@@ -78,7 +78,7 @@
     return text.toString();
 }
 
-bool ShadowValue::equals(const ShadowValue& other) const
+bool CSSShadowValue::equals(const CSSShadowValue& other) const
 {
     return compareCSSValuePtr(color, other.color)
         && compareCSSValuePtr(x, other.x)
diff --git a/Source/core/css/ShadowValue.h b/Source/core/css/CSSShadowValue.h
similarity index 82%
rename from Source/core/css/ShadowValue.h
rename to Source/core/css/CSSShadowValue.h
index 6e0192e..dd90ea9 100644
--- a/Source/core/css/ShadowValue.h
+++ b/Source/core/css/CSSShadowValue.h
@@ -18,8 +18,8 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#ifndef ShadowValue_h
-#define ShadowValue_h
+#ifndef CSSShadowValue_h
+#define CSSShadowValue_h
 
 #include "core/css/CSSValue.h"
 #include "wtf/PassRefPtr.h"
@@ -30,21 +30,21 @@
 class CSSPrimitiveValue;
 
 // Used for text-shadow and box-shadow
-class ShadowValue : public CSSValue {
+class CSSShadowValue : public CSSValue {
 public:
-    static PassRefPtr<ShadowValue> create(PassRefPtr<CSSPrimitiveValue> x,
+    static PassRefPtr<CSSShadowValue> create(PassRefPtr<CSSPrimitiveValue> x,
         PassRefPtr<CSSPrimitiveValue> y,
         PassRefPtr<CSSPrimitiveValue> blur,
         PassRefPtr<CSSPrimitiveValue> spread,
         PassRefPtr<CSSPrimitiveValue> style,
         PassRefPtr<CSSPrimitiveValue> color)
     {
-        return adoptRef(new ShadowValue(x, y, blur, spread, style, color));
+        return adoptRef(new CSSShadowValue(x, y, blur, spread, style, color));
     }
 
     String customCssText() const;
 
-    bool equals(const ShadowValue&) const;
+    bool equals(const CSSShadowValue&) const;
 
     RefPtr<CSSPrimitiveValue> x;
     RefPtr<CSSPrimitiveValue> y;
@@ -54,7 +54,7 @@
     RefPtr<CSSPrimitiveValue> color;
 
 private:
-    ShadowValue(PassRefPtr<CSSPrimitiveValue> x,
+    CSSShadowValue(PassRefPtr<CSSPrimitiveValue> x,
         PassRefPtr<CSSPrimitiveValue> y,
         PassRefPtr<CSSPrimitiveValue> blur,
         PassRefPtr<CSSPrimitiveValue> spread,
@@ -62,6 +62,8 @@
         PassRefPtr<CSSPrimitiveValue> color);
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(ShadowValue);
+
 } // namespace
 
 #endif
diff --git a/Source/core/css/CSSStyleDeclaration.h b/Source/core/css/CSSStyleDeclaration.h
index 5d30cae..94d77b5 100644
--- a/Source/core/css/CSSStyleDeclaration.h
+++ b/Source/core/css/CSSStyleDeclaration.h
@@ -23,6 +23,7 @@
 
 #include "CSSPropertyNames.h"
 #include "bindings/v8/ScriptWrappable.h"
+#include "core/css/CSSVariablesIterator.h"
 #include "core/css/CSSVariablesMap.h"
 #include "wtf/Forward.h"
 #include "wtf/Noncopyable.h"
@@ -61,9 +62,10 @@
     PassRefPtr<CSSVariablesMap> var();
     virtual unsigned variableCount() const = 0;
     virtual String variableValue(const AtomicString& name) const = 0;
-    virtual void setVariableValue(const AtomicString& name, const String& value, ExceptionState&) = 0;
+    virtual bool setVariableValue(const AtomicString& name, const String& value, ExceptionState&) = 0; // Return value indicates whether variable was added.
     virtual bool removeVariable(const AtomicString& name) = 0;
-    virtual void clearVariables(ExceptionState&) = 0;
+    virtual bool clearVariables(ExceptionState&) = 0;
+    virtual PassRefPtr<CSSVariablesIterator> variablesIterator() const = 0;
 
     // CSSPropertyID versions of the CSSOM functions to support bindings and editing.
     // Use the non-virtual methods in the concrete subclasses when possible.
diff --git a/Source/core/css/CSSStyleDeclaration.idl b/Source/core/css/CSSStyleDeclaration.idl
index 4f1bdf6..649a579 100644
--- a/Source/core/css/CSSStyleDeclaration.idl
+++ b/Source/core/css/CSSStyleDeclaration.idl
@@ -37,6 +37,6 @@
     [Custom, CustomEnumerateProperty] getter (DOMString or float) (DOMString name);
     [Custom] setter void (DOMString propertyName, [TreatNullAs=NullString] DOMString propertyValue);
     readonly attribute CSSRule          parentRule;
-    [EnabledAtRuntime=CSSVariables] readonly attribute CSSVariablesMap var;
+    [RuntimeEnabled=CSSVariables] readonly attribute CSSVariablesMap var;
 };
 
diff --git a/Source/core/css/CSSTimingFunctionValue.h b/Source/core/css/CSSTimingFunctionValue.h
index 87f2b7a..3f81d6a 100644
--- a/Source/core/css/CSSTimingFunctionValue.h
+++ b/Source/core/css/CSSTimingFunctionValue.h
@@ -63,6 +63,8 @@
     double m_y2;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(CubicBezierTimingFunctionValue);
+
 class CSSStepsTimingFunctionValue : public CSSValue {
 public:
     static PassRefPtr<CSSStepsTimingFunctionValue> create(int steps, bool stepAtStart)
@@ -89,6 +91,8 @@
     bool m_stepAtStart;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(StepsTimingFunctionValue);
+
 } // namespace
 
 #endif
diff --git a/Source/core/css/CSSToStyleMap.cpp b/Source/core/css/CSSToStyleMap.cpp
index 0ccfbf4..4dacaa7 100644
--- a/Source/core/css/CSSToStyleMap.cpp
+++ b/Source/core/css/CSSToStyleMap.cpp
@@ -308,8 +308,7 @@
     if (!value->isPrimitiveValue())
         return;
 
-    CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
-    switch (primitiveValue->getValueID()) {
+    switch (toCSSPrimitiveValue(value)->getValueID()) {
     case CSSValueAlpha:
         type = MaskAlpha;
         break;
@@ -335,8 +334,7 @@
     if (!value->isPrimitiveValue())
         return;
 
-    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
-    animation->setDelay(primitiveValue->computeTime<double, CSSPrimitiveValue::Seconds>());
+    animation->setDelay(toCSSPrimitiveValue(value)->computeTime<double, CSSPrimitiveValue::Seconds>());
 }
 
 void CSSToStyleMap::mapAnimationDirection(CSSAnimationData* layer, CSSValue* value) const
@@ -349,8 +347,7 @@
     if (!value->isPrimitiveValue())
         return;
 
-    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
-    switch (primitiveValue->getValueID()) {
+    switch (toCSSPrimitiveValue(value)->getValueID()) {
     case CSSValueNormal:
         layer->setDirection(CSSAnimationData::AnimationDirectionNormal);
         break;
@@ -522,10 +519,10 @@
     }
 
     if (value->isCubicBezierTimingFunctionValue()) {
-        CSSCubicBezierTimingFunctionValue* cubicTimingFunction = static_cast<CSSCubicBezierTimingFunctionValue*>(value);
+        CSSCubicBezierTimingFunctionValue* cubicTimingFunction = toCSSCubicBezierTimingFunctionValue(value);
         animation->setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2()));
     } else if (value->isStepsTimingFunctionValue()) {
-        CSSStepsTimingFunctionValue* stepsTimingFunction = static_cast<CSSStepsTimingFunctionValue*>(value);
+        CSSStepsTimingFunctionValue* stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
         animation->setTimingFunction(StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart()));
     }
 }
diff --git a/Source/core/css/CSSTransformValue.h b/Source/core/css/CSSTransformValue.h
index 68c83cb..b37197d 100644
--- a/Source/core/css/CSSTransformValue.h
+++ b/Source/core/css/CSSTransformValue.h
@@ -79,6 +79,8 @@
     TransformOperationType m_type;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(TransformValue);
+
 }
 
 #endif
diff --git a/Source/core/css/CSSUnicodeRangeValue.h b/Source/core/css/CSSUnicodeRangeValue.h
index 91af8ec..03a45cd 100644
--- a/Source/core/css/CSSUnicodeRangeValue.h
+++ b/Source/core/css/CSSUnicodeRangeValue.h
@@ -57,6 +57,8 @@
     UChar32 m_to;
 };
 
+DEFINE_CSS_VALUE_TYPE_CASTS(UnicodeRangeValue);
+
 } // namespace WebCore
 
 #endif // CSSUnicodeRangeValue_h
diff --git a/Source/core/css/CSSValue.cpp b/Source/core/css/CSSValue.cpp
index c32bab7..cd6970f 100644
--- a/Source/core/css/CSSValue.cpp
+++ b/Source/core/css/CSSValue.cpp
@@ -36,6 +36,8 @@
 #include "core/css/CSSCursorImageValue.h"
 #include "core/css/CSSFilterValue.h"
 #include "core/css/CSSFontFaceSrcValue.h"
+#include "core/css/CSSFontFeatureValue.h"
+#include "core/css/CSSFontValue.h"
 #include "core/css/CSSFunctionValue.h"
 #include "core/css/CSSGradientValue.h"
 #include "core/css/CSSGridTemplateValue.h"
@@ -49,14 +51,12 @@
 #include "core/css/CSSReflectValue.h"
 #include "core/css/CSSSVGDocumentValue.h"
 #include "core/css/CSSShaderValue.h"
+#include "core/css/CSSShadowValue.h"
 #include "core/css/CSSTimingFunctionValue.h"
 #include "core/css/CSSTransformValue.h"
 #include "core/css/CSSUnicodeRangeValue.h"
 #include "core/css/CSSValueList.h"
 #include "core/css/CSSVariableValue.h"
-#include "core/css/FontFeatureValue.h"
-#include "core/css/FontValue.h"
-#include "core/css/ShadowValue.h"
 #include "core/svg/SVGColor.h"
 #include "core/svg/SVGPaint.h"
 
@@ -66,7 +66,7 @@
     uint32_t bitfields;
 };
 
-COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
+COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small);
 
 class TextCloneCSSValue : public CSSValue {
 public:
@@ -87,7 +87,7 @@
 
 bool CSSValue::isImplicitInitialValue() const
 {
-    return m_classType == InitialClass && static_cast<const CSSInitialValue*>(this)->isImplicit();
+    return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit();
 }
 
 CSSValue::Type CSSValue::cssValueType() const
@@ -113,9 +113,9 @@
     else if (isValueList())
         toCSSValueList(this)->addSubresourceStyleURLs(urls, styleSheet);
     else if (classType() == FontFaceSrcClass)
-        static_cast<const CSSFontFaceSrcValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
+        toCSSFontFaceSrcValue(this)->addSubresourceStyleURLs(urls, styleSheet);
     else if (classType() == ReflectClass)
-        static_cast<const CSSReflectValue*>(this)->addSubresourceStyleURLs(urls, styleSheet);
+        toCSSReflectValue(this)->addSubresourceStyleURLs(urls, styleSheet);
 }
 
 bool CSSValue::hasFailedOrCanceledSubresources() const
@@ -126,13 +126,13 @@
     if (isValueList())
         return toCSSValueList(this)->hasFailedOrCanceledSubresources();
     if (classType() == FontFaceSrcClass)
-        return static_cast<const CSSFontFaceSrcValue*>(this)->hasFailedOrCanceledSubresources();
+        return toCSSFontFaceSrcValue(this)->hasFailedOrCanceledSubresources();
     if (classType() == ImageClass)
         return toCSSImageValue(this)->hasFailedOrCanceledSubresources();
     if (classType() == CrossfadeClass)
-        return static_cast<const CSSCrossfadeValue*>(this)->hasFailedOrCanceledSubresources();
+        return toCSSCrossfadeValue(this)->hasFailedOrCanceledSubresources();
     if (classType() == ImageSetClass)
-        return static_cast<const CSSImageSetValue*>(this)->hasFailedOrCanceledSubresources();
+        return toCSSImageSetValue(this)->hasFailedOrCanceledSubresources();
 
     return false;
 }
@@ -161,11 +161,11 @@
         case CursorImageClass:
             return compareCSSValues<CSSCursorImageValue>(*this, other);
         case FontClass:
-            return compareCSSValues<FontValue>(*this, other);
+            return compareCSSValues<CSSFontValue>(*this, other);
         case FontFaceSrcClass:
             return compareCSSValues<CSSFontFaceSrcValue>(*this, other);
         case FontFeatureClass:
-            return compareCSSValues<FontFeatureValue>(*this, other);
+            return compareCSSValues<CSSFontFeatureValue>(*this, other);
         case FunctionClass:
             return compareCSSValues<CSSFunctionValue>(*this, other);
         case LinearGradientClass:
@@ -187,7 +187,7 @@
         case ReflectClass:
             return compareCSSValues<CSSReflectValue>(*this, other);
         case ShadowClass:
-            return compareCSSValues<ShadowValue>(*this, other);
+            return compareCSSValues<CSSShadowValue>(*this, other);
         case CubicBezierTimingFunctionClass:
             return compareCSSValues<CSSCubicBezierTimingFunctionValue>(*this, other);
         case StepsTimingFunctionClass:
@@ -241,73 +241,73 @@
 
     switch (classType()) {
     case AspectRatioClass:
-        return static_cast<const CSSAspectRatioValue*>(this)->customCssText();
+        return toCSSAspectRatioValue(this)->customCssText();
     case BorderImageSliceClass:
-        return static_cast<const CSSBorderImageSliceValue*>(this)->customCssText();
+        return toCSSBorderImageSliceValue(this)->customCssText();
     case CanvasClass:
-        return static_cast<const CSSCanvasValue*>(this)->customCssText();
+        return toCSSCanvasValue(this)->customCssText();
     case CursorImageClass:
-        return static_cast<const CSSCursorImageValue*>(this)->customCssText();
+        return toCSSCursorImageValue(this)->customCssText();
     case FontClass:
-        return static_cast<const FontValue*>(this)->customCssText();
+        return toCSSFontValue(this)->customCssText();
     case FontFaceSrcClass:
-        return static_cast<const CSSFontFaceSrcValue*>(this)->customCssText();
+        return toCSSFontFaceSrcValue(this)->customCssText();
     case FontFeatureClass:
-        return static_cast<const FontFeatureValue*>(this)->customCssText();
+        return toCSSFontFeatureValue(this)->customCssText();
     case FunctionClass:
-        return static_cast<const CSSFunctionValue*>(this)->customCssText();
+        return toCSSFunctionValue(this)->customCssText();
     case LinearGradientClass:
-        return static_cast<const CSSLinearGradientValue*>(this)->customCssText();
+        return toCSSLinearGradientValue(this)->customCssText();
     case RadialGradientClass:
-        return static_cast<const CSSRadialGradientValue*>(this)->customCssText();
+        return toCSSRadialGradientValue(this)->customCssText();
     case CrossfadeClass:
-        return static_cast<const CSSCrossfadeValue*>(this)->customCssText();
+        return toCSSCrossfadeValue(this)->customCssText();
     case ImageClass:
         return toCSSImageValue(this)->customCssText();
     case InheritedClass:
-        return static_cast<const CSSInheritedValue*>(this)->customCssText();
+        return toCSSInheritedValue(this)->customCssText();
     case InitialClass:
-        return static_cast<const CSSInitialValue*>(this)->customCssText();
+        return toCSSInitialValue(this)->customCssText();
     case GridTemplateClass:
-        return static_cast<const CSSGridTemplateValue*>(this)->customCssText();
+        return toCSSGridTemplateValue(this)->customCssText();
     case PrimitiveClass:
         return toCSSPrimitiveValue(this)->customCssText();
     case ReflectClass:
-        return static_cast<const CSSReflectValue*>(this)->customCssText();
+        return toCSSReflectValue(this)->customCssText();
     case ShadowClass:
-        return static_cast<const ShadowValue*>(this)->customCssText();
+        return toCSSShadowValue(this)->customCssText();
     case CubicBezierTimingFunctionClass:
-        return static_cast<const CSSCubicBezierTimingFunctionValue*>(this)->customCssText();
+        return toCSSCubicBezierTimingFunctionValue(this)->customCssText();
     case StepsTimingFunctionClass:
-        return static_cast<const CSSStepsTimingFunctionValue*>(this)->customCssText();
+        return toCSSStepsTimingFunctionValue(this)->customCssText();
     case UnicodeRangeClass:
-        return static_cast<const CSSUnicodeRangeValue*>(this)->customCssText();
+        return toCSSUnicodeRangeValue(this)->customCssText();
     case ValueListClass:
         return toCSSValueList(this)->customCssText();
     case CSSTransformClass:
-        return static_cast<const CSSTransformValue*>(this)->customCssText();
+        return toCSSTransformValue(this)->customCssText();
     case LineBoxContainClass:
-        return static_cast<const CSSLineBoxContainValue*>(this)->customCssText();
+        return toCSSLineBoxContainValue(this)->customCssText();
     case CalculationClass:
-        return static_cast<const CSSCalcValue*>(this)->customCssText();
+        return toCSSCalcValue(this)->customCssText();
     case ImageSetClass:
-        return static_cast<const CSSImageSetValue*>(this)->customCssText();
+        return toCSSImageSetValue(this)->customCssText();
     case CSSFilterClass:
-        return static_cast<const CSSFilterValue*>(this)->customCssText();
+        return toCSSFilterValue(this)->customCssText();
     case CSSArrayFunctionValueClass:
-        return static_cast<const CSSArrayFunctionValue*>(this)->customCssText();
+        return toCSSArrayFunctionValue(this)->customCssText();
     case CSSMixFunctionValueClass:
-        return static_cast<const CSSMixFunctionValue*>(this)->customCssText();
+        return toCSSMixFunctionValue(this)->customCssText();
     case CSSShaderClass:
-        return static_cast<const CSSShaderValue*>(this)->customCssText();
+        return toCSSShaderValue(this)->customCssText();
     case VariableClass:
         return toCSSVariableValue(this)->value();
     case SVGColorClass:
-        return static_cast<const SVGColor*>(this)->customCssText();
+        return toSVGColor(this)->customCssText();
     case SVGPaintClass:
-        return static_cast<const SVGPaint*>(this)->customCssText();
+        return toSVGPaint(this)->customCssText();
     case CSSSVGDocumentClass:
-        return static_cast<const CSSSVGDocumentValue*>(this)->customCssText();
+        return toCSSSVGDocumentValue(this)->customCssText();
     }
     ASSERT_NOT_REACHED();
     return String();
@@ -319,11 +319,11 @@
     case PrimitiveClass:
         return toCSSPrimitiveValue(this)->customSerializeResolvingVariables(variables);
     case ReflectClass:
-        return static_cast<const CSSReflectValue*>(this)->customSerializeResolvingVariables(variables);
+        return toCSSReflectValue(this)->customSerializeResolvingVariables(variables);
     case ValueListClass:
         return toCSSValueList(this)->customSerializeResolvingVariables(variables);
     case CSSTransformClass:
-        return static_cast<const CSSTransformValue*>(this)->customSerializeResolvingVariables(variables);
+        return toCSSTransformValue(this)->customSerializeResolvingVariables(variables);
     default:
         return cssText();
     }
@@ -346,43 +346,43 @@
         delete toCSSBorderImageSliceValue(this);
         return;
     case CanvasClass:
-        delete static_cast<CSSCanvasValue*>(this);
+        delete toCSSCanvasValue(this);
         return;
     case CursorImageClass:
-        delete static_cast<CSSCursorImageValue*>(this);
+        delete toCSSCursorImageValue(this);
         return;
     case FontClass:
-        delete static_cast<FontValue*>(this);
+        delete toCSSFontValue(this);
         return;
     case FontFaceSrcClass:
-        delete static_cast<CSSFontFaceSrcValue*>(this);
+        delete toCSSFontFaceSrcValue(this);
         return;
     case FontFeatureClass:
-        delete static_cast<FontFeatureValue*>(this);
+        delete toCSSFontFeatureValue(this);
         return;
     case FunctionClass:
-        delete static_cast<CSSFunctionValue*>(this);
+        delete toCSSFunctionValue(this);
         return;
     case LinearGradientClass:
-        delete static_cast<CSSLinearGradientValue*>(this);
+        delete toCSSLinearGradientValue(this);
         return;
     case RadialGradientClass:
-        delete static_cast<CSSRadialGradientValue*>(this);
+        delete toCSSRadialGradientValue(this);
         return;
     case CrossfadeClass:
-        delete static_cast<CSSCrossfadeValue*>(this);
+        delete toCSSCrossfadeValue(this);
         return;
     case ImageClass:
         delete toCSSImageValue(this);
         return;
     case InheritedClass:
-        delete static_cast<CSSInheritedValue*>(this);
+        delete toCSSInheritedValue(this);
         return;
     case InitialClass:
-        delete static_cast<CSSInitialValue*>(this);
+        delete toCSSInitialValue(this);
         return;
     case GridTemplateClass:
-        delete static_cast<CSSGridTemplateValue*>(this);
+        delete toCSSGridTemplateValue(this);
         return;
     case PrimitiveClass:
         delete toCSSPrimitiveValue(this);
@@ -391,55 +391,55 @@
         delete toCSSReflectValue(this);
         return;
     case ShadowClass:
-        delete static_cast<ShadowValue*>(this);
+        delete toCSSShadowValue(this);
         return;
     case CubicBezierTimingFunctionClass:
-        delete static_cast<CSSCubicBezierTimingFunctionValue*>(this);
+        delete toCSSCubicBezierTimingFunctionValue(this);
         return;
     case StepsTimingFunctionClass:
-        delete static_cast<CSSStepsTimingFunctionValue*>(this);
+        delete toCSSStepsTimingFunctionValue(this);
         return;
     case UnicodeRangeClass:
-        delete static_cast<CSSUnicodeRangeValue*>(this);
+        delete toCSSUnicodeRangeValue(this);
         return;
     case ValueListClass:
         delete toCSSValueList(this);
         return;
     case CSSTransformClass:
-        delete static_cast<CSSTransformValue*>(this);
+        delete toCSSTransformValue(this);
         return;
     case LineBoxContainClass:
-        delete static_cast<CSSLineBoxContainValue*>(this);
+        delete toCSSLineBoxContainValue(this);
         return;
     case CalculationClass:
-        delete static_cast<CSSCalcValue*>(this);
+        delete toCSSCalcValue(this);
         return;
     case ImageSetClass:
         delete toCSSImageSetValue(this);
         return;
     case CSSFilterClass:
-        delete static_cast<CSSFilterValue*>(this);
+        delete toCSSFilterValue(this);
         return;
     case CSSArrayFunctionValueClass:
-        delete static_cast<CSSArrayFunctionValue*>(this);
+        delete toCSSArrayFunctionValue(this);
         return;
     case CSSMixFunctionValueClass:
-        delete static_cast<CSSMixFunctionValue*>(this);
+        delete toCSSMixFunctionValue(this);
         return;
     case CSSShaderClass:
-        delete static_cast<CSSShaderValue*>(this);
+        delete toCSSShaderValue(this);
         return;
     case VariableClass:
         delete toCSSVariableValue(this);
         return;
     case SVGColorClass:
-        delete static_cast<SVGColor*>(this);
+        delete toSVGColor(this);
         return;
     case SVGPaintClass:
-        delete static_cast<SVGPaint*>(this);
+        delete toSVGPaint(this);
         return;
     case CSSSVGDocumentClass:
-        delete static_cast<CSSSVGDocumentValue*>(this);
+        delete toCSSSVGDocumentValue(this);
         return;
     }
     ASSERT_NOT_REACHED();
@@ -456,19 +456,19 @@
     case CursorImageClass:
         return toCSSImageValue(this)->cloneForCSSOM();
     case CSSFilterClass:
-        return static_cast<const CSSFilterValue*>(this)->cloneForCSSOM();
+        return toCSSFilterValue(this)->cloneForCSSOM();
     case CSSArrayFunctionValueClass:
-        return static_cast<const CSSArrayFunctionValue*>(this)->cloneForCSSOM();
+        return toCSSArrayFunctionValue(this)->cloneForCSSOM();
     case CSSMixFunctionValueClass:
-        return static_cast<const CSSMixFunctionValue*>(this)->cloneForCSSOM();
+        return toCSSMixFunctionValue(this)->cloneForCSSOM();
     case CSSTransformClass:
-        return static_cast<const CSSTransformValue*>(this)->cloneForCSSOM();
+        return toCSSTransformValue(this)->cloneForCSSOM();
     case ImageSetClass:
-        return static_cast<const CSSImageSetValue*>(this)->cloneForCSSOM();
+        return toCSSImageSetValue(this)->cloneForCSSOM();
     case SVGColorClass:
-        return static_cast<const SVGColor*>(this)->cloneForCSSOM();
+        return toSVGColor(this)->cloneForCSSOM();
     case SVGPaintClass:
-        return static_cast<const SVGPaint*>(this)->cloneForCSSOM();
+        return toSVGPaint(this)->cloneForCSSOM();
     default:
         ASSERT(!isSubtypeExposedToCSSOM());
         return TextCloneCSSValue::create(classType(), cssText());
diff --git a/Source/core/css/CSSValue.h b/Source/core/css/CSSValue.h
index d62f81e..61532b9 100644
--- a/Source/core/css/CSSValue.h
+++ b/Source/core/css/CSSValue.h
@@ -71,7 +71,9 @@
 
     bool isAspectRatioValue() const { return m_classType == AspectRatioClass; }
     bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; }
+    bool isCanvasValue() const { return m_classType == CanvasClass; }
     bool isCursorImageValue() const { return m_classType == CursorImageClass; }
+    bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
     bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
     bool isFontValue() const { return m_classType == FontClass; }
     bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
@@ -83,22 +85,25 @@
     bool isImplicitInitialValue() const;
     bool isInheritedValue() const { return m_classType == InheritedClass; }
     bool isInitialValue() const { return m_classType == InitialClass; }
+    bool isLinearGradientValue() const { return m_classType == LinearGradientClass; }
+    bool isRadialGradientValue() const { return m_classType == RadialGradientClass; }
     bool isReflectValue() const { return m_classType == ReflectClass; }
     bool isShadowValue() const { return m_classType == ShadowClass; }
     bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
     bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
-    bool isCSSTransformValue() const { return m_classType == CSSTransformClass; }
-    bool isCSSLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
-    bool isCalculationValue() const {return m_classType == CalculationClass; }
-    bool isCSSFilterValue() const { return m_classType == CSSFilterClass; }
-    bool isCSSArrayFunctionValue() const { return m_classType == CSSArrayFunctionValueClass; }
-    bool isCSSMixFunctionValue() const { return m_classType == CSSMixFunctionValueClass; }
-    bool isCSSShaderValue() const { return m_classType == CSSShaderClass; }
+    bool isTransformValue() const { return m_classType == CSSTransformClass; }
+    bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
+    bool isCalcValue() const {return m_classType == CalculationClass; }
+    bool isFilterValue() const { return m_classType == CSSFilterClass; }
+    bool isArrayFunctionValue() const { return m_classType == CSSArrayFunctionValueClass; }
+    bool isMixFunctionValue() const { return m_classType == CSSMixFunctionValueClass; }
+    bool isShaderValue() const { return m_classType == CSSShaderClass; }
     bool isVariableValue() const { return m_classType == VariableClass; }
     bool isGridTemplateValue() const { return m_classType == GridTemplateClass; }
     bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; }
     bool isSVGPaint() const { return m_classType == SVGPaintClass; }
-    bool isCSSSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
+    bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
+    bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
 
     bool isCSSOMSafe() const { return m_isCSSOMSafe; }
     bool isSubtypeExposedToCSSOM() const
diff --git a/Source/core/css/CSSValueKeywords.in b/Source/core/css/CSSValueKeywords.in
index f4bc3ca..41346de 100644
--- a/Source/core/css/CSSValueKeywords.in
+++ b/Source/core/css/CSSValueKeywords.in
@@ -4,7 +4,7 @@
 
 // The mode argument is used to limit the keyword to be used only for certain
 // CSSParserModes. Values that have the prefix -internal- are automatically
-// only for UASheetMode.
+// only for UASheetMode or CSSAttributeMode.
 
 inherit
 initial
@@ -229,6 +229,13 @@
 -webkit-center
 -webkit-match-parent
 //
+// CSS_PROP_TEXT_JUSTIFY:
+//
+//auto
+//none
+inter-word
+distribute
+//
 // CSS_PROP_LIST_STYLE_POSITION:
 //
 outside
@@ -454,6 +461,7 @@
 pre
 pre-line
 pre-wrap
+-internal-presence
 relative
 scroll
 separate
@@ -964,6 +972,9 @@
 // object-fit
 scale-down
 
+// column-fill
+balance
+
 // overflow
 -webkit-paged-x
 -webkit-paged-y
diff --git a/Source/core/css/CSSValuePool.cpp b/Source/core/css/CSSValuePool.cpp
index eaf8555..140dc72 100644
--- a/Source/core/css/CSSValuePool.cpp
+++ b/Source/core/css/CSSValuePool.cpp
@@ -29,6 +29,7 @@
 #include "CSSValueKeywords.h"
 #include "core/css/CSSParser.h"
 #include "core/css/CSSValueList.h"
+#include "core/rendering/style/RenderStyle.h"
 
 namespace WebCore {
 
@@ -115,6 +116,11 @@
     return cache[intValue];
 }
 
+PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(const Length& value, const RenderStyle* style)
+{
+    return CSSPrimitiveValue::create(value, style->effectiveZoom());
+}
+
 PassRefPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName)
 {
     RefPtr<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).iterator->value;
diff --git a/Source/core/css/CSSValuePool.h b/Source/core/css/CSSValuePool.h
index ba63c18..02376a0 100644
--- a/Source/core/css/CSSValuePool.h
+++ b/Source/core/css/CSSValuePool.h
@@ -52,7 +52,8 @@
     PassRefPtr<CSSPrimitiveValue> createColorValue(unsigned rgbValue);
     PassRefPtr<CSSPrimitiveValue> createValue(double value, CSSPrimitiveValue::UnitTypes);
     PassRefPtr<CSSPrimitiveValue> createValue(const String& value, CSSPrimitiveValue::UnitTypes type) { return CSSPrimitiveValue::create(value, type); }
-    PassRefPtr<CSSPrimitiveValue> createValue(const Length& value, const RenderStyle* style) { return CSSPrimitiveValue::create(value, style); }
+    PassRefPtr<CSSPrimitiveValue> createValue(const Length& value, const RenderStyle*);
+    PassRefPtr<CSSPrimitiveValue> createValue(const Length& value, float zoom) { return CSSPrimitiveValue::create(value, zoom); }
     template<typename T> static PassRefPtr<CSSPrimitiveValue> createValue(T value) { return CSSPrimitiveValue::create(value); }
 
 private:
diff --git a/Source/core/css/CSSValueTestHelper.h b/Source/core/css/CSSValueTestHelper.h
new file mode 100644
index 0000000..765ea30
--- /dev/null
+++ b/Source/core/css/CSSValueTestHelper.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Make testing with gtest and gmock nicer by adding pretty print and other
+ * helper functions.
+ */
+
+#ifndef CSSValueTestHelper_h
+#define CSSValueTestHelper_h
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSValue.h"
+
+#include <iostream>
+
+namespace testing {
+namespace internal {
+
+// gtest tests won't compile with clang when trying to EXPECT_EQ a class that
+// has the "template<typename T> operator T*()" private.
+// (See https://code.google.com/p/googletest/issues/detail?id=442)
+//
+// Work around is to define this custom IsNullLiteralHelper.
+char(&IsNullLiteralHelper(const WebCore::CSSValue&))[2];
+
+}
+}
+
+namespace WebCore {
+
+inline bool operator==(const CSSValue& a, const CSSValue& b)
+{
+    return a.equals(b);
+}
+
+inline void PrintTo(const CSSValue& cssValue, ::std::ostream* os, const char* typeName = "CSSValue")
+{
+    *os << typeName << "(" << cssValue.cssText().utf8().data() << ")";
+}
+
+inline void PrintTo(const CSSPrimitiveValue& cssValue, ::std::ostream* os, const char* typeName = "CSSPrimitiveValue")
+{
+    PrintTo(*static_cast<const CSSValue*>(&cssValue), os, typeName);
+}
+
+}
+
+#endif
diff --git a/Source/core/css/CSSVariableValue.h b/Source/core/css/CSSVariableValue.h
index 5e691e1..54577fb 100644
--- a/Source/core/css/CSSVariableValue.h
+++ b/Source/core/css/CSSVariableValue.h
@@ -59,17 +59,7 @@
     const String m_value;
 };
 
-inline CSSVariableValue* toCSSVariableValue(CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isVariableValue());
-    return static_cast<CSSVariableValue*>(value);
-}
-
-inline const CSSVariableValue* toCSSVariableValue(const CSSValue* value)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isVariableValue());
-    return static_cast<const CSSVariableValue*>(value);
-}
+DEFINE_CSS_VALUE_TYPE_CASTS(VariableValue);
 
 }
 
diff --git a/Source/core/css/CSSVariablesIterator.h b/Source/core/css/CSSVariablesIterator.h
new file mode 100644
index 0000000..edfe3a7
--- /dev/null
+++ b/Source/core/css/CSSVariablesIterator.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSVariablesIterator_h
+#define CSSVariablesIterator_h
+
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class CSSVariablesIterator : public RefCounted<CSSVariablesIterator> {
+public:
+    virtual ~CSSVariablesIterator() { }
+    virtual void advance() = 0;
+    virtual bool atEnd() const = 0;
+    virtual AtomicString name() const = 0;
+    virtual String value() const = 0;
+    virtual void addedVariable(const AtomicString& name) { }
+    virtual void removedVariable(const AtomicString& name) { }
+    virtual void clearedVariables() { }
+};
+
+}
+
+#endif // CSSVariablesIterator_h
diff --git a/Source/core/css/CSSVariablesMap.cpp b/Source/core/css/CSSVariablesMap.cpp
index 599a9dc..48e67eb 100644
--- a/Source/core/css/CSSVariablesMap.cpp
+++ b/Source/core/css/CSSVariablesMap.cpp
@@ -55,23 +55,68 @@
     return false;
 }
 
-void CSSVariablesMap::set(const AtomicString& name, const String& value, ExceptionState& es) const
+void CSSVariablesMap::set(const AtomicString& name, const String& value, ExceptionState& es)
 {
-    if (m_styleDeclaration)
-        m_styleDeclaration->setVariableValue(name, value, es);
+    if (!m_styleDeclaration)
+        return;
+    if (m_styleDeclaration->setVariableValue(name, value, es)) {
+        Iterators::iterator end = m_activeIterators.end();
+        for (Iterators::iterator it = m_activeIterators.begin(); it != end; ++it)
+            (*it)->addedVariable(name);
+    }
 }
 
-bool CSSVariablesMap::remove(const AtomicString& name) const
+bool CSSVariablesMap::remove(const AtomicString& name)
 {
-    if (m_styleDeclaration)
-        return m_styleDeclaration->removeVariable(name);
+    if (!m_styleDeclaration)
+        return false;
+    if (m_styleDeclaration->removeVariable(name)) {
+        Iterators::iterator end = m_activeIterators.end();
+        for (Iterators::iterator it = m_activeIterators.begin(); it != end; ++it)
+            (*it)->removedVariable(name);
+        return true;
+    }
     return false;
 }
 
-void CSSVariablesMap::clear(ExceptionState& es) const
+void CSSVariablesMap::clear(ExceptionState& es)
 {
-    if (m_styleDeclaration)
-        return m_styleDeclaration->clearVariables(es);
+    if (!m_styleDeclaration)
+        return;
+    if (m_styleDeclaration->clearVariables(es)) {
+        Iterators::iterator end = m_activeIterators.end();
+        for (Iterators::iterator it = m_activeIterators.begin(); it != end; ++it)
+            (*it)->clearedVariables();
+    }
+}
+
+void CSSVariablesMap::forEach(PassRefPtr<CSSVariablesMapForEachCallback> callback, ScriptValue& thisArg) const
+{
+    forEach(callback, &thisArg);
+}
+
+void CSSVariablesMap::forEach(PassRefPtr<CSSVariablesMapForEachCallback> callback) const
+{
+    forEach(callback, 0);
+}
+
+void CSSVariablesMap::forEach(PassRefPtr<CSSVariablesMapForEachCallback> callback, ScriptValue* thisArg) const
+{
+    if (!m_styleDeclaration)
+        return;
+    RefPtr<CSSVariablesIterator> iterator = m_styleDeclaration->variablesIterator();
+    m_activeIterators.append(iterator.get());
+    while (!iterator->atEnd()) {
+        String name = iterator->name();
+        String value = iterator->value();
+        if (thisArg)
+            callback->handleItem(*thisArg, value, name, const_cast<CSSVariablesMap*>(this));
+        else
+            callback->handleItem(value, name, const_cast<CSSVariablesMap*>(this));
+        iterator->advance();
+    }
+    ASSERT(m_activeIterators.last() == iterator.get());
+    m_activeIterators.removeLast();
 }
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSVariablesMap.h b/Source/core/css/CSSVariablesMap.h
index 5c23695..3bd9460 100644
--- a/Source/core/css/CSSVariablesMap.h
+++ b/Source/core/css/CSSVariablesMap.h
@@ -29,12 +29,14 @@
 #define CSSVariablesMap_h
 
 #include "RuntimeEnabledFeatures.h"
+#include "core/css/CSSVariablesMapForEachCallback.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
 class CSSStyleDeclaration;
+class CSSVariablesIterator;
 class ExceptionState;
 
 class CSSVariablesMap : public RefCounted<CSSVariablesMap> {
@@ -49,9 +51,11 @@
     unsigned size() const;
     String get(const AtomicString& name) const;
     bool has(const AtomicString& name) const;
-    void set(const AtomicString& name, const String& value, ExceptionState&) const;
-    bool remove(const AtomicString& name) const;
-    void clear(ExceptionState&) const;
+    void set(const AtomicString& name, const String& value, ExceptionState&);
+    bool remove(const AtomicString& name);
+    void clear(ExceptionState&);
+    void forEach(PassRefPtr<CSSVariablesMapForEachCallback>, ScriptValue& thisArg) const;
+    void forEach(PassRefPtr<CSSVariablesMapForEachCallback>) const;
 
     void clearStyleDeclaration() { m_styleDeclaration = 0; }
 
@@ -62,7 +66,11 @@
         ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
     }
 
+    void forEach(PassRefPtr<CSSVariablesMapForEachCallback>, ScriptValue* thisArg) const;
+
     CSSStyleDeclaration* m_styleDeclaration;
+    typedef Vector<CSSVariablesIterator*> Iterators;
+    mutable Iterators m_activeIterators;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSVariablesMap.idl b/Source/core/css/CSSVariablesMap.idl
index b6ab78a..3c88025 100644
--- a/Source/core/css/CSSVariablesMap.idl
+++ b/Source/core/css/CSSVariablesMap.idl
@@ -32,4 +32,5 @@
     [RaisesException] void set(DOMString name, DOMString value);
     [ImplementedAs=remove] boolean delete(DOMString name);
     [RaisesException] void clear();
+    void forEach(CSSVariablesMapForEachCallback callback, optional any thisArg);
 };
diff --git a/Source/core/css/CSSVariablesMapForEachCallback.h b/Source/core/css/CSSVariablesMapForEachCallback.h
new file mode 100644
index 0000000..bb412bb
--- /dev/null
+++ b/Source/core/css/CSSVariablesMapForEachCallback.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSVariablesMapForEachCallback_h
+#define CSSVariablesMapForEachCallback_h
+
+#include "bindings/v8/ScriptValue.h"
+#include "wtf/RefCounted.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class CSSVariablesMap;
+
+class CSSVariablesMapForEachCallback : public RefCounted<CSSVariablesMapForEachCallback> {
+public:
+    virtual ~CSSVariablesMapForEachCallback() { }
+    virtual bool handleItem(ScriptValue thisValue, const String& value, const String& name, CSSVariablesMap*) = 0;
+    virtual bool handleItem(const String& value, const String& name, CSSVariablesMap*) = 0;
+};
+
+} // namespace WebCore
+
+#endif // CSSVariablesMapForEachCallback_h
diff --git a/Source/core/css/CSSVariablesMapForEachCallback.idl b/Source/core/css/CSSVariablesMapForEachCallback.idl
new file mode 100644
index 0000000..d66eb61
--- /dev/null
+++ b/Source/core/css/CSSVariablesMapForEachCallback.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+callback interface CSSVariablesMapForEachCallback {
+    [CallWith=ThisValue] boolean handleItem(DOMString value, DOMString name, CSSVariablesMap map);
+    boolean handleItem(DOMString value, DOMString name, CSSVariablesMap map);
+};
diff --git a/Source/core/css/DocumentRuleSets.cpp b/Source/core/css/DocumentRuleSets.cpp
index 298d23d..00df1c0 100644
--- a/Source/core/css/DocumentRuleSets.cpp
+++ b/Source/core/css/DocumentRuleSets.cpp
@@ -49,12 +49,6 @@
     }
 }
 
-void ShadowDistributedRules::collectMatchRequests(bool includeEmptyRules, Vector<MatchRequest>& matchRequests)
-{
-    for (ShadowDistributedRuleSetMap::iterator it = m_shadowDistributedRuleSetMap.begin(); it != m_shadowDistributedRuleSetMap.end(); ++it)
-        matchRequests.append(MatchRequest(it->value.get(), includeEmptyRules, it->key));
-}
-
 void ShadowDistributedRules::reset(const ContainerNode* scopingNode)
 {
     m_shadowDistributedRuleSetMap.remove(scopingNode);
@@ -74,13 +68,13 @@
 {
 }
 
-void DocumentRuleSets::initUserStyle(StyleEngine* styleSheetCollection, const MediaQueryEvaluator& medium, StyleResolver& resolver)
+void DocumentRuleSets::initUserStyle(StyleEngine* styleSheetCollection, const Vector<RefPtr<StyleRule> >& watchedSelectors, const MediaQueryEvaluator& medium, StyleResolver& resolver)
 {
     OwnPtr<RuleSet> tempUserStyle = RuleSet::create();
     if (CSSStyleSheet* pageUserSheet = styleSheetCollection->pageUserSheet())
         tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), medium, &resolver);
-    collectRulesFromUserStyleSheets(styleSheetCollection->injectedUserStyleSheets(), *tempUserStyle, medium, resolver);
     collectRulesFromUserStyleSheets(styleSheetCollection->documentUserStyleSheets(), *tempUserStyle, medium, resolver);
+    collectRulesFromWatchedSelectors(watchedSelectors, *tempUserStyle);
     if (tempUserStyle->ruleCount() > 0 || tempUserStyle->pageRules().size() > 0)
         m_userStyle = tempUserStyle.release();
 }
@@ -93,6 +87,12 @@
     }
 }
 
+void DocumentRuleSets::collectRulesFromWatchedSelectors(const Vector<RefPtr<StyleRule> >& watchedSelectors, RuleSet& userStyle)
+{
+    for (unsigned i = 0; i < watchedSelectors.size(); ++i)
+        userStyle.addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
+}
+
 void DocumentRuleSets::resetAuthorStyle()
 {
     m_shadowDistributedRules.clear();
diff --git a/Source/core/css/DocumentRuleSets.h b/Source/core/css/DocumentRuleSets.h
index 4434ec5..3b38ac5 100644
--- a/Source/core/css/DocumentRuleSets.h
+++ b/Source/core/css/DocumentRuleSets.h
@@ -43,12 +43,15 @@
 class ShadowDistributedRules {
 public:
     void addRule(StyleRule*, size_t selectorIndex, ContainerNode* scopingNode, AddRuleFlags);
-    void collectMatchRequests(bool includeEmptyRules, Vector<MatchRequest>&);
     void clear() { m_shadowDistributedRuleSetMap.clear(); }
     void reset(const ContainerNode* scopingNode);
     bool isEmpty() const { return m_shadowDistributedRuleSetMap.isEmpty(); }
     void collectFeaturesTo(RuleFeatureSet&);
 
+    typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> >::iterator iterator;
+    iterator begin() { return m_shadowDistributedRuleSetMap.begin(); }
+    iterator end() { return m_shadowDistributedRuleSetMap.end(); }
+
 private:
     typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ShadowDistributedRuleSetMap;
     ShadowDistributedRuleSetMap m_shadowDistributedRuleSetMap;
@@ -60,7 +63,7 @@
     ~DocumentRuleSets();
     RuleSet* userStyle() const { return m_userStyle.get(); }
 
-    void initUserStyle(StyleEngine*, const MediaQueryEvaluator&, StyleResolver&);
+    void initUserStyle(StyleEngine*, const Vector<RefPtr<StyleRule> >& watchedSelectors, const MediaQueryEvaluator&, StyleResolver&);
     void resetAuthorStyle();
     void collectFeaturesTo(RuleFeatureSet&, bool isViewSource);
 
@@ -68,6 +71,7 @@
 
 private:
     void collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&, RuleSet& userStyle, const MediaQueryEvaluator&, StyleResolver&);
+    void collectRulesFromWatchedSelectors(const Vector<RefPtr<StyleRule> >&, RuleSet& userStyle);
     OwnPtr<RuleSet> m_userStyle;
     ShadowDistributedRules m_shadowDistributedRules;
 };
diff --git a/Source/core/css/ElementRuleCollector.cpp b/Source/core/css/ElementRuleCollector.cpp
index 5ccfc77..deff32a 100644
--- a/Source/core/css/ElementRuleCollector.cpp
+++ b/Source/core/css/ElementRuleCollector.cpp
@@ -48,12 +48,15 @@
     , m_regionForStyling(0)
     , m_pseudoStyleRequest(NOPSEUDO)
     , m_mode(SelectorChecker::ResolvingStyle)
-    , m_behaviorAtBoundary(SelectorChecker::DoesNotCrossBoundary)
     , m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(context.parentNode()))
     , m_sameOriginOnly(false)
     , m_matchingUARules(false)
 { }
 
+ElementRuleCollector::~ElementRuleCollector()
+{
+}
+
 MatchResult& ElementRuleCollector::matchedResult()
 {
     return m_result;
@@ -107,7 +110,7 @@
     if (elementApplyAuthorStyles)
         return true;
     // c) the rules comes from a scoped style sheet within the same tree scope
-    if (!scopingNode || &treeScope == &scopingNode->treeScope())
+    if (!scopingNode || treeScope == scopingNode->treeScope())
         return true;
     // d) the rules comes from a scoped style sheet within an active shadow root whose host is the given element
     if (element->isInShadowTree() && (behaviorAtBoundary & SelectorChecker::ScopeIsShadowHost) && scopingNode == element->containingShadowRoot()->host())
@@ -118,7 +121,7 @@
     return false;
 }
 
-void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest, RuleRange& ruleRange, CascadeScope cascadeScope, CascadeOrder cascadeOrder)
+void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest, RuleRange& ruleRange, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder)
 {
     ASSERT(matchRequest.ruleSet);
     ASSERT(m_context.element());
@@ -127,11 +130,11 @@
     const AtomicString& pseudoId = element->shadowPseudoId();
     if (!pseudoId.isEmpty()) {
         ASSERT(element->isStyledElement());
-        collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId.impl()), ignoreCascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId.impl()), behaviorAtBoundary, ignoreCascadeScope, cascadeOrder, matchRequest, ruleRange);
     }
 
     if (element->isWebVTTElement())
-        collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), cascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
     // Check whether other types of rules are applicable in the current tree scope. Criteria for this:
     // a) it's a UA rule
     // b) the tree scope allows author rules
@@ -139,27 +142,27 @@
     // d) the rules comes from a scoped style sheet within an active shadow root whose host is the given element
     // e) the rules can cross boundaries
     // b)-e) is checked in rulesApplicableInCurrentTreeScope.
-    if (!m_matchingUARules && !rulesApplicableInCurrentTreeScope(element, matchRequest.scope, m_behaviorAtBoundary, matchRequest.elementApplyAuthorStyles))
+    if (!m_matchingUARules && !rulesApplicableInCurrentTreeScope(element, matchRequest.scope, behaviorAtBoundary, matchRequest.elementApplyAuthorStyles))
         return;
 
     // We need to collect the rules for id, class, tag, and everything else into a buffer and
     // then sort the buffer.
     if (element->hasID())
-        collectMatchingRulesForList(matchRequest.ruleSet->idRules(element->idForStyleResolution().impl()), cascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectMatchingRulesForList(matchRequest.ruleSet->idRules(element->idForStyleResolution().impl()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
     if (element->isStyledElement() && element->hasClass()) {
         for (size_t i = 0; i < element->classNames().size(); ++i)
-            collectMatchingRulesForList(matchRequest.ruleSet->classRules(element->classNames()[i].impl()), cascadeScope, cascadeOrder, matchRequest, ruleRange);
+            collectMatchingRulesForList(matchRequest.ruleSet->classRules(element->classNames()[i].impl()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
     }
 
     if (element->isLink())
-        collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules(), cascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
     if (SelectorChecker::matchesFocusPseudoClass(element))
-        collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(), cascadeScope, cascadeOrder, matchRequest, ruleRange);
-    collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element->localName().impl()), cascadeScope, cascadeOrder, matchRequest, ruleRange);
-    collectMatchingRulesForList(matchRequest.ruleSet->universalRules(), cascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+    collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element->localName().impl()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+    collectMatchingRulesForList(matchRequest.ruleSet->universalRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
 }
 
-void ElementRuleCollector::collectMatchingRulesForRegion(const MatchRequest& matchRequest, RuleRange& ruleRange, CascadeScope cascadeScope, CascadeOrder cascadeOrder)
+void ElementRuleCollector::collectMatchingRulesForRegion(const MatchRequest& matchRequest, RuleRange& ruleRange, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder)
 {
     if (!m_regionForStyling)
         return;
@@ -170,7 +173,7 @@
         if (checkRegionSelector(regionSelector, toElement(m_regionForStyling->node()))) {
             RuleSet* regionRules = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.at(i).ruleSet.get();
             ASSERT(regionRules);
-            collectMatchingRules(MatchRequest(regionRules, matchRequest.includeEmptyRules, matchRequest.scope), ruleRange, cascadeScope, cascadeOrder);
+            collectMatchingRules(MatchRequest(regionRules, matchRequest.includeEmptyRules, matchRequest.scope), ruleRange, behaviorAtBoundary, cascadeScope, cascadeOrder);
         }
     }
 }
@@ -199,9 +202,11 @@
     }
 }
 
-inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, const ContainerNode* scope, PseudoId& dynamicPseudo)
+inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, const ContainerNode* scope, PseudoId& dynamicPseudo, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary)
 {
-    if (ruleData.hasFastCheckableSelector()) {
+    // They can't match because the fast path uses a pool of tag/class/ids, collected from
+    // elements in that tree and those will never match the host, since it's in a different pool.
+    if (ruleData.hasFastCheckableSelector() && SelectorChecker::isHostInItsShadowTree(m_context.element(), behaviorAtBoundary, scope)) {
         // We know this selector does not include any pseudo elements.
         if (m_pseudoStyleRequest.pseudoId != NOPSEUDO)
             return false;
@@ -221,14 +226,14 @@
     }
 
     // Slow path.
-    SelectorChecker selectorChecker(document(), m_mode);
+    SelectorChecker selectorChecker(m_context.element()->document(), m_mode);
     SelectorChecker::SelectorCheckingContext context(ruleData.selector(), m_context.element(), SelectorChecker::VisitedMatchEnabled);
     context.elementStyle = m_style.get();
     context.scope = scope;
     context.pseudoId = m_pseudoStyleRequest.pseudoId;
     context.scrollbar = m_pseudoStyleRequest.scrollbar;
     context.scrollbarPart = m_pseudoStyleRequest.scrollbarPart;
-    context.behaviorAtBoundary = m_behaviorAtBoundary;
+    context.behaviorAtBoundary = behaviorAtBoundary;
     SelectorChecker::Match match = selectorChecker.match(context, dynamicPseudo, DOMSiblingTraversalStrategy());
     if (match != SelectorChecker::SelectorMatches)
         return false;
@@ -237,14 +242,14 @@
     return true;
 }
 
-void ElementRuleCollector::collectRuleIfMatches(const RuleData& ruleData, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
+void ElementRuleCollector::collectRuleIfMatches(const RuleData& ruleData, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
 {
     if (m_canUseFastReject && m_selectorFilter.fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
         return;
 
     StyleRule* rule = ruleData.rule();
     PseudoId dynamicPseudo = NOPSEUDO;
-    if (ruleMatches(ruleData, matchRequest.scope, dynamicPseudo)) {
+    if (ruleMatches(ruleData, matchRequest.scope, dynamicPseudo, behaviorAtBoundary)) {
         // If the rule has no properties to apply, then ignore it in the non-debug mode.
         const StylePropertySet* properties = rule->properties();
         if (!properties || (properties->isEmpty() && !matchRequest.includeEmptyRules))
@@ -258,7 +263,7 @@
             if (m_mode == SelectorChecker::CollectingRules)
                 return;
             // FIXME: Matching should not modify the style directly.
-            if (dynamicPseudo < FIRST_INTERNAL_PSEUDOID)
+            if (m_style && dynamicPseudo < FIRST_INTERNAL_PSEUDOID)
                 m_style->setHasPseudoStyle(dynamicPseudo);
         } else {
             // Update our first/last rule indices in the matched rules array.
@@ -273,22 +278,22 @@
     }
 }
 
-void ElementRuleCollector::collectMatchingRulesForList(const RuleData* rules, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
+void ElementRuleCollector::collectMatchingRulesForList(const RuleData* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
 {
     if (!rules)
         return;
     while (!rules->isLastInArray())
-        collectRuleIfMatches(*rules++, cascadeScope, cascadeOrder, matchRequest, ruleRange);
-    collectRuleIfMatches(*rules, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectRuleIfMatches(*rules++, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+    collectRuleIfMatches(*rules, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
 }
 
-void ElementRuleCollector::collectMatchingRulesForList(const Vector<RuleData>* rules, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
+void ElementRuleCollector::collectMatchingRulesForList(const Vector<RuleData>* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
 {
     if (!rules)
         return;
     unsigned size = rules->size();
     for (unsigned i = 0; i < size; ++i)
-        collectRuleIfMatches(rules->at(i), cascadeScope, cascadeOrder, matchRequest, ruleRange);
+        collectRuleIfMatches(rules->at(i), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
 }
 
 static inline bool compareRules(const MatchedRule& matchedRule1, const MatchedRule& matchedRule2)
@@ -314,11 +319,10 @@
     // To check whether a given RuleSet has any rule matching a given element,
     // should not see the element's treescope. Because RuleSet has no
     // information about "scope".
-    m_behaviorAtBoundary = SelectorChecker::StaysWithinTreeScope;
     int firstRuleIndex = -1, lastRuleIndex = -1;
     RuleRange ruleRange(firstRuleIndex, lastRuleIndex);
     // FIXME: Verify whether it's ok to ignore CascadeScope here.
-    collectMatchingRules(MatchRequest(ruleSet), ruleRange);
+    collectMatchingRules(MatchRequest(ruleSet), ruleRange, SelectorChecker::StaysWithinTreeScope);
 
     return m_matchedRules && !m_matchedRules->isEmpty();
 }
diff --git a/Source/core/css/ElementRuleCollector.h b/Source/core/css/ElementRuleCollector.h
index 60f7abc..bf83216 100644
--- a/Source/core/css/ElementRuleCollector.h
+++ b/Source/core/css/ElementRuleCollector.h
@@ -76,10 +76,9 @@
 class ElementRuleCollector {
     WTF_MAKE_NONCOPYABLE(ElementRuleCollector);
 public:
-    ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle*);
+    ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle* = 0);
+    ~ElementRuleCollector();
 
-    void setBehaviorAtBoundary(SelectorChecker::BehaviorAtBoundary boundary) { m_behaviorAtBoundary = boundary; }
-    SelectorChecker::BehaviorAtBoundary behaviorAtBoundary() const { return m_behaviorAtBoundary; }
     void setCanUseFastReject(bool canUseFastReject) { m_canUseFastReject = canUseFastReject; }
     bool canUseFastReject() const { return m_canUseFastReject; }
 
@@ -94,8 +93,8 @@
     MatchResult& matchedResult();
     PassRefPtr<CSSRuleList> matchedRuleList();
 
-    void collectMatchingRules(const MatchRequest&, RuleRange&, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
-    void collectMatchingRulesForRegion(const MatchRequest&, RuleRange&, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
+    void collectMatchingRules(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
+    void collectMatchingRulesForRegion(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
     void sortAndTransferMatchedRules();
     void clearMatchedRules();
     void addElementStyleProperties(const StylePropertySet*, bool isCacheable = true);
@@ -105,12 +104,10 @@
     void sortAndTransferMatchedRulesWithOnlySortBySpecificity();
 
 private:
-    Document& document() { return m_context.document(); }
-
-    void collectRuleIfMatches(const RuleData&, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
-    void collectMatchingRulesForList(const Vector<RuleData>*, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
-    void collectMatchingRulesForList(const RuleData*, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
-    bool ruleMatches(const RuleData&, const ContainerNode* scope, PseudoId&);
+    void collectRuleIfMatches(const RuleData&, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
+    void collectMatchingRulesForList(const Vector<RuleData>*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
+    void collectMatchingRulesForList(const RuleData*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
+    bool ruleMatches(const RuleData&, const ContainerNode* scope, PseudoId&, SelectorChecker::BehaviorAtBoundary);
 
     void sortMatchedRules();
     void addMatchedRule(const RuleData*, CascadeScope, CascadeOrder);
@@ -125,7 +122,6 @@
     const RenderRegion* m_regionForStyling;
     PseudoStyleRequest m_pseudoStyleRequest;
     SelectorChecker::Mode m_mode;
-    SelectorChecker::BehaviorAtBoundary m_behaviorAtBoundary;
     bool m_canUseFastReject;
     bool m_sameOriginOnly;
     bool m_matchingUARules;
diff --git a/Source/core/css/FontFace.cpp b/Source/core/css/FontFace.cpp
index 98a3f07..b462bb1 100644
--- a/Source/core/css/FontFace.cpp
+++ b/Source/core/css/FontFace.cpp
@@ -45,7 +45,7 @@
 #include "core/css/StylePropertySet.h"
 #include "core/css/StyleRule.h"
 #include "core/dom/Document.h"
-#include "core/page/Frame.h"
+#include "core/frame/Frame.h"
 #include "core/page/Settings.h"
 #include "core/platform/graphics/FontTraitsMask.h"
 #include "core/svg/SVGFontFaceElement.h"
@@ -412,7 +412,7 @@
 
     for (int i = 0; i < srcLength; i++) {
         // An item in the list either specifies a string (local font name) or a URL (remote font to download).
-        CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i));
+        CSSFontFaceSrcValue* item = toCSSFontFaceSrcValue(srcList->itemWithoutBoundsCheck(i));
         OwnPtr<CSSFontFaceSource> source;
 
 #if ENABLE(SVG_FONTS)
@@ -446,8 +446,8 @@
     if (CSSValueList* rangeList = toCSSValueList(m_unicodeRange.get())) {
         unsigned numRanges = rangeList->length();
         for (unsigned i = 0; i < numRanges; i++) {
-            CSSUnicodeRangeValue* range = static_cast<CSSUnicodeRangeValue*>(rangeList->itemWithoutBoundsCheck(i));
-            cssFontFace->addRange(range->from(), range->to());
+            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i));
+            cssFontFace->ranges().add(range->from(), range->to());
         }
     }
     return cssFontFace;
diff --git a/Source/core/css/FontFace.idl b/Source/core/css/FontFace.idl
index a66872b..874872f 100644
--- a/Source/core/css/FontFace.idl
+++ b/Source/core/css/FontFace.idl
@@ -36,7 +36,7 @@
 };
 
 [
-    EnabledAtRuntime=FontLoadEvents,
+    RuntimeEnabled=FontLoadEvents,
     Constructor(DOMString family, DOMString source, Dictionary descriptors),
     ConstructorRaisesException
 ] interface FontFace {
diff --git a/Source/core/css/FontFaceSet.cpp b/Source/core/css/FontFaceSet.cpp
index d241d24..b593895 100644
--- a/Source/core/css/FontFaceSet.cpp
+++ b/Source/core/css/FontFaceSet.cpp
@@ -40,7 +40,7 @@
 #include "core/css/StylePropertySet.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/page/FrameView.h"
+#include "core/frame/FrameView.h"
 #include "core/platform/HistogramSupport.h"
 
 namespace WebCore {
@@ -50,7 +50,7 @@
 
 class LoadFontPromiseResolver : public CSSSegmentedFontFace::LoadFontCallback {
 public:
-    static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ScriptExecutionContext* context)
+    static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ExecutionContext* context)
     {
         int numFamilies = 0;
         for (const FontFamily* f = &family; f; f = f->next())
@@ -72,7 +72,7 @@
     }
 
 private:
-    LoadFontPromiseResolver(int numLoading, ScriptExecutionContext* context)
+    LoadFontPromiseResolver(int numLoading, ExecutionContext* context)
         : m_numLoading(numLoading)
         , m_errorOccured(false)
         , m_scriptState(ScriptState::current())
@@ -121,7 +121,7 @@
 
 class FontsReadyPromiseResolver {
 public:
-    static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptExecutionContext* context)
+    static PassOwnPtr<FontsReadyPromiseResolver> create(ExecutionContext* context)
     {
         return adoptPtr(new FontsReadyPromiseResolver(context));
     }
@@ -140,7 +140,7 @@
     }
 
 private:
-    FontsReadyPromiseResolver(ScriptExecutionContext* context)
+    FontsReadyPromiseResolver(ExecutionContext* context)
         : m_scriptState(ScriptState::current())
         , m_resolver(ScriptPromiseResolver::create(context))
     { }
@@ -163,27 +163,17 @@
 
 Document* FontFaceSet::document() const
 {
-    return toDocument(scriptExecutionContext());
-}
-
-EventTargetData* FontFaceSet::eventTargetData()
-{
-    return &m_eventTargetData;
-}
-
-EventTargetData* FontFaceSet::ensureEventTargetData()
-{
-    return &m_eventTargetData;
+    return toDocument(executionContext());
 }
 
 const AtomicString& FontFaceSet::interfaceName() const
 {
-    return eventNames().interfaceForFontFaceSet;
+    return EventTargetNames::FontFaceSet;
 }
 
-ScriptExecutionContext* FontFaceSet::scriptExecutionContext() const
+ExecutionContext* FontFaceSet::executionContext() const
 {
-    return ActiveDOMObject::scriptExecutionContext();
+    return ActiveDOMObject::executionContext();
 }
 
 AtomicString FontFaceSet::status() const
@@ -257,7 +247,7 @@
 
     ++m_loadingCount;
     if (m_loadingCount == 1 && !m_shouldFireDoneEvent)
-        scheduleEvent(CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadingEvent));
+        scheduleEvent(CSSFontFaceLoadEvent::createForFontFaces(EventTypeNames::loading));
     m_shouldFireDoneEvent = false;
 }
 
@@ -291,7 +281,7 @@
 
 ScriptPromise FontFaceSet::ready()
 {
-    OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(scriptExecutionContext());
+    OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(executionContext());
     ScriptPromise promise = resolver->promise();
     m_readyResolvers.append(resolver.release());
     if (!m_timer.isActive())
@@ -317,10 +307,10 @@
         m_shouldFireDoneEvent = false;
         RefPtr<CSSFontFaceLoadEvent> doneEvent;
         RefPtr<CSSFontFaceLoadEvent> errorEvent;
-        doneEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadingdoneEvent, m_loadedFonts);
+        doneEvent = CSSFontFaceLoadEvent::createForFontFaces(EventTypeNames::loadingdone, m_loadedFonts);
         m_loadedFonts.clear();
         if (!m_failedFonts.isEmpty()) {
-            errorEvent = CSSFontFaceLoadEvent::createForFontFaces(eventNames().loadingerrorEvent, m_failedFonts);
+            errorEvent = CSSFontFaceLoadEvent::createForFontFaces(EventTypeNames::loadingerror, m_failedFonts);
             m_failedFonts.clear();
         }
         dispatchEvent(doneEvent);
@@ -336,9 +326,14 @@
     }
 }
 
-Vector<RefPtr<FontFace> > FontFaceSet::match(const String& fontString, const String&, ExceptionState& es)
+static const String& nullToSpace(const String& s)
 {
-    // FIXME: The second parameter (text) is ignored.
+    DEFINE_STATIC_LOCAL(String, space, (" "));
+    return s.isNull() ? space : s;
+}
+
+Vector<RefPtr<FontFace> > FontFaceSet::match(const String& fontString, const String& text, ExceptionState& es)
+{
     Vector<RefPtr<FontFace> > matchedFonts;
 
     Font font;
@@ -350,14 +345,13 @@
     for (const FontFamily* f = &font.family(); f; f = f->next()) {
         CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector()->getFontFace(font.fontDescription(), f->family());
         if (face)
-            matchedFonts.append(face->fontFaces());
+            matchedFonts.append(face->fontFaces(nullToSpace(text)));
     }
     return matchedFonts;
 }
 
-ScriptPromise FontFaceSet::load(const String& fontString, const String&, ExceptionState& es)
+ScriptPromise FontFaceSet::load(const String& fontString, const String& text, ExceptionState& es)
 {
-    // FIXME: The second parameter (text) is ignored.
     Font font;
     if (!resolveFontStyle(fontString, font)) {
         es.throwUninformativeAndGenericDOMException(SyntaxError);
@@ -365,21 +359,20 @@
     }
 
     Document* d = document();
-    RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(font.family(), scriptExecutionContext());
+    RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(font.family(), executionContext());
     for (const FontFamily* f = &font.family(); f; f = f->next()) {
         CSSSegmentedFontFace* face = d->styleResolver()->fontSelector()->getFontFace(font.fontDescription(), f->family());
         if (!face) {
             resolver->error(d);
             continue;
         }
-        face->loadFont(font.fontDescription(), resolver);
+        face->loadFont(font.fontDescription(), nullToSpace(text), resolver);
     }
     return resolver->promise();
 }
 
-bool FontFaceSet::check(const String& fontString, const String&, ExceptionState& es)
+bool FontFaceSet::check(const String& fontString, const String& text, ExceptionState& es)
 {
-    // FIXME: The second parameter (text) is ignored.
     Font font;
     if (!resolveFontStyle(fontString, font)) {
         es.throwUninformativeAndGenericDOMException(SyntaxError);
@@ -388,7 +381,7 @@
 
     for (const FontFamily* f = &font.family(); f; f = f->next()) {
         CSSSegmentedFontFace* face = document()->styleResolver()->fontSelector()->getFontFace(font.fontDescription(), f->family());
-        if (!face || !face->checkFont())
+        if (!face || !face->checkFont(nullToSpace(text)))
             return false;
     }
     return true;
diff --git a/Source/core/css/FontFaceSet.h b/Source/core/css/FontFaceSet.h
index 11ad874..10ca084 100644
--- a/Source/core/css/FontFaceSet.h
+++ b/Source/core/css/FontFaceSet.h
@@ -30,9 +30,9 @@
 #include "core/css/FontFace.h"
 #include "core/dom/ActiveDOMObject.h"
 #include "core/events/EventListener.h"
-#include "core/events/EventNames.h"
 #include "core/events/EventTarget.h"
-#include "core/platform/Timer.h"
+#include "core/events/ThreadLocalEventNames.h"
+#include "platform/Timer.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/Vector.h"
@@ -53,9 +53,9 @@
 class FontResource;
 class FontsReadyPromiseResolver;
 class LoadFontPromiseResolver;
-class ScriptExecutionContext;
+class ExecutionContext;
 
-class FontFaceSet : public RefCounted<FontFaceSet>, public ActiveDOMObject, public EventTarget {
+class FontFaceSet : public RefCounted<FontFaceSet>, public ActiveDOMObject, public EventTargetWithInlineData {
 public:
     static PassRefPtr<FontFaceSet> create(Document* document)
     {
@@ -74,8 +74,8 @@
 
     AtomicString status() const;
 
-    virtual ScriptExecutionContext* scriptExecutionContext() const;
-    virtual const AtomicString& interfaceName() const;
+    virtual ExecutionContext* executionContext() const OVERRIDE;
+    virtual const AtomicString& interfaceName() const OVERRIDE;
 
     using RefCounted<FontFaceSet>::ref;
     using RefCounted<FontFaceSet>::deref;
@@ -102,10 +102,8 @@
 
     FontFaceSet(Document*);
 
-    virtual void refEventTarget() { ref(); }
-    virtual void derefEventTarget() { deref(); }
-    virtual EventTargetData* eventTargetData();
-    virtual EventTargetData* ensureEventTargetData();
+    virtual void refEventTarget() OVERRIDE { ref(); }
+    virtual void derefEventTarget() OVERRIDE { deref(); }
 
     void scheduleEvent(PassRefPtr<Event>);
     void queueDoneEvent(FontFace*);
@@ -115,7 +113,6 @@
     bool resolveFontStyle(const String&, Font&);
     void timerFired(Timer<FontFaceSet>*);
 
-    EventTargetData m_eventTargetData;
     unsigned m_loadingCount;
     Vector<RefPtr<Event> > m_pendingEvents;
     Vector<RefPtr<LoadFontPromiseResolver> > m_pendingLoadResolvers;
diff --git a/Source/core/css/FontFaceSet.idl b/Source/core/css/FontFaceSet.idl
index 9fe5d56..da6a824 100644
--- a/Source/core/css/FontFaceSet.idl
+++ b/Source/core/css/FontFaceSet.idl
@@ -32,7 +32,7 @@
 
 [
     NoInterfaceObject,
-    EnabledAtRuntime=FontLoadEvents,
+    RuntimeEnabled=FontLoadEvents,
     ActiveDOMObject,
     GenerateIsReachable=document
 ] interface FontFaceSet : EventTarget {
@@ -43,8 +43,8 @@
 
     [RaisesException] sequence<FontFace> match(DOMString font, [Default=NullString] optional DOMString text);
     [RaisesException] boolean check(DOMString font, [Default=NullString] optional DOMString text);
-    [EnabledAtRuntime=Promise, RaisesException] Promise load(DOMString font, [Default=NullString] optional DOMString text);
-    [EnabledAtRuntime=Promise] Promise ready();
+    [RuntimeEnabled=Promise, RaisesException] Promise load(DOMString font, [Default=NullString] optional DOMString text);
+    [RuntimeEnabled=Promise] Promise ready();
 
     readonly attribute FontFaceSetLoadStatus status;
 };
diff --git a/Source/core/css/InspectorCSSOMWrappers.cpp b/Source/core/css/InspectorCSSOMWrappers.cpp
index 595d22c..324c012 100644
--- a/Source/core/css/InspectorCSSOMWrappers.cpp
+++ b/Source/core/css/InspectorCSSOMWrappers.cpp
@@ -107,7 +107,6 @@
 {
     collectFromStyleSheets(styleSheetCollection->activeAuthorStyleSheets());
     collect(styleSheetCollection->pageUserSheet());
-    collectFromStyleSheets(styleSheetCollection->injectedUserStyleSheets());
     collectFromStyleSheets(styleSheetCollection->documentUserStyleSheets());
 }
 
diff --git a/Source/core/css/LengthFunctions.cpp b/Source/core/css/LengthFunctions.cpp
index 3a91ce2..be2dfc9 100644
--- a/Source/core/css/LengthFunctions.cpp
+++ b/Source/core/css/LengthFunctions.cpp
@@ -24,9 +24,9 @@
 #include "config.h"
 #include "core/css/LengthFunctions.h"
 
-#include "core/platform/LayoutUnit.h"
 #include "core/platform/Length.h"
 #include "core/rendering/RenderView.h"
+#include "platform/LayoutUnit.h"
 
 namespace WebCore {
 
diff --git a/Source/core/css/MediaList.cpp b/Source/core/css/MediaList.cpp
index fdc4b36..ce88391 100644
--- a/Source/core/css/MediaList.cpp
+++ b/Source/core/css/MediaList.cpp
@@ -28,7 +28,7 @@
 #include "core/css/MediaQueryExp.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/page/DOMWindow.h"
+#include "core/frame/DOMWindow.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
diff --git a/Source/core/css/MediaQueryEvaluator.cpp b/Source/core/css/MediaQueryEvaluator.cpp
index 01800e4..7c6320a 100644
--- a/Source/core/css/MediaQueryEvaluator.cpp
+++ b/Source/core/css/MediaQueryEvaluator.cpp
@@ -37,18 +37,18 @@
 #include "core/css/MediaFeatureNames.h"
 #include "core/css/MediaList.h"
 #include "core/css/MediaQuery.h"
-#include "core/css/MediaQueryExp.h"
-#include "core/css/resolver/StyleResolver.h"
+#include "core/css/resolver/MediaQueryResult.h"
 #include "core/dom/NodeRenderStyle.h"
-#include "core/page/Frame.h"
-#include "core/page/FrameView.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/frame/Frame.h"
+#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/page/Settings.h"
 #include "core/platform/PlatformScreen.h"
-#include "core/platform/graphics/FloatRect.h"
 #include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/style/RenderStyle.h"
+#include "platform/geometry/FloatRect.h"
 #include "wtf/HashMap.h"
 
 namespace WebCore {
@@ -117,7 +117,7 @@
     return r == MediaQuery::Not ? !value : value;
 }
 
-bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, StyleResolver* styleResolver) const
+bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, MediaQueryResultList* viewportDependentMediaQueryResults) const
 {
     if (!querySet)
         return true;
@@ -137,11 +137,8 @@
             size_t j = 0;
             for (; j < expressions.size(); ++j) {
                 bool exprResult = eval(expressions.at(j).get());
-                // FIXME: Instead of storing these on StyleResolver, we should store them locally
-                // and then any client of this method can grab at them afterwords.
-                // Alternatively we could use an explicit out-parameter of this method.
-                if (styleResolver && expressions.at(j)->isViewportDependent())
-                    styleResolver->addViewportDependentMediaQueryResult(expressions.at(j).get(), exprResult);
+                if (viewportDependentMediaQueryResults && expressions.at(j)->isViewportDependent())
+                    viewportDependentMediaQueryResults->append(adoptPtr(new MediaQueryResult(*expressions.at(j), exprResult)));
                 if (!exprResult)
                     break;
             }
@@ -360,11 +357,13 @@
 static bool deviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
 {
     if (value) {
-        FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         int length;
-        long height = sg.height();
-        InspectorInstrumentation::applyScreenHeightOverride(frame, &height);
-        return computeLength(value, !frame->document()->inQuirksMode(), style, length) && compareValue(static_cast<int>(height), length, op);
+        if (!computeLength(value, !frame->document()->inQuirksMode(), style, length))
+            return false;
+        int height = static_cast<int>(screenRect(frame->page()->mainFrame()->view()).height());
+        if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
+            height = lroundf(height * frame->page()->deviceScaleFactor());
+        return compareValue(height, length, op);
     }
     // ({,min-,max-}device-height)
     // assume if we have a device, assume non-zero
@@ -374,11 +373,13 @@
 static bool deviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
 {
     if (value) {
-        FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         int length;
-        long width = sg.width();
-        InspectorInstrumentation::applyScreenWidthOverride(frame, &width);
-        return computeLength(value, !frame->document()->inQuirksMode(), style, length) && compareValue(static_cast<int>(width), length, op);
+        if (!computeLength(value, !frame->document()->inQuirksMode(), style, length))
+            return false;
+        int width = static_cast<int>(screenRect(frame->page()->mainFrame()->view()).width());
+        if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
+            width = lroundf(width * frame->page()->deviceScaleFactor());
+        return compareValue(width, length, op);
     }
     // ({,min-,max-}device-width)
     // assume if we have a device, assume non-zero
diff --git a/Source/core/css/MediaQueryEvaluator.h b/Source/core/css/MediaQueryEvaluator.h
index eb67ac7..c663d12 100644
--- a/Source/core/css/MediaQueryEvaluator.h
+++ b/Source/core/css/MediaQueryEvaluator.h
@@ -33,9 +33,9 @@
 namespace WebCore {
 class Frame;
 class MediaQueryExp;
+class MediaQueryResult;
 class MediaQuerySet;
 class RenderStyle;
-class StyleResolver;
 
 /**
  * Class that evaluates css media queries as defined in
@@ -73,8 +73,9 @@
     bool mediaTypeMatch(const AtomicString& mediaTypeToMatch) const;
     bool mediaTypeMatchSpecific(const char* mediaTypeToMatch) const;
 
+    typedef Vector<OwnPtr<MediaQueryResult> > MediaQueryResultList;
     /** Evaluates a list of media queries */
-    bool eval(const MediaQuerySet*, StyleResolver* = 0) const;
+    bool eval(const MediaQuerySet*, MediaQueryResultList* = 0) const;
 
     /** Evaluates media query subexpression, ie "and (media-feature: value)" part */
     bool eval(const MediaQueryExp*) const;
diff --git a/Source/core/css/MediaQueryMatcher.cpp b/Source/core/css/MediaQueryMatcher.cpp
index 1d16128..3d50338 100644
--- a/Source/core/css/MediaQueryMatcher.cpp
+++ b/Source/core/css/MediaQueryMatcher.cpp
@@ -26,8 +26,8 @@
 #include "core/css/MediaQueryListListener.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/page/Frame.h"
-#include "core/page/FrameView.h"
+#include "core/frame/Frame.h"
+#include "core/frame/FrameView.h"
 
 namespace WebCore {
 
diff --git a/Source/core/css/PageRuleCollector.cpp b/Source/core/css/PageRuleCollector.cpp
index 65c409e..e449452 100644
--- a/Source/core/css/PageRuleCollector.cpp
+++ b/Source/core/css/PageRuleCollector.cpp
@@ -40,10 +40,11 @@
     return r1->selector()->specificity() < r2->selector()->specificity();
 }
 
-bool PageRuleCollector::isLeftPage(int pageIndex) const
+bool PageRuleCollector::isLeftPage(const RenderStyle* rootElementStyle, int pageIndex) const
 {
     bool isFirstPageLeft = false;
-    if (!m_context.rootElementStyle() || !m_context.rootElementStyle()->isLeftToRightDirection())
+    ASSERT(rootElementStyle);
+    if (!rootElementStyle->isLeftToRightDirection())
         isFirstPageLeft = true;
 
     return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2;
@@ -61,9 +62,8 @@
     return "";
 }
 
-PageRuleCollector::PageRuleCollector(const ElementResolveContext& context, int pageIndex)
-    : m_context(context)
-    , m_isLeftPage(isLeftPage(pageIndex))
+PageRuleCollector::PageRuleCollector(const RenderStyle* rootElementStyle, int pageIndex)
+    : m_isLeftPage(isLeftPage(rootElementStyle, pageIndex))
     , m_isFirstPage(isFirstPage(pageIndex))
     , m_pageName(pageName(pageIndex)) { }
 
diff --git a/Source/core/css/PageRuleCollector.h b/Source/core/css/PageRuleCollector.h
index 296ee6f..8325161 100644
--- a/Source/core/css/PageRuleCollector.h
+++ b/Source/core/css/PageRuleCollector.h
@@ -32,20 +32,19 @@
 
 class PageRuleCollector {
 public:
-    PageRuleCollector(const ElementResolveContext&, int pageIndex);
+    PageRuleCollector(const RenderStyle* rootElementStyle, int pageIndex);
 
     void matchPageRules(RuleSet* rules);
     MatchResult& matchedResult() { return m_result; }
 
 private:
-    bool isLeftPage(int pageIndex) const;
-    bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
+    bool isLeftPage(const RenderStyle* rootElementStyle, int pageIndex) const;
+    bool isRightPage(const RenderStyle* rootElementStyle, int pageIndex) const { return !isLeftPage(rootElementStyle, pageIndex); }
     bool isFirstPage(int pageIndex) const;
     String pageName(int pageIndex) const;
 
     void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName);
 
-    const ElementResolveContext& m_context;
     const bool m_isLeftPage;
     const bool m_isFirstPage;
     const String m_pageName;
diff --git a/Source/core/css/PropertySetCSSStyleDeclaration.cpp b/Source/core/css/PropertySetCSSStyleDeclaration.cpp
index 900dc36..88f93c1 100644
--- a/Source/core/css/PropertySetCSSStyleDeclaration.cpp
+++ b/Source/core/css/PropertySetCSSStyleDeclaration.cpp
@@ -281,7 +281,7 @@
     return m_propertySet->variableValue(name);
 }
 
-void PropertySetCSSStyleDeclaration::setVariableValue(const AtomicString& name, const String& value, ExceptionState&)
+bool PropertySetCSSStyleDeclaration::setVariableValue(const AtomicString& name, const String& value, ExceptionState&)
 {
     ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
     StyleAttributeMutationScope mutationScope(this);
@@ -290,6 +290,7 @@
     didMutate(changed ? PropertyChanged : NoChanges);
     if (changed)
         mutationScope.enqueueMutationRecord();
+    return changed;
 }
 
 bool PropertySetCSSStyleDeclaration::removeVariable(const AtomicString& name)
@@ -304,7 +305,7 @@
     return changed;
 }
 
-void PropertySetCSSStyleDeclaration::clearVariables(ExceptionState&)
+bool PropertySetCSSStyleDeclaration::clearVariables(ExceptionState&)
 {
     ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
     StyleAttributeMutationScope mutationScope(this);
@@ -313,6 +314,12 @@
     didMutate(changed ? PropertyChanged : NoChanges);
     if (changed)
         mutationScope.enqueueMutationRecord();
+    return changed;
+}
+
+PassRefPtr<CSSVariablesIterator> PropertySetCSSStyleDeclaration::variablesIterator() const
+{
+    return m_propertySet->variablesIterator();
 }
 
 CSSValue* PropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* internalValue)
diff --git a/Source/core/css/PropertySetCSSStyleDeclaration.h b/Source/core/css/PropertySetCSSStyleDeclaration.h
index 4bb4c7f..3329981 100644
--- a/Source/core/css/PropertySetCSSStyleDeclaration.h
+++ b/Source/core/css/PropertySetCSSStyleDeclaration.h
@@ -70,9 +70,10 @@
 
     virtual unsigned variableCount() const OVERRIDE;
     virtual String variableValue(const AtomicString& name) const OVERRIDE;
-    virtual void setVariableValue(const AtomicString& name, const String& value, ExceptionState&) OVERRIDE;
+    virtual bool setVariableValue(const AtomicString& name, const String& value, ExceptionState&) OVERRIDE;
     virtual bool removeVariable(const AtomicString& name) OVERRIDE;
-    virtual void clearVariables(ExceptionState&) OVERRIDE;
+    virtual bool clearVariables(ExceptionState&) OVERRIDE;
+    virtual PassRefPtr<CSSVariablesIterator> variablesIterator() const OVERRIDE;
 
     virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const OVERRIDE;
     virtual PassRefPtr<MutableStylePropertySet> copyProperties() const OVERRIDE;
diff --git a/Source/core/css/PseudoStyleRequest.h b/Source/core/css/PseudoStyleRequest.h
index c07cb2f..11b93fc 100644
--- a/Source/core/css/PseudoStyleRequest.h
+++ b/Source/core/css/PseudoStyleRequest.h
@@ -22,8 +22,8 @@
 #ifndef PseudoStyleRequest_h
 #define PseudoStyleRequest_h
 
-#include "core/platform/ScrollTypes.h"
 #include "core/rendering/style/RenderStyleConstants.h"
+#include "platform/scroll/ScrollTypes.h"
 
 namespace WebCore {
 
diff --git a/Source/core/css/RuleSet.cpp b/Source/core/css/RuleSet.cpp
index 87fd2dc..3509682 100644
--- a/Source/core/css/RuleSet.cpp
+++ b/Source/core/css/RuleSet.cpp
@@ -371,7 +371,7 @@
             addPageRule(static_cast<StyleRulePage*>(rule));
         else if (rule->isMediaRule()) {
             StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule);
-            if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver)))
+            if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver->viewportDependentMediaQueryResults())))
                 addChildRules(mediaRule->childRules(), medium, resolver, scope, hasDocumentSecurityOrigin, addRuleFlags);
         } else if (rule->isFontFaceRule() && resolver) {
             // Add this font face to our set.
@@ -411,7 +411,7 @@
     const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules();
     for (unsigned i = 0; i < importRules.size(); ++i) {
         StyleRuleImport* importRule = importRules[i].get();
-        if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), resolver)))
+        if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), resolver->viewportDependentMediaQueryResults())))
             addRulesFromSheet(importRule->styleSheet(), medium, resolver, scope);
     }
 
diff --git a/Source/core/css/SelectorChecker.cpp b/Source/core/css/SelectorChecker.cpp
index 80222e1..d5326b9 100644
--- a/Source/core/css/SelectorChecker.cpp
+++ b/Source/core/css/SelectorChecker.cpp
@@ -49,8 +49,7 @@
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/page/FocusController.h"
-#include "core/page/Frame.h"
-#include "core/page/Page.h"
+#include "core/frame/Frame.h"
 #include "core/platform/ScrollableArea.h"
 #include "core/platform/ScrollbarTheme.h"
 #include "core/rendering/RenderObject.h"
@@ -263,7 +262,7 @@
     case CSSSelector::ShadowPseudo:
         {
             // If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope.
-            if (context.scope && &context.scope->treeScope() == &context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope)
+            if (context.scope && context.scope->treeScope() == context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope)
                 return SelectorFailsCompletely;
             Element* shadowHostNode = context.element->shadowHost();
             if (!shadowHostNode)
@@ -388,20 +387,21 @@
     const CSSSelector* const & selector = context.selector;
     ASSERT(element);
     ASSERT(selector);
+    bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.behaviorAtBoundary, context.scope);
 
     if (selector->m_match == CSSSelector::Tag)
-        return SelectorChecker::tagMatches(element, selector->tagQName());
+        return SelectorChecker::tagMatches(element, selector->tagQName(), elementIsHostInItsShadowTree ? MatchingHostInItsShadowTree : MatchingElement);
 
     if (selector->m_match == CSSSelector::Class)
-        return element->hasClass() && element->classNames().contains(selector->value());
+        return element->hasClass() && element->classNames().contains(selector->value()) && !elementIsHostInItsShadowTree;
 
     if (selector->m_match == CSSSelector::Id)
-        return element->hasID() && element->idForStyleResolution() == selector->value();
+        return element->hasID() && element->idForStyleResolution() == selector->value() && !elementIsHostInItsShadowTree;
 
     if (selector->isAttributeSelector()) {
         const QualifiedName& attr = selector->attribute();
 
-        if (!element->hasAttributes())
+        if (!element->hasAttributes() || elementIsHostInItsShadowTree)
             return false;
 
         bool caseSensitive = !m_documentIsHTML || HTMLDocument::isCaseSensitiveAttribute(attr);
@@ -614,9 +614,7 @@
         case CSSSelector::PseudoAutofill:
             if (!element || !element->isFormControlElement())
                 break;
-            if (element->hasTagName(inputTag))
-                return toHTMLInputElement(element)->isAutofilled();
-            break;
+            return toHTMLFormControlElement(element)->isAutofilled();
         case CSSSelector::PseudoAnyLink:
         case CSSSelector::PseudoLink:
             // :visited and :link matches are separated later when applying the style. Here both classes match all links...
diff --git a/Source/core/css/SelectorChecker.h b/Source/core/css/SelectorChecker.h
index aba4e03..28325b3 100644
--- a/Source/core/css/SelectorChecker.h
+++ b/Source/core/css/SelectorChecker.h
@@ -54,6 +54,11 @@
         ScopeIsShadowHost = 8
     };
 
+    enum MatchingTagType {
+        MatchingElement = 0,
+        MatchingHostInItsShadowTree
+    };
+
     struct SelectorCheckingContext {
         // Initial selector constructor
         SelectorCheckingContext(const CSSSelector* selector, Element* element, VisitedMatchType visitedMatchType)
@@ -98,7 +103,7 @@
 
     Mode mode() const { return m_mode; }
 
-    static bool tagMatches(const Element*, const QualifiedName&);
+    static bool tagMatches(const Element*, const QualifiedName&, MatchingTagType = MatchingElement);
     static bool isCommonPseudoClassSelector(const CSSSelector*);
     static bool matchesFocusPseudoClass(const Element*);
     static bool checkExactAttribute(const Element*, const QualifiedName& selectorAttributeName, const StringImpl* value);
@@ -106,6 +111,8 @@
     enum LinkMatchMask { MatchLink = 1, MatchVisited = 2, MatchAll = MatchLink | MatchVisited };
     static unsigned determineLinkMatchType(const CSSSelector*);
 
+    static bool isHostInItsShadowTree(const Element*, BehaviorAtBoundary, const ContainerNode* scope);
+
 private:
     bool checkScrollbarPseudoClass(const SelectorCheckingContext&, Document*, const CSSSelector*) const;
     Element* parentElement(const SelectorCheckingContext&) const;
@@ -129,12 +136,12 @@
         || pseudoType == CSSSelector::PseudoFocus;
 }
 
-inline bool SelectorChecker::tagMatches(const Element* element, const QualifiedName& tagQName)
+inline bool SelectorChecker::tagMatches(const Element* element, const QualifiedName& tagQName, MatchingTagType matchingTagType)
 {
     if (tagQName == anyQName())
         return true;
     const AtomicString& localName = tagQName.localName();
-    if (localName != starAtom && localName != element->localName())
+    if (localName != starAtom && (localName != element->localName() || matchingTagType == MatchingHostInItsShadowTree))
         return false;
     const AtomicString& namespaceURI = tagQName.namespaceURI();
     return namespaceURI == starAtom || namespaceURI == element->namespaceURI();
@@ -153,6 +160,11 @@
     return false;
 }
 
+inline bool SelectorChecker::isHostInItsShadowTree(const Element* element, BehaviorAtBoundary behaviorAtBoundary, const ContainerNode* scope)
+{
+    return (behaviorAtBoundary & ScopeIsShadowHost) && scope == element;
+}
+
 }
 
 #endif
diff --git a/Source/core/css/SiblingTraversalStrategies.h b/Source/core/css/SiblingTraversalStrategies.h
index 8751e94..5e0bc09 100644
--- a/Source/core/css/SiblingTraversalStrategies.h
+++ b/Source/core/css/SiblingTraversalStrategies.h
@@ -78,14 +78,8 @@
 inline int DOMSiblingTraversalStrategy::countElementsBefore(Element* element) const
 {
     int count = 0;
-    for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) {
-        unsigned index = sibling->childIndex();
-        if (index) {
-            count += index;
-            break;
-        }
+    for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling())
         count++;
-    }
 
     return count;
 }
@@ -104,8 +98,14 @@
 inline int DOMSiblingTraversalStrategy::countElementsAfter(Element* element) const
 {
     int count = 0;
-    for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling())
+    for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
+        unsigned index = sibling->childIndex();
+        if (index) {
+            count += index;
+            break;
+        }
         ++count;
+    }
 
     return count;
 }
@@ -139,7 +139,7 @@
     int countElementsOfTypeAfter(Element*, const QualifiedName&) const;
 
 private:
-    Vector<Node*> m_siblings;
+    const Vector<Node*>& m_siblings;
     int m_nth;
 };
 
diff --git a/Source/core/css/StyleMedia.cpp b/Source/core/css/StyleMedia.cpp
index 6f003f7..7d66459 100644
--- a/Source/core/css/StyleMedia.cpp
+++ b/Source/core/css/StyleMedia.cpp
@@ -30,8 +30,8 @@
 #include "core/css/MediaQueryEvaluator.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/page/Frame.h"
-#include "core/page/FrameView.h"
+#include "core/frame/Frame.h"
+#include "core/frame/FrameView.h"
 
 namespace WebCore {
 
diff --git a/Source/core/css/StyleMedia.h b/Source/core/css/StyleMedia.h
index fdf620d..21848f5 100644
--- a/Source/core/css/StyleMedia.h
+++ b/Source/core/css/StyleMedia.h
@@ -27,7 +27,7 @@
 #ifndef StyleMedia_h
 #define StyleMedia_h
 
-#include "core/page/DOMWindowProperty.h"
+#include "core/frame/DOMWindowProperty.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
diff --git a/Source/core/css/StylePropertySerializer.cpp b/Source/core/css/StylePropertySerializer.cpp
index 66008fe..dbe5d9f 100644
--- a/Source/core/css/StylePropertySerializer.cpp
+++ b/Source/core/css/StylePropertySerializer.cpp
@@ -62,8 +62,8 @@
     for (unsigned n = 0; n < size; ++n) {
         StylePropertySet::PropertyReference property = m_propertySet.propertyAt(n);
         CSSPropertyID propertyID = property.id();
-        // Only enabled properties should be part of the style.
-        ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID));
+        // Only enabled or internal properties should be part of the style.
+        ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
         CSSPropertyID shorthandPropertyID = CSSPropertyInvalid;
         CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid;
         String value;
diff --git a/Source/core/css/StylePropertySet.cpp b/Source/core/css/StylePropertySet.cpp
index d19d158..3bbd748 100644
--- a/Source/core/css/StylePropertySet.cpp
+++ b/Source/core/css/StylePropertySet.cpp
@@ -286,17 +286,18 @@
 
     size_t index = findVariableIndex(name);
     if (index != kNotFound) {
-        CSSValue* cssValue = m_propertyVector.at(index).value();
+        const CSSValue* cssValue = m_propertyVector.at(index).value();
         if (toCSSVariableValue(cssValue)->value() == value)
             return false;
     }
 
     CSSProperty property(CSSPropertyVariable, CSSVariableValue::create(name, value), important);
-    if (index == kNotFound)
+    if (index == kNotFound) {
         m_propertyVector.append(property);
-    else
-        m_propertyVector.at(index) = property;
-    return true;
+        return true;
+    }
+    m_propertyVector.at(index) = property;
+    return false;
 }
 
 void MutableStylePropertySet::appendPrefixingVariantProperty(const CSSProperty& property)
@@ -421,6 +422,7 @@
     CSSPropertyTextAlign,
     CSSPropertyTextAlignLast,
     CSSPropertyTextIndent,
+    CSSPropertyTextJustify,
     CSSPropertyWidows
 };
 
@@ -483,8 +485,8 @@
     uint16_t id = static_cast<uint16_t>(propertyID);
     for (int n = propertyCount() - 1 ; n >= 0; --n) {
         if (id == propertyAt(n).propertyMetadata().m_propertyID) {
-            // Only enabled properties should be part of the style.
-            ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID));
+            // Only enabled or internal properties should be part of the style.
+            ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
             return n;
         }
     }
@@ -563,6 +565,58 @@
     return removePropertiesInSet(&variablesId, 1);
 }
 
+PassRefPtr<MutableStylePropertySet::VariablesIterator> MutableStylePropertySet::VariablesIterator::create(MutableStylePropertySet* propertySet)
+{
+    ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
+    const size_t propertyCount = propertySet->propertyCount();
+    size_t variableCount = 0;
+    Vector<AtomicString> remainingNames(propertyCount);
+    for (int i = propertyCount; i--; ) {
+        const PropertyReference& property = propertySet->propertyAt(i);
+        if (property.id() == CSSPropertyVariable)
+            remainingNames[variableCount++] = toCSSVariableValue(property.value())->name();
+    }
+    remainingNames.shrink(variableCount);
+
+    RefPtr<VariablesIterator> iterator = adoptRef(new VariablesIterator(propertySet));
+    // FIXME: Make use of the Vector move constructor when rvalues are supported on all platforms.
+    iterator->takeRemainingNames(remainingNames);
+    return iterator.release();
+}
+
+void MutableStylePropertySet::VariablesIterator::addedVariable(const AtomicString& name)
+{
+    ASSERT(!m_remainingNames.contains(name));
+    ASSERT(!m_newNames.contains(name));
+    m_newNames.append(name);
+}
+
+void MutableStylePropertySet::VariablesIterator::removedVariable(const AtomicString& name)
+{
+    size_t index = m_remainingNames.find(name);
+    if (index != kNotFound)
+        m_remainingNames.remove(index);
+    index = m_newNames.find(name);
+    if (index != kNotFound)
+        m_newNames.remove(index);
+}
+
+void MutableStylePropertySet::VariablesIterator::clearedVariables()
+{
+    m_remainingNames.clear();
+    m_newNames.clear();
+}
+
+void MutableStylePropertySet::VariablesIterator::advance()
+{
+    if (!atEnd())
+        m_remainingNames.removeLast();
+    if (!m_newNames.isEmpty()) {
+        m_remainingNames.appendVector(m_newNames);
+        m_newNames.clear();
+    }
+}
+
 PassRefPtr<MutableStylePropertySet> StylePropertySet::mutableCopy() const
 {
     return adoptRef(new MutableStylePropertySet(*this));
diff --git a/Source/core/css/StylePropertySet.h b/Source/core/css/StylePropertySet.h
index 8e9c913..81b5ad1 100644
--- a/Source/core/css/StylePropertySet.h
+++ b/Source/core/css/StylePropertySet.h
@@ -25,6 +25,7 @@
 #include "core/css/CSSParserMode.h"
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSProperty.h"
+#include "core/css/CSSVariablesIterator.h"
 #include "core/css/PropertySetCSSStyleDeclaration.h"
 #include "wtf/ListHashSet.h"
 #include "wtf/Vector.h"
@@ -174,6 +175,7 @@
 
 class MutableStylePropertySet : public StylePropertySet {
 public:
+    ~MutableStylePropertySet() { }
     static PassRefPtr<MutableStylePropertySet> create(CSSParserMode = CSSQuirksMode);
     static PassRefPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
 
@@ -204,6 +206,8 @@
     bool removeVariable(const AtomicString& name);
     bool clearVariables();
 
+    PassRefPtr<CSSVariablesIterator> variablesIterator() { return VariablesIterator::create(this); }
+
     void mergeAndOverrideOnConflict(const StylePropertySet*);
 
     void clear();
@@ -215,6 +219,26 @@
     Vector<CSSProperty, 4> m_propertyVector;
 
 private:
+    class VariablesIterator : public CSSVariablesIterator {
+    public:
+        virtual ~VariablesIterator() { }
+        static PassRefPtr<VariablesIterator> create(MutableStylePropertySet*);
+    private:
+        explicit VariablesIterator(MutableStylePropertySet* propertySet) : m_propertySet(propertySet) { }
+        void takeRemainingNames(Vector<AtomicString>& remainingNames) { m_remainingNames.swap(remainingNames); }
+        virtual void advance() OVERRIDE;
+        virtual bool atEnd() const OVERRIDE { return m_remainingNames.isEmpty(); }
+        virtual AtomicString name() const OVERRIDE { return m_remainingNames.last(); }
+        virtual String value() const OVERRIDE { return m_propertySet->variableValue(name()); }
+        virtual void addedVariable(const AtomicString& name) OVERRIDE;
+        virtual void removedVariable(const AtomicString& name) OVERRIDE;
+        virtual void clearedVariables() OVERRIDE;
+
+        RefPtr<MutableStylePropertySet> m_propertySet;
+        Vector<AtomicString> m_remainingNames;
+        Vector<AtomicString> m_newNames;
+    };
+
     explicit MutableStylePropertySet(CSSParserMode);
     explicit MutableStylePropertySet(const StylePropertySet&);
     MutableStylePropertySet(const CSSProperty* properties, unsigned count);
diff --git a/Source/core/css/StyleRule.cpp b/Source/core/css/StyleRule.cpp
index 3008e84..bb53bb8 100644
--- a/Source/core/css/StyleRule.cpp
+++ b/Source/core/css/StyleRule.cpp
@@ -43,7 +43,7 @@
     unsigned bitfields;
 };
 
-COMPILE_ASSERT(sizeof(StyleRuleBase) == sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
+COMPILE_ASSERT(sizeof(StyleRuleBase) <= sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
 
 PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
 {
diff --git a/Source/core/css/StyleSheet.h b/Source/core/css/StyleSheet.h
index 6ca572e..2207b5a 100644
--- a/Source/core/css/StyleSheet.h
+++ b/Source/core/css/StyleSheet.h
@@ -51,7 +51,6 @@
     virtual KURL baseURL() const = 0;
     virtual bool isLoading() const = 0;
     virtual bool isCSSStyleSheet() const { return false; }
-    virtual bool isXSLStyleSheet() const { return false; }
 };
 
 } // namespace
diff --git a/Source/core/css/StyleSheetContents.cpp b/Source/core/css/StyleSheetContents.cpp
index 9eeb6f1..07d3430 100644
--- a/Source/core/css/StyleSheetContents.cpp
+++ b/Source/core/css/StyleSheetContents.cpp
@@ -29,6 +29,7 @@
 #include "core/css/StyleRuleImport.h"
 #include "core/dom/Node.h"
 #include "core/fetch/CSSStyleSheetResource.h"
+#include "platform/TraceEvent.h"
 #include "weborigin/SecurityOrigin.h"
 #include "wtf/Deque.h"
 
@@ -271,6 +272,8 @@
 
 void StyleSheetContents::parseAuthorStyleSheet(const CSSStyleSheetResource* cachedStyleSheet, const SecurityOrigin* securityOrigin)
 {
+    TRACE_EVENT0("webkit", "StyleSheetContents::parseAuthorStyleSheet");
+
     bool enforceMIMEType = isStrictParserMode(m_parserContext.mode);
     bool hasValidMIMEType = false;
     String sheetText = cachedStyleSheet->sheetText(enforceMIMEType, &hasValidMIMEType);
diff --git a/Source/core/css/StyleSheetList.cpp b/Source/core/css/StyleSheetList.cpp
index b773deb..17ad7b4 100644
--- a/Source/core/css/StyleSheetList.cpp
+++ b/Source/core/css/StyleSheetList.cpp
@@ -31,8 +31,8 @@
 
 using namespace HTMLNames;
 
-StyleSheetList::StyleSheetList(Document* document)
-    : m_document(document)
+StyleSheetList::StyleSheetList(TreeScope* treeScope)
+    : m_treeScope(treeScope)
 {
 }
 
@@ -40,20 +40,20 @@
 {
 }
 
-inline const Vector<RefPtr<StyleSheet> >& StyleSheetList::styleSheets() const
+inline const Vector<RefPtr<StyleSheet> >& StyleSheetList::styleSheets()
 {
-    if (!m_document)
+    if (!m_treeScope)
         return m_detachedStyleSheets;
-    return m_document->styleEngine()->styleSheetsForStyleSheetList();
+    return document()->styleEngine()->styleSheetsForStyleSheetList(*m_treeScope);
 }
 
 void StyleSheetList::detachFromDocument()
 {
-    m_detachedStyleSheets = m_document->styleEngine()->styleSheetsForStyleSheetList();
-    m_document = 0;
+    m_detachedStyleSheets = document()->styleEngine()->styleSheetsForStyleSheetList(*m_treeScope);
+    m_treeScope = 0;
 }
 
-unsigned StyleSheetList::length() const
+unsigned StyleSheetList::length()
 {
     return styleSheets().size();
 }
@@ -66,7 +66,7 @@
 
 HTMLStyleElement* StyleSheetList::getNamedItem(const String& name) const
 {
-    if (!m_document)
+    if (!m_treeScope)
         return 0;
 
     // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
@@ -75,7 +75,7 @@
     // and doesn't look for name attribute.
     // But unicity of stylesheet ids is good practice anyway ;)
     // FIXME: We should figure out if we should change this or fix the spec.
-    Element* element = m_document->getElementById(name);
+    Element* element = m_treeScope->getElementById(name);
     if (element && element->hasTagName(styleTag))
         return toHTMLStyleElement(element);
     return 0;
diff --git a/Source/core/css/StyleSheetList.h b/Source/core/css/StyleSheetList.h
index e340f04..cd813bc 100644
--- a/Source/core/css/StyleSheetList.h
+++ b/Source/core/css/StyleSheetList.h
@@ -22,6 +22,7 @@
 #define StyleSheetList_h
 
 #include "core/css/CSSStyleSheet.h"
+#include "core/dom/TreeScope.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -29,30 +30,29 @@
 
 namespace WebCore {
 
-class Document;
 class HTMLStyleElement;
 class StyleSheet;
 
 class StyleSheetList : public RefCounted<StyleSheetList> {
 public:
-    static PassRefPtr<StyleSheetList> create(Document* document) { return adoptRef(new StyleSheetList(document)); }
+    static PassRefPtr<StyleSheetList> create(TreeScope* treeScope) { return adoptRef(new StyleSheetList(treeScope)); }
     ~StyleSheetList();
 
-    unsigned length() const;
+    unsigned length();
     StyleSheet* item(unsigned index);
 
     HTMLStyleElement* getNamedItem(const String&) const;
 
-    Document* document() { return m_document; }
+    Document* document() { return m_treeScope->documentScope(); }
 
     void detachFromDocument();
     CSSStyleSheet* anonymousNamedGetter(const AtomicString&);
 
 private:
-    StyleSheetList(Document*);
-    const Vector<RefPtr<StyleSheet> >& styleSheets() const;
+    StyleSheetList(TreeScope*);
+    const Vector<RefPtr<StyleSheet> >& styleSheets();
 
-    Document* m_document;
+    TreeScope* m_treeScope;
     Vector<RefPtr<StyleSheet> > m_detachedStyleSheets;
 };
 
diff --git a/Source/core/css/WebKitCSSRegionRule.idl b/Source/core/css/WebKitCSSRegionRule.idl
index ad91ce0..6811344 100644
--- a/Source/core/css/WebKitCSSRegionRule.idl
+++ b/Source/core/css/WebKitCSSRegionRule.idl
@@ -28,7 +28,7 @@
  */
 
 [
-    EnabledAtRuntime=CSSRegions,
+    RuntimeEnabled=CSSRegions,
     ImplementedAs=CSSRegionRule
 ] interface WebKitCSSRegionRule : CSSRule {
     readonly attribute CSSRuleList cssRules;
diff --git a/Source/core/css/html.css b/Source/core/css/html.css
index b41ccf0..335a57e 100644
--- a/Source/core/css/html.css
+++ b/Source/core/css/html.css
@@ -667,7 +667,7 @@
     text-align: start !important;
 }
 
-input:-webkit-autofill {
+input:-webkit-autofill, textarea:-webkit-autofill {
     background-color: #FAFFBD !important;
     background-image:none !important;
     color: #000000 !important;
diff --git a/Source/core/css/mediaControlsAndroid.css b/Source/core/css/mediaControlsAndroid.css
index 69bdd8d..a258fa7 100644
--- a/Source/core/css/mediaControlsAndroid.css
+++ b/Source/core/css/mediaControlsAndroid.css
@@ -30,10 +30,14 @@
     height: 35px;
 }
 
-audio::-webkit-media-controls-enclosure, video::-webkit-media-controls-enclosure {
+audio::-webkit-media-controls-enclosure {
     height: 35px;
 }
 
+video::-webkit-media-controls-enclosure {
+    height: 40px;
+}
+
 audio::-webkit-media-controls-overlay-enclosure {
     display: none;
 }
@@ -54,7 +58,6 @@
 
 audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
     height: 35px;
-    border-radius: 0;
 }
 
 audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button {
diff --git a/Source/core/css/resolver/AnimatedStyleBuilder.cpp b/Source/core/css/resolver/AnimatedStyleBuilder.cpp
index bc86494..9991a83 100644
--- a/Source/core/css/resolver/AnimatedStyleBuilder.cpp
+++ b/Source/core/css/resolver/AnimatedStyleBuilder.cpp
@@ -31,10 +31,18 @@
 #include "config.h"
 #include "core/css/resolver/AnimatedStyleBuilder.h"
 
+#include "core/animation/AnimatableClipPathOperation.h"
 #include "core/animation/AnimatableColor.h"
+#include "core/animation/AnimatableDouble.h"
 #include "core/animation/AnimatableImage.h"
+#include "core/animation/AnimatableLength.h"
 #include "core/animation/AnimatableLengthBox.h"
-#include "core/animation/AnimatableNumber.h"
+#include "core/animation/AnimatableLengthSize.h"
+#include "core/animation/AnimatableRepeatable.h"
+#include "core/animation/AnimatableSVGLength.h"
+#include "core/animation/AnimatableSVGPaint.h"
+#include "core/animation/AnimatableShapeValue.h"
+#include "core/animation/AnimatableStrokeDasharrayList.h"
 #include "core/animation/AnimatableTransform.h"
 #include "core/animation/AnimatableUnknown.h"
 #include "core/animation/AnimatableValue.h"
@@ -51,30 +59,123 @@
 
 namespace {
 
-Length animatableValueToLength(const AnimatableValue* value, const StyleResolverState& state)
+Length animatableValueToLength(const AnimatableValue* value, const StyleResolverState& state, NumberRange range = AllValues)
 {
     const RenderStyle* style = state.style();
-    if (value->isNumber())
-        return toAnimatableNumber(value)->toLength(style, state.rootElementStyle(), style->effectiveZoom());
+    if (value->isLength())
+        return toAnimatableLength(value)->toLength(style, state.rootElementStyle(), style->effectiveZoom(), range);
     RefPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
     CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
     return cssPrimitiveValue->convertToLength<AnyConversion>(style, state.rootElementStyle(), style->effectiveZoom());
 }
 
-template<typename T> T animatableValueRoundClampTo(const AnimatableValue* value)
+template<typename T> T animatableValueRoundClampTo(const AnimatableValue* value, T min = defaultMinimumForClamp<T>(), T max = defaultMaximumForClamp<T>())
 {
     COMPILE_ASSERT(WTF::IsInteger<T>::value, ShouldUseIntegralTypeTWhenRoundingValues);
-    return clampTo<T>(round(toAnimatableNumber(value)->toDouble()));
+    return clampTo<T>(round(toAnimatableDouble(value)->toDouble()), min, max);
 }
 
-LengthBox animatableValueToLengthBox(const AnimatableValue* value, const StyleResolverState& state)
+LengthBox animatableValueToLengthBox(const AnimatableValue* value, const StyleResolverState& state, NumberRange range = AllValues)
 {
     const AnimatableLengthBox* animatableLengthBox = toAnimatableLengthBox(value);
     return LengthBox(
-        animatableValueToLength(animatableLengthBox->top(), state),
-        animatableValueToLength(animatableLengthBox->right(), state),
-        animatableValueToLength(animatableLengthBox->bottom(), state),
-        animatableValueToLength(animatableLengthBox->left(), state));
+        animatableValueToLength(animatableLengthBox->top(), state, range),
+        animatableValueToLength(animatableLengthBox->right(), state, range),
+        animatableValueToLength(animatableLengthBox->bottom(), state, range),
+        animatableValueToLength(animatableLengthBox->left(), state, range));
+}
+
+LengthSize animatableValueToLengthSize(const AnimatableValue* value, const StyleResolverState& state, NumberRange range)
+{
+    const AnimatableLengthSize* animatableLengthSize = toAnimatableLengthSize(value);
+    return LengthSize(
+        animatableValueToLength(animatableLengthSize->width(), state, range),
+        animatableValueToLength(animatableLengthSize->height(), state, range));
+}
+
+template <CSSPropertyID property>
+void setFillSize(FillLayer* fillLayer, const AnimatableValue* value, const StyleResolverState& state)
+{
+    if (value->isLengthSize())
+        fillLayer->setSize(FillSize(SizeLength, animatableValueToLengthSize(value, state, NonNegativeValues)));
+    else
+        state.styleMap().mapFillSize(property, fillLayer, toAnimatableUnknown(value)->toCSSValue().get());
+}
+
+SVGLength animatableValueToNonNegativeSVGLength(const AnimatableValue* value)
+{
+    SVGLength length = toAnimatableSVGLength(value)->toSVGLength();
+    if (length.valueInSpecifiedUnits() < 0)
+        length.setValueInSpecifiedUnits(0);
+    return length;
+}
+
+template <CSSPropertyID property>
+void setOnFillLayers(FillLayer* fillLayer, const AnimatableValue* value, StyleResolverState& state)
+{
+    const Vector<RefPtr<AnimatableValue> >& values = toAnimatableRepeatable(value)->values();
+    ASSERT(!values.isEmpty());
+    FillLayer* prev = 0;
+    for (size_t i = 0; i < values.size(); ++i) {
+        if (!fillLayer) {
+            switch (property) {
+            case CSSPropertyBackgroundImage:
+            case CSSPropertyBackgroundPositionX:
+            case CSSPropertyBackgroundPositionY:
+            case CSSPropertyBackgroundSize:
+                fillLayer = new FillLayer(BackgroundFillLayer);
+                break;
+            case CSSPropertyWebkitMaskPositionX:
+            case CSSPropertyWebkitMaskPositionY:
+                fillLayer = new FillLayer(MaskFillLayer);
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+            }
+            prev->setNext(fillLayer);
+        }
+        switch (property) {
+        case CSSPropertyBackgroundImage:
+            fillLayer->setImage(toAnimatableImage(values[i].get())->toStyleImage());
+            break;
+        case CSSPropertyBackgroundPositionX:
+        case CSSPropertyWebkitMaskPositionX:
+            fillLayer->setXPosition(animatableValueToLength(values[i].get(), state));
+            break;
+        case CSSPropertyBackgroundPositionY:
+        case CSSPropertyWebkitMaskPositionY:
+            fillLayer->setYPosition(animatableValueToLength(values[i].get(), state));
+            break;
+        case CSSPropertyBackgroundSize:
+            setFillSize<property>(fillLayer, values[i].get(), state);
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        prev = fillLayer;
+        fillLayer = fillLayer->next();
+    }
+    while (fillLayer) {
+        switch (property) {
+        case CSSPropertyBackgroundImage:
+            fillLayer->clearImage();
+            break;
+        case CSSPropertyBackgroundPositionX:
+        case CSSPropertyWebkitMaskPositionX:
+            fillLayer->clearXPosition();
+            break;
+        case CSSPropertyBackgroundPositionY:
+        case CSSPropertyWebkitMaskPositionY:
+            fillLayer->clearYPosition();
+            break;
+        case CSSPropertyBackgroundSize:
+            fillLayer->clearSize();
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+        }
+        fillLayer = fillLayer->next();
+    }
 }
 
 } // namespace
@@ -92,24 +193,45 @@
         style->setBackgroundColor(toAnimatableColor(value)->color());
         style->setVisitedLinkBackgroundColor(toAnimatableColor(value)->visitedLinkColor());
         return;
+    case CSSPropertyBackgroundImage:
+        setOnFillLayers<CSSPropertyBackgroundImage>(style->accessBackgroundLayers(), value, state);
+        return;
+    case CSSPropertyBackgroundPositionX:
+        setOnFillLayers<CSSPropertyBackgroundPositionX>(style->accessBackgroundLayers(), value, state);
+        return;
+    case CSSPropertyBackgroundPositionY:
+        setOnFillLayers<CSSPropertyBackgroundPositionY>(style->accessBackgroundLayers(), value, state);
+        return;
+    case CSSPropertyBackgroundSize:
+        setOnFillLayers<CSSPropertyBackgroundSize>(style->accessBackgroundLayers(), value, state);
+        return;
+    case CSSPropertyBaselineShift:
+        style->setBaselineShiftValue(toAnimatableSVGLength(value)->toSVGLength());
+        return;
     case CSSPropertyBorderBottomColor:
         style->setBorderBottomColor(toAnimatableColor(value)->color());
         style->setVisitedLinkBorderBottomColor(toAnimatableColor(value)->visitedLinkColor());
         return;
+    case CSSPropertyBorderBottomLeftRadius:
+        style->setBorderBottomLeftRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+        return;
+    case CSSPropertyBorderBottomRightRadius:
+        style->setBorderBottomRightRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+        return;
     case CSSPropertyBorderBottomWidth:
         style->setBorderBottomWidth(animatableValueRoundClampTo<unsigned>(value));
         return;
     case CSSPropertyBorderImageOutset:
-        style->setBorderImageOutset(animatableValueToLengthBox(value, state));
+        style->setBorderImageOutset(animatableValueToLengthBox(value, state, NonNegativeValues));
         return;
     case CSSPropertyBorderImageSlice:
-        style->setBorderImageSlices(animatableValueToLengthBox(value, state));
+        style->setBorderImageSlices(animatableValueToLengthBox(value, state, NonNegativeValues));
         return;
     case CSSPropertyBorderImageSource:
         style->setBorderImageSource(toAnimatableImage(value)->toStyleImage());
         return;
     case CSSPropertyBorderImageWidth:
-        style->setBorderImageWidth(animatableValueToLengthBox(value, state));
+        style->setBorderImageWidth(animatableValueToLengthBox(value, state, NonNegativeValues));
         return;
     case CSSPropertyBorderLeftColor:
         style->setBorderLeftColor(toAnimatableColor(value)->color());
@@ -129,6 +251,12 @@
         style->setBorderTopColor(toAnimatableColor(value)->color());
         style->setVisitedLinkBorderTopColor(toAnimatableColor(value)->visitedLinkColor());
         return;
+    case CSSPropertyBorderTopLeftRadius:
+        style->setBorderTopLeftRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+        return;
+    case CSSPropertyBorderTopRightRadius:
+        style->setBorderTopRightRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+        return;
     case CSSPropertyBorderTopWidth:
         style->setBorderTopWidth(animatableValueRoundClampTo<unsigned>(value));
         return;
@@ -137,20 +265,57 @@
         return;
     case CSSPropertyClip:
         style->setClip(animatableValueToLengthBox(value, state));
+        style->setHasClip(true);
         return;
     case CSSPropertyColor:
         style->setColor(toAnimatableColor(value)->color());
         style->setVisitedLinkColor(toAnimatableColor(value)->visitedLinkColor());
         return;
+    case CSSPropertyFillOpacity:
+        style->setFillOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
+        return;
+    case CSSPropertyFill:
+        {
+            const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
+            style->accessSVGStyle()->setFillPaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri());
+        }
+        return;
+    case CSSPropertyFlexGrow:
+        style->setFlexGrow(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
+        return;
+    case CSSPropertyFlexShrink:
+        style->setFlexShrink(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
+        return;
+    case CSSPropertyFlexBasis:
+        style->setFlexBasis(animatableValueToLength(value, state, NonNegativeValues));
+        return;
+    case CSSPropertyFloodColor:
+        style->setFloodColor(toAnimatableColor(value)->color());
+        return;
+    case CSSPropertyFloodOpacity:
+        style->setFloodOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
+        return;
+    case CSSPropertyFontSize:
+        style->setFontSize(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
+        return;
     case CSSPropertyHeight:
-        style->setHeight(animatableValueToLength(value, state));
+        style->setHeight(animatableValueToLength(value, state, NonNegativeValues));
+        return;
+    case CSSPropertyKerning:
+        style->setKerning(toAnimatableSVGLength(value)->toSVGLength());
         return;
     case CSSPropertyLeft:
         style->setLeft(animatableValueToLength(value, state));
         return;
+    case CSSPropertyLightingColor:
+        style->setLightingColor(toAnimatableColor(value)->color());
+        return;
     case CSSPropertyListStyleImage:
         style->setListStyleImage(toAnimatableImage(value)->toStyleImage());
         return;
+    case CSSPropertyLetterSpacing:
+        style->setLetterSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
+        return;
     case CSSPropertyMarginBottom:
         style->setMarginBottom(animatableValueToLength(value, state));
         return;
@@ -164,19 +329,22 @@
         style->setMarginTop(animatableValueToLength(value, state));
         return;
     case CSSPropertyMaxHeight:
-        style->setMaxHeight(animatableValueToLength(value, state));
+        style->setMaxHeight(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyMaxWidth:
-        style->setMaxWidth(animatableValueToLength(value, state));
+        style->setMaxWidth(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyMinHeight:
-        style->setMinHeight(animatableValueToLength(value, state));
+        style->setMinHeight(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyMinWidth:
-        style->setMinWidth(animatableValueToLength(value, state));
+        style->setMinWidth(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyOpacity:
-        style->setOpacity(toAnimatableNumber(value)->toDouble());
+        style->setOpacity(toAnimatableDouble(value)->toDouble());
+        return;
+    case CSSPropertyOrphans:
+        style->setOrphans(animatableValueRoundClampTo<unsigned short>(value, 1));
         return;
     case CSSPropertyOutlineColor:
         style->setOutlineColor(toAnimatableColor(value)->color());
@@ -189,51 +357,110 @@
         style->setOutlineWidth(animatableValueRoundClampTo<unsigned short>(value));
         return;
     case CSSPropertyPaddingBottom:
-        style->setPaddingBottom(animatableValueToLength(value, state));
+        style->setPaddingBottom(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyPaddingLeft:
-        style->setPaddingLeft(animatableValueToLength(value, state));
+        style->setPaddingLeft(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyPaddingRight:
-        style->setPaddingRight(animatableValueToLength(value, state));
+        style->setPaddingRight(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyPaddingTop:
-        style->setPaddingTop(animatableValueToLength(value, state));
+        style->setPaddingTop(animatableValueToLength(value, state, NonNegativeValues));
         return;
     case CSSPropertyRight:
         style->setRight(animatableValueToLength(value, state));
         return;
+    case CSSPropertyStrokeWidth:
+        style->setStrokeWidth(animatableValueToNonNegativeSVGLength(value));
+        return;
+    case CSSPropertyStopColor:
+        style->setStopColor(toAnimatableColor(value)->color());
+        return;
+    case CSSPropertyStopOpacity:
+        style->setStopOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
+        return;
+    case CSSPropertyStrokeDasharray:
+        style->setStrokeDashArray(toAnimatableStrokeDasharrayList(value)->toSVGLengthVector());
+        return;
+    case CSSPropertyStrokeDashoffset:
+        style->setStrokeDashOffset(toAnimatableSVGLength(value)->toSVGLength());
+        return;
+    case CSSPropertyStrokeMiterlimit:
+        style->setStrokeMiterLimit(clampTo<float>(toAnimatableDouble(value)->toDouble(), 1));
+        return;
+    case CSSPropertyStrokeOpacity:
+        style->setStrokeOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
+        return;
+    case CSSPropertyStroke:
+        {
+            const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
+            style->accessSVGStyle()->setStrokePaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri());
+        }
+        return;
     case CSSPropertyTextDecorationColor:
         style->setTextDecorationColor(toAnimatableColor(value)->color());
         style->setVisitedLinkTextDecorationColor(toAnimatableColor(value)->visitedLinkColor());
         return;
+    case CSSPropertyTextIndent:
+        style->setTextIndent(animatableValueToLength(value, state));
+        return;
     case CSSPropertyTop:
         style->setTop(animatableValueToLength(value, state));
         return;
+    case CSSPropertyWebkitBorderHorizontalSpacing:
+        style->setHorizontalBorderSpacing(animatableValueRoundClampTo<unsigned short>(value));
+        return;
+    case CSSPropertyWebkitBorderVerticalSpacing:
+        style->setVerticalBorderSpacing(animatableValueRoundClampTo<unsigned short>(value));
+        return;
+    case CSSPropertyWebkitClipPath:
+        style->setClipPath(toAnimatableClipPathOperation(value)->clipPathOperation());
+        return;
+    case CSSPropertyWebkitColumnCount:
+        style->setColumnCount(animatableValueRoundClampTo<unsigned short>(value, 1));
+        return;
+    case CSSPropertyWebkitColumnGap:
+        style->setColumnGap(clampTo(toAnimatableDouble(value)->toDouble(), 0));
+        return;
     case CSSPropertyWebkitColumnRuleColor:
         style->setColumnRuleColor(toAnimatableColor(value)->color());
         style->setVisitedLinkColumnRuleColor(toAnimatableColor(value)->visitedLinkColor());
         return;
+    case CSSPropertyWebkitColumnWidth:
+        style->setColumnWidth(clampTo(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::epsilon()));
+        return;
+    case CSSPropertyWebkitColumnRuleWidth:
+        style->setColumnRuleWidth(animatableValueRoundClampTo<unsigned short>(value));
+        return;
     case CSSPropertyWebkitMaskBoxImageSource:
         style->setMaskBoxImageSource(toAnimatableImage(value)->toStyleImage());
         return;
     case CSSPropertyWebkitMaskImage:
         style->setMaskImage(toAnimatableImage(value)->toStyleImage());
         return;
+    case CSSPropertyWebkitMaskPositionX:
+        setOnFillLayers<CSSPropertyWebkitMaskPositionX>(style->accessMaskLayers(), value, state);
+        return;
+    case CSSPropertyWebkitMaskPositionY:
+        setOnFillLayers<CSSPropertyWebkitMaskPositionY>(style->accessMaskLayers(), value, state);
+        return;
+    case CSSPropertyWebkitPerspective:
+        style->setPerspective(clampTo<float>(toAnimatableDouble(value)->toDouble()));
+        return;
     case CSSPropertyWebkitPerspectiveOriginX:
         style->setPerspectiveOriginX(animatableValueToLength(value, state));
         return;
     case CSSPropertyWebkitPerspectiveOriginY:
         style->setPerspectiveOriginY(animatableValueToLength(value, state));
         return;
+    case CSSPropertyWebkitShapeInside:
+        style->setShapeInside(toAnimatableShapeValue(value)->shapeValue());
+        return;
     case CSSPropertyWebkitTextEmphasisColor:
         style->setTextEmphasisColor(toAnimatableColor(value)->color());
         style->setVisitedLinkTextEmphasisColor(toAnimatableColor(value)->visitedLinkColor());
         return;
-    case CSSPropertyWebkitTextFillColor:
-        style->setTextFillColor(toAnimatableColor(value)->color());
-        style->setVisitedLinkTextFillColor(toAnimatableColor(value)->visitedLinkColor());
-        return;
     case CSSPropertyWebkitTextStrokeColor:
         style->setTextStrokeColor(toAnimatableColor(value)->color());
         style->setVisitedLinkTextStrokeColor(toAnimatableColor(value)->visitedLinkColor());
@@ -247,8 +474,17 @@
     case CSSPropertyWebkitTransformOriginY:
         style->setTransformOriginY(animatableValueToLength(value, state));
         return;
+    case CSSPropertyWebkitTransformOriginZ:
+        style->setTransformOriginZ(toAnimatableDouble(value)->toDouble());
+        return;
+    case CSSPropertyWidows:
+        style->setWidows(animatableValueRoundClampTo<unsigned short>(value, 1));
+        return;
     case CSSPropertyWidth:
-        style->setWidth(animatableValueToLength(value, state));
+        style->setWidth(animatableValueToLength(value, state, NonNegativeValues));
+        return;
+    case CSSPropertyWordSpacing:
+        style->setWordSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
         return;
     case CSSPropertyVisibility:
         style->setVisibility(toAnimatableVisibility(value)->visibility());
@@ -256,6 +492,9 @@
     case CSSPropertyZIndex:
         style->setZIndex(animatableValueRoundClampTo<int>(value));
         return;
+    case CSSPropertyZoom:
+        style->setZoom(clampTo<float>(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::denorm_min()));
+        return;
     default:
         RELEASE_ASSERT_WITH_MESSAGE(!CSSAnimations::isAnimatableProperty(property), "Web Animations not yet implemented: Unable to apply AnimatableValue to RenderStyle: %s", getPropertyNameString(property).utf8().data());
         ASSERT_NOT_REACHED();
diff --git a/Source/core/css/resolver/ElementResolveContext.cpp b/Source/core/css/resolver/ElementResolveContext.cpp
index 00f9315..408475f9 100644
--- a/Source/core/css/resolver/ElementResolveContext.cpp
+++ b/Source/core/css/resolver/ElementResolveContext.cpp
@@ -29,19 +29,20 @@
 
 namespace WebCore {
 
-ElementResolveContext::ElementResolveContext(Element* element)
-    : m_element(element)
-    , m_elementLinkState(element ? element->document().visitedLinkState()->determineLinkState(element) : NotInsideLink)
+ElementResolveContext::ElementResolveContext(Element& element)
+    : m_element(&element)
+    , m_elementLinkState(element.document().visitedLinkState()->determineLinkState(element))
     , m_distributedToInsertionPoint(false)
     , m_resetStyleInheritance(false)
 {
     NodeRenderingTraversal::ParentDetails parentDetails;
-    m_parentNode = NodeRenderingTraversal::parent(element, &parentDetails);
+    m_parentNode = NodeRenderingTraversal::parent(&element, &parentDetails);
     m_distributedToInsertionPoint = parentDetails.insertionPoint();
     m_resetStyleInheritance = parentDetails.resetStyleInheritance();
 
-    Node* documentElement = document().documentElement();
-    RenderStyle* documentStyle = document().renderStyle();
+    const Document& document = element.document();
+    Node* documentElement = document.documentElement();
+    RenderStyle* documentStyle = document.renderStyle();
     m_rootElementStyle = documentElement && element != documentElement ? documentElement->renderStyle() : documentStyle;
     if (!m_rootElementStyle)
         m_rootElementStyle = documentStyle;
diff --git a/Source/core/css/resolver/ElementResolveContext.h b/Source/core/css/resolver/ElementResolveContext.h
index ebbe1cf..f255e89 100644
--- a/Source/core/css/resolver/ElementResolveContext.h
+++ b/Source/core/css/resolver/ElementResolveContext.h
@@ -45,14 +45,11 @@
     {
     }
 
-    explicit ElementResolveContext(Element*);
-
-    Document& document() const { return m_element->document(); }
-    bool isDocumentElement() const { return m_element && m_element == m_element->document().documentElement(); }
+    explicit ElementResolveContext(Element&);
 
     Element* element() const { return m_element; }
     const ContainerNode* parentNode() const { return m_parentNode; }
-    RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
+    const RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
     EInsideLink elementLinkState() const { return m_elementLinkState; }
     bool distributedToInsertionPoint() const { return m_distributedToInsertionPoint; }
     bool resetStyleInheritance() const { return m_resetStyleInheritance; }
diff --git a/Source/core/css/resolver/ElementStyleResources.cpp b/Source/core/css/resolver/ElementStyleResources.cpp
index 6534ea8..7ac45d0 100644
--- a/Source/core/css/resolver/ElementStyleResources.cpp
+++ b/Source/core/css/resolver/ElementStyleResources.cpp
@@ -45,15 +45,15 @@
 
     if (value->isImageGeneratorValue()) {
         if (value->isGradientValue())
-            return generatedOrPendingFromValue(property, static_cast<CSSGradientValue*>(value)->gradientWithStylesResolved(textLinkColors, currentColor).get());
-        return generatedOrPendingFromValue(property, static_cast<CSSImageGeneratorValue*>(value));
+            return generatedOrPendingFromValue(property, toCSSGradientValue(value)->gradientWithStylesResolved(textLinkColors, currentColor).get());
+        return generatedOrPendingFromValue(property, toCSSImageGeneratorValue(value));
     }
 
     if (value->isImageSetValue())
         return setOrPendingFromValue(property, toCSSImageSetValue(value));
 
     if (value->isCursorImageValue())
-        return cursorOrPendingFromValue(property, static_cast<CSSCursorImageValue*>(value));
+        return cursorOrPendingFromValue(property, toCSSCursorImageValue(value));
 
     return 0;
 }
@@ -96,12 +96,4 @@
     m_pendingSVGDocuments.set(filterOperation, cssSVGDocumentValue);
 }
 
-void ElementStyleResources::clear()
-{
-    m_pendingImageProperties.clear();
-    m_pendingSVGDocuments.clear();
-    m_hasPendingShaders = false;
-    m_deviceScaleFactor = 1;
-}
-
 }
diff --git a/Source/core/css/resolver/ElementStyleResources.h b/Source/core/css/resolver/ElementStyleResources.h
index 08aaede..ee73d8c 100644
--- a/Source/core/css/resolver/ElementStyleResources.h
+++ b/Source/core/css/resolver/ElementStyleResources.h
@@ -45,9 +45,6 @@
 
 // Holds information about resources, requested by stylesheets.
 // Lifetime: per-element style resolve.
-// FIXME: At least for the moment, the lifetime actually matches that of StyleResolverState,
-// but all data is cleared for each element resolve. We must investigate performance
-// implications of matching effective and intended lifetime.
 class ElementStyleResources {
 WTF_MAKE_NONCOPYABLE(ElementStyleResources);
 public:
@@ -71,8 +68,6 @@
 
     void addPendingSVGDocument(FilterOperation*, CSSSVGDocumentValue*);
 
-    void clear();
-
 private:
     PendingImagePropertyMap m_pendingImageProperties;
     PendingSVGDocumentMap m_pendingSVGDocuments;
diff --git a/Source/core/css/resolver/FilterOperationResolver.cpp b/Source/core/css/resolver/FilterOperationResolver.cpp
index 39d0f95..adedad5 100644
--- a/Source/core/css/resolver/FilterOperationResolver.cpp
+++ b/Source/core/css/resolver/FilterOperationResolver.cpp
@@ -34,7 +34,7 @@
 #include "core/css/CSSParser.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSShaderValue.h"
-#include "core/css/ShadowValue.h"
+#include "core/css/CSSShadowValue.h"
 #include "core/css/resolver/TransformBuilder.h"
 #include "core/platform/graphics/filters/custom/CustomFilterArrayParameter.h"
 #include "core/platform/graphics/filters/custom/CustomFilterConstants.h"
@@ -102,8 +102,8 @@
 
 static StyleShader* styleShader(CSSValue* value, StyleResolverState& state)
 {
-    if (value->isCSSShaderValue())
-        return cachedOrPendingStyleShaderFromValue(static_cast<CSSShaderValue*>(value), state);
+    if (value->isShaderValue())
+        return cachedOrPendingStyleShaderFromValue(toCSSShaderValue(value), state);
     return 0;
 }
 
@@ -161,14 +161,14 @@
     if (!values->length())
         return 0;
 
-    if (parameterValue->isCSSArrayFunctionValue())
+    if (parameterValue->isArrayFunctionValue())
         return parseCustomFilterArrayParameter(name, values);
 
     // If the first value of the list is a transform function,
     // then we could safely assume that all the remaining items
     // are transforms. parseCustomFilterTransformParameter will
     // return 0 if that assumption is incorrect.
-    if (values->itemWithoutBoundsCheck(0)->isCSSTransformValue())
+    if (values->itemWithoutBoundsCheck(0)->isTransformValue())
         return parseCustomFilterTransformParameter(name, values, state);
 
     // We can have only arrays of booleans or numbers, so use the first value to choose between those two.
@@ -252,19 +252,25 @@
     unsigned shadersListLength = shadersList->length();
     ASSERT(shadersListLength);
 
-    CSSShaderValue* vertexShader = toCSSShaderValue(shadersList->itemWithoutBoundsCheck(0));
+    CSSShaderValue* vertexShader = 0;
     CSSShaderValue* fragmentShader = 0;
+
+    if (shadersList->itemWithoutBoundsCheck(0)->isShaderValue())
+        vertexShader = toCSSShaderValue(shadersList->itemWithoutBoundsCheck(0));
+
     CustomFilterProgramType programType = PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE;
     CustomFilterProgramMixSettings mixSettings;
 
     if (shadersListLength > 1) {
         CSSValue* fragmentShaderOrMixFunction = shadersList->itemWithoutBoundsCheck(1);
-        if (fragmentShaderOrMixFunction->isCSSMixFunctionValue()) {
-            CSSMixFunctionValue* mixFunction = static_cast<CSSMixFunctionValue*>(fragmentShaderOrMixFunction);
+        if (fragmentShaderOrMixFunction->isMixFunctionValue()) {
+            CSSMixFunctionValue* mixFunction = toCSSMixFunctionValue(fragmentShaderOrMixFunction);
             CSSValueListIterator iterator(mixFunction);
 
             ASSERT(mixFunction->length());
-            fragmentShader = toCSSShaderValue(iterator.value());
+            if (iterator.value()->isShaderValue())
+                fragmentShader = toCSSShaderValue(iterator.value());
+
             iterator.advance();
 
             ASSERT(mixFunction->length() <= 3);
@@ -280,7 +286,8 @@
             }
         } else {
             programType = PROGRAM_TYPE_NO_ELEMENT_TEXTURE;
-            fragmentShader = toCSSShaderValue(fragmentShaderOrMixFunction);
+            if (fragmentShaderOrMixFunction->isShaderValue())
+                fragmentShader = toCSSShaderValue(fragmentShaderOrMixFunction);
         }
     }
 
@@ -374,10 +381,10 @@
     FilterOperations operations;
     for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
         CSSValue* currValue = i.value();
-        if (!currValue->isCSSFilterValue())
+        if (!currValue->isFilterValue())
             continue;
 
-        CSSFilterValue* filterValue = static_cast<CSSFilterValue*>(i.value());
+        CSSFilterValue* filterValue = toCSSFilterValue(i.value());
         FilterOperation::OperationType operationType = filterOperationForType(filterValue->operationType());
 
         if (operationType == FilterOperation::VALIDATED_CUSTOM) {
@@ -398,10 +405,10 @@
                 continue;
             CSSValue* argument = filterValue->itemWithoutBoundsCheck(0);
 
-            if (!argument->isCSSSVGDocumentValue())
+            if (!argument->isSVGDocumentValue())
                 continue;
 
-            CSSSVGDocumentValue* svgDocumentValue = static_cast<CSSSVGDocumentValue*>(argument);
+            CSSSVGDocumentValue* svgDocumentValue = toCSSSVGDocumentValue(argument);
             KURL url = state.document().completeURL(svgDocumentValue->url());
 
             RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), url.fragmentIdentifier(), operationType);
@@ -416,7 +423,7 @@
         }
 
         // Check that all parameters are primitive values, with the
-        // exception of drop shadow which has a ShadowValue parameter.
+        // exception of drop shadow which has a CSSShadowValue parameter.
         if (operationType != FilterOperation::DROP_SHADOW) {
             bool haveNonPrimitiveValue = false;
             for (unsigned j = 0; j < filterValue->length(); ++j) {
@@ -484,7 +491,7 @@
             if (!cssValue->isShadowValue())
                 continue;
 
-            ShadowValue* item = static_cast<ShadowValue*>(cssValue);
+            CSSShadowValue* item = toCSSShadowValue(cssValue);
             IntPoint location(item->x->computeLength<int>(style, rootStyle, zoomFactor), item->y->computeLength<int>(style, rootStyle, zoomFactor));
             int blur = item->blur ? item->blur->computeLength<int>(style, rootStyle, zoomFactor) : 0;
             Color shadowColor;
diff --git a/Source/core/css/resolver/FontBuilder.cpp b/Source/core/css/resolver/FontBuilder.cpp
index 684f36d..b9655fc 100644
--- a/Source/core/css/resolver/FontBuilder.cpp
+++ b/Source/core/css/resolver/FontBuilder.cpp
@@ -24,13 +24,13 @@
 #include "core/css/resolver/FontBuilder.h"
 
 #include "core/css/CSSCalculationValue.h"
-#include "core/css/FontFeatureValue.h"
+#include "core/css/CSSFontFeatureValue.h"
 #include "core/css/FontSize.h"
-#include "core/page/Frame.h"
+#include "core/frame/Frame.h"
 #include "core/page/Settings.h"
-#include "core/platform/text/LocaleToScriptMapping.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/rendering/RenderView.h"
+#include "platform/text/LocaleToScriptMapping.h"
 
 namespace WebCore {
 
@@ -77,13 +77,6 @@
     m_fontDirty = false;
 }
 
-void FontBuilder::clear()
-{
-    m_document = 0;
-    m_style = 0;
-    m_fontDirty = false;
-}
-
 void FontBuilder::setInitial(float effectiveZoom)
 {
     ASSERT(m_document && m_document->settings());
@@ -505,7 +498,7 @@
         CSSValue* item = list->itemWithoutBoundsCheck(i);
         if (!item->isFontFeatureValue())
             continue;
-        FontFeatureValue* feature = static_cast<FontFeatureValue*>(item);
+        CSSFontFeatureValue* feature = toCSSFontFeatureValue(item);
         settings->append(FontFeature(feature->tag(), feature->value()));
     }
     scope.fontDescription().setFeatureSettings(settings.release());
diff --git a/Source/core/css/resolver/FontBuilder.h b/Source/core/css/resolver/FontBuilder.h
index 8aa5d38..847fed9 100644
--- a/Source/core/css/resolver/FontBuilder.h
+++ b/Source/core/css/resolver/FontBuilder.h
@@ -43,7 +43,6 @@
 
     // FIXME: The name is probably wrong, but matches StyleResolverState callsite for consistency.
     void initForStyleResolve(const Document&, RenderStyle*, bool useSVGZoomRules);
-    void clear();
 
     void setInitial(float effectiveZoom);
 
diff --git a/Source/core/css/resolver/MatchedPropertiesCache.cpp b/Source/core/css/resolver/MatchedPropertiesCache.cpp
index 1736795..d3c222a 100644
--- a/Source/core/css/resolver/MatchedPropertiesCache.cpp
+++ b/Source/core/css/resolver/MatchedPropertiesCache.cpp
@@ -148,6 +148,9 @@
         return false;
     if (style->hasCurrentColor())
         return false;
+    // CSSPropertyInternalCallback sets the rule's selector name into the RenderStyle, and that's not recalculated if the RenderStyle is loaded from the cache, so don't cache it.
+    if (!style->callbackSelectors().isEmpty())
+        return false;
     // The cache assumes static knowledge about which properties are inherited.
     if (parentStyle->hasExplicitlyInheritedProperties())
         return false;
diff --git a/Source/core/css/resolver/MatchedPropertiesCache.h b/Source/core/css/resolver/MatchedPropertiesCache.h
index f1ccc3d..2e5297d 100644
--- a/Source/core/css/resolver/MatchedPropertiesCache.h
+++ b/Source/core/css/resolver/MatchedPropertiesCache.h
@@ -25,7 +25,7 @@
 
 #include "core/css/resolver/MatchResult.h"
 
-#include "core/platform/Timer.h"
+#include "platform/Timer.h"
 #include "wtf/Forward.h"
 #include "wtf/HashMap.h"
 #include "wtf/Noncopyable.h"
diff --git a/Source/core/css/resolver/ScopedStyleResolver.cpp b/Source/core/css/resolver/ScopedStyleResolver.cpp
index cb60fdc..3bc70ed 100644
--- a/Source/core/css/resolver/ScopedStyleResolver.cpp
+++ b/Source/core/css/resolver/ScopedStyleResolver.cpp
@@ -34,6 +34,7 @@
 #include "core/css/RuleSet.h"
 #include "core/css/StyleRule.h"
 #include "core/css/resolver/StyleResolver.h" // For MatchRequest.
+#include "core/css/resolver/ViewportStyleResolver.h"
 #include "core/dom/Document.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
@@ -146,7 +147,7 @@
     bool applyAuthorStyles = treeScope.applyAuthorStyles();
 
     for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent()) {
-        if (&scopedResolver->treeScope() == &treeScope || (applyAuthorStyles && &scopedResolver->treeScope() == &document))
+        if (scopedResolver->treeScope() == treeScope || (applyAuthorStyles && scopedResolver->treeScope() == document))
             resolvers.append(scopedResolver);
     }
 }
@@ -187,7 +188,7 @@
     if (!cacheIsValid(&scopingNode))
         return;
 
-    if (m_cache.scopedResolver && &m_cache.scopedResolver->scopingNode() == &scopingNode)
+    if (m_cache.scopedResolver && m_cache.scopedResolver->scopingNode() == scopingNode)
         m_cache.scopedResolver = m_cache.scopedResolver->parent();
     m_cache.nodeForScopedStyles = scopingNode.parentOrShadowHostNode();
 }
@@ -378,10 +379,10 @@
         shadowRoot = shadow->oldestShadowRoot();
 
     RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
-    collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::DoesNotCrossBoundary | SelectorChecker::ScopeContainsLastMatchedElement));
+    SelectorChecker::BehaviorAtBoundary boundary = static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::DoesNotCrossBoundary | SelectorChecker::ScopeContainsLastMatchedElement);
     for (; shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) {
         if (RuleSet* ruleSet = atHostRuleSetFor(shadowRoot))
-            collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, &m_scopingNode), ruleRange, cascadeScope);
+            collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, &m_scopingNode), ruleRange, boundary, cascadeScope);
     }
 
     collector.sortAndTransferMatchedRules();
@@ -413,9 +414,8 @@
 
     MatchRequest matchRequest(m_authorStyle.get(), includeEmptyRules, scopingNode, applyAuthorStyles);
     RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
-    collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBoundary>(behaviorAtBoundary));
-    collector.collectMatchingRules(matchRequest, ruleRange, cascadeScope, cascadeOrder);
-    collector.collectMatchingRulesForRegion(matchRequest, ruleRange, cascadeScope, cascadeOrder);
+    collector.collectMatchingRules(matchRequest, ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(behaviorAtBoundary), cascadeScope, cascadeOrder);
+    collector.collectMatchingRulesForRegion(matchRequest, ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(behaviorAtBoundary), cascadeScope, cascadeOrder);
 }
 
 void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector)
@@ -427,8 +427,10 @@
 
 void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const
 {
+    // Only consider the global author RuleSet for @viewport rules.
+    ASSERT(m_scopingNode.isDocumentNode());
     if (m_authorStyle)
-        resolver->collectViewportRules(m_authorStyle.get(), StyleResolver::AuthorOrigin);
+        resolver->viewportStyleResolver()->collectViewportRules(m_authorStyle.get(), ViewportStyleResolver::AuthorOrigin);
 }
 
 } // namespace WebCore
diff --git a/Source/core/css/resolver/ScopedStyleResolver.h b/Source/core/css/resolver/ScopedStyleResolver.h
index 5372edd..09b1edf 100644
--- a/Source/core/css/resolver/ScopedStyleResolver.h
+++ b/Source/core/css/resolver/ScopedStyleResolver.h
@@ -60,7 +60,7 @@
     void setParent(ScopedStyleResolver* newParent) { m_parent = newParent; }
     ScopedStyleResolver* parent() { return m_parent; }
 
-    bool hasOnlyEmptyRuleSets() const { return !m_authorStyle->ruleCount() && m_atHostRules.isEmpty(); }
+    bool hasOnlyEmptyRuleSets() const { return (!m_authorStyle || !m_authorStyle->ruleCount()) && m_atHostRules.isEmpty(); }
 
 public:
     bool checkRegionStyle(Element*);
diff --git a/Source/core/css/resolver/SharedStyleFinder.cpp b/Source/core/css/resolver/SharedStyleFinder.cpp
index aad32e7..2a6dd7b 100644
--- a/Source/core/css/resolver/SharedStyleFinder.cpp
+++ b/Source/core/css/resolver/SharedStyleFinder.cpp
@@ -90,7 +90,7 @@
     if (element->isDefaultButtonForForm() != context.element()->isDefaultButtonForForm())
         return false;
 
-    if (context.document().containsValidityStyleRules()) {
+    if (element->document().containsValidityStyleRules()) {
         bool willValidate = element->willValidate();
 
         if (willValidate != context.element()->willValidate())
@@ -245,7 +245,7 @@
     if (element->isWebVTTElement() && context.element()->isWebVTTElement() && toWebVTTElement(element)->isPastNode() != toWebVTTElement(context.element())->isPastNode())
         return false;
 
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&context.document())) {
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&element->document())) {
         if (element == fullscreen->webkitCurrentFullScreenElement() || context.element() == fullscreen->webkitCurrentFullScreenElement())
             return false;
     }
@@ -297,7 +297,15 @@
     return 0;
 }
 
-RenderStyle* SharedStyleFinder::locateSharedStyle(const ElementResolveContext& context, RenderStyle* newStyle)
+bool SharedStyleFinder::matchesRuleSet(const ElementResolveContext& context, RuleSet* ruleSet)
+{
+    if (!ruleSet)
+        return false;
+    ElementRuleCollector collector(context, m_styleResolver->selectorFilter());
+    return collector.hasAnyMatchingRules(ruleSet);
+}
+
+RenderStyle* SharedStyleFinder::locateSharedStyle(const ElementResolveContext& context)
 {
     STYLE_STATS_ADD_SEARCH();
 
@@ -329,11 +337,8 @@
     if (!shareElement)
         return 0;
 
-    // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
-    if (m_styleResolver->styleSharingCandidateMatchesRuleSet(context, newStyle, m_siblingRuleSet))
-        return 0;
-    // Can't share if attribute rules apply.
-    if (m_styleResolver->styleSharingCandidateMatchesRuleSet(context, newStyle, m_uncommonAttributeRuleSet))
+    // Can't share if sibling or attribute rules apply. This is checked at the end as it should rarely fail.
+    if (matchesRuleSet(context, m_siblingRuleSet) || matchesRuleSet(context, m_uncommonAttributeRuleSet))
         return 0;
     // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
     if (parentElementPreventsSharing(context.element()->parentElement()))
diff --git a/Source/core/css/resolver/SharedStyleFinder.h b/Source/core/css/resolver/SharedStyleFinder.h
index d407279..1e12375 100644
--- a/Source/core/css/resolver/SharedStyleFinder.h
+++ b/Source/core/css/resolver/SharedStyleFinder.h
@@ -35,7 +35,6 @@
 
 class SharedStyleFinder {
 public:
-    // FIXME: StyleResolver* only used for calling styleSharingCandidateMatchesRuleSet.
     // RuleSets are passed non-const as the act of matching against them can cause them
     // to be compacted. :(
     SharedStyleFinder(const RuleFeatureSet& features, RuleSet* siblingRuleSet,
@@ -48,7 +47,7 @@
     { }
 
     // FIXME: It is not necessarily safe to call this method more than once.
-    RenderStyle* locateSharedStyle(const ElementResolveContext&, RenderStyle* newStyle);
+    RenderStyle* locateSharedStyle(const ElementResolveContext&);
 
 private:
     Element* findElementForStyleSharing(const ElementResolveContext&) const;
@@ -61,6 +60,7 @@
     bool canShareStyleWithElement(const ElementResolveContext&, Element*) const;
     bool canShareStyleWithControl(const ElementResolveContext&, Element*) const;
     bool sharingCandidateHasIdenticalStyleAffectingAttributes(const ElementResolveContext&, Element*) const;
+    bool matchesRuleSet(const ElementResolveContext&, RuleSet*);
 
     bool m_elementAffectedByClassRules;
     const RuleFeatureSet& m_features;
diff --git a/Source/core/css/resolver/StyleAdjuster.cpp b/Source/core/css/resolver/StyleAdjuster.cpp
index 10f572f..735e099 100644
--- a/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/Source/core/css/resolver/StyleAdjuster.cpp
@@ -39,8 +39,7 @@
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLTableElement.h"
 #include "core/html/HTMLTextAreaElement.h"
-#include "core/page/FrameView.h"
-#include "core/page/Page.h"
+#include "core/frame/FrameView.h"
 #include "core/page/Settings.h"
 #include "core/platform/Length.h"
 #include "core/rendering/Pagination.h"
@@ -278,8 +277,9 @@
         || style->hasFilter()
         || style->hasBlendMode()
         || style->position() == StickyPosition
-        || (style->position() == FixedPosition && e && e->document().page() && e->document().page()->settings().fixedPositionCreatesStackingContext())
+        || (style->position() == FixedPosition && e && e->document().settings() && e->document().settings()->fixedPositionCreatesStackingContext())
         || isInTopLayer(e, style)
+        || style->hasFlowFrom()
         ))
         style->setZIndex(0);
 
@@ -336,10 +336,6 @@
     style->adjustBackgroundLayers();
     style->adjustMaskLayers();
 
-    // Do the same for animations and transitions.
-    style->adjustAnimations();
-    style->adjustTransitions();
-
     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
     // alter fonts and heights/widths.
     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
diff --git a/Source/core/css/resolver/StyleBuilderCustom.cpp b/Source/core/css/resolver/StyleBuilderCustom.cpp
index 24cdb1a..0bff4f1 100644
--- a/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -46,6 +46,7 @@
 #include "core/css/BasicShapeFunctions.h"
 #include "core/css/CSSAspectRatioValue.h"
 #include "core/css/CSSCursorImageValue.h"
+#include "core/css/CSSFontValue.h"
 #include "core/css/CSSFunctionValue.h"
 #include "core/css/CSSGradientValue.h"
 #include "core/css/CSSGridTemplateValue.h"
@@ -55,20 +56,20 @@
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSProperty.h"
 #include "core/css/CSSReflectValue.h"
+#include "core/css/CSSShadowValue.h"
 #include "core/css/CSSVariableValue.h"
 #include "core/css/Counter.h"
-#include "core/css/FontValue.h"
 #include "core/css/Pair.h"
 #include "core/css/Rect.h"
-#include "core/css/ShadowValue.h"
 #include "core/css/StylePropertySet.h"
+#include "core/css/StyleRule.h"
 #include "core/css/resolver/ElementStyleResources.h"
 #include "core/css/resolver/FilterOperationResolver.h"
 #include "core/css/resolver/FontBuilder.h"
 #include "core/css/resolver/StyleBuilder.h"
 #include "core/css/resolver/StyleResolverState.h"
 #include "core/css/resolver/TransformBuilder.h"
-#include "core/page/Frame.h"
+#include "core/frame/Frame.h"
 #include "core/page/Settings.h"
 #include "core/platform/graphics/FontDescription.h"
 #include "core/rendering/style/CounterContent.h"
@@ -151,7 +152,7 @@
         for (int i = 0; i < len; i++) {
             CSSValue* item = list->itemWithoutBoundsCheck(i);
             if (item->isCursorImageValue()) {
-                CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(item);
+                CSSCursorImageValue* image = toCSSCursorImageValue(item);
                 if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style.
                     state.style()->setUnique();
                 state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot());
@@ -281,7 +282,7 @@
         lineHeight = primitiveValue->computeLength<Length>(state.style(), state.rootElementStyle(), multiplier);
     } else if (primitiveValue->isPercentage()) {
         // FIXME: percentage should not be restricted to an integer here.
-        lineHeight = Length((state.style()->fontSize() * primitiveValue->getIntValue()) / 100, Fixed);
+        lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed);
     } else if (primitiveValue->isNumber()) {
         // FIXME: number and percentage values should produce the same type of Length (ie. Fixed or Percent).
         lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
@@ -799,7 +800,7 @@
 }
 
 #if ENABLE(CSS3_TEXT)
-void StyleBuilderFunctions::applyValueCSSPropetyWebkitTextUnderlinePosition(StyleResolverState& state, CSSValue* value)
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextUnderlinePosition(StyleResolverState& state, CSSValue* value)
 {
     // This is true if value is 'auto' or 'alphabetic'.
     if (value->isPrimitiveValue()) {
@@ -1207,8 +1208,8 @@
         return primitiveValue->hasVariableReference();
     }
 
-    if (value->isCalculationValue())
-        return static_cast<CSSCalcValue*>(value)->hasVariableReference();
+    if (value->isCalcValue())
+        return toCSSCalcValue(value)->hasVariableReference();
 
     if (value->isReflectValue()) {
         CSSReflectValue* reflectValue = toCSSReflectValue(value);
@@ -1327,9 +1328,9 @@
                 CSSValue* item = i.value();
                 if (item->isImageGeneratorValue()) {
                     if (item->isGradientValue())
-                        state.style()->setContent(StyleGeneratedImage::create(static_cast<CSSGradientValue*>(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
+                        state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
                     else
-                        state.style()->setContent(StyleGeneratedImage::create(static_cast<CSSImageGeneratorValue*>(item)), didSet);
+                        state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet);
                     didSet = true;
                 } else if (item->isImageSetValue()) {
                     state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
@@ -1502,7 +1503,7 @@
             CSSValue* currValue = i.value();
             if (!currValue->isShadowValue())
                 continue;
-            ShadowValue* item = static_cast<ShadowValue*>(currValue);
+            CSSShadowValue* item = toCSSShadowValue(currValue);
             int x = item->x->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor);
             int y = item->y->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor);
             int blur = item->blur ? item->blur->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor) : 0;
@@ -1632,6 +1633,15 @@
         state.style()->setTapHighlightColor(col);
         return;
     }
+    case CSSPropertyInternalCallback: {
+        if (isInherit || isInitial)
+            return;
+        if (primitiveValue && primitiveValue->getValueID() == CSSValueInternalPresence) {
+            state.style()->addCallbackSelector(state.currentRule()->selectorList().selectorsText());
+            return;
+        }
+        break;
+    }
     case CSSPropertyInvalid:
         return;
     // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
@@ -1717,11 +1727,10 @@
             return;
         }
 
-        if (!value->isCSSLineBoxContainValue())
+        if (!value->isLineBoxContainValue())
             return;
 
-        CSSLineBoxContainValue* lineBoxContainValue = static_cast<CSSLineBoxContainValue*>(value);
-        state.style()->setLineBoxContain(lineBoxContainValue->value());
+        state.style()->setLineBoxContain(toCSSLineBoxContainValue(value)->value());
         return;
     }
 
@@ -1986,6 +1995,7 @@
     case CSSPropertyTextDecorationStyle:
     case CSSPropertyTextDecorationColor:
     case CSSPropertyTextIndent:
+    case CSSPropertyTextJustify:
     case CSSPropertyTextOverflow:
     case CSSPropertyTextRendering:
     case CSSPropertyTextTransform:
@@ -2028,6 +2038,7 @@
     case CSSPropertyWebkitColumnBreakBefore:
     case CSSPropertyWebkitColumnBreakInside:
     case CSSPropertyWebkitColumnCount:
+    case CSSPropertyColumnFill:
     case CSSPropertyWebkitColumnGap:
     case CSSPropertyWebkitColumnProgression:
     case CSSPropertyWebkitColumnRuleColor:
@@ -2112,6 +2123,7 @@
     case CSSPropertyWebkitWrapFlow:
     case CSSPropertyWebkitShapeMargin:
     case CSSPropertyWebkitShapePadding:
+    case CSSPropertyWebkitShapeImageThreshold:
     case CSSPropertyWebkitWrapThrough:
     case CSSPropertyWebkitShapeInside:
     case CSSPropertyWebkitShapeOutside:
@@ -2205,7 +2217,7 @@
             return;
         }
         if (value->isSVGPaint()) {
-            SVGPaint* svgPaint = static_cast<SVGPaint*>(value);
+            SVGPaint* svgPaint = toSVGPaint(value);
             svgStyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
         }
         break;
@@ -2223,7 +2235,7 @@
             return;
         }
         if (value->isSVGPaint()) {
-            SVGPaint* svgPaint = static_cast<SVGPaint*>(value);
+            SVGPaint* svgPaint = toSVGPaint(value);
             svgStyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
         }
         break;
@@ -2344,14 +2356,14 @@
     {
         HANDLE_SVG_INHERIT_AND_INITIAL(stopColor, StopColor);
         if (value->isSVGColor())
-            state.style()->accessSVGStyle()->setStopColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color()));
+            state.style()->accessSVGStyle()->setStopColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
         break;
     }
     case CSSPropertyLightingColor:
     {
         HANDLE_SVG_INHERIT_AND_INITIAL(lightingColor, LightingColor);
         if (value->isSVGColor())
-            state.style()->accessSVGStyle()->setLightingColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color()));
+            state.style()->accessSVGStyle()->setLightingColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
         break;
     }
     case CSSPropertyFloodOpacity:
@@ -2366,7 +2378,7 @@
     {
         HANDLE_SVG_INHERIT_AND_INITIAL(floodColor, FloodColor);
         if (value->isSVGColor())
-            state.style()->accessSVGStyle()->setFloodColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color()));
+            state.style()->accessSVGStyle()->setFloodColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
         break;
     }
     case CSSPropertyGlyphOrientationHorizontal:
diff --git a/Source/core/css/resolver/StyleBuilderCustom.h b/Source/core/css/resolver/StyleBuilderCustom.h
index 597c501..e2156f0 100644
--- a/Source/core/css/resolver/StyleBuilderCustom.h
+++ b/Source/core/css/resolver/StyleBuilderCustom.h
@@ -53,9 +53,8 @@
 template <typename T>
 T StyleBuilderConverter::convertComputedLength(StyleResolverState& state, CSSValue* value)
 {
-    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     float zoom = state.style()->effectiveZoom();
-    return primitiveValue->computeLength<T>(state.style(), state.rootElementStyle(), zoom);
+    return toCSSPrimitiveValue(value)->computeLength<T>(state.style(), state.rootElementStyle(), zoom);
 }
 
 template <typename T>
@@ -69,6 +68,8 @@
         return 3;
     if (valueID == CSSValueThick)
         return 5;
+    if (primitiveValue->isViewportPercentageLength())
+        return intValueForLength(primitiveValue->viewportPercentageLength(), 0, state.document().renderView());
     if (valueID == CSSValueInvalid) {
         float zoom = state.style()->effectiveZoom();
         // Any original result that was >= 1 should not be allowed to fall below 1.
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp
index 63748e5..4a880f6 100644
--- a/Source/core/css/resolver/StyleResolver.cpp
+++ b/Source/core/css/resolver/StyleResolver.cpp
@@ -33,7 +33,7 @@
 #include "HTMLNames.h"
 #include "RuntimeEnabledFeatures.h"
 #include "StylePropertyShorthand.h"
-#include "core/animation/AnimatableNumber.h"
+#include "core/animation/AnimatableLength.h"
 #include "core/animation/AnimatableValue.h"
 #include "core/animation/Animation.h"
 #include "core/animation/DocumentTimeline.h"
@@ -63,6 +63,7 @@
 #include "core/css/resolver/StyleAdjuster.h"
 #include "core/css/resolver/StyleBuilder.h"
 #include "core/css/resolver/ViewportStyleResolver.h"
+#include "core/dom/CSSSelectorWatch.h"
 #include "core/dom/NodeRenderStyle.h"
 #include "core/dom/StyleEngine.h"
 #include "core/dom/Text.h"
@@ -70,8 +71,8 @@
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/Frame.h"
-#include "core/page/FrameView.h"
+#include "core/frame/Frame.h"
+#include "core/frame/FrameView.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/style/KeyframeList.h"
 #include "core/rendering/style/StyleCustomFilterProgramCache.h"
@@ -83,6 +84,32 @@
 
 using namespace std;
 
+namespace {
+
+using namespace WebCore;
+
+PassRefPtr<TimingFunction> generateTimingFunction(const KeyframeAnimationEffect::KeyframeVector keyframes, const HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions)
+{
+    // Generate the chained timing function. Note that timing functions apply
+    // from the keyframe in which they're specified to the next keyframe.
+    bool isTimingFunctionLinearThroughout = true;
+    RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
+    for (size_t i = 0; i < keyframes.size() - 1; ++i) {
+        double lowerBound = keyframes[i]->offset();
+        ASSERT(lowerBound >=0 && lowerBound < 1);
+        double upperBound = keyframes[i + 1]->offset();
+        ASSERT(upperBound > 0 && upperBound <= 1);
+        TimingFunction* timingFunction = perKeyframeTimingFunctions.get(lowerBound);
+        isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunction::LinearFunction;
+        chainedTimingFunction->appendSegment(upperBound, timingFunction);
+    }
+    if (isTimingFunctionLinearThroughout)
+        return LinearTimingFunction::create();
+    return chainedTimingFunction;
+}
+
+} // namespace
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -114,6 +141,8 @@
 {
     Element* root = document.documentElement();
 
+    m_fontSelector->registerForInvalidationCallbacks(this);
+
     CSSDefaultStyleSheets::initDefaultStyle(root);
 
     // construct document root element default style. this is needed
@@ -137,7 +166,7 @@
     m_styleTree.clear();
 
     StyleEngine* styleSheetCollection = document.styleEngine();
-    m_ruleSets.initUserStyle(styleSheetCollection, *m_medium, *this);
+    m_ruleSets.initUserStyle(styleSheetCollection, CSSSelectorWatch::from(document).watchedCallbackSelectors(), *m_medium, *this);
 
 #if ENABLE(SVG_FONTS)
     if (document.svgExtensions()) {
@@ -159,7 +188,7 @@
     for (unsigned i = firstNew; i < size; ++i) {
         CSSStyleSheet* cssSheet = styleSheets[i].get();
         ASSERT(!cssSheet->disabled());
-        if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), this))
+        if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
             continue;
 
         StyleSheetContents* sheet = cssSheet->contents();
@@ -295,6 +324,12 @@
     m_styleSharingList.clear();
 }
 
+void StyleResolver::fontsNeedUpdate(FontSelector* fontSelector)
+{
+    invalidateMatchedPropertiesCache();
+    m_document.setNeedsStyleRecalc();
+}
+
 void StyleResolver::pushParentElement(Element* parent)
 {
     ASSERT(parent);
@@ -338,34 +373,31 @@
 
 StyleResolver::~StyleResolver()
 {
+    m_fontSelector->unregisterForInvalidationCallbacks(this);
     m_fontSelector->clearDocument();
     m_viewportStyleResolver->clearDocument();
 }
 
-inline void StyleResolver::matchShadowDistributedRules(ElementRuleCollector& collector, bool includeEmptyRules)
+inline void StyleResolver::collectShadowDistributedRules(ElementRuleCollector& collector, bool includeEmptyRules)
 {
-    // FIXME: Determine tree position.
-    CascadeScope cascadeScope = ignoreCascadeScope;
-
     if (m_ruleSets.shadowDistributedRules().isEmpty())
         return;
 
     bool previousCanUseFastReject = collector.canUseFastReject();
-    SelectorChecker::BehaviorAtBoundary previousBoundary = collector.behaviorAtBoundary();
-    collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::CrossesBoundary | SelectorChecker::ScopeContainsLastMatchedElement));
     collector.setCanUseFastReject(false);
 
-    collector.clearMatchedRules();
-    collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
     RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
 
-    Vector<MatchRequest> matchRequests;
-    m_ruleSets.shadowDistributedRules().collectMatchRequests(includeEmptyRules, matchRequests);
-    for (size_t i = 0; i < matchRequests.size(); ++i)
-        collector.collectMatchingRules(matchRequests[i], ruleRange, cascadeScope);
-    collector.sortAndTransferMatchedRules();
+    for (ShadowDistributedRules::iterator it = m_ruleSets.shadowDistributedRules().begin(); it != m_ruleSets.shadowDistributedRules().end(); ++it) {
+        unsigned boundaryBehavior = SelectorChecker::CrossesBoundary | SelectorChecker::ScopeContainsLastMatchedElement;
+        const ContainerNode* scopingNode = it->key;
 
-    collector.setBehaviorAtBoundary(previousBoundary);
+        if (scopingNode && scopingNode->isShadowRoot()) {
+            boundaryBehavior |= SelectorChecker::ScopeIsShadowHost;
+            scopingNode = toShadowRoot(scopingNode)->host();
+        }
+        collector.collectMatchingRules(MatchRequest(it->value.get(), includeEmptyRules, scopingNode), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope);
+    }
     collector.setCanUseFastReject(previousCanUseFastReject);
 }
 
@@ -381,7 +413,7 @@
     return element->treeScope().applyAuthorStyles() || (element->shadow() && element->shadow()->applyAuthorStyles());
 }
 
-void StyleResolver::matchScopedAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree)
+void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree)
 {
     collector.clearMatchedRules();
     collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
@@ -393,19 +425,20 @@
     for (int j = resolversInShadowTree.size() - 1; j >= 0; --j)
         resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope, cascadeOrder++);
 
-    if (resolvers.isEmpty() || &resolvers.first()->treeScope() != &element->treeScope())
+    if (resolvers.isEmpty() || resolvers.first()->treeScope() != element->treeScope())
         ++cascadeScope;
     cascadeOrder += resolvers.size();
     for (unsigned i = 0; i < resolvers.size(); ++i)
         resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, --cascadeOrder);
 
+    collectShadowDistributedRules(collector, includeEmptyRules);
     collector.sortAndTransferMatchedRules();
 
     if (!resolvers.isEmpty())
         matchHostRules(element, resolvers.first(), collector, includeEmptyRules);
 }
 
-void StyleResolver::matchScopedAuthorRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
+void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
 {
     if (m_styleTree.hasOnlyScopedResolverForDocument()) {
         m_styleTree.scopedStyleResolverForDocument()->matchAuthorRules(collector, includeEmptyRules, applyAuthorStylesOf(element));
@@ -418,7 +451,7 @@
     Vector<ScopedStyleResolver*, 8> resolversInShadowTree;
     m_styleTree.collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree);
     if (!resolversInShadowTree.isEmpty()) {
-        matchScopedAuthorRulesForShadowHost(element, collector, includeEmptyRules, resolvers, resolversInShadowTree);
+        matchAuthorRulesForShadowHost(element, collector, includeEmptyRules, resolvers, resolversInShadowTree);
         return;
     }
 
@@ -434,20 +467,15 @@
     for (unsigned i = 0; i < resolvers.size(); ++i, --cascadeOrder) {
         ScopedStyleResolver* resolver = resolvers.at(i);
         // FIXME: Need to clarify how to treat style scoped.
-        resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, &resolver->treeScope() == &element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder);
+        resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder);
     }
 
+    collectShadowDistributedRules(collector, includeEmptyRules);
     collector.sortAndTransferMatchedRules();
 
     matchHostRules(element, resolvers.first(), collector, includeEmptyRules);
 }
 
-void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
-{
-    matchScopedAuthorRules(element, collector, includeEmptyRules);
-    matchShadowDistributedRules(collector, includeEmptyRules);
-}
-
 void StyleResolver::matchUserRules(ElementRuleCollector& collector, bool includeEmptyRules)
 {
     if (!m_ruleSets.userStyle())
@@ -546,15 +574,6 @@
     }
 }
 
-bool StyleResolver::styleSharingCandidateMatchesRuleSet(const ElementResolveContext& context, RenderStyle* style, RuleSet* ruleSet)
-{
-    if (!ruleSet)
-        return false;
-
-    ElementRuleCollector collector(context, m_selectorFilter, style);
-    return collector.hasAnyMatchingRules(ruleSet);
-}
-
 PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document, CSSFontSelector* fontSelector)
 {
     const Frame* frame = document.frame();
@@ -631,7 +650,7 @@
 
     if (sharingBehavior == AllowStyleSharing && !state.distributedToInsertionPoint() && state.parentStyle()) {
         SharedStyleFinder styleFinder(m_features, m_siblingRuleSet.get(), m_uncommonAttributeRuleSet.get(), this);
-        RefPtr<RenderStyle> sharedStyle = styleFinder.locateSharedStyle(state.elementContext(), state.style());
+        RefPtr<RenderStyle> sharedStyle = styleFinder.locateSharedStyle(state.elementContext());
         if (sharedStyle)
             return sharedStyle.release();
     }
@@ -689,6 +708,7 @@
         StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
         adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element);
     }
+
     document().didAccessStyleResolver();
 
     // FIXME: Shouldn't this be on RenderBody::styleDidChange?
@@ -833,19 +853,23 @@
     }
 }
 
-void StyleResolver::resolveKeyframes(const Element* element, const RenderStyle* style, const AtomicString& name, TimingFunction* defaultTimingFunction, KeyframeAnimationEffect::KeyframeVector& keyframes, RefPtr<TimingFunction>& timingFunction)
+void StyleResolver::resolveKeyframes(Element* element, const RenderStyle* style, const AtomicString& name, TimingFunction* defaultTimingFunction, Vector<std::pair<KeyframeAnimationEffect::KeyframeVector, RefPtr<TimingFunction> > >& keyframesAndTimingFunctions)
 {
     ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
     const StyleRuleKeyframes* keyframesRule = matchScopedKeyframesRule(element, name.impl());
     if (!keyframesRule)
         return;
 
-    // Construct and populate the style for each keyframe
-    HashMap<double, RefPtr<TimingFunction> > timingFunctions;
     const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyframes();
+    if (styleKeyframes.isEmpty())
+        return;
+
+    // Construct and populate the style for each keyframe
+    KeyframeAnimationEffect::KeyframeVector keyframes;
+    HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions;
     for (size_t i = 0; i < styleKeyframes.size(); ++i) {
         const StyleKeyframe* styleKeyframe = styleKeyframes[i].get();
-        RefPtr<RenderStyle> keyframeStyle = styleForKeyframe(0, style, styleKeyframe);
+        RefPtr<RenderStyle> keyframeStyle = styleForKeyframe(element, style, styleKeyframe);
         RefPtr<Keyframe> keyframe = Keyframe::create();
         const Vector<double>& offsets = styleKeyframe->keys();
         ASSERT(!offsets.isEmpty());
@@ -856,7 +880,6 @@
             CSSPropertyID property = properties->propertyAt(j).id();
             if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) {
                 // FIXME: This sometimes gets the wrong timing function. See crbug.com/288540.
-
                 timingFunction = KeyframeValue::timingFunction(keyframeStyle.get(), name);
             } else if (CSSAnimations::isAnimatableProperty(property)) {
                 keyframe->setPropertyValue(property, CSSAnimatableValueFactory::create(property, keyframeStyle.get()).get());
@@ -864,15 +887,16 @@
         }
         keyframes.append(keyframe);
         // The last keyframe specified at a given offset is used.
-        timingFunctions.set(offsets[0], timingFunction);
+        perKeyframeTimingFunctions.set(offsets[0], timingFunction);
         for (size_t j = 1; j < offsets.size(); ++j) {
             keyframes.append(keyframe->cloneWithOffset(offsets[j]));
-            timingFunctions.set(offsets[j], timingFunction);
+            perKeyframeTimingFunctions.set(offsets[j], timingFunction);
         }
     }
+    ASSERT(!keyframes.isEmpty());
 
-    if (keyframes.isEmpty())
-        return;
+    if (!perKeyframeTimingFunctions.contains(0))
+        perKeyframeTimingFunctions.set(0, defaultTimingFunction);
 
     // Remove duplicate keyframes. In CSS the last keyframe at a given offset takes priority.
     std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets);
@@ -902,59 +926,92 @@
     ASSERT(!keyframes.first()->offset());
     ASSERT(keyframes.last()->offset() == 1);
 
-    // Generate the chained timing function. Note that timing functions apply
-    // from the keyframe in which they're specified to the next keyframe.
-    // FIXME: Handle keyframe sets where some keyframes don't specify all
-    // properties. In this case, timing functions apply between the keyframes
-    // which specify a particular property, so we'll need a separate chained
-    // timing function (and therefore animation) for each property. See
-    // LayoutTests/animations/missing-keyframe-properties-timing-function.html
-    if (!timingFunctions.contains(0))
-        timingFunctions.set(0, defaultTimingFunction);
-    bool isTimingFunctionLinearThroughout = true;
-    RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
-    for (size_t i = 0; i < keyframes.size() - 1; ++i) {
-        double lowerBound = keyframes[i]->offset();
-        ASSERT(lowerBound >=0 && lowerBound < 1);
-        double upperBound = keyframes[i + 1]->offset();
-        ASSERT(upperBound > 0 && upperBound <= 1);
-        TimingFunction* timingFunction = timingFunctions.get(lowerBound);
-        ASSERT(timingFunction);
-        isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunction::LinearFunction;
-        chainedTimingFunction->appendSegment(upperBound, timingFunction);
-    }
-    if (isTimingFunctionLinearThroughout)
-        timingFunction = LinearTimingFunction::create();
-    else
-        timingFunction = chainedTimingFunction;
-
     // Snapshot current property values for 0% and 100% if missing.
-    HashSet<CSSPropertyID> allProperties;
-    for (size_t i = 0; i < keyframes.size(); i++) {
-        const HashSet<CSSPropertyID>& keyframeProperties = keyframes[i]->properties();
-        for (HashSet<CSSPropertyID>::const_iterator iter = keyframeProperties.begin(); iter != keyframeProperties.end(); ++iter)
+    PropertySet allProperties;
+    size_t numKeyframes = keyframes.size();
+    for (size_t i = 0; i < numKeyframes; i++) {
+        const PropertySet& keyframeProperties = keyframes[i]->properties();
+        for (PropertySet::const_iterator iter = keyframeProperties.begin(); iter != keyframeProperties.end(); ++iter)
             allProperties.add(*iter);
     }
-    const HashSet<CSSPropertyID>& startKeyframeProperties = startKeyframe->properties();
-    const HashSet<CSSPropertyID>& endKeyframeProperties = endKeyframe->properties();
+    const PropertySet& startKeyframeProperties = startKeyframe->properties();
+    const PropertySet& endKeyframeProperties = endKeyframe->properties();
     bool missingStartValues = startKeyframeProperties.size() < allProperties.size();
     bool missingEndValues = endKeyframeProperties.size() < allProperties.size();
-    if (!missingStartValues && !missingEndValues)
-        return;
-    for (HashSet<CSSPropertyID>::const_iterator iter = allProperties.begin(); iter != allProperties.end(); ++iter) {
-        const CSSPropertyID property = *iter;
-        bool startNeedsValue = missingStartValues && !startKeyframeProperties.contains(property);
-        bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains(property);
-        if (!startNeedsValue && !endNeedsValue)
-            continue;
-        RefPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::create(property, style);
-        if (startNeedsValue)
-            startKeyframe->setPropertyValue(property, snapshotValue.get());
-        if (endNeedsValue)
-            endKeyframe->setPropertyValue(property, snapshotValue.get());
+    if (missingStartValues || missingEndValues) {
+        for (PropertySet::const_iterator iter = allProperties.begin(); iter != allProperties.end(); ++iter) {
+            const CSSPropertyID property = *iter;
+            bool startNeedsValue = missingStartValues && !startKeyframeProperties.contains(property);
+            bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains(property);
+            if (!startNeedsValue && !endNeedsValue)
+                continue;
+            RefPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::create(property, style);
+            if (startNeedsValue)
+                startKeyframe->setPropertyValue(property, snapshotValue.get());
+            if (endNeedsValue)
+                endKeyframe->setPropertyValue(property, snapshotValue.get());
+        }
     }
     ASSERT(startKeyframe->properties().size() == allProperties.size());
     ASSERT(endKeyframe->properties().size() == allProperties.size());
+
+    // Determine how many keyframes specify each property. Note that this must
+    // be done after we've filled in end keyframes.
+    typedef HashCountedSet<CSSPropertyID> PropertyCountedSet;
+    PropertyCountedSet propertyCounts;
+    for (size_t i = 0; i < numKeyframes; ++i) {
+        const PropertySet& properties = keyframes[i]->properties();
+        for (PropertySet::const_iterator iter = properties.begin(); iter != properties.end(); ++iter)
+            propertyCounts.add(*iter);
+    }
+
+    // Split keyframes into groups, where each group contains only keyframes
+    // which specify all properties used in that group. Each group is animated
+    // in a separate animation, to allow per-keyframe timing functions to be
+    // applied correctly.
+    for (PropertyCountedSet::const_iterator iter = propertyCounts.begin(); iter != propertyCounts.end(); ++iter) {
+        const CSSPropertyID property = iter->key;
+        const size_t count = iter->value;
+        ASSERT(count <= numKeyframes);
+        if (count == numKeyframes)
+            continue;
+        KeyframeAnimationEffect::KeyframeVector splitOutKeyframes;
+        for (size_t i = 0; i < numKeyframes; i++) {
+            Keyframe* keyframe = keyframes[i].get();
+            if (!keyframe->properties().contains(property)) {
+                ASSERT(i && i != numKeyframes - 1);
+                continue;
+            }
+            RefPtr<Keyframe> clonedKeyframe = Keyframe::create();
+            clonedKeyframe->setOffset(keyframe->offset());
+            clonedKeyframe->setComposite(keyframe->composite());
+            clonedKeyframe->setPropertyValue(property, keyframe->propertyValue(property));
+            splitOutKeyframes.append(clonedKeyframe);
+            // Note that it's OK if this keyframe ends up having no
+            // properties. This can only happen when none of the properties
+            // are specified in all keyframes, in which case we won't animate
+            // anything with these keyframes.
+            keyframe->clearPropertyValue(property);
+        }
+        ASSERT(!splitOutKeyframes.first()->offset());
+        ASSERT(splitOutKeyframes.last()->offset() == 1);
+#ifndef NDEBUG
+        for (size_t j = 0; j < splitOutKeyframes.size(); ++j)
+            ASSERT(splitOutKeyframes[j]->properties().size() == 1);
+#endif
+        keyframesAndTimingFunctions.append(std::make_pair(splitOutKeyframes, generateTimingFunction(splitOutKeyframes, perKeyframeTimingFunctions)));
+    }
+
+    size_t numPropertiesSpecifiedInAllKeyframes = keyframes.first()->properties().size();
+#ifndef NDEBUG
+    for (size_t i = 1; i < numKeyframes; ++i)
+        ASSERT(keyframes[i]->properties().size() == numPropertiesSpecifiedInAllKeyframes);
+#endif
+
+    // If the animation specifies any keyframes, we always provide at least one
+    // vector of resolved keyframes, even if no properties are animated.
+    if (numPropertiesSpecifiedInAllKeyframes || keyframesAndTimingFunctions.isEmpty())
+        keyframesAndTimingFunctions.append(std::make_pair(keyframes, generateTimingFunction(keyframes, perKeyframeTimingFunctions)));
 }
 
 PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle)
@@ -982,7 +1039,7 @@
 
     {
         // Check UA, user and author rules.
-    ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
+        ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
         collector.setPseudoStyleRequest(pseudoStyleRequest);
 
         matchUARules(collector);
@@ -1007,9 +1064,6 @@
         adjuster.adjustRenderStyle(state.style(), state.parentStyle(), 0);
     }
 
-    // Start loading resources referenced by this style.
-    m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
-
     document().didAccessStyleResolver();
 
     // Now return the style.
@@ -1022,12 +1076,13 @@
     StyleResolverState state(document(), document().documentElement()); // m_rootElementStyle will be set to the document style.
 
     state.setStyle(RenderStyle::create());
-    if (state.rootElementStyle())
-        state.style()->inheritFrom(state.rootElementStyle());
+    const RenderStyle* rootElementStyle = state.rootElementStyle() ? state.rootElementStyle() : document().renderStyle();
+    ASSERT(rootElementStyle);
+    state.style()->inheritFrom(rootElementStyle);
 
     state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
 
-    PageRuleCollector collector(state.elementContext(), pageIndex);
+    PageRuleCollector collector(rootElementStyle, pageIndex);
 
     collector.matchPageRules(CSSDefaultStyleSheets::defaultPrintStyle);
     collector.matchPageRules(m_ruleSets.userStyle());
@@ -1064,13 +1119,13 @@
 
 void StyleResolver::collectViewportRules()
 {
-    collectViewportRules(CSSDefaultStyleSheets::defaultStyle, UserAgentOrigin);
+    viewportStyleResolver()->collectViewportRules(CSSDefaultStyleSheets::defaultStyle, ViewportStyleResolver::UserAgentOrigin);
 
     if (document().isMobileDocument())
-        collectViewportRules(CSSDefaultStyleSheets::xhtmlMobileProfileStyle(), UserAgentOrigin);
+        viewportStyleResolver()->collectViewportRules(CSSDefaultStyleSheets::xhtmlMobileProfileStyle(), ViewportStyleResolver::UserAgentOrigin);
 
     if (m_ruleSets.userStyle())
-        collectViewportRules(m_ruleSets.userStyle(), UserAgentOrigin);
+        viewportStyleResolver()->collectViewportRules(m_ruleSets.userStyle(), ViewportStyleResolver::UserAgentOrigin);
 
     if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
         scopedResolver->collectViewportRulesTo(this);
@@ -1078,17 +1133,6 @@
     viewportStyleResolver()->resolve();
 }
 
-void StyleResolver::collectViewportRules(RuleSet* rules, ViewportOrigin origin)
-{
-    rules->compactRulesIfNeeded();
-
-    const Vector<StyleRuleViewport*>& viewportRules = rules->viewportRules();
-    if (origin == AuthorOrigin && viewportRules.size())
-        viewportStyleResolver()->setHasAuthorStyle();
-    for (size_t i = 0; i < viewportRules.size(); ++i)
-        viewportStyleResolver()->addViewportRule(viewportRules[i]);
-}
-
 PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()
 {
     StyleResolverState state(document(), 0);
@@ -1187,27 +1231,27 @@
     const Element* element = state.element();
     const CSSAnimationUpdate* update = state.animationUpdate();
     AnimationStack* animationStack = timeline->animationStack(element);
-    if (!animationStack)
-        return false;
     bool didApply = false;
 
-    const Vector<Animation*>& animations = animationStack->activeAnimations(element);
-    for (size_t i = 0; i < animations.size(); ++i) {
-        RefPtr<Animation> animation = animations.at(i);
-        if (update && update->isCancelled(animation->player()))
-            continue;
-        const AnimationEffect::CompositableValueMap* compositableValues = animation->compositableValues();
-        for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues->begin(); iter != compositableValues->end(); ++iter) {
-            CSSPropertyID property = iter->key;
-            if (!isPropertyForPass<pass>(property))
+    if (animationStack) {
+        const Vector<Animation*>& animations = animationStack->activeAnimations(element);
+        for (size_t i = 0; i < animations.size(); ++i) {
+            RefPtr<Animation> animation = animations.at(i);
+            if (update && update->isCancelledAnimation(animation->player()))
                 continue;
-            RELEASE_ASSERT_WITH_MESSAGE(!iter->value->dependsOnUnderlyingValue(), "Not yet implemented: An interface for compositing onto the underlying value.");
-            RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(0);
-            if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
-                state.setLineHeightValue(toAnimatableNumber(animatableValue.get())->toCSSValue().get());
-            else
-                AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
-            didApply = true;
+            const AnimationEffect::CompositableValueMap* compositableValues = animation->compositableValues();
+            for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues->begin(); iter != compositableValues->end(); ++iter) {
+                CSSPropertyID property = iter->key;
+                if (!isPropertyForPass<pass>(property))
+                    continue;
+                RELEASE_ASSERT_WITH_MESSAGE(!iter->value->dependsOnUnderlyingValue(), "Web Animations not yet implemented: An interface for compositing onto the underlying value.");
+                RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(0);
+                if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
+                    state.setLineHeightValue(toAnimatableLength(animatableValue.get())->toCSSValue().get());
+                else
+                    AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
+                didApply = true;
+            }
         }
     }
 
@@ -1220,20 +1264,22 @@
     //     applyAnimatedProperties(state, resolved);
     const Vector<CSSAnimationUpdate::NewAnimation>& newAnimations = update->newAnimations();
     for (size_t i = 0; i < newAnimations.size(); ++i) {
-        RefPtr<InertAnimation> animation = newAnimations.at(i).animation;
-        OwnPtr<AnimationEffect::CompositableValueMap> compositableValues = animation->sample();
-        if (!compositableValues)
-            continue;
-        for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues->begin(); iter != compositableValues->end(); ++iter) {
-            CSSPropertyID property = iter->key;
-            if (!isPropertyForPass<pass>(property))
+        const HashSet<RefPtr<InertAnimation> >& animations = newAnimations.at(i).animations;
+        for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = animations.begin(); animationsIter != animations.end(); ++animationsIter) {
+            OwnPtr<AnimationEffect::CompositableValueMap> compositableValues = (*animationsIter)->sample();
+            if (!compositableValues)
                 continue;
-            RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(AnimatableValue::neutralValue());
-            if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
-                state.setLineHeightValue(toAnimatableNumber(animatableValue.get())->toCSSValue().get());
-            else
-                AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
-            didApply = true;
+            for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues->begin(); iter != compositableValues->end(); ++iter) {
+                CSSPropertyID property = iter->key;
+                if (!isPropertyForPass<pass>(property))
+                    continue;
+                RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(AnimatableValue::neutralValue());
+                if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
+                    state.setLineHeightValue(toAnimatableLength(animatableValue.get())->toCSSValue().get());
+                else
+                    AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
+                didApply = true;
+            }
         }
     }
     return didApply;
@@ -1332,6 +1378,7 @@
 void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
 {
     ASSERT((propertyWhitelistType != PropertyWhitelistRegion) || state.regionForStyling());
+    state.setCurrentRule(rule);
 
     unsigned propertyCount = properties->propertyCount();
     for (unsigned i = 0; i < propertyCount; ++i) {
@@ -1396,23 +1443,6 @@
     m_matchedPropertiesCache.clear();
 }
 
-void StyleResolver::calculateCSSAnimationUpdate(StyleResolverState& state)
-{
-    if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
-        return;
-
-    const Element* element = state.element();
-    ASSERT(element);
-
-    if (!CSSAnimations::needsUpdate(element, state.style()))
-        return;
-
-    ActiveAnimations* activeAnimations = element->activeAnimations();
-    const CSSAnimationDataList* animations = state.style()->animations();
-    const CSSAnimations* cssAnimations = activeAnimations ? activeAnimations->cssAnimations() : 0;
-    state.setAnimationUpdate(CSSAnimations::calculateUpdate(element, state.style(), cssAnimations, animations, this));
-}
-
 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchResult& matchResult)
 {
     const Element* element = state.element();
@@ -1457,6 +1487,12 @@
     applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
     applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
 
+    // Match transition-property / animation-name length by trimming and
+    // lengthening other transition / animation property lists
+    // FIXME: This is wrong because we shouldn't affect the computed values
+    state.style()->adjustAnimations();
+    state.style()->adjustTransitions();
+
     // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
     // high-priority properties first, i.e., those properties that other properties depend on.
     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
@@ -1496,7 +1532,7 @@
     applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
 
     if (RuntimeEnabledFeatures::webAnimationsEnabled() && !applyInheritedOnly) {
-        calculateCSSAnimationUpdate(state);
+        state.setAnimationUpdate(CSSAnimations::calculateUpdate(state.element(), state.style(), this));
         // Apply animated properties, then reapply any rules marked important.
         if (applyAnimatedProperties<HighPriorityProperties>(state, element->document().timeline())) {
             bool important = true;
@@ -1559,11 +1595,6 @@
     }
 }
 
-void StyleResolver::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)
-{
-    m_viewportDependentMediaQueryResults.append(adoptPtr(new MediaQueryResult(*expr, result)));
-}
-
 bool StyleResolver::affectedByViewportChange() const
 {
     unsigned s = m_viewportDependentMediaQueryResults.size();
diff --git a/Source/core/css/resolver/StyleResolver.h b/Source/core/css/resolver/StyleResolver.h
index 16cf401..d24ad25 100644
--- a/Source/core/css/resolver/StyleResolver.h
+++ b/Source/core/css/resolver/StyleResolver.h
@@ -58,7 +58,6 @@
 class KeyframeList;
 class KeyframeValue;
 class MediaQueryEvaluator;
-class MediaQueryExp;
 class MediaQueryResult;
 class RenderRegion;
 class RuleData;
@@ -173,7 +172,7 @@
 };
 
 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
-class StyleResolver {
+class StyleResolver : public FontSelectorClient {
     WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
 public:
     StyleResolver(Document&, bool matchAuthorAndUserStyles);
@@ -192,10 +191,7 @@
         RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0);
 
     // FIXME: The following logic related to animations and keyframes should be factored out of StyleResolver
-    // The body of calculateCSSAnimationUpdate can move to CSSAnimations.cpp and take just const element, const style,
-    // and const ScopedStyleTree
-    void calculateCSSAnimationUpdate(StyleResolverState&);
-    void resolveKeyframes(const Element*, const RenderStyle*, const AtomicString& animationName, TimingFunction* defaultTimingFunction, KeyframeAnimationEffect::KeyframeVector&, RefPtr<TimingFunction>&);
+    void resolveKeyframes(Element*, const RenderStyle*, const AtomicString& animationName, TimingFunction* defaultTimingFunction, Vector<std::pair<KeyframeAnimationEffect::KeyframeVector, RefPtr<TimingFunction> > >&);
     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
     const StyleRuleKeyframes* matchScopedKeyframesRule(const Element*, const StringImpl* animationName);
     PassRefPtr<RenderStyle> styleForKeyframe(Element*, const RenderStyle*, const StyleKeyframe*);
@@ -231,9 +227,6 @@
         return m_styleTree.ensureScopedStyleResolver(scope ? *scope : document());
     }
 
-    // FIXME: Used by SharingStyleFinder, but should be removed.
-    bool styleSharingCandidateMatchesRuleSet(const ElementResolveContext&, RenderStyle*, RuleSet*);
-
     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
     enum CSSRuleFilter {
         UAAndUserCSSRules   = 1 << 1,
@@ -252,8 +245,8 @@
     CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
     ViewportStyleResolver* viewportStyleResolver() { return m_viewportStyleResolver.get(); }
 
-    // FIXME: This logic belongs in MediaQueryEvaluator.
-    void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
+    typedef Vector<OwnPtr<MediaQueryResult> > MediaQueryResultList;
+    MediaQueryResultList* viewportDependentMediaQueryResults() { return &m_viewportDependentMediaQueryResults; }
     bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); }
     bool affectedByViewportChange() const;
 
@@ -269,12 +262,6 @@
     // FIXME: StyleResolver should not have this member or method.
     InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
 
-    enum ViewportOrigin { UserAgentOrigin, AuthorOrigin };
-
-    // Exposed for ScopedStyleResolver.
-    // FIXME: Likely belongs on viewportStyleResolver.
-    void collectViewportRules(RuleSet*, ViewportOrigin);
-
     const RuleFeatureSet& ruleFeatureSet() const { return m_features; }
 
     StyleSharingList& styleSharingList() { return m_styleSharingList; }
@@ -287,16 +274,20 @@
 #ifdef STYLE_STATS
     ALWAYS_INLINE static StyleSharingStats& styleSharingStats() { return m_styleSharingStats; }
 #endif
+
+private:
+    // FontSelectorClient implementation.
+    virtual void fontsNeedUpdate(FontSelector*);
+
 private:
     // FIXME: This should probably go away, folded into FontBuilder.
     void updateFont(StyleResolverState&);
 
     void matchUARules(ElementRuleCollector&, RuleSet*);
     void matchAuthorRules(Element*, ElementRuleCollector&, bool includeEmptyRules);
-    void matchShadowDistributedRules(ElementRuleCollector&, bool includeEmptyRules);
-    void matchScopedAuthorRulesForShadowHost(Element*, ElementRuleCollector&, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree);
+    void collectShadowDistributedRules(ElementRuleCollector&, bool includeEmptyRules);
+    void matchAuthorRulesForShadowHost(Element*, ElementRuleCollector&, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree);
     void matchHostRules(Element*, ScopedStyleResolver*, ElementRuleCollector&, bool includeEmptyRules);
-    void matchScopedAuthorRules(Element*, ElementRuleCollector&, bool includeEmptyRules);
     void matchAllRules(StyleResolverState&, ElementRuleCollector&, bool matchAuthorAndUserStyles, bool includeSMILProperties);
     void matchUARules(ElementRuleCollector&);
     void matchUserRules(ElementRuleCollector&, bool includeEmptyRules);
@@ -343,6 +334,8 @@
     MatchedPropertiesCache m_matchedPropertiesCache;
 
     OwnPtr<MediaQueryEvaluator> m_medium;
+    MediaQueryResultList m_viewportDependentMediaQueryResults;
+
     RefPtr<RenderStyle> m_rootDefaultStyle;
 
     Document& m_document;
@@ -351,7 +344,6 @@
     bool m_matchAuthorAndUserStyles;
 
     RefPtr<CSSFontSelector> m_fontSelector;
-    Vector<OwnPtr<MediaQueryResult> > m_viewportDependentMediaQueryResults;
 
     RefPtr<ViewportStyleResolver> m_viewportStyleResolver;
 
diff --git a/Source/core/css/resolver/StyleResolverState.cpp b/Source/core/css/resolver/StyleResolverState.cpp
index b98a30c..7c76cca 100644
--- a/Source/core/css/resolver/StyleResolverState.cpp
+++ b/Source/core/css/resolver/StyleResolverState.cpp
@@ -30,44 +30,25 @@
 namespace WebCore {
 
 StyleResolverState::StyleResolverState(Document& document, Element* element, RenderStyle* parentStyle, RenderRegion* regionForStyling)
-    : m_elementContext(element ? ElementResolveContext(element) : ElementResolveContext())
-    , m_document(element ? m_elementContext.document() : document)
-    , m_regionForStyling(0)
+    : m_elementContext(element ? ElementResolveContext(*element) : ElementResolveContext())
+    , m_document(document)
+    , m_style(0)
+    , m_parentStyle(parentStyle)
+    , m_regionForStyling(regionForStyling)
     , m_applyPropertyToRegularStyle(true)
     , m_applyPropertyToVisitedLinkStyle(false)
     , m_lineHeightValue(0)
     , m_styleMap(*this, m_elementStyleResources)
+    , m_currentRule(0)
 {
-    m_regionForStyling = regionForStyling;
-
     if (m_elementContext.resetStyleInheritance())
         m_parentStyle = 0;
-    else if (parentStyle)
-        m_parentStyle = parentStyle;
-    else if (m_elementContext.parentNode())
+    else if (!parentStyle && m_elementContext.parentNode())
         m_parentStyle = m_elementContext.parentNode()->renderStyle();
-    else
-        m_parentStyle = 0;
 
-    m_style = 0;
-    m_elementStyleResources.clear();
-    m_fontBuilder.clear();
-
-    // FIXME: StyleResolverState is never passed between documents
-    // so we should be able to do this initialization at StyleResolverState
-    // createion time instead of now, correct?
+    // FIXME: How can we not have a page here?
     if (Page* page = document.page())
         m_elementStyleResources.setDeviceScaleFactor(page->deviceScaleFactor());
 }
 
-StyleResolverState::~StyleResolverState()
-{
-    m_elementContext = ElementResolveContext();
-    m_style = 0;
-    m_parentStyle = 0;
-    m_regionForStyling = 0;
-    m_elementStyleResources.clear();
-    m_fontBuilder.clear();
-}
-
 } // namespace WebCore
diff --git a/Source/core/css/resolver/StyleResolverState.h b/Source/core/css/resolver/StyleResolverState.h
index 6bf00dc..b97071d 100644
--- a/Source/core/css/resolver/StyleResolverState.h
+++ b/Source/core/css/resolver/StyleResolverState.h
@@ -39,12 +39,12 @@
 
 class FontDescription;
 class RenderRegion;
+class StyleRule;
 
 class StyleResolverState {
 WTF_MAKE_NONCOPYABLE(StyleResolverState);
 public:
     StyleResolverState(Document&, Element*, RenderStyle* parentStyle = 0, RenderRegion* regionForStyling = 0);
-    ~StyleResolverState();
 
     // In FontFaceSet and CanvasRenderingContext2D, we don't have an element to grab the document from.
     // This is why we have to store the document separately.
@@ -73,6 +73,9 @@
 
     const RenderRegion* regionForStyling() const { return m_regionForStyling; }
 
+    void setCurrentRule(StyleRule* currentRule) { m_currentRule = currentRule; }
+    const StyleRule* currentRule() const { return m_currentRule; }
+
     // FIXME: These are effectively side-channel "out parameters" for the various
     // map functions. When we map from CSS to style objects we use this state object
     // to track various meta-data about that mapping (e.g. if it's cache-able).
@@ -162,6 +165,8 @@
     // a back-pointer to this object.
     CSSToStyleMap m_styleMap;
     Vector<AtomicString> m_contentAttrValues;
+
+    StyleRule* m_currentRule;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/resolver/StyleResourceLoader.cpp b/Source/core/css/resolver/StyleResourceLoader.cpp
index 3158763..ca5de33 100644
--- a/Source/core/css/resolver/StyleResourceLoader.cpp
+++ b/Source/core/css/resolver/StyleResourceLoader.cpp
@@ -251,9 +251,6 @@
 
     // Start loading the SVG Documents referenced by this style.
     loadPendingSVGDocuments(renderStyle, elementStyleResources);
-
-    // FIXME: Investigate if this clearing is necessary.
-    elementStyleResources.clear();
 }
 
 }
diff --git a/Source/core/css/resolver/TransformBuilder.cpp b/Source/core/css/resolver/TransformBuilder.cpp
index f13e02d..d65b7ed 100644
--- a/Source/core/css/resolver/TransformBuilder.cpp
+++ b/Source/core/css/resolver/TransformBuilder.cpp
@@ -37,7 +37,7 @@
 #include "core/platform/graphics/transforms/RotateTransformOperation.h"
 #include "core/platform/graphics/transforms/ScaleTransformOperation.h"
 #include "core/platform/graphics/transforms/SkewTransformOperation.h"
-#include "core/platform/graphics/transforms/TransformationMatrix.h"
+#include "platform/transforms/TransformationMatrix.h"
 #include "core/platform/graphics/transforms/TranslateTransformOperation.h"
 #include "core/rendering/style/RenderStyle.h"
 
@@ -97,10 +97,10 @@
     for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
         CSSValue* currValue = i.value();
 
-        if (!currValue->isCSSTransformValue())
+        if (!currValue->isTransformValue())
             continue;
 
-        CSSTransformValue* transformValue = static_cast<CSSTransformValue*>(i.value());
+        CSSTransformValue* transformValue = toCSSTransformValue(i.value());
         if (!transformValue->length())
             continue;
 
diff --git a/Source/core/css/resolver/ViewportStyleResolver.cpp b/Source/core/css/resolver/ViewportStyleResolver.cpp
index f38f7d7..21e30fe 100644
--- a/Source/core/css/resolver/ViewportStyleResolver.cpp
+++ b/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -35,7 +35,7 @@
 #include "core/css/StyleRule.h"
 #include "core/dom/Document.h"
 #include "core/dom/NodeRenderStyle.h"
-#include "core/dom/ViewportArguments.h"
+#include "core/dom/ViewportDescription.h"
 
 namespace WebCore {
 
@@ -50,7 +50,16 @@
 {
 }
 
-void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule)
+void ViewportStyleResolver::collectViewportRules(RuleSet* rules, Origin origin)
+{
+    rules->compactRulesIfNeeded();
+
+    const Vector<StyleRuleViewport*>& viewportRules = rules->viewportRules();
+    for (size_t i = 0; i < viewportRules.size(); ++i)
+        addViewportRule(viewportRules[i], origin);
+}
+
+void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule, Origin origin)
 {
     StylePropertySet* propertySet = viewportRule->mutableProperties();
 
@@ -58,6 +67,9 @@
     if (!propertyCount)
         return;
 
+    if (origin == AuthorOrigin)
+        m_hasAuthorStyle = true;
+
     if (!m_propertySet) {
         m_propertySet = propertySet->mutableCopy();
         return;
@@ -82,23 +94,23 @@
     if (!m_propertySet || (!m_hasAuthorStyle && m_document->hasLegacyViewportTag())) {
         ASSERT(!m_hasAuthorStyle);
         m_propertySet = 0;
-        m_document->setViewportArguments(ViewportArguments());
+        m_document->setViewportDescription(ViewportDescription());
         return;
     }
 
-    ViewportArguments arguments(m_hasAuthorStyle ? ViewportArguments::AuthorStyleSheet : ViewportArguments::UserAgentStyleSheet);
+    ViewportDescription description(m_hasAuthorStyle ? ViewportDescription::AuthorStyleSheet : ViewportDescription::UserAgentStyleSheet);
 
-    arguments.userZoom = viewportArgumentValue(CSSPropertyUserZoom);
-    arguments.zoom = viewportArgumentValue(CSSPropertyZoom);
-    arguments.minZoom = viewportArgumentValue(CSSPropertyMinZoom);
-    arguments.maxZoom = viewportArgumentValue(CSSPropertyMaxZoom);
-    arguments.minWidth = viewportLengthValue(CSSPropertyMinWidth);
-    arguments.maxWidth = viewportLengthValue(CSSPropertyMaxWidth);
-    arguments.minHeight = viewportLengthValue(CSSPropertyMinHeight);
-    arguments.maxHeight = viewportLengthValue(CSSPropertyMaxHeight);
-    arguments.orientation = viewportArgumentValue(CSSPropertyOrientation);
+    description.userZoom = viewportArgumentValue(CSSPropertyUserZoom);
+    description.zoom = viewportArgumentValue(CSSPropertyZoom);
+    description.minZoom = viewportArgumentValue(CSSPropertyMinZoom);
+    description.maxZoom = viewportArgumentValue(CSSPropertyMaxZoom);
+    description.minWidth = viewportLengthValue(CSSPropertyMinWidth);
+    description.maxWidth = viewportLengthValue(CSSPropertyMaxWidth);
+    description.minHeight = viewportLengthValue(CSSPropertyMinHeight);
+    description.maxHeight = viewportLengthValue(CSSPropertyMaxHeight);
+    description.orientation = viewportArgumentValue(CSSPropertyOrientation);
 
-    m_document->setViewportArguments(arguments);
+    m_document->setViewportDescription(description);
 
     m_propertySet = 0;
     m_hasAuthorStyle = false;
@@ -106,7 +118,7 @@
 
 float ViewportStyleResolver::viewportArgumentValue(CSSPropertyID id) const
 {
-    float defaultValue = ViewportArguments::ValueAuto;
+    float defaultValue = ViewportDescription::ValueAuto;
 
     // UserZoom default value is CSSValueZoom, which maps to true, meaning that
     // yes, it is user scalable. When the value is set to CSSValueFixed, we
@@ -143,13 +155,13 @@
     case CSSValueAuto:
         return defaultValue;
     case CSSValueLandscape:
-        return ViewportArguments::ValueLandscape;
+        return ViewportDescription::ValueLandscape;
     case CSSValuePortrait:
-        return ViewportArguments::ValuePortrait;
+        return ViewportDescription::ValuePortrait;
     case CSSValueZoom:
         return defaultValue;
     case CSSValueInternalExtendToZoom:
-        return ViewportArguments::ValueExtendToZoom;
+        return ViewportDescription::ValueExtendToZoom;
     case CSSValueFixed:
         return 0;
     default:
diff --git a/Source/core/css/resolver/ViewportStyleResolver.h b/Source/core/css/resolver/ViewportStyleResolver.h
index b71128e..bb0a36f 100644
--- a/Source/core/css/resolver/ViewportStyleResolver.h
+++ b/Source/core/css/resolver/ViewportStyleResolver.h
@@ -31,6 +31,7 @@
 #define ViewportStyleResolver_h
 
 #include "CSSPropertyNames.h"
+#include "core/css/RuleSet.h"
 #include "core/platform/Length.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -50,8 +51,9 @@
 
     ~ViewportStyleResolver();
 
-    void setHasAuthorStyle() { m_hasAuthorStyle = true; }
-    void addViewportRule(StyleRuleViewport*);
+    enum Origin { UserAgentOrigin, AuthorOrigin };
+
+    void collectViewportRules(RuleSet*, Origin);
 
     void clearDocument();
     void resolve();
@@ -59,6 +61,8 @@
 private:
     explicit ViewportStyleResolver(Document*);
 
+    void addViewportRule(StyleRuleViewport*, Origin);
+
     float viewportArgumentValue(CSSPropertyID) const;
     Length viewportLengthValue(CSSPropertyID) const;