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;