diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/css | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz |
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/css')
130 files changed, 8863 insertions, 6031 deletions
diff --git a/Source/WebCore/css/CSSAllInOne.cpp b/Source/WebCore/css/CSSAllInOne.cpp index 0065a2690..71c92c477 100644 --- a/Source/WebCore/css/CSSAllInOne.cpp +++ b/Source/WebCore/css/CSSAllInOne.cpp @@ -33,7 +33,6 @@ #include "CSSComputedStyleDeclaration.cpp" #include "CSSCrossfadeValue.cpp" #include "CSSCursorImageValue.cpp" -#include "CSSFlexValue.cpp" #include "CSSFontFace.cpp" #include "CSSFontFaceRule.cpp" #include "CSSFontFaceSource.cpp" @@ -52,7 +51,6 @@ #include "CSSPageRule.cpp" #include "CSSParser.cpp" #include "CSSParserValues.cpp" -#include "CSSPropertyLonghand.cpp" #include "CSSPropertySourceData.cpp" #include "CSSReflectValue.cpp" #include "CSSRule.cpp" @@ -60,10 +58,8 @@ #include "CSSSegmentedFontFace.cpp" #include "CSSSelector.cpp" #include "CSSSelectorList.cpp" -#include "CSSStyleApplyProperty.cpp" #include "CSSStyleDeclaration.cpp" #include "CSSStyleRule.cpp" -#include "CSSStyleSelector.cpp" #include "CSSStyleSheet.cpp" #include "CSSTimingFunctionValue.cpp" #include "CSSUnicodeRangeValue.cpp" @@ -71,4 +67,7 @@ #include "CSSValueList.cpp" #include "CSSValuePool.cpp" #include "CSSWrapShapes.cpp" +#include "StyleBuilder.cpp" #include "StylePropertySet.cpp" +#include "StylePropertyShorthand.cpp" +#include "StyleResolver.cpp" diff --git a/Source/WebCore/css/CSSCalculationValue.cpp b/Source/WebCore/css/CSSCalculationValue.cpp index 7828c6542..618c39c12 100755 --- a/Source/WebCore/css/CSSCalculationValue.cpp +++ b/Source/WebCore/css/CSSCalculationValue.cpp @@ -31,9 +31,9 @@ #include "config.h" #include "CSSCalculationValue.h" -#include "CSSStyleSelector.h" #include "CSSValueList.h" #include "Length.h" +#include "StyleResolver.h" #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> @@ -123,7 +123,7 @@ public: return adoptPtr(new CalcExpressionNumber(m_value->computeLength<float>(style, rootStyle, zoom))); case CalcPercent: case CalcPercentLength: - return adoptPtr(new CalcExpressionLength(CSSStyleSelector::convertToFloatLength(m_value.get(), style, rootStyle, zoom))); + return adoptPtr(new CalcExpressionLength(StyleResolver::convertToFloatLength(m_value.get(), style, rootStyle, zoom))); // Only types that could be part of a Length expression can be converted // to a CalcExpressionNode. CalcPercentNumber makes no sense as a Length. case CalcPercentNumber: diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index 6c497f6ba..3ffb7ff5c 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -54,10 +54,11 @@ #include "Pair.h" #include "Rect.h" #include "RenderBox.h" -#include "RenderLayer.h" #include "RenderStyle.h" +#include "RenderView.h" #include "ShadowValue.h" #include "StylePropertySet.h" +#include "StylePropertyShorthand.h" #if ENABLE(CSS_FILTERS) #include "StyleCustomFilterProgram.h" #include "WebKitCSSFilterValue.h" @@ -72,7 +73,7 @@ namespace WebCore { // List of all properties we know how to compute, omitting shorthands. -static const int computedProperties[] = { +static const CSSPropertyID computedProperties[] = { CSSPropertyBackgroundAttachment, CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, @@ -219,12 +220,17 @@ static const int computedProperties[] = { #if ENABLE(DASHBOARD_SUPPORT) CSSPropertyWebkitDashboardRegion, #endif +#if ENABLE(CSS_FILTERS) + CSSPropertyWebkitFilter, +#endif + CSSPropertyWebkitFlex, CSSPropertyWebkitFlexOrder, CSSPropertyWebkitFlexPack, CSSPropertyWebkitFlexAlign, CSSPropertyWebkitFlexItemAlign, CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexFlow, + CSSPropertyWebkitFlexLinePack, CSSPropertyWebkitFlexWrap, CSSPropertyWebkitFontKerning, CSSPropertyWebkitFontSmoothing, @@ -277,6 +283,8 @@ static const int computedProperties[] = { CSSPropertyWebkitPerspectiveOrigin, CSSPropertyWebkitPrintColorAdjust, CSSPropertyWebkitRtlOrdering, + CSSPropertyWebkitShapeInside, + CSSPropertyWebkitShapeOutside, #if ENABLE(TOUCH_EVENTS) CSSPropertyWebkitTapHighlightColor, #endif @@ -369,7 +377,7 @@ static int valueForRepeatRule(int rule) } } -static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image, CSSValuePool* cssValuePool) +static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image) { // Create the slices. RefPtr<CSSPrimitiveValue> top; @@ -378,9 +386,9 @@ static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const Ni RefPtr<CSSPrimitiveValue> left; if (image.imageSlices().top().isPercent()) - top = cssValuePool->createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - top = cssValuePool->createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER); + top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_NUMBER); if (image.imageSlices().right() == image.imageSlices().top() && image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().left() == image.imageSlices().top()) { @@ -389,26 +397,26 @@ static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const Ni left = top; } else { if (image.imageSlices().right().isPercent()) - right = cssValuePool->createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - right = cssValuePool->createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER); + right = cssValuePool().createValue(image.imageSlices().right().value(), CSSPrimitiveValue::CSS_NUMBER); if (image.imageSlices().bottom() == image.imageSlices().top() && image.imageSlices().right() == image.imageSlices().left()) { bottom = top; left = right; } else { if (image.imageSlices().bottom().isPercent()) - bottom = cssValuePool->createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - bottom = cssValuePool->createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER); + bottom = cssValuePool().createValue(image.imageSlices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER); if (image.imageSlices().left() == image.imageSlices().right()) left = right; else { if (image.imageSlices().left().isPercent()) - left = cssValuePool->createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - left = cssValuePool->createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER); + left = cssValuePool().createValue(image.imageSlices().left().value(), CSSPrimitiveValue::CSS_NUMBER); } } } @@ -419,10 +427,10 @@ static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const Ni quad->setBottom(bottom); quad->setLeft(left); - return CSSBorderImageSliceValue::create(cssValuePool->createValue(quad.release()), image.fill()); + return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill()); } -static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box) { // Create the slices. RefPtr<CSSPrimitiveValue> top; @@ -431,9 +439,9 @@ static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& RefPtr<CSSPrimitiveValue> left; if (box.top().isRelative()) - top = cssValuePool->createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER); + top = cssValuePool().createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER); else - top = cssValuePool->createValue(box.top()); + top = cssValuePool().createValue(box.top()); if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) { right = top; @@ -441,26 +449,26 @@ static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& left = top; } else { if (box.right().isRelative()) - right = cssValuePool->createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER); + right = cssValuePool().createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER); else - right = cssValuePool->createValue(box.right()); + right = cssValuePool().createValue(box.right()); if (box.bottom() == box.top() && box.right() == box.left()) { bottom = top; left = right; } else { if (box.bottom().isRelative()) - bottom = cssValuePool->createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER); + bottom = cssValuePool().createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER); else - bottom = cssValuePool->createValue(box.bottom()); + bottom = cssValuePool().createValue(box.bottom()); if (box.left() == box.right()) left = right; else { if (box.left().isRelative()) - left = cssValuePool->createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER); + left = cssValuePool().createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER); else - left = cssValuePool->createValue(box.left()); + left = cssValuePool().createValue(box.left()); } } } @@ -471,26 +479,26 @@ static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& quad->setBottom(bottom); quad->setLeft(left); - return cssValuePool->createValue(quad.release()); + return cssValuePool().createValue(quad.release()); } -static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image) { RefPtr<CSSPrimitiveValue> horizontalRepeat; RefPtr<CSSPrimitiveValue> verticalRepeat; - horizontalRepeat = cssValuePool->createIdentifierValue(valueForRepeatRule(image.horizontalRule())); + horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule())); if (image.horizontalRule() == image.verticalRule()) verticalRepeat = horizontalRepeat; else - verticalRepeat = cssValuePool->createIdentifierValue(valueForRepeatRule(image.verticalRule())); - return cssValuePool->createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release())); + verticalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.verticalRule())); + return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release())); } -static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) { if (!image.hasImage()) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); // Image first. RefPtr<CSSValue> imageValue; @@ -498,52 +506,52 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, imageValue = image.image()->cssValue(); // Create the image slice. - RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image, cssValuePool); + RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image); // Create the border area slices. - RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), cssValuePool); + RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices()); // Create the border outset. - RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), cssValuePool); + RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset()); // Create the repeat rules. - RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image, cssValuePool); + RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image); return createBorderImageValue(imageValue, imageSlices, borderSlices, outset, repeat); } -inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style, CSSValuePool* cssValuePool) +inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle* style) { - return cssValuePool->createValue(adjustForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); + return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); } -inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style, CSSValuePool* cssValuePool) +inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style) { - return cssValuePool->createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); } -static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style) { if (length.isFixed()) - return zoomAdjustedPixelValue(length.value(), style, cssValuePool); - return cssValuePool->createValue(length); + return zoomAdjustedPixelValue(length.value(), style); + return cssValuePool().createValue(length); } -static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style) { if (!reflection) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); RefPtr<CSSPrimitiveValue> offset; if (reflection->offset().isPercent()) - offset = cssValuePool->createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); else - offset = zoomAdjustedPixelValue(reflection->offset().value(), style, cssValuePool); + offset = zoomAdjustedPixelValue(reflection->offset().value(), style); - return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask(), cssValuePool)); + return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask())); } -static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, CSSPropertyID propertyID, RenderView* renderView) { if (!style) return 0; @@ -568,53 +576,54 @@ static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int prope if (style->position() == AbsolutePosition || style->position() == FixedPosition) { if (l.type() == WebCore::Fixed) - return zoomAdjustedPixelValue(l.value(), style, cssValuePool); - return cssValuePool->createValue(l); + return zoomAdjustedPixelValue(l.value(), style); + else if (l.isViewportPercentage()) + return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style); + return cssValuePool().createValue(l); } if (style->position() == RelativePosition) // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined. // In other words if left is auto and right is not auto, then left's computed value is negative right(). // So we should get the opposite length unit and see if it is auto. - return cssValuePool->createValue(l); + return cssValuePool().createValue(l); - return cssValuePool->createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueAuto); } PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const { // This function does NOT look at visited information, so that computed style doesn't expose that. - CSSValuePool* cssValuePool = m_node->document()->cssValuePool().get(); if (!color.isValid()) - return cssValuePool->createColorValue(style->color().rgb()); - return cssValuePool->createColorValue(color.rgb()); + return cssValuePool().createColorValue(style->color().rgb()); + return cssValuePool().createColorValue(color.rgb()); } -static PassRefPtr<CSSValueList> getBorderRadiusCornerValues(LengthSize radius, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValueList> getBorderRadiusCornerValues(LengthSize radius, const RenderStyle* style, RenderView* renderView) { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (radius.width().type() == Percent) - list->append(cssValuePool->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); + list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); else - list->append(zoomAdjustedPixelValue(radius.width().value(), style, cssValuePool)); + list->append(zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style)); if (radius.height().type() == Percent) - list->append(cssValuePool->createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); + list->append(cssValuePool().createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); else - list->append(zoomAdjustedPixelValue(radius.height().value(), style, cssValuePool)); + list->append(zoomAdjustedPixelValue(valueForLength(radius.height(), 0, renderView), style)); return list.release(); } -static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, RenderView* renderView) { if (radius.width() == radius.height()) { if (radius.width().type() == Percent) - return cssValuePool->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); - return zoomAdjustedPixelValue(radius.width().value(), style, cssValuePool); + return cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + return zoomAdjustedPixelValue(valueForLength(radius.width(), 0, renderView), style); } - return getBorderRadiusCornerValues(radius, style, cssValuePool); + return getBorderRadiusCornerValues(radius, style, renderView); } -static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* style, RenderView* renderView) { RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated(); bool showHorizontalBottomLeft = style->borderTopRightRadius().width() != style->borderBottomLeftRadius().width(); @@ -626,10 +635,10 @@ static PassRefPtr<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle* bool showVerticalTopRight = (style->borderTopRightRadius().height() != style->borderTopLeftRadius().height()) || showVerticalBottomRight; bool showVerticalTopLeft = (style->borderTopLeftRadius().width() != style->borderTopLeftRadius().height()); - RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, cssValuePool); - RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, cssValuePool); - RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, cssValuePool); - RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, cssValuePool); + RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style->borderTopLeftRadius(), style, renderView); + RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style->borderTopRightRadius(), style, renderView); + RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style->borderBottomRightRadius(), style, renderView); + RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style->borderBottomLeftRadius(), style, renderView); RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated(); horizontalRadii->append(topLeftRadius->item(0)); @@ -662,18 +671,13 @@ static LayoutRect sizingBox(RenderObject* renderer) return LayoutRect(); RenderBox* box = toRenderBox(renderer); - return box->style()->boxSizing() == CONTENT_BOX ? box->contentBoxRect() : box->borderBoxRect(); -} - -static inline bool hasCompositedLayer(RenderObject* renderer) -{ - return renderer && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->isComposited(); + return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect(); } -static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style) { if (!renderer || style->transform().operations().isEmpty()) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); LayoutRect box = sizingBox(renderer); @@ -687,34 +691,34 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend if (transform.isAffine()) { transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation); - transformVal->append(cssValuePool->createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(zoomAdjustedNumberValue(transform.e(), style, cssValuePool)); - transformVal->append(zoomAdjustedNumberValue(transform.f(), style, cssValuePool)); + transformVal->append(cssValuePool().createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(zoomAdjustedNumberValue(transform.e(), style)); + transformVal->append(zoomAdjustedNumberValue(transform.f(), style)); } else { transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation); - transformVal->append(cssValuePool->createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); - - transformVal->append(cssValuePool->createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); - - transformVal->append(cssValuePool->createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(cssValuePool->createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); - - transformVal->append(zoomAdjustedNumberValue(transform.m41(), style, cssValuePool)); - transformVal->append(zoomAdjustedNumberValue(transform.m42(), style, cssValuePool)); - transformVal->append(zoomAdjustedNumberValue(transform.m43(), style, cssValuePool)); - transformVal->append(cssValuePool->createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); + + transformVal->append(cssValuePool().createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); + + transformVal->append(cssValuePool().createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(cssValuePool().createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); + + transformVal->append(zoomAdjustedNumberValue(transform.m41(), style)); + transformVal->append(zoomAdjustedNumberValue(transform.m42(), style)); + transformVal->append(zoomAdjustedNumberValue(transform.m43(), style)); + transformVal->append(cssValuePool().createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); } RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); @@ -727,9 +731,8 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter) const { RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated(); - CSSValuePool* cssValuePool = m_node->document()->cssValuePool().get(); for (unsigned i = 0; i < numberParameter->size(); ++i) - numberParameterValue->append(cssValuePool->createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER)); + numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER)); return numberParameterValue.release(); } @@ -750,10 +753,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForCustomFilterParameter( #if ENABLE(CSS_FILTERS) PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* style) const { - CSSValuePool* cssValuePool = m_node->document()->cssValuePool().get(); - if (style->filter().operations().isEmpty()) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); @@ -766,68 +767,68 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* st case FilterOperation::REFERENCE: { ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation); - filterValue->append(cssValuePool->createValue(referenceOperation->reference(), CSSPrimitiveValue::CSS_STRING)); + filterValue->append(cssValuePool().createValue(referenceOperation->reference(), CSSPrimitiveValue::CSS_STRING)); break; } case FilterOperation::GRAYSCALE: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::GrayscaleFilterOperation); - filterValue->append(cssValuePool->createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::SEPIA: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SepiaFilterOperation); - filterValue->append(cssValuePool->createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::SATURATE: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SaturateFilterOperation); - filterValue->append(cssValuePool->createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::HUE_ROTATE: { BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::HueRotateFilterOperation); - filterValue->append(cssValuePool->createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG)); + filterValue->append(cssValuePool().createValue(colorMatrixOperation->amount(), CSSPrimitiveValue::CSS_DEG)); break; } case FilterOperation::INVERT: { BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::InvertFilterOperation); - filterValue->append(cssValuePool->createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::OPACITY: { BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::OpacityFilterOperation); - filterValue->append(cssValuePool->createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(componentTransferOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::BRIGHTNESS: { BasicComponentTransferFilterOperation* brightnessOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BrightnessFilterOperation); - filterValue->append(cssValuePool->createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(brightnessOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::CONTRAST: { BasicComponentTransferFilterOperation* contrastOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ContrastFilterOperation); - filterValue->append(cssValuePool->createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); + filterValue->append(cssValuePool().createValue(contrastOperation->amount(), CSSPrimitiveValue::CSS_NUMBER)); break; } case FilterOperation::BLUR: { BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation); - filterValue->append(zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style, cssValuePool)); + filterValue->append(zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style)); break; } case FilterOperation::DROP_SHADOW: { DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation); filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::DropShadowFilterOperation); // We want our computed style to look like that of a text shadow (has neither spread nor inset style). - ShadowData shadowData = ShadowData(dropShadowOperation->x(), dropShadowOperation->y(), dropShadowOperation->stdDeviation(), 0, Normal, false, dropShadowOperation->color()); + ShadowData shadowData = ShadowData(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, false, dropShadowOperation->color()); filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style)); break; } @@ -845,22 +846,22 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* st if (program->vertexShader()) shadersList->append(program->vertexShader()->cssValue()); else - shadersList->append(cssValuePool->createIdentifierValue(CSSValueNone)); + shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone)); if (program->fragmentShader()) shadersList->append(program->fragmentShader()->cssValue()); else - shadersList->append(cssValuePool->createIdentifierValue(CSSValueNone)); + shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone)); filterValue->append(shadersList.release()); RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated(); - meshParameters->append(cssValuePool->createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER)); - meshParameters->append(cssValuePool->createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER)); - meshParameters->append(cssValuePool->createValue(customOperation->meshBoxType())); + meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER)); + meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER)); + meshParameters->append(cssValuePool().createValue(customOperation->meshBoxType())); // FIXME: The specification doesn't have any "attached" identifier. Should we add one? // https://bugs.webkit.org/show_bug.cgi?id=72700 if (customOperation->meshType() == CustomFilterOperation::DETACHED) - meshParameters->append(cssValuePool->createIdentifierValue(CSSValueDetached)); + meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached)); filterValue->append(meshParameters.release()); @@ -872,7 +873,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* st for (size_t i = 0; i < parametersSize; ++i) { const CustomFilterParameter* parameter = parameters.at(i).get(); RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated(); - parameterCSSNameAndValue->append(cssValuePool->createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING)); + parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING)); parameterCSSNameAndValue->append(valueForCustomFilterParameter(parameter)); parametersCSSValue->append(parameterCSSNameAndValue.release()); } @@ -893,62 +894,62 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(RenderStyle* st #endif #if ENABLE(CSS_GRID_LAYOUT) -static PassRefPtr<CSSValue> valueForGridTrackBreadth(const Length& trackLength, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> valueForGridTrackBreadth(const Length& trackLength, const RenderStyle* style) { if (trackLength.isPercent()) - return cssValuePool->createValue(trackLength); + return cssValuePool().createValue(trackLength); if (trackLength.isAuto()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(trackLength.value(), style, cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(trackLength.value(), style); } -static PassRefPtr<CSSValue> valueForGridTrackList(const Vector<Length>& trackLengths, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> valueForGridTrackList(const Vector<Length>& trackLengths, const RenderStyle* style) { // We should have at least an element! ASSERT(trackLengths.size()); // Handle the 'none' case here. if (trackLengths.size() == 1 && trackLengths[0].isUndefined()) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); for (size_t i = 0; i < trackLengths.size(); ++i) - list->append(valueForGridTrackBreadth(trackLengths[i], style, cssValuePool)); + list->append(valueForGridTrackBreadth(trackLengths[i], style)); return list.release(); } -static PassRefPtr<CSSValue> valueForGridPosition(const Length& position, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> valueForGridPosition(const Length& position) { if (position.isAuto()) - return cssValuePool->createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueAuto); ASSERT(position.isFixed()); - return cssValuePool->createValue(position.value(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(position.value(), CSSPrimitiveValue::CSS_NUMBER); } #endif -static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); if (animList) { for (size_t i = 0; i < animList->size(); ++i) - list->append(cssValuePool->createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S)); + list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S)); } else { // Note that initialAnimationDelay() is used for both transitions and animations - list->append(cssValuePool->createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); + list->append(cssValuePool().createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); } return list.release(); } -static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); if (animList) { for (size_t i = 0; i < animList->size(); ++i) - list->append(cssValuePool->createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S)); + list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S)); } else { // Note that initialAnimationDuration() is used for both transitions and animations - list->append(cssValuePool->createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); + list->append(cssValuePool().createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); } return list.release(); } @@ -985,10 +986,10 @@ static PassRefPtr<CSSValue> getTimingFunctionValue(const AnimationList* animList return list.release(); } -static PassRefPtr<CSSValue> createLineBoxContainValue(CSSValuePool* cssValuePool, unsigned lineBoxContain) +static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain) { if (!lineBoxContain) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); return CSSLineBoxContainValue::create(lineBoxContain); } @@ -1025,7 +1026,7 @@ String CSSComputedStyleDeclaration::cssText() const for (unsigned i = 0; i < numComputedProperties; i++) { if (i) result += " "; - result += getPropertyName(static_cast<CSSPropertyID>(computedProperties[i])); + result += getPropertyName(computedProperties[i]); result += ": "; result += getPropertyValue(computedProperties[i]); result += ";"; @@ -1057,13 +1058,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringK if (!style) return 0; - CSSValuePool* cssValuePool = m_node->document()->cssValuePool().get(); - if (int keywordSize = style->fontDescription().keywordSize()) - return cssValuePool->createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize)); + return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize)); - return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get()); } bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const @@ -1078,28 +1077,25 @@ bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const return style->fontDescription().useFixedDefaultSize(); } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, int id, RenderStyle* style) const +PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, RenderStyle* style) const { - CSSValuePool* cssValuePool = m_node->document()->cssValuePool().get(); if (!shadow) - return cssValuePool->createIdentifierValue(CSSValueNone); - - CSSPropertyID propertyID = static_cast<CSSPropertyID>(id); + return cssValuePool().createIdentifierValue(CSSValueNone); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const ShadowData* s = shadow; s; s = s->next()) { - RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style, cssValuePool); - RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style, cssValuePool); - RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style, cssValuePool); - RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style, cssValuePool); - RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool->createIdentifierValue(CSSValueInset); - RefPtr<CSSPrimitiveValue> color = cssValuePool->createColorValue(s->color().rgb()); + RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style); + RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style); + RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style); + 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())); } return list.release(); } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID) const +PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const { return getPropertyCSSValue(propertyID, UpdateLayout); } @@ -1121,31 +1117,31 @@ static int identifierForFamily(const AtomicString& family) return 0; } -static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family) { if (int familyIdentifier = identifierForFamily(family)) - return cssValuePool->createIdentifierValue(familyIdentifier); - return cssValuePool->createValue(family.string(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(familyIdentifier); + return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING); } -static PassRefPtr<CSSValue> renderUnicodeBidiFlagsToCSSValue(EUnicodeBidi unicodeBidi, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> renderUnicodeBidiFlagsToCSSValue(EUnicodeBidi unicodeBidi) { switch (unicodeBidi) { case UBNormal: - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueNormal); case Embed: - return cssValuePool->createIdentifierValue(CSSValueEmbed); + return cssValuePool().createIdentifierValue(CSSValueEmbed); case Plaintext: - return cssValuePool->createIdentifierValue(CSSValueWebkitPlaintext); + return cssValuePool().createIdentifierValue(CSSValueWebkitPlaintext); case Override: - return cssValuePool->createIdentifierValue(CSSValueBidiOverride); + return cssValuePool().createIdentifierValue(CSSValueBidiOverride); case Isolate: - return cssValuePool->createIdentifierValue(CSSValueWebkitIsolate); + return cssValuePool().createIdentifierValue(CSSValueWebkitIsolate); case OverrideIsolate: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(cssValuePool->createIdentifierValue(CSSValueBidiOverride)); - list->append(cssValuePool->createIdentifierValue(CSSValueWebkitIsolate)); + list->append(cssValuePool().createIdentifierValue(CSSValueBidiOverride)); + list->append(cssValuePool().createIdentifierValue(CSSValueWebkitIsolate)); return list; } } @@ -1153,78 +1149,78 @@ static PassRefPtr<CSSValue> renderUnicodeBidiFlagsToCSSValue(EUnicodeBidi unicod return 0; } -static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration) { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (textDecoration & UNDERLINE) - list->append(cssValuePool->createIdentifierValue(CSSValueUnderline)); + list->append(cssValuePool().createIdentifierValue(CSSValueUnderline)); if (textDecoration & OVERLINE) - list->append(cssValuePool->createIdentifierValue(CSSValueOverline)); + list->append(cssValuePool().createIdentifierValue(CSSValueOverline)); if (textDecoration & LINE_THROUGH) - list->append(cssValuePool->createIdentifierValue(CSSValueLineThrough)); + list->append(cssValuePool().createIdentifierValue(CSSValueLineThrough)); if (textDecoration & BLINK) - list->append(cssValuePool->createIdentifierValue(CSSValueBlink)); + list->append(cssValuePool().createIdentifierValue(CSSValueBlink)); if (!list->length()) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); return list; } -static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat) { // For backwards compatibility, if both values are equal, just return one of them. And // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand. if (xRepeat == yRepeat) - return cssValuePool->createValue(xRepeat); + return cssValuePool().createValue(xRepeat); if (xRepeat == RepeatFill && yRepeat == NoRepeatFill) - return cssValuePool->createIdentifierValue(CSSValueRepeatX); + return cssValuePool().createIdentifierValue(CSSValueRepeatX); if (xRepeat == NoRepeatFill && yRepeat == RepeatFill) - return cssValuePool->createIdentifierValue(CSSValueRepeatY); + return cssValuePool().createIdentifierValue(CSSValueRepeatY); RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(cssValuePool->createValue(xRepeat)); - list->append(cssValuePool->createValue(yRepeat)); + list->append(cssValuePool().createValue(xRepeat)); + list->append(cssValuePool().createValue(yRepeat)); return list.release(); } -static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle* style) { if (fillSize.type == Contain) - return cssValuePool->createIdentifierValue(CSSValueContain); + return cssValuePool().createIdentifierValue(CSSValueContain); if (fillSize.type == Cover) - return cssValuePool->createIdentifierValue(CSSValueCover); + return cssValuePool().createIdentifierValue(CSSValueCover); if (fillSize.size.height().isAuto()) - return zoomAdjustedPixelValueForLength(fillSize.size.width(), style, cssValuePool); + return zoomAdjustedPixelValueForLength(fillSize.size.width(), style); RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style, cssValuePool)); - list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style, cssValuePool)); + list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style)); + list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style)); return list.release(); } -static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style) { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) { if (contentData->isCounter()) { const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter(); ASSERT(counter); - list->append(cssValuePool->createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); + list->append(cssValuePool().createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); } else if (contentData->isImage()) { const StyleImage* image = static_cast<const ImageContentData*>(contentData)->image(); ASSERT(image); list->append(image->cssValue()); } else if (contentData->isText()) - list->append(cssValuePool->createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING)); + list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING)); } if (!style->regionThread().isNull()) - list->append(cssValuePool->createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING)); + list->append(cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING)); return list.release(); } -static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, int propertyID, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID) { const CounterDirectiveMap* map = style->counterDirectives(); if (!map) @@ -1232,91 +1228,91 @@ static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, int prop RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) { - list->append(cssValuePool->createValue(it->first.get(), CSSPrimitiveValue::CSS_STRING)); + list->append(cssValuePool().createValue(it->first.get(), CSSPrimitiveValue::CSS_STRING)); short number = propertyID == CSSPropertyCounterIncrement ? it->second.m_incrementValue : it->second.m_resetValue; - list->append(cssValuePool->createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); } return list.release(); } -static void logUnimplementedPropertyID(int propertyID) +static void logUnimplementedPropertyID(CSSPropertyID propertyID) { - DEFINE_STATIC_LOCAL(HashSet<int>, propertyIDSet, ()); - if (!propertyIDSet.add(propertyID).second) + DEFINE_STATIC_LOCAL(HashSet<CSSPropertyID>, propertyIDSet, ()); + if (!propertyIDSet.add(propertyID).isNewEntry) return; - LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(static_cast<CSSPropertyID>(propertyID))); + LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID)); } -static PassRefPtr<CSSValueList> fontFamilyFromStyle(RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSValueList> fontFamilyFromStyle(RenderStyle* style) { const FontFamily& firstFamily = style->fontDescription().family(); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FontFamily* family = &firstFamily; family; family = family->next()) - list->append(valueForFamily(family->family(), cssValuePool)); + list->append(valueForFamily(family->family())); return list.release(); } -static PassRefPtr<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle* style, RenderView* renderView) { Length length = style->lineHeight(); if (length.isNegative()) - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueNormal); if (length.isPercent()) // This is imperfect, because it doesn't include the zoom factor and the real computation // for how high to be in pixels does include things like minimum font size and the zoom factor. // 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, cssValuePool); - return zoomAdjustedPixelValue(length.value(), style, cssValuePool); + return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style); + return zoomAdjustedPixelValue(valueForLength(length, 0, renderView), style); } -static PassRefPtr<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle* style) { - return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style, cssValuePool); + return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style); } -static PassRefPtr<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style) { if (style->fontDescription().italic()) - return cssValuePool->createIdentifierValue(CSSValueItalic); - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueItalic); + return cssValuePool().createIdentifierValue(CSSValueNormal); } -static PassRefPtr<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style) { if (style->fontDescription().smallCaps()) - return cssValuePool->createIdentifierValue(CSSValueSmallCaps); - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueSmallCaps); + return cssValuePool().createIdentifierValue(CSSValueNormal); } -static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style) { switch (style->fontDescription().weight()) { case FontWeight100: - return cssValuePool->createIdentifierValue(CSSValue100); + return cssValuePool().createIdentifierValue(CSSValue100); case FontWeight200: - return cssValuePool->createIdentifierValue(CSSValue200); + return cssValuePool().createIdentifierValue(CSSValue200); case FontWeight300: - return cssValuePool->createIdentifierValue(CSSValue300); + return cssValuePool().createIdentifierValue(CSSValue300); case FontWeightNormal: - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueNormal); case FontWeight500: - return cssValuePool->createIdentifierValue(CSSValue500); + return cssValuePool().createIdentifierValue(CSSValue500); case FontWeight600: - return cssValuePool->createIdentifierValue(CSSValue600); + return cssValuePool().createIdentifierValue(CSSValue600); case FontWeightBold: - return cssValuePool->createIdentifierValue(CSSValueBold); + return cssValuePool().createIdentifierValue(CSSValueBold); case FontWeight800: - return cssValuePool->createIdentifierValue(CSSValue800); + return cssValuePool().createIdentifierValue(CSSValue800); case FontWeight900: - return cssValuePool->createIdentifierValue(CSSValue900); + return cssValuePool().createIdentifierValue(CSSValue900); } ASSERT_NOT_REACHED(); - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueNormal); } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const +PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const { Node* node = m_node.get(); if (!node) @@ -1329,7 +1325,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper RenderObject* renderer = node->renderer(); RefPtr<RenderStyle> style; - if (renderer && hasCompositedLayer(renderer) && AnimationController::supportsAcceleratedAnimationOfProperty(static_cast<CSSPropertyID>(propertyID))) { + if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) { style = renderer->animation()->getAnimatedStyleForRenderer(renderer); if (m_pseudoElementSpecifier) { // FIXME: This cached pseudo style will only exist if the animation has been run at least once. @@ -1348,27 +1344,25 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper renderer = renderer->beforePseudoElementRenderer(); } - CSSValuePool* cssValuePool = node->document()->cssValuePool().get(); - propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode()); - switch (static_cast<CSSPropertyID>(propertyID)) { + switch (propertyID) { case CSSPropertyInvalid: break; case CSSPropertyBackgroundColor: - return cssValuePool->createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb()); + return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb()); case CSSPropertyBackgroundImage: case CSSPropertyWebkitMaskImage: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers(); if (!layers) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); if (!layers->next()) { if (layers->image()) return layers->image()->cssValue(); - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); } RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); @@ -1376,7 +1370,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper if (currLayer->image()) list->append(currLayer->image()->cssValue()); else - list->append(cssValuePool->createIdentifierValue(CSSValueNone)); + list->append(cssValuePool().createIdentifierValue(CSSValueNone)); } return list.release(); } @@ -1385,11 +1379,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskSize: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return fillSizeToCSSValue(layers->size(), style.get(), cssValuePool); + return fillSizeToCSSValue(layers->size(), style.get()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(fillSizeToCSSValue(currLayer->size(), style.get(), cssValuePool)); + list->append(fillSizeToCSSValue(currLayer->size(), style.get())); return list.release(); } @@ -1397,11 +1391,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskRepeat: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY(), cssValuePool); + return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY(), cssValuePool)); + list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY())); return list.release(); } @@ -1409,11 +1403,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskComposite: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return cssValuePool->createValue(layers->composite()); + return cssValuePool().createValue(layers->composite()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool->createValue(currLayer->composite())); + list->append(cssValuePool().createValue(currLayer->composite())); return list.release(); } @@ -1421,11 +1415,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskAttachment: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskAttachment ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return cssValuePool->createValue(layers->attachment()); + return cssValuePool().createValue(layers->attachment()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool->createValue(currLayer->attachment())); + list->append(cssValuePool().createValue(currLayer->attachment())); return list.release(); } @@ -1439,13 +1433,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip; if (!layers->next()) { EFillBox box = isClip ? layers->clip() : layers->origin(); - return cssValuePool->createValue(box); + return cssValuePool().createValue(box); } RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { EFillBox box = isClip ? currLayer->clip() : currLayer->origin(); - list->append(cssValuePool->createValue(box)); + list->append(cssValuePool().createValue(box)); } return list.release(); @@ -1455,16 +1449,16 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(zoomAdjustedPixelValueForLength(layers->xPosition(), style.get(), cssValuePool)); - list->append(zoomAdjustedPixelValueForLength(layers->yPosition(), style.get(), cssValuePool)); + list->append(zoomAdjustedPixelValueForLength(layers->xPosition(), style.get())); + list->append(zoomAdjustedPixelValueForLength(layers->yPosition(), style.get())); return list.release(); } RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated(); - positionList->append(zoomAdjustedPixelValueForLength(currLayer->xPosition(), style.get(), cssValuePool)); - positionList->append(zoomAdjustedPixelValueForLength(currLayer->yPosition(), style.get(), cssValuePool)); + positionList->append(zoomAdjustedPixelValueForLength(currLayer->xPosition(), style.get())); + positionList->append(zoomAdjustedPixelValueForLength(currLayer->yPosition(), style.get())); list->append(positionList); } @@ -1474,11 +1468,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskPositionX: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return cssValuePool->createValue(layers->xPosition()); + return cssValuePool().createValue(layers->xPosition()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool->createValue(currLayer->xPosition())); + list->append(cssValuePool().createValue(currLayer->xPosition())); return list.release(); } @@ -1486,123 +1480,123 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskPositionY: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return cssValuePool->createValue(layers->yPosition()); + return cssValuePool().createValue(layers->yPosition()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(cssValuePool->createValue(currLayer->yPosition())); + list->append(cssValuePool().createValue(currLayer->yPosition())); return list.release(); } case CSSPropertyBorderCollapse: if (style->borderCollapse()) - return cssValuePool->createIdentifierValue(CSSValueCollapse); - return cssValuePool->createIdentifierValue(CSSValueSeparate); + return cssValuePool().createIdentifierValue(CSSValueCollapse); + return cssValuePool().createIdentifierValue(CSSValueSeparate); case CSSPropertyBorderSpacing: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), cssValuePool)); - list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), cssValuePool)); + list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get())); + list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get())); return list.release(); } case CSSPropertyWebkitBorderHorizontalSpacing: - return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()); case CSSPropertyWebkitBorderVerticalSpacing: - return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()); case CSSPropertyBorderImageSource: if (style->borderImageSource()) return style->borderImageSource()->cssValue(); - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); case CSSPropertyBorderTopColor: - return m_allowVisitedStyle ? cssValuePool->createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor()); + return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor()); case CSSPropertyBorderRightColor: - return m_allowVisitedStyle ? cssValuePool->createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor()); + return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor()); case CSSPropertyBorderBottomColor: - return m_allowVisitedStyle ? cssValuePool->createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor()); + return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor()); case CSSPropertyBorderLeftColor: - return m_allowVisitedStyle ? cssValuePool->createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor()); + return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor()); case CSSPropertyBorderTopStyle: - return cssValuePool->createValue(style->borderTopStyle()); + return cssValuePool().createValue(style->borderTopStyle()); case CSSPropertyBorderRightStyle: - return cssValuePool->createValue(style->borderRightStyle()); + return cssValuePool().createValue(style->borderRightStyle()); case CSSPropertyBorderBottomStyle: - return cssValuePool->createValue(style->borderBottomStyle()); + return cssValuePool().createValue(style->borderBottomStyle()); case CSSPropertyBorderLeftStyle: - return cssValuePool->createValue(style->borderLeftStyle()); + return cssValuePool().createValue(style->borderLeftStyle()); case CSSPropertyBorderTopWidth: - return zoomAdjustedPixelValue(style->borderTopWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->borderTopWidth(), style.get()); case CSSPropertyBorderRightWidth: - return zoomAdjustedPixelValue(style->borderRightWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->borderRightWidth(), style.get()); case CSSPropertyBorderBottomWidth: - return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get()); case CSSPropertyBorderLeftWidth: - return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get()); case CSSPropertyBottom: - return getPositionOffsetValue(style.get(), CSSPropertyBottom, cssValuePool); + return getPositionOffsetValue(style.get(), CSSPropertyBottom, m_node->document()->renderView()); case CSSPropertyWebkitBoxAlign: - return cssValuePool->createValue(style->boxAlign()); + return cssValuePool().createValue(style->boxAlign()); case CSSPropertyWebkitBoxDirection: - return cssValuePool->createValue(style->boxDirection()); + return cssValuePool().createValue(style->boxDirection()); case CSSPropertyWebkitBoxFlex: - return cssValuePool->createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxFlexGroup: - return cssValuePool->createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxLines: - return cssValuePool->createValue(style->boxLines()); + return cssValuePool().createValue(style->boxLines()); case CSSPropertyWebkitBoxOrdinalGroup: - return cssValuePool->createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxOrient: - return cssValuePool->createValue(style->boxOrient()); + return cssValuePool().createValue(style->boxOrient()); case CSSPropertyWebkitBoxPack: - return cssValuePool->createValue(style->boxPack()); + return cssValuePool().createValue(style->boxPack()); case CSSPropertyWebkitBoxReflect: - return valueForReflection(style->boxReflect(), style.get(), cssValuePool); + return valueForReflection(style->boxReflect(), style.get()); case CSSPropertyBoxShadow: case CSSPropertyWebkitBoxShadow: return valueForShadow(style->boxShadow(), propertyID, style.get()); case CSSPropertyCaptionSide: - return cssValuePool->createValue(style->captionSide()); + return cssValuePool().createValue(style->captionSide()); case CSSPropertyClear: - return cssValuePool->createValue(style->clear()); + return cssValuePool().createValue(style->clear()); case CSSPropertyColor: - return cssValuePool->createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb()); + return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb()); case CSSPropertyWebkitPrintColorAdjust: - return cssValuePool->createValue(style->printColorAdjust()); + return cssValuePool().createValue(style->printColorAdjust()); case CSSPropertyWebkitColumnAxis: - return cssValuePool->createValue(style->columnAxis()); + return cssValuePool().createValue(style->columnAxis()); case CSSPropertyWebkitColumnCount: if (style->hasAutoColumnCount()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitColumnGap: if (style->hasNormalColumnGap()) - return cssValuePool->createIdentifierValue(CSSValueNormal); - return zoomAdjustedPixelValue(style->columnGap(), style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueNormal); + return zoomAdjustedPixelValue(style->columnGap(), style.get()); case CSSPropertyWebkitColumnRuleColor: - return m_allowVisitedStyle ? cssValuePool->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor()); + return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor()); case CSSPropertyWebkitColumnRuleStyle: - return cssValuePool->createValue(style->columnRuleStyle()); + return cssValuePool().createValue(style->columnRuleStyle()); case CSSPropertyWebkitColumnRuleWidth: - return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get()); case CSSPropertyWebkitColumnSpan: if (style->columnSpan()) - return cssValuePool->createIdentifierValue(CSSValueAll); - return cssValuePool->createValue(1, CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createIdentifierValue(CSSValueAll); + return cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitColumnBreakAfter: - return cssValuePool->createValue(style->columnBreakAfter()); + return cssValuePool().createValue(style->columnBreakAfter()); case CSSPropertyWebkitColumnBreakBefore: - return cssValuePool->createValue(style->columnBreakBefore()); + return cssValuePool().createValue(style->columnBreakBefore()); case CSSPropertyWebkitColumnBreakInside: - return cssValuePool->createValue(style->columnBreakInside()); + return cssValuePool().createValue(style->columnBreakInside()); case CSSPropertyWebkitColumnWidth: if (style->hasAutoColumnWidth()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(style->columnWidth(), style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(style->columnWidth(), style.get()); case CSSPropertyWebkitRegionBreakAfter: - return cssValuePool->createValue(style->regionBreakAfter()); + return cssValuePool().createValue(style->regionBreakAfter()); case CSSPropertyWebkitRegionBreakBefore: - return cssValuePool->createValue(style->regionBreakBefore()); + return cssValuePool().createValue(style->regionBreakBefore()); case CSSPropertyWebkitRegionBreakInside: - return cssValuePool->createValue(style->regionBreakInside()); + return cssValuePool().createValue(style->regionBreakInside()); case CSSPropertyCursor: { RefPtr<CSSValueList> list; CursorList* cursors = style->cursors(); @@ -1612,7 +1606,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper if (StyleImage* image = cursors->at(i).image()) list->append(image->cssValue()); } - RefPtr<CSSValue> value = cssValuePool->createValue(style->cursor()); + RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor()); if (list) { list->append(value); return list.release(); @@ -1620,45 +1614,65 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return value.release(); } case CSSPropertyDirection: - return cssValuePool->createValue(style->direction()); + return cssValuePool().createValue(style->direction()); case CSSPropertyDisplay: - return cssValuePool->createValue(style->display()); + return cssValuePool().createValue(style->display()); case CSSPropertyEmptyCells: - return cssValuePool->createValue(style->emptyCells()); + return cssValuePool().createValue(style->emptyCells()); + case CSSPropertyWebkitFlex: { + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + list->append(cssValuePool().createValue(style->positiveFlex())); + list->append(cssValuePool().createValue(style->negativeFlex())); + + Length preferredSize = style->flexPreferredSize(); + if (preferredSize.isAuto()) + list->append(cssValuePool().createIdentifierValue(CSSValueAuto)); + else if (preferredSize.isPercent()) + list->append(cssValuePool().createValue(preferredSize.value(), CSSPrimitiveValue::CSS_PERCENTAGE)); + else + list->append(cssValuePool().createValue(preferredSize.value(), CSSPrimitiveValue::CSS_PX)); + + return list.release(); + } case CSSPropertyWebkitFlexOrder: - return cssValuePool->createValue(style->flexOrder(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->flexOrder(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitFlexPack: - return cssValuePool->createValue(style->flexPack()); + return cssValuePool().createValue(style->flexPack()); case CSSPropertyWebkitFlexAlign: - return cssValuePool->createValue(style->flexAlign()); + return cssValuePool().createValue(style->flexAlign()); case CSSPropertyWebkitFlexItemAlign: - if (style->flexItemAlign() == AlignAuto && m_node && m_node->parentNode() && m_node->parentNode()->computedStyle()) - return cssValuePool->createValue(m_node->parentNode()->computedStyle()->flexAlign()); - return cssValuePool->createValue(style->flexItemAlign()); + if (style->flexItemAlign() == AlignAuto) { + if (m_node && m_node->parentNode() && m_node->parentNode()->computedStyle()) + return cssValuePool().createValue(m_node->parentNode()->computedStyle()->flexAlign()); + return cssValuePool().createValue(AlignStretch); + } + return cssValuePool().createValue(style->flexItemAlign()); case CSSPropertyWebkitFlexDirection: - return cssValuePool->createValue(style->flexDirection()); + return cssValuePool().createValue(style->flexDirection()); case CSSPropertyWebkitFlexWrap: - return cssValuePool->createValue(style->flexWrap()); + return cssValuePool().createValue(style->flexWrap()); + case CSSPropertyWebkitFlexLinePack: + return cssValuePool().createValue(style->flexLinePack()); case CSSPropertyWebkitFlexFlow: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(cssValuePool->createValue(style->flexDirection())); - list->append(cssValuePool->createValue(style->flexWrap())); + list->append(cssValuePool().createValue(style->flexDirection())); + list->append(cssValuePool().createValue(style->flexWrap())); return list.release(); } case CSSPropertyFloat: - return cssValuePool->createValue(style->floating()); + return cssValuePool().createValue(style->floating()); case CSSPropertyFont: { RefPtr<FontValue> computedFont = FontValue::create(); - computedFont->style = fontStyleFromStyle(style.get(), cssValuePool); - computedFont->variant = fontVariantFromStyle(style.get(), cssValuePool); - computedFont->weight = fontWeightFromStyle(style.get(), cssValuePool); - computedFont->size = fontSizeFromStyle(style.get(), cssValuePool); - computedFont->lineHeight = lineHeightFromStyle(style.get(), cssValuePool); - computedFont->family = fontFamilyFromStyle(style.get(), cssValuePool); + computedFont->style = fontStyleFromStyle(style.get()); + computedFont->variant = fontVariantFromStyle(style.get()); + computedFont->weight = fontWeightFromStyle(style.get()); + computedFont->size = fontSizeFromStyle(style.get()); + computedFont->lineHeight = lineHeightFromStyle(style.get(), m_node->document()->renderView()); + computedFont->family = fontFamilyFromStyle(style.get()); return computedFont.release(); } case CSSPropertyFontFamily: { - RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get(), cssValuePool); + RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get()); // If there's only a single family, return that as a CSSPrimitiveValue. // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string. if (fontFamilyList->length() == 1) @@ -1666,17 +1680,17 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return fontFamilyList.release(); } case CSSPropertyFontSize: - return fontSizeFromStyle(style.get(), cssValuePool); + return fontSizeFromStyle(style.get()); case CSSPropertyFontStyle: - return fontStyleFromStyle(style.get(), cssValuePool); + return fontStyleFromStyle(style.get()); case CSSPropertyFontVariant: - return fontVariantFromStyle(style.get(), cssValuePool); + return fontVariantFromStyle(style.get()); case CSSPropertyFontWeight: - return fontWeightFromStyle(style.get(), cssValuePool); + return fontWeightFromStyle(style.get()); case CSSPropertyWebkitFontFeatureSettings: { const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings(); if (!featureSettings || !featureSettings->size()) - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueNormal); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (unsigned i = 0; i < featureSettings->size(); ++i) { const FontFeature& feature = featureSettings->at(i); @@ -1687,36 +1701,36 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper } #if ENABLE(CSS_GRID_LAYOUT) case CSSPropertyWebkitGridColumns: { - return valueForGridTrackList(style->gridColumns(), style.get(), cssValuePool); + return valueForGridTrackList(style->gridColumns(), style.get()); } case CSSPropertyWebkitGridRows: { - return valueForGridTrackList(style->gridRows(), style.get(), cssValuePool); + return valueForGridTrackList(style->gridRows(), style.get()); } case CSSPropertyWebkitGridColumn: - return valueForGridPosition(style->gridItemColumn(), cssValuePool); + return valueForGridPosition(style->gridItemColumn()); case CSSPropertyWebkitGridRow: - return valueForGridPosition(style->gridItemRow(), cssValuePool); + return valueForGridPosition(style->gridItemRow()); #endif case CSSPropertyHeight: if (renderer) { // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property, // the "height" property does not apply for non-replaced inline elements. if (!renderer->isReplaced() && renderer->isInline()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get()); } - return zoomAdjustedPixelValueForLength(style->height(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(style->height(), style.get()); case CSSPropertyWebkitHighlight: if (style->highlight() == nullAtom) - return cssValuePool->createIdentifierValue(CSSValueNone); - return cssValuePool->createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool().createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitHyphens: - return cssValuePool->createValue(style->hyphens()); + return cssValuePool().createValue(style->hyphens()); case CSSPropertyWebkitHyphenateCharacter: if (style->hyphenationString().isNull()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitHyphenateLimitAfter: if (style->hyphenationLimitAfter() < 0) return CSSPrimitiveValue::createIdentifier(CSSValueAuto); @@ -1731,165 +1745,165 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBorderFit: if (style->borderFit() == BorderFitBorder) - return cssValuePool->createIdentifierValue(CSSValueBorder); - return cssValuePool->createIdentifierValue(CSSValueLines); + return cssValuePool().createIdentifierValue(CSSValueBorder); + return cssValuePool().createIdentifierValue(CSSValueLines); case CSSPropertyImageRendering: return CSSPrimitiveValue::create(style->imageRendering()); case CSSPropertyLeft: - return getPositionOffsetValue(style.get(), CSSPropertyLeft, cssValuePool); + return getPositionOffsetValue(style.get(), CSSPropertyLeft, m_node->document()->renderView()); case CSSPropertyLetterSpacing: if (!style->letterSpacing()) - return cssValuePool->createIdentifierValue(CSSValueNormal); - return zoomAdjustedPixelValue(style->letterSpacing(), style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueNormal); + return zoomAdjustedPixelValue(style->letterSpacing(), style.get()); case CSSPropertyWebkitLineClamp: if (style->lineClamp().isNone()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return cssValuePool->createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyLineHeight: - return lineHeightFromStyle(style.get(), cssValuePool); + return lineHeightFromStyle(style.get(), m_node->document()->renderView()); case CSSPropertyListStyleImage: if (style->listStyleImage()) return style->listStyleImage()->cssValue(); - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); case CSSPropertyListStylePosition: - return cssValuePool->createValue(style->listStylePosition()); + return cssValuePool().createValue(style->listStylePosition()); case CSSPropertyListStyleType: - return cssValuePool->createValue(style->listStyleType()); + return cssValuePool().createValue(style->listStyleType()); case CSSPropertyWebkitLocale: if (style->locale().isNull()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->locale(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->locale(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyMarginTop: { Length marginTop = style->marginTop(); if (marginTop.isFixed() || !renderer || !renderer->isBox()) - return zoomAdjustedPixelValueForLength(marginTop, style.get(), cssValuePool); - return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(marginTop, style.get()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->marginTop(), style.get()); } case CSSPropertyMarginRight: { Length marginRight = style->marginRight(); if (marginRight.isFixed() || !renderer || !renderer->isBox()) - return zoomAdjustedPixelValueForLength(marginRight, style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(marginRight, style.get()); int value; - if (marginRight.isPercent()) + if (marginRight.isPercent() || marginRight.isViewportPercentage()) // RenderBox gives a marginRight() that is the distance between the right-edge of the child box // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute // value of the specified margin-right % instead of relying on RenderBox's marginRight() value. - value = marginRight.calcMinValue(toRenderBox(renderer)->containingBlockLogicalWidthForContent()); + value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document()->renderView()); else value = toRenderBox(renderer)->marginRight(); - return zoomAdjustedPixelValue(value, style.get(), cssValuePool); + return zoomAdjustedPixelValue(value, style.get()); } case CSSPropertyMarginBottom: { Length marginBottom = style->marginBottom(); if (marginBottom.isFixed() || !renderer || !renderer->isBox()) - return zoomAdjustedPixelValueForLength(marginBottom, style.get(), cssValuePool); - return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(marginBottom, style.get()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->marginBottom(), style.get()); } case CSSPropertyMarginLeft: { Length marginLeft = style->marginLeft(); if (marginLeft.isFixed() || !renderer || !renderer->isBox()) - return zoomAdjustedPixelValueForLength(marginLeft, style.get(), cssValuePool); - return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(marginLeft, style.get()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->marginLeft(), style.get()); } case CSSPropertyWebkitMarqueeDirection: - return cssValuePool->createValue(style->marqueeDirection()); + return cssValuePool().createValue(style->marqueeDirection()); case CSSPropertyWebkitMarqueeIncrement: - return cssValuePool->createValue(style->marqueeIncrement()); + return cssValuePool().createValue(style->marqueeIncrement()); case CSSPropertyWebkitMarqueeRepetition: if (style->marqueeLoopCount() < 0) - return cssValuePool->createIdentifierValue(CSSValueInfinite); - return cssValuePool->createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createIdentifierValue(CSSValueInfinite); + return cssValuePool().createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitMarqueeStyle: - return cssValuePool->createValue(style->marqueeBehavior()); + return cssValuePool().createValue(style->marqueeBehavior()); case CSSPropertyWebkitUserModify: - return cssValuePool->createValue(style->userModify()); + return cssValuePool().createValue(style->userModify()); case CSSPropertyMaxHeight: { const Length& maxHeight = style->maxHeight(); if (maxHeight.isUndefined()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return zoomAdjustedPixelValueForLength(maxHeight, style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueNone); + return zoomAdjustedPixelValueForLength(maxHeight, style.get()); } case CSSPropertyMaxWidth: { const Length& maxWidth = style->maxWidth(); if (maxWidth.isUndefined()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return zoomAdjustedPixelValueForLength(maxWidth, style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueNone); + return zoomAdjustedPixelValueForLength(maxWidth, style.get()); } case CSSPropertyMinHeight: - return zoomAdjustedPixelValueForLength(style->minHeight(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(style->minHeight(), style.get()); case CSSPropertyMinWidth: - return zoomAdjustedPixelValueForLength(style->minWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(style->minWidth(), style.get()); case CSSPropertyOpacity: - return cssValuePool->createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyOrphans: - return cssValuePool->createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyOutlineColor: - return m_allowVisitedStyle ? cssValuePool->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor()); + return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor()); case CSSPropertyOutlineOffset: - return zoomAdjustedPixelValue(style->outlineOffset(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->outlineOffset(), style.get()); case CSSPropertyOutlineStyle: if (style->outlineStyleIsAuto()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->outlineStyle()); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->outlineStyle()); case CSSPropertyOutlineWidth: - return zoomAdjustedPixelValue(style->outlineWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->outlineWidth(), style.get()); case CSSPropertyOverflow: - return cssValuePool->createValue(max(style->overflowX(), style->overflowY())); + return cssValuePool().createValue(max(style->overflowX(), style->overflowY())); case CSSPropertyOverflowX: - return cssValuePool->createValue(style->overflowX()); + return cssValuePool().createValue(style->overflowX()); case CSSPropertyOverflowY: - return cssValuePool->createValue(style->overflowY()); + return cssValuePool().createValue(style->overflowY()); case CSSPropertyPaddingTop: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingTop(ExcludeIntrinsicPadding), style.get(), cssValuePool); - return zoomAdjustedPixelValueForLength(style->paddingTop(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingTop(), style.get()); + return zoomAdjustedPixelValueForLength(style->paddingTop(), style.get()); case CSSPropertyPaddingRight: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingRight(ExcludeIntrinsicPadding), style.get(), cssValuePool); - return zoomAdjustedPixelValueForLength(style->paddingRight(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingRight(), style.get()); + return zoomAdjustedPixelValueForLength(style->paddingRight(), style.get()); case CSSPropertyPaddingBottom: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingBottom(ExcludeIntrinsicPadding), style.get(), cssValuePool); - return zoomAdjustedPixelValueForLength(style->paddingBottom(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingBottom(), style.get()); + return zoomAdjustedPixelValueForLength(style->paddingBottom(), style.get()); case CSSPropertyPaddingLeft: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingLeft(ExcludeIntrinsicPadding), style.get(), cssValuePool); - return zoomAdjustedPixelValueForLength(style->paddingLeft(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(toRenderBox(renderer)->computedCSSPaddingLeft(), style.get()); + return zoomAdjustedPixelValueForLength(style->paddingLeft(), style.get()); case CSSPropertyPageBreakAfter: - return cssValuePool->createValue(style->pageBreakAfter()); + return cssValuePool().createValue(style->pageBreakAfter()); case CSSPropertyPageBreakBefore: - return cssValuePool->createValue(style->pageBreakBefore()); + return cssValuePool().createValue(style->pageBreakBefore()); case CSSPropertyPageBreakInside: { EPageBreak pageBreak = style->pageBreakInside(); ASSERT(pageBreak != PBALWAYS); if (pageBreak == PBALWAYS) return 0; - return cssValuePool->createValue(style->pageBreakInside()); + return cssValuePool().createValue(style->pageBreakInside()); } case CSSPropertyPosition: - return cssValuePool->createValue(style->position()); + return cssValuePool().createValue(style->position()); case CSSPropertyRight: - return getPositionOffsetValue(style.get(), CSSPropertyRight, cssValuePool); + return getPositionOffsetValue(style.get(), CSSPropertyRight, m_node->document()->renderView()); case CSSPropertyTableLayout: - return cssValuePool->createValue(style->tableLayout()); + return cssValuePool().createValue(style->tableLayout()); case CSSPropertyTextAlign: - return cssValuePool->createValue(style->textAlign()); + return cssValuePool().createValue(style->textAlign()); case CSSPropertyTextDecoration: - return renderTextDecorationFlagsToCSSValue(style->textDecoration(), cssValuePool); + return renderTextDecorationFlagsToCSSValue(style->textDecoration()); case CSSPropertyWebkitTextDecorationsInEffect: - return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect(), cssValuePool); + return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect()); case CSSPropertyWebkitTextFillColor: return currentColorOrValidColor(style.get(), style->textFillColor()); case CSSPropertyWebkitTextEmphasisColor: return currentColorOrValidColor(style.get(), style->textEmphasisColor()); case CSSPropertyWebkitTextEmphasisPosition: - return cssValuePool->createValue(style->textEmphasisPosition()); + return cssValuePool().createValue(style->textEmphasisPosition()); case CSSPropertyWebkitTextEmphasisStyle: switch (style->textEmphasisMark()) { case TextEmphasisMarkNone: - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); case TextEmphasisMarkCustom: - return cssValuePool->createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); case TextEmphasisMarkAuto: ASSERT_NOT_REACHED(); // Fall through @@ -1899,129 +1913,129 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case TextEmphasisMarkTriangle: case TextEmphasisMarkSesame: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(cssValuePool->createValue(style->textEmphasisFill())); - list->append(cssValuePool->createValue(style->textEmphasisMark())); + list->append(cssValuePool().createValue(style->textEmphasisFill())); + list->append(cssValuePool().createValue(style->textEmphasisMark())); return list.release(); } } case CSSPropertyTextIndent: - return zoomAdjustedPixelValueForLength(style->textIndent(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(style->textIndent(), style.get()); case CSSPropertyTextShadow: return valueForShadow(style->textShadow(), propertyID, style.get()); case CSSPropertyTextRendering: - return cssValuePool->createValue(style->fontDescription().textRenderingMode()); + return cssValuePool().createValue(style->fontDescription().textRenderingMode()); case CSSPropertyTextOverflow: if (style->textOverflow()) - return cssValuePool->createIdentifierValue(CSSValueEllipsis); - return cssValuePool->createIdentifierValue(CSSValueClip); + return cssValuePool().createIdentifierValue(CSSValueEllipsis); + return cssValuePool().createIdentifierValue(CSSValueClip); case CSSPropertyWebkitTextSecurity: - return cssValuePool->createValue(style->textSecurity()); + return cssValuePool().createValue(style->textSecurity()); case CSSPropertyWebkitTextSizeAdjust: if (style->textSizeAdjust()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueNone); case CSSPropertyWebkitTextStrokeColor: return currentColorOrValidColor(style.get(), style->textStrokeColor()); case CSSPropertyWebkitTextStrokeWidth: - return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get()); case CSSPropertyTextTransform: - return cssValuePool->createValue(style->textTransform()); + return cssValuePool().createValue(style->textTransform()); case CSSPropertyTop: - return getPositionOffsetValue(style.get(), CSSPropertyTop, cssValuePool); + return getPositionOffsetValue(style.get(), CSSPropertyTop, m_node->document()->renderView()); case CSSPropertyUnicodeBidi: - return renderUnicodeBidiFlagsToCSSValue(style->unicodeBidi(), cssValuePool); + return renderUnicodeBidiFlagsToCSSValue(style->unicodeBidi()); case CSSPropertyVerticalAlign: switch (style->verticalAlign()) { case BASELINE: - return cssValuePool->createIdentifierValue(CSSValueBaseline); + return cssValuePool().createIdentifierValue(CSSValueBaseline); case MIDDLE: - return cssValuePool->createIdentifierValue(CSSValueMiddle); + return cssValuePool().createIdentifierValue(CSSValueMiddle); case SUB: - return cssValuePool->createIdentifierValue(CSSValueSub); + return cssValuePool().createIdentifierValue(CSSValueSub); case SUPER: - return cssValuePool->createIdentifierValue(CSSValueSuper); + return cssValuePool().createIdentifierValue(CSSValueSuper); case TEXT_TOP: - return cssValuePool->createIdentifierValue(CSSValueTextTop); + return cssValuePool().createIdentifierValue(CSSValueTextTop); case TEXT_BOTTOM: - return cssValuePool->createIdentifierValue(CSSValueTextBottom); + return cssValuePool().createIdentifierValue(CSSValueTextBottom); case TOP: - return cssValuePool->createIdentifierValue(CSSValueTop); + return cssValuePool().createIdentifierValue(CSSValueTop); case BOTTOM: - return cssValuePool->createIdentifierValue(CSSValueBottom); + return cssValuePool().createIdentifierValue(CSSValueBottom); case BASELINE_MIDDLE: - return cssValuePool->createIdentifierValue(CSSValueWebkitBaselineMiddle); + return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle); case LENGTH: - return cssValuePool->createValue(style->verticalAlignLength()); + return cssValuePool().createValue(style->verticalAlignLength()); } ASSERT_NOT_REACHED(); return 0; case CSSPropertyVisibility: - return cssValuePool->createValue(style->visibility()); + return cssValuePool().createValue(style->visibility()); case CSSPropertyWhiteSpace: - return cssValuePool->createValue(style->whiteSpace()); + return cssValuePool().createValue(style->whiteSpace()); case CSSPropertyWidows: - return cssValuePool->createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWidth: if (renderer) { // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property, // the "width" property does not apply for non-replaced inline elements. if (!renderer->isReplaced() && renderer->isInline()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get()); } - return zoomAdjustedPixelValueForLength(style->width(), style.get(), cssValuePool); + return zoomAdjustedPixelValueForLength(style->width(), style.get()); case CSSPropertyWordBreak: - return cssValuePool->createValue(style->wordBreak()); + return cssValuePool().createValue(style->wordBreak()); case CSSPropertyWordSpacing: - return zoomAdjustedPixelValue(style->wordSpacing(), style.get(), cssValuePool); + return zoomAdjustedPixelValue(style->wordSpacing(), style.get()); case CSSPropertyWordWrap: - return cssValuePool->createValue(style->wordWrap()); + return cssValuePool().createValue(style->wordWrap()); case CSSPropertyWebkitLineBreak: - return cssValuePool->createValue(style->khtmlLineBreak()); + return cssValuePool().createValue(style->khtmlLineBreak()); case CSSPropertyWebkitNbspMode: - return cssValuePool->createValue(style->nbspMode()); + return cssValuePool().createValue(style->nbspMode()); case CSSPropertyWebkitMatchNearestMailBlockquoteColor: - return cssValuePool->createValue(style->matchNearestMailBlockquoteColor()); + return cssValuePool().createValue(style->matchNearestMailBlockquoteColor()); case CSSPropertyResize: - return cssValuePool->createValue(style->resize()); + return cssValuePool().createValue(style->resize()); case CSSPropertyWebkitFontKerning: - return cssValuePool->createValue(style->fontDescription().kerning()); + return cssValuePool().createValue(style->fontDescription().kerning()); case CSSPropertyWebkitFontSmoothing: - return cssValuePool->createValue(style->fontDescription().fontSmoothing()); + return cssValuePool().createValue(style->fontDescription().fontSmoothing()); case CSSPropertyWebkitFontVariantLigatures: { FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState(); FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState(); FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState(); if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState && historicalLigaturesState == FontDescription::NormalLigaturesState) - return cssValuePool->createIdentifierValue(CSSValueNormal); + return cssValuePool().createIdentifierValue(CSSValueNormal); RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated(); if (commonLigaturesState != FontDescription::NormalLigaturesState) - valueList->append(cssValuePool->createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures)); + valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures)); if (discretionaryLigaturesState != FontDescription::NormalLigaturesState) - valueList->append(cssValuePool->createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures)); + valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures)); if (historicalLigaturesState != FontDescription::NormalLigaturesState) - valueList->append(cssValuePool->createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures)); + valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures)); return valueList; } case CSSPropertyZIndex: if (style->hasAutoZIndex()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyZoom: - return cssValuePool->createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); + return cssValuePool().createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyBoxSizing: if (style->boxSizing() == CONTENT_BOX) - return cssValuePool->createIdentifierValue(CSSValueContentBox); - return cssValuePool->createIdentifierValue(CSSValueBorderBox); + return cssValuePool().createIdentifierValue(CSSValueContentBox); + return cssValuePool().createIdentifierValue(CSSValueBorderBox); #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: { const Vector<StyleDashboardRegion>& regions = style->dashboardRegions(); unsigned count = regions.size(); if (count == 1 && regions[0].type == StyleDashboardRegion::None) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); RefPtr<DashboardRegion> firstRegion; DashboardRegion* previousRegion = 0; @@ -2031,10 +2045,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper region->m_label = styleRegion.label; LengthBox offset = styleRegion.offset; - region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get(), cssValuePool)); - region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get(), cssValuePool)); - region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get(), cssValuePool)); - region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get(), cssValuePool)); + region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get())); + region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get())); + region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get())); + region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get())); region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle); @@ -2044,27 +2058,27 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper firstRegion = region; previousRegion = region.get(); } - return cssValuePool->createValue(firstRegion.release()); + return cssValuePool().createValue(firstRegion.release()); } #endif case CSSPropertyWebkitAnimationDelay: - return getDelayValue(style->animations(), cssValuePool); + return getDelayValue(style->animations()); case CSSPropertyWebkitAnimationDirection: { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) { if (t->animation(i)->direction()) - list->append(cssValuePool->createIdentifierValue(CSSValueAlternate)); + list->append(cssValuePool().createIdentifierValue(CSSValueAlternate)); else - list->append(cssValuePool->createIdentifierValue(CSSValueNormal)); + list->append(cssValuePool().createIdentifierValue(CSSValueNormal)); } } else - list->append(cssValuePool->createIdentifierValue(CSSValueNormal)); + list->append(cssValuePool().createIdentifierValue(CSSValueNormal)); return list.release(); } case CSSPropertyWebkitAnimationDuration: - return getDurationValue(style->animations(), cssValuePool); + return getDurationValue(style->animations()); case CSSPropertyWebkitAnimationFillMode: { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); @@ -2072,21 +2086,21 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper for (size_t i = 0; i < t->size(); ++i) { switch (t->animation(i)->fillMode()) { case AnimationFillModeNone: - list->append(cssValuePool->createIdentifierValue(CSSValueNone)); + list->append(cssValuePool().createIdentifierValue(CSSValueNone)); break; case AnimationFillModeForwards: - list->append(cssValuePool->createIdentifierValue(CSSValueForwards)); + list->append(cssValuePool().createIdentifierValue(CSSValueForwards)); break; case AnimationFillModeBackwards: - list->append(cssValuePool->createIdentifierValue(CSSValueBackwards)); + list->append(cssValuePool().createIdentifierValue(CSSValueBackwards)); break; case AnimationFillModeBoth: - list->append(cssValuePool->createIdentifierValue(CSSValueBoth)); + list->append(cssValuePool().createIdentifierValue(CSSValueBoth)); break; } } } else - list->append(cssValuePool->createIdentifierValue(CSSValueNone)); + list->append(cssValuePool().createIdentifierValue(CSSValueNone)); return list.release(); } case CSSPropertyWebkitAnimationIterationCount: { @@ -2094,14 +2108,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) { - int iterationCount = t->animation(i)->iterationCount(); + double iterationCount = t->animation(i)->iterationCount(); if (iterationCount == Animation::IterationCountInfinite) - list->append(cssValuePool->createIdentifierValue(CSSValueInfinite)); + list->append(cssValuePool().createIdentifierValue(CSSValueInfinite)); else - list->append(cssValuePool->createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); } } else - list->append(cssValuePool->createValue(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); + list->append(cssValuePool().createValue(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); return list.release(); } case CSSPropertyWebkitAnimationName: { @@ -2109,9 +2123,9 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper const AnimationList* t = style->animations(); if (t) { for (size_t i = 0; i < t->size(); ++i) - list->append(cssValuePool->createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); + list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); } else - list->append(cssValuePool->createIdentifierValue(CSSValueNone)); + list->append(cssValuePool().createIdentifierValue(CSSValueNone)); return list.release(); } case CSSPropertyWebkitAnimationPlayState: { @@ -2121,221 +2135,223 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper for (size_t i = 0; i < t->size(); ++i) { int prop = t->animation(i)->playState(); if (prop == AnimPlayStatePlaying) - list->append(cssValuePool->createIdentifierValue(CSSValueRunning)); + list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); else - list->append(cssValuePool->createIdentifierValue(CSSValuePaused)); + list->append(cssValuePool().createIdentifierValue(CSSValuePaused)); } } else - list->append(cssValuePool->createIdentifierValue(CSSValueRunning)); + list->append(cssValuePool().createIdentifierValue(CSSValueRunning)); return list.release(); } case CSSPropertyWebkitAnimationTimingFunction: return getTimingFunctionValue(style->animations()); case CSSPropertyWebkitAppearance: - return cssValuePool->createValue(style->appearance()); + return cssValuePool().createValue(style->appearance()); case CSSPropertyWebkitAspectRatio: if (!style->hasAspectRatio()) - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator()); case CSSPropertyWebkitBackfaceVisibility: - return cssValuePool->createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); + return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); case CSSPropertyWebkitBorderImage: - return valueForNinePieceImage(style->borderImage(), cssValuePool); + return valueForNinePieceImage(style->borderImage()); case CSSPropertyBorderImageOutset: - return valueForNinePieceImageQuad(style->borderImage().outset(), cssValuePool); + return valueForNinePieceImageQuad(style->borderImage().outset()); case CSSPropertyBorderImageRepeat: - return valueForNinePieceImageRepeat(style->borderImage(), cssValuePool); + return valueForNinePieceImageRepeat(style->borderImage()); case CSSPropertyBorderImageSlice: - return valueForNinePieceImageSlice(style->borderImage(), cssValuePool); + return valueForNinePieceImageSlice(style->borderImage()); case CSSPropertyBorderImageWidth: - return valueForNinePieceImageQuad(style->borderImage().borderSlices(), cssValuePool); + return valueForNinePieceImageQuad(style->borderImage().borderSlices()); case CSSPropertyWebkitMaskBoxImage: - return valueForNinePieceImage(style->maskBoxImage(), cssValuePool); + return valueForNinePieceImage(style->maskBoxImage()); case CSSPropertyWebkitMaskBoxImageOutset: - return valueForNinePieceImageQuad(style->maskBoxImage().outset(), cssValuePool); + return valueForNinePieceImageQuad(style->maskBoxImage().outset()); case CSSPropertyWebkitMaskBoxImageRepeat: - return valueForNinePieceImageRepeat(style->maskBoxImage(), cssValuePool); + return valueForNinePieceImageRepeat(style->maskBoxImage()); case CSSPropertyWebkitMaskBoxImageSlice: - return valueForNinePieceImageSlice(style->maskBoxImage(), cssValuePool); + return valueForNinePieceImageSlice(style->maskBoxImage()); case CSSPropertyWebkitMaskBoxImageWidth: - return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices(), cssValuePool); + return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices()); case CSSPropertyWebkitMaskBoxImageSource: if (style->maskBoxImageSource()) return style->maskBoxImageSource()->cssValue(); - return cssValuePool->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); case CSSPropertyWebkitFontSizeDelta: // Not a real style property -- used by the editing engine -- so has no computed value. break; case CSSPropertyWebkitMarginBottomCollapse: case CSSPropertyWebkitMarginAfterCollapse: - return cssValuePool->createValue(style->marginAfterCollapse()); + return cssValuePool().createValue(style->marginAfterCollapse()); case CSSPropertyWebkitMarginTopCollapse: case CSSPropertyWebkitMarginBeforeCollapse: - return cssValuePool->createValue(style->marginBeforeCollapse()); + return cssValuePool().createValue(style->marginBeforeCollapse()); #if ENABLE(OVERFLOW_SCROLLING) case CSSPropertyWebkitOverflowScrolling: if (!style->useTouchOverflowScrolling()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createIdentifierValue(CSSValueTouch); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueTouch); #endif case CSSPropertyWebkitPerspective: if (!style->hasPerspective()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return zoomAdjustedPixelValue(style->perspective(), style.get(), cssValuePool); + return cssValuePool().createIdentifierValue(CSSValueNone); + return zoomAdjustedPixelValue(style->perspective(), style.get()); case CSSPropertyWebkitPerspectiveOrigin: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (renderer) { LayoutRect box = sizingBox(renderer); - list->append(zoomAdjustedPixelValue(style->perspectiveOriginX().calcMinValue(box.width()), style.get(), cssValuePool)); - list->append(zoomAdjustedPixelValue(style->perspectiveOriginY().calcMinValue(box.height()), style.get(), cssValuePool)); + RenderView* renderView = m_node->document()->renderView(); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get())); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get())); } else { - list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get(), cssValuePool)); - list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get(), cssValuePool)); + list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get())); + list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get())); } return list.release(); } case CSSPropertyWebkitRtlOrdering: - return cssValuePool->createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical); + return cssValuePool().createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical); #if ENABLE(TOUCH_EVENTS) case CSSPropertyWebkitTapHighlightColor: return currentColorOrValidColor(style.get(), style->tapHighlightColor()); #endif case CSSPropertyWebkitUserDrag: - return cssValuePool->createValue(style->userDrag()); + return cssValuePool().createValue(style->userDrag()); case CSSPropertyWebkitUserSelect: - return cssValuePool->createValue(style->userSelect()); + return cssValuePool().createValue(style->userSelect()); case CSSPropertyBorderBottomLeftRadius: - return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), cssValuePool); + return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), m_node->document()->renderView()); case CSSPropertyBorderBottomRightRadius: - return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), cssValuePool); + return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), m_node->document()->renderView()); case CSSPropertyBorderTopLeftRadius: - return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), cssValuePool); + return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), m_node->document()->renderView()); case CSSPropertyBorderTopRightRadius: - return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), cssValuePool); + return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), m_node->document()->renderView()); case CSSPropertyClip: { if (!style->hasClip()) - return cssValuePool->createIdentifierValue(CSSValueAuto); + return cssValuePool().createIdentifierValue(CSSValueAuto); RefPtr<Rect> rect = Rect::create(); - rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get(), cssValuePool)); - rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get(), cssValuePool)); - rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get(), cssValuePool)); - rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get(), cssValuePool)); - return cssValuePool->createValue(rect.release()); + rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get())); + rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get())); + rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get())); + rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get())); + return cssValuePool().createValue(rect.release()); } case CSSPropertySpeak: - return cssValuePool->createValue(style->speak()); + return cssValuePool().createValue(style->speak()); case CSSPropertyWebkitTransform: - return computedTransform(renderer, style.get(), cssValuePool); + return computedTransform(renderer, style.get()); case CSSPropertyWebkitTransformOrigin: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (renderer) { - IntRect box = sizingBox(renderer); - list->append(zoomAdjustedPixelValue(style->transformOriginX().calcMinValue(box.width()), style.get(), cssValuePool)); - list->append(zoomAdjustedPixelValue(style->transformOriginY().calcMinValue(box.height()), style.get(), cssValuePool)); + LayoutRect box = sizingBox(renderer); + RenderView* renderView = m_node->document()->renderView(); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), style.get())); + list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), style.get())); if (style->transformOriginZ() != 0) - list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), cssValuePool)); + list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get())); } else { - list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get(), cssValuePool)); - list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get(), cssValuePool)); + list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get())); + list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get())); if (style->transformOriginZ() != 0) - list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), cssValuePool)); + list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get())); } return list.release(); } case CSSPropertyWebkitTransformStyle: - return cssValuePool->createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); + return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); case CSSPropertyWebkitTransitionDelay: - return getDelayValue(style->transitions(), cssValuePool); + return getDelayValue(style->transitions()); case CSSPropertyWebkitTransitionDuration: - return getDurationValue(style->transitions(), cssValuePool); + return getDurationValue(style->transitions()); case CSSPropertyWebkitTransitionProperty: { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->transitions(); if (t) { for (size_t i = 0; i < t->size(); ++i) { - int prop = t->animation(i)->property(); RefPtr<CSSValue> propertyValue; - if (prop == cAnimateNone) - propertyValue = cssValuePool->createIdentifierValue(CSSValueNone); - else if (prop == cAnimateAll) - propertyValue = cssValuePool->createIdentifierValue(CSSValueAll); + const Animation* animation = t->animation(i); + if (animation->animationMode() == Animation::AnimateNone) + propertyValue = cssValuePool().createIdentifierValue(CSSValueNone); + else if (animation->animationMode() == Animation::AnimateAll) + propertyValue = cssValuePool().createIdentifierValue(CSSValueAll); else - propertyValue = cssValuePool->createValue(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING); + propertyValue = cssValuePool().createValue(getPropertyName(animation->property()), CSSPrimitiveValue::CSS_STRING); list->append(propertyValue); } } else - list->append(cssValuePool->createIdentifierValue(CSSValueAll)); + list->append(cssValuePool().createIdentifierValue(CSSValueAll)); return list.release(); } case CSSPropertyWebkitTransitionTimingFunction: return getTimingFunctionValue(style->transitions()); case CSSPropertyPointerEvents: - return cssValuePool->createValue(style->pointerEvents()); + return cssValuePool().createValue(style->pointerEvents()); case CSSPropertyWebkitColorCorrection: - return cssValuePool->createValue(style->colorSpace()); + return cssValuePool().createValue(style->colorSpace()); case CSSPropertyWebkitLineGrid: if (style->lineGrid().isNull()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return cssValuePool->createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitLineSnap: return CSSPrimitiveValue::create(style->lineSnap()); case CSSPropertyWebkitLineAlign: return CSSPrimitiveValue::create(style->lineAlign()); case CSSPropertyWebkitWritingMode: - return cssValuePool->createValue(style->writingMode()); + return cssValuePool().createValue(style->writingMode()); case CSSPropertyWebkitTextCombine: - return cssValuePool->createValue(style->textCombine()); + return cssValuePool().createValue(style->textCombine()); case CSSPropertyWebkitTextOrientation: return CSSPrimitiveValue::create(style->fontDescription().textOrientation()); case CSSPropertyWebkitLineBoxContain: - return createLineBoxContainValue(cssValuePool, style->lineBoxContain()); + return createLineBoxContainValue(style->lineBoxContain()); case CSSPropertyContent: - return contentToCSSValue(style.get(), cssValuePool); + return contentToCSSValue(style.get()); case CSSPropertyCounterIncrement: - return counterToCSSValue(style.get(), propertyID, cssValuePool); + return counterToCSSValue(style.get(), propertyID); case CSSPropertyCounterReset: - return counterToCSSValue(style.get(), propertyID, cssValuePool); + return counterToCSSValue(style.get(), propertyID); case CSSPropertyWebkitFlowInto: if (style->flowThread().isNull()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return cssValuePool->createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitFlowFrom: if (style->regionThread().isNull()) - return cssValuePool->createIdentifierValue(CSSValueNone); - return cssValuePool->createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createIdentifierValue(CSSValueNone); + return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitRegionOverflow: - return cssValuePool->createValue(style->regionOverflow()); + return cssValuePool().createValue(style->regionOverflow()); case CSSPropertyWebkitWrapFlow: - return cssValuePool->createValue(style->wrapFlow()); + return cssValuePool().createValue(style->wrapFlow()); case CSSPropertyWebkitWrapMargin: - return cssValuePool->createValue(style->wrapMargin()); + return cssValuePool().createValue(style->wrapMargin()); case CSSPropertyWebkitWrapPadding: - return cssValuePool->createValue(style->wrapPadding()); - case CSSPropertyWebkitWrapShapeInside: + return cssValuePool().createValue(style->wrapPadding()); + case CSSPropertyWebkitShapeInside: if (!style->wrapShapeInside()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->wrapShapeInside()); - case CSSPropertyWebkitWrapShapeOutside: + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->wrapShapeInside()); + case CSSPropertyWebkitShapeOutside: if (!style->wrapShapeOutside()) - return cssValuePool->createIdentifierValue(CSSValueAuto); - return cssValuePool->createValue(style->wrapShapeOutside()); + return cssValuePool().createIdentifierValue(CSSValueAuto); + return cssValuePool().createValue(style->wrapShapeOutside()); case CSSPropertyWebkitWrapThrough: - return cssValuePool->createValue(style->wrapThrough()); + return cssValuePool().createValue(style->wrapThrough()); #if ENABLE(CSS_FILTERS) case CSSPropertyWebkitFilter: return valueForFilter(style.get()); #endif case CSSPropertyBackground: { - const int properties[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, + const CSSPropertyID properties[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); + return getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(properties, WTF_ARRAY_LENGTH(properties))); } case CSSPropertyBorder: { RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout); - const int properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, + const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { if (value->cssText() != getPropertyCSSValue(properties[i], DoNotUpdateLayout)->cssText()) @@ -2343,65 +2359,32 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper } return value.release(); } - case CSSPropertyBorderBottom: { - const int properties[3] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle, - CSSPropertyBorderBottomColor }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); - } - case CSSPropertyBorderColor: { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, - CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return getCSSPropertyValuesForSidesShorthand(properties); - } - case CSSPropertyBorderLeft: { - const int properties[3] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle, - CSSPropertyBorderLeftColor }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); - } + case CSSPropertyBorderBottom: + return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand()); + case CSSPropertyBorderColor: + return getCSSPropertyValuesForSidesShorthand(borderColorShorthand()); + case CSSPropertyBorderLeft: + return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand()); case CSSPropertyBorderImage: - return valueForNinePieceImage(style->borderImage(), cssValuePool); + return valueForNinePieceImage(style->borderImage()); case CSSPropertyBorderRadius: - return getBorderRadiusShorthandValue(style.get(), cssValuePool); - case CSSPropertyBorderRight: { - const int properties[3] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle, - CSSPropertyBorderRightColor }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); - } - case CSSPropertyBorderStyle: { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, - CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return getCSSPropertyValuesForSidesShorthand(properties); - } - case CSSPropertyBorderTop: { - const int properties[3] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle, - CSSPropertyBorderTopColor }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); - } - case CSSPropertyBorderWidth: { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, - CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return getCSSPropertyValuesForSidesShorthand(properties); - } - case CSSPropertyListStyle: { - const int properties[3] = { CSSPropertyListStyleType, CSSPropertyListStylePosition, - CSSPropertyListStyleImage }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); - } - case CSSPropertyMargin: { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, - CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return getCSSPropertyValuesForSidesShorthand(properties); - } - case CSSPropertyOutline: { - const int properties[3] = { CSSPropertyOutlineColor, CSSPropertyOutlineStyle, - CSSPropertyOutlineWidth }; - return getCSSPropertyValuesForShorthandProperties(properties, WTF_ARRAY_LENGTH(properties)); - } - case CSSPropertyPadding: { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, - CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return getCSSPropertyValuesForSidesShorthand(properties); - } + return getBorderRadiusShorthandValue(style.get(), m_node->document()->renderView()); + case CSSPropertyBorderRight: + return getCSSPropertyValuesForShorthandProperties(borderRightShorthand()); + case CSSPropertyBorderStyle: + return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand()); + case CSSPropertyBorderTop: + return getCSSPropertyValuesForShorthandProperties(borderTopShorthand()); + case CSSPropertyBorderWidth: + return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand()); + case CSSPropertyListStyle: + return getCSSPropertyValuesForShorthandProperties(listStyleShorthand()); + case CSSPropertyMargin: + return getCSSPropertyValuesForSidesShorthand(marginShorthand()); + case CSSPropertyOutline: + return getCSSPropertyValuesForShorthandProperties(outlineShorthand()); + case CSSPropertyPadding: + return getCSSPropertyValuesForSidesShorthand(paddingShorthand()); /* Individual properties not part of the spec */ case CSSPropertyBackgroundRepeatX: case CSSPropertyBackgroundRepeatY: @@ -2542,7 +2525,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return 0; } -String CSSComputedStyleDeclaration::getPropertyValue(int propertyID) const +String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const { RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); if (value) @@ -2569,7 +2552,7 @@ String CSSComputedStyleDeclaration::item(unsigned i) const if (i >= length()) return ""; - return getPropertyName(static_cast<CSSPropertyID>(computedProperties[i])); + return getPropertyName(computedProperties[i]); } bool CSSComputedStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const @@ -2598,24 +2581,24 @@ PassRefPtr<StylePropertySet> CSSComputedStyleDeclaration::makeMutable() return copy(); } -PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForShorthandProperties(const int* properties, size_t size) const +PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) const { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - for (size_t i = 0; i < size; ++i) { - RefPtr<CSSValue> value = getPropertyCSSValue(properties[i], DoNotUpdateLayout); + for (size_t i = 0; i < shorthand.length(); ++i) { + RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout); list->append(value); } return list.release(); } -PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand(const int* properties) const +PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand& shorthand) const { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); // Assume the properties are in the usual order top, right, bottom, left. - RefPtr<CSSValue> topValue = getPropertyCSSValue(properties[0], DoNotUpdateLayout); - RefPtr<CSSValue> rightValue = getPropertyCSSValue(properties[1], DoNotUpdateLayout); - RefPtr<CSSValue> bottomValue = getPropertyCSSValue(properties[2], DoNotUpdateLayout); - RefPtr<CSSValue> leftValue = getPropertyCSSValue(properties[3], DoNotUpdateLayout); + RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout); + RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout); + RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout); + RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout); // All 4 properties must be specified. if (!topValue || !rightValue || !bottomValue || !leftValue) @@ -2636,7 +2619,7 @@ PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::getCSSPropertyValuesForSid return list.release(); } -PassRefPtr<StylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const +PassRefPtr<StylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const { Vector<CSSProperty> list; list.reserveInitialCapacity(length); @@ -2655,15 +2638,16 @@ CSSRule* CSSComputedStyleDeclaration::parentRule() const PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return 0; - return getPropertyCSSValue(propertyID); + RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); + return value ? value->cloneForCSSOM() : 0; } String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); return getPropertyValue(propertyID); diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.h b/Source/WebCore/css/CSSComputedStyleDeclaration.h index de4494194..dcacca87c 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.h +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.h @@ -30,13 +30,13 @@ namespace WebCore { class CSSPrimitiveValue; class CSSValueList; -class CSSValuePool; class Color; class Node; class RenderStyle; class SVGPaint; class ShadowData; class StylePropertySet; +class StylePropertyShorthand; #if ENABLE(CSS_SHADERS) class CustomFilterNumberParameter; @@ -56,21 +56,21 @@ public: virtual void ref() OVERRIDE; virtual void deref() OVERRIDE; - PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const; - String getPropertyValue(int propertyID) const; - bool getPropertyPriority(int propertyID) const; + PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const; + String getPropertyValue(CSSPropertyID) const; + bool getPropertyPriority(CSSPropertyID) const; virtual PassRefPtr<StylePropertySet> copy() const; virtual PassRefPtr<StylePropertySet> makeMutable(); - PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID, EUpdateLayout) const; + PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID, EUpdateLayout) const; PassRefPtr<CSSValue> getFontSizeCSSValuePreferringKeyword() const; bool useFixedFontDefaultSize() const; #if ENABLE(SVG) - PassRefPtr<CSSValue> getSVGPropertyCSSValue(int propertyID, EUpdateLayout) const; + PassRefPtr<CSSValue> getSVGPropertyCSSValue(CSSPropertyID, EUpdateLayout) const; #endif - PassRefPtr<StylePropertySet> copyPropertiesInSet(const int* set, unsigned length) const; + PassRefPtr<StylePropertySet> copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const; private: CSSComputedStyleDeclaration(PassRefPtr<Node>, bool allowVisitedStyle, const String&); @@ -94,7 +94,7 @@ private: virtual bool cssPropertyMatches(const CSSProperty*) const; - PassRefPtr<CSSValue> valueForShadow(const ShadowData*, int, RenderStyle*) const; + PassRefPtr<CSSValue> valueForShadow(const ShadowData*, CSSPropertyID, RenderStyle*) const; PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle*, const Color&) const; #if ENABLE(SVG) PassRefPtr<SVGPaint> adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint>, RenderStyle*) const; @@ -109,8 +109,8 @@ private: PassRefPtr<CSSValue> valueForFilter(RenderStyle*) const; #endif - PassRefPtr<CSSValueList> getCSSPropertyValuesForShorthandProperties(const int* properties, size_t) const; - PassRefPtr<CSSValueList> getCSSPropertyValuesForSidesShorthand(const int* properties) const; + PassRefPtr<CSSValueList> getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand&) const; + PassRefPtr<CSSValueList> getCSSPropertyValuesForSidesShorthand(const StylePropertyShorthand&) const; RefPtr<Node> m_node; PseudoId m_pseudoElementSpecifier; diff --git a/Source/WebCore/css/CSSCursorImageValue.cpp b/Source/WebCore/css/CSSCursorImageValue.cpp index f41276b21..f8506848f 100644 --- a/Source/WebCore/css/CSSCursorImageValue.cpp +++ b/Source/WebCore/css/CSSCursorImageValue.cpp @@ -63,8 +63,7 @@ CSSCursorImageValue::CSSCursorImageValue(const String& url, const IntPoint& hotS CSSCursorImageValue::~CSSCursorImageValue() { #if ENABLE(SVG) - const String& url = getStringValue(); - if (!isSVGCursorIdentifier(url)) + if (!isSVGCursorIdentifier(url())) return; HashSet<SVGElement*>::const_iterator it = m_referencedElements.begin(); @@ -73,7 +72,7 @@ CSSCursorImageValue::~CSSCursorImageValue() for (; it != end; ++it) { SVGElement* referencedElement = *it; referencedElement->cursorImageValueRemoved(); - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document())) + if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), referencedElement->document())) cursorElement->removeClient(referencedElement); } #endif @@ -87,11 +86,10 @@ bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element) if (!element || !element->isSVGElement()) return false; - const String& url = getStringValue(); - if (!isSVGCursorIdentifier(url)) + if (!isSVGCursorIdentifier(url())) return false; - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->document())) { + if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), element->document())) { // FIXME: This will override hot spot specified in CSS, which is probably incorrect. SVGLengthContext lengthContext(0); float x = roundf(cursorElement->x().value(lengthContext)); @@ -116,17 +114,15 @@ bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element) StyleCachedImage* CSSCursorImageValue::cachedImage(CachedResourceLoader* loader) { - String url = getStringValue(); - #if ENABLE(SVG) - if (isSVGCursorIdentifier(url) && loader && loader->document()) { + if (isSVGCursorIdentifier(url()) && loader && loader->document()) { // FIXME: This will fail if the <cursor> element is in a shadow DOM (bug 59827) - if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, loader->document())) - url = cursorElement->href(); + if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), loader->document())) + return CSSImageValue::cachedImage(loader, cursorElement->href()); } #endif - return CSSImageValue::cachedImage(loader, url); + return CSSImageValue::cachedImage(loader, url()); } #if ENABLE(SVG) diff --git a/Source/WebCore/css/CSSFlexValue.cpp b/Source/WebCore/css/CSSFlexValue.cpp deleted file mode 100644 index 3594507c4..000000000 --- a/Source/WebCore/css/CSSFlexValue.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 "CSSFlexValue.h" - -#include <wtf/text/StringBuilder.h> - -namespace WebCore { - -String CSSFlexValue::customCssText() const -{ - StringBuilder result; - result.append("-webkit-flex("); - result.append(String::number(m_positiveFlex)); - result.append(" "); - result.append(String::number(m_negativeFlex)); - result.append(" "); - result.append(m_preferredSize->cssText()); - result.append(")"); - return result.toString(); -} - -} diff --git a/Source/WebCore/css/CSSFlexValue.h b/Source/WebCore/css/CSSFlexValue.h deleted file mode 100644 index 58c6cce5a..000000000 --- a/Source/WebCore/css/CSSFlexValue.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2011 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 CSSFlexValue_h -#define CSSFlexValue_h - -#include "CSSPrimitiveValue.h" -#include "CSSValue.h" - -namespace WebCore { - -class CSSFlexValue : public CSSValue { -public: - static PassRefPtr<CSSFlexValue> create(float positiveFlex, float negativeFlex, PassRefPtr<CSSPrimitiveValue> preferredSize) - { - return adoptRef(new CSSFlexValue(positiveFlex, negativeFlex, preferredSize)); - } - - String customCssText() const; - - float positiveFlex() { return m_positiveFlex; } - float negativeFlex() { return m_negativeFlex; } - CSSPrimitiveValue* preferredSize() { return m_preferredSize.get(); } - -private: - CSSFlexValue(float positiveFlex, float negativeFlex, PassRefPtr<CSSPrimitiveValue> preferredSize) - : CSSValue(FlexClass) - , m_positiveFlex(positiveFlex) - , m_negativeFlex(negativeFlex) - , m_preferredSize(preferredSize) - { - } - - float m_positiveFlex; - float m_negativeFlex; - RefPtr<CSSPrimitiveValue> m_preferredSize; -}; - -} - -#endif diff --git a/Source/WebCore/css/CSSFontFaceRule.cpp b/Source/WebCore/css/CSSFontFaceRule.cpp index 0972a4b47..7b611bb56 100644 --- a/Source/WebCore/css/CSSFontFaceRule.cpp +++ b/Source/WebCore/css/CSSFontFaceRule.cpp @@ -23,33 +23,36 @@ #include "CSSFontFaceRule.h" #include "StylePropertySet.h" +#include "StyleRule.h" namespace WebCore { -CSSFontFaceRule::CSSFontFaceRule(CSSStyleSheet* parent) +CSSFontFaceRule::CSSFontFaceRule(StyleRuleFontFace* fontFaceRule, CSSStyleSheet* parent) : CSSRule(parent, CSSRule::FONT_FACE_RULE) + , m_fontFaceRule(fontFaceRule) { } CSSFontFaceRule::~CSSFontFaceRule() { - if (m_style) - m_style->clearParentRule(this); + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->clearParentRule(); +} + +CSSStyleDeclaration* CSSFontFaceRule::style() const +{ + if (!m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_fontFaceRule->properties(), const_cast<CSSFontFaceRule*>(this)); + return m_propertiesCSSOMWrapper.get(); } String CSSFontFaceRule::cssText() const { String result("@font-face"); result += " { "; - result += m_style->asText(); + result += m_fontFaceRule->properties()->asText(); result += "}"; return result; } -void CSSFontFaceRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls) -{ - if (m_style) - m_style->addSubresourceStyleURLs(urls, parentStyleSheet()); -} - } // namespace WebCore diff --git a/Source/WebCore/css/CSSFontFaceRule.h b/Source/WebCore/css/CSSFontFaceRule.h index ab858f298..222fc3133 100644 --- a/Source/WebCore/css/CSSFontFaceRule.h +++ b/Source/WebCore/css/CSSFontFaceRule.h @@ -23,38 +23,32 @@ #define CSSFontFaceRule_h #include "CSSRule.h" -#include "StylePropertySet.h" +#include "PropertySetCSSStyleDeclaration.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> namespace WebCore { +class CSSStyleDeclaration; +class StyleRuleFontFace; +class StyleRuleCSSStyleDeclaration; + class CSSFontFaceRule : public CSSRule { public: - static PassRefPtr<CSSFontFaceRule> create() - { - return adoptRef(new CSSFontFaceRule(0)); - } - static PassRefPtr<CSSFontFaceRule> create(CSSStyleSheet* parent) - { - return adoptRef(new CSSFontFaceRule(parent)); - } + static PassRefPtr<CSSFontFaceRule> create(StyleRuleFontFace* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSFontFaceRule(rule, sheet)); } ~CSSFontFaceRule(); - CSSStyleDeclaration* style() const { return m_style->ensureRuleCSSStyleDeclaration(this); } + CSSStyleDeclaration* style() const; String cssText() const; - StylePropertySet* declaration() const { return m_style.get(); } - void setDeclaration(PassRefPtr<StylePropertySet> style) { m_style = style; } - - void addSubresourceStyleURLs(ListHashSet<KURL>& urls); - private: - CSSFontFaceRule(CSSStyleSheet* parent); + CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent); - RefPtr<StylePropertySet> m_style; + RefPtr<StyleRuleFontFace> m_fontFaceRule; + + mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper; }; } // namespace WebCore diff --git a/Source/WebCore/css/CSSFontFaceSource.cpp b/Source/WebCore/css/CSSFontFaceSource.cpp index e36735afb..dd904d37f 100644 --- a/Source/WebCore/css/CSSFontFaceSource.cpp +++ b/Source/WebCore/css/CSSFontFaceSource.cpp @@ -114,7 +114,7 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri unsigned hashKey = (fontDescription.computedPixelSize() + 1) << 6 | fontDescription.widthVariant() << 4 | (fontDescription.textOrientation() == TextOrientationUpright ? 8 : 0) | (fontDescription.orientation() == Vertical ? 4 : 0) | (syntheticBold ? 2 : 0) | (syntheticItalic ? 1 : 0); - SimpleFontData*& cachedData = m_fontDataTable.add(hashKey, 0).first->second; + SimpleFontData*& cachedData = m_fontDataTable.add(hashKey, 0).iterator->second; if (cachedData) return cachedData; diff --git a/Source/WebCore/css/CSSFontFaceSrcValue.cpp b/Source/WebCore/css/CSSFontFaceSrcValue.cpp index 3cdece883..83eab3998 100644 --- a/Source/WebCore/css/CSSFontFaceSrcValue.cpp +++ b/Source/WebCore/css/CSSFontFaceSrcValue.cpp @@ -73,7 +73,7 @@ String CSSFontFaceSrcValue::customCssText() const return result; } -void CSSFontFaceSrcValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +void CSSFontFaceSrcValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetInternal* styleSheet) { if (!isLocal()) addSubresourceURL(urls, styleSheet->completeURL(m_resource)); diff --git a/Source/WebCore/css/CSSFontFaceSrcValue.h b/Source/WebCore/css/CSSFontFaceSrcValue.h index a5f54de47..670d82a59 100644 --- a/Source/WebCore/css/CSSFontFaceSrcValue.h +++ b/Source/WebCore/css/CSSFontFaceSrcValue.h @@ -65,7 +65,7 @@ public: String customCssText() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetInternal*); CachedFont* cachedFont(Document*); diff --git a/Source/WebCore/css/CSSFontSelector.cpp b/Source/WebCore/css/CSSFontSelector.cpp index 6d22fdccd..cb3262e52 100644 --- a/Source/WebCore/css/CSSFontSelector.cpp +++ b/Source/WebCore/css/CSSFontSelector.cpp @@ -29,13 +29,11 @@ #include "CachedFont.h" #include "CSSFontFace.h" -#include "CSSFontFaceRule.h" #include "CSSFontFaceSource.h" #include "CSSFontFaceSrcValue.h" #include "CSSPrimitiveValue.h" #include "CSSPropertyNames.h" #include "CSSSegmentedFontFace.h" -#include "CSSStyleSelector.h" #include "CSSUnicodeRangeValue.h" #include "CSSValueKeywords.h" #include "CSSValueList.h" @@ -47,6 +45,8 @@ #include "Settings.h" #include "SimpleFontData.h" #include "StylePropertySet.h" +#include "StyleResolver.h" +#include "StyleRule.h" #include "WebKitFontFamilyNames.h" #include <wtf/text/AtomicString.h> @@ -83,10 +83,10 @@ bool CSSFontSelector::isEmpty() const return m_fonts.isEmpty(); } -void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule) +void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule) { // Obtain the font-family property and the src property. Both must be defined. - const StylePropertySet* style = fontFaceRule->declaration(); + const StylePropertySet* style = fontFaceRule->properties(); RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSSPropertyFontFamily); RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc); RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange); @@ -285,7 +285,7 @@ void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule) if (familyName.isEmpty()) continue; - OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add(familyName, nullptr).first->second; + OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add(familyName, nullptr).iterator->second; if (!familyFontFaces) { familyFontFaces = adoptPtr(new Vector<RefPtr<CSSFontFace> >); @@ -333,8 +333,8 @@ void CSSFontSelector::dispatchInvalidationCallbacks() // FIXME: Make Document a FontSelectorClient so that it can simply register for invalidation callbacks. if (!m_document) return; - if (CSSStyleSelector* styleSelector = m_document->styleSelectorIfExists()) - styleSelector->invalidateMatchedPropertiesCache(); + if (StyleResolver* styleResolver = m_document->styleResolverIfExists()) + styleResolver->invalidateMatchedPropertiesCache(); if (m_document->inPageCache() || !m_document->renderer()) return; m_document->scheduleForcedStyleRecalc(); @@ -487,13 +487,13 @@ FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, c return fontDataForGenericFamily(m_document, fontDescription, familyName); } - OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).first->second; + OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->second; if (!segmentedFontFaceCache) segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >); FontTraitsMask traitsMask = fontDescription.traitsMask(); - RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).first->second; + RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->second; if (!face) { face = CSSSegmentedFontFace::create(this); diff --git a/Source/WebCore/css/CSSFontSelector.h b/Source/WebCore/css/CSSFontSelector.h index a5f8db5d2..3e7bda3fd 100644 --- a/Source/WebCore/css/CSSFontSelector.h +++ b/Source/WebCore/css/CSSFontSelector.h @@ -43,6 +43,7 @@ class CSSSegmentedFontFace; class CachedFont; class Document; class FontDescription; +class StyleRuleFontFace; class CSSFontSelector : public FontSelector { public: @@ -58,7 +59,7 @@ public: void clearDocument(); - void addFontFaceRule(const CSSFontFaceRule*); + void addFontFaceRule(const StyleRuleFontFace*); void fontLoaded(); virtual void fontCacheInvalidated(); diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp index d8d7253d1..a314a8602 100644 --- a/Source/WebCore/css/CSSGradientValue.cpp +++ b/Source/WebCore/css/CSSGradientValue.cpp @@ -26,7 +26,7 @@ #include "config.h" #include "CSSGradientValue.h" -#include "CSSStyleSelector.h" +#include "CSSCalculationValue.h" #include "CSSValueKeywords.h" #include "GeneratorGeneratedImage.h" #include "Gradient.h" @@ -36,6 +36,7 @@ #include "NodeRenderStyle.h" #include "PlatformString.h" #include "RenderObject.h" +#include "StyleResolver.h" using namespace std; @@ -114,7 +115,7 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend // We have to resolve colors. for (unsigned i = 0; i < m_stops.size(); i++) { const CSSGradientColorStop& stop = m_stops[i]; - Color color = renderer->document()->styleSelector()->colorFromPrimitiveValue(stop.m_color.get()); + Color color = renderer->document()->styleResolver()->colorFromPrimitiveValue(stop.m_color.get()); float offset; if (stop.m_position->isPercentage()) @@ -147,17 +148,21 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend for (size_t i = 0; i < numStops; ++i) { const CSSGradientColorStop& stop = m_stops[i]; - stops[i].color = renderer->document()->styleSelector()->colorFromPrimitiveValue(stop.m_color.get()); + stops[i].color = renderer->document()->styleResolver()->colorFromPrimitiveValue(stop.m_color.get()); if (stop.m_position) { if (stop.m_position->isPercentage()) stops[i].offset = stop.m_position->getFloatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100; - else if (stop.m_position->isLength()) { - float length = stop.m_position->computeLength<float>(style, rootStyle, style->effectiveZoom()); + else if (stop.m_position->isLength() || stop.m_position->isCalculatedPercentageWithLength()) { if (!computedGradientLength) { FloatSize gradientSize(gradientStart - gradientEnd); gradientLength = gradientSize.diagonalLength(); } + float length; + if (stop.m_position->isLength()) + length = stop.m_position->computeLength<float>(style, rootStyle, style->effectiveZoom()); + else + length = stop.m_position->cssCalcValue()->toCalcValue(style, rootStyle, style->effectiveZoom())->evaluate(gradientLength); stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0; } else { ASSERT_NOT_REACHED(); @@ -365,8 +370,12 @@ static float positionFromValue(CSSPrimitiveValue* value, RenderStyle* style, Ren if (value->isNumber()) return value->getFloatValue() * zoomFactor; + int edgeDistance = isHorizontal ? size.width() : size.height(); if (value->isPercentage()) - return value->getFloatValue() / 100.f * (isHorizontal ? size.width() : size.height()); + return value->getFloatValue() / 100.f * edgeDistance; + + if (value->isCalculatedPercentageWithLength()) + return value->cssCalcValue()->toCalcValue(style, rootStyle, style->effectiveZoom())->evaluate(edgeDistance); switch (value->getIdent()) { case CSSValueTop: diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y index 1eef6b1e1..dbee3d9ba 100644 --- a/Source/WebCore/css/CSSGrammar.y +++ b/Source/WebCore/css/CSSGrammar.y @@ -24,11 +24,10 @@ #include "config.h" -#include "CSSMediaRule.h" #include "CSSParser.h" +#include "CSSParserMode.h" #include "CSSPrimitiveValue.h" #include "CSSPropertyNames.h" -#include "CSSRuleList.h" #include "CSSSelector.h" #include "CSSSelectorList.h" #include "CSSStyleSheet.h" @@ -36,6 +35,7 @@ #include "HTMLNames.h" #include "MediaList.h" #include "MediaQueryExp.h" +#include "StyleRule.h" #include "WebKitCSSKeyframeRule.h" #include "WebKitCSSKeyframesRule.h" #include <wtf/FastMalloc.h> @@ -68,22 +68,23 @@ using namespace HTMLNames; double number; CSSParserString string; - CSSRule* rule; - CSSRuleList* ruleList; + StyleRuleBase* rule; + Vector<RefPtr<StyleRuleBase> >* ruleList; CSSParserSelector* selector; Vector<OwnPtr<CSSParserSelector> >* selectorList; CSSSelector::MarginBoxType marginBox; CSSSelector::Relation relation; - MediaList* mediaList; + MediaQuerySet* mediaList; MediaQuery* mediaQuery; MediaQuery::Restrictor mediaQueryRestrictor; MediaQueryExp* mediaQueryExp; CSSParserValue value; CSSParserValueList* valueList; Vector<OwnPtr<MediaQueryExp> >* mediaQueryExpList; - WebKitCSSKeyframeRule* keyframeRule; - WebKitCSSKeyframesRule* keyframesRule; + StyleKeyframe* keyframe; + StyleRuleKeyframes* keyframesRule; float val; + CSSPropertyID id; } %{ @@ -100,7 +101,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser) %} -%expect 55 +%expect 58 %nonassoc LOWEST_PREC @@ -189,6 +190,9 @@ static int cssyylex(YYSTYPE* yylval, void* parser) %token <number> PERCENTAGE %token <number> FLOATTOKEN %token <number> INTEGER +%token <number> VW +%token <number> VH +%token <number> VMIN %token <string> URI %token <string> FUNCTION @@ -242,12 +246,12 @@ static int cssyylex(YYSTYPE* yylval, void* parser) %type <mediaQueryExpList> maybe_and_media_query_exp_list %type <string> keyframe_name -%type <keyframeRule> keyframe_rule +%type <keyframe> keyframe_rule %type <keyframesRule> keyframes_rule %type <valueList> key_list %type <value> key -%type <integer> property +%type <id> property %type <selector> specifier %type <selector> specifier_list @@ -376,9 +380,9 @@ closing_brace: charset: CHARSET_SYM maybe_space STRING maybe_space ';' { CSSParser* p = static_cast<CSSParser*>(parser); - $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3); - if ($$ && p->m_styleSheet) - p->m_styleSheet->append($$); + if (p->m_styleSheet) + p->m_styleSheet->parserSetEncodingFromCharsetRule($3); + $$ = 0; } | CHARSET_SYM error invalid_block { } @@ -391,6 +395,9 @@ ignored_charset: // Ignore any @charset rule not at the beginning of the style sheet. $$ = 0; } + | CHARSET_SYM maybe_space ';' { + $$ = 0; + } ; rule_list: @@ -398,7 +405,7 @@ rule_list: | rule_list rule maybe_sgml { CSSParser* p = static_cast<CSSParser*>(parser); if ($2 && p->m_styleSheet) - p->m_styleSheet->append($2); + p->m_styleSheet->parserAppendRule($2); } ; @@ -457,6 +464,9 @@ import: IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' { $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5); } + | IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list TOKEN_EOF { + $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5); + } | IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list invalid_block { $$ = 0; } @@ -564,7 +574,7 @@ media_query: maybe_media_list: /* empty */ { - $$ = static_cast<CSSParser*>(parser)->createMediaList(); + $$ = static_cast<CSSParser*>(parser)->createMediaQuerySet(); } | media_list ; @@ -572,15 +582,15 @@ maybe_media_list: media_list: media_query { CSSParser* p = static_cast<CSSParser*>(parser); - $$ = p->createMediaList(); - $$->appendMediaQuery(p->sinkFloatingMediaQuery($1)); + $$ = p->createMediaQuerySet(); + $$->addMediaQuery(p->sinkFloatingMediaQuery($1)); p->updateLastMediaLine($$); } | media_list ',' maybe_space media_query { $$ = $1; if ($$) { CSSParser* p = static_cast<CSSParser*>(parser); - $$->appendMediaQuery(p->sinkFloatingMediaQuery($4)); + $$->addMediaQuery(p->sinkFloatingMediaQuery($4)); p->updateLastMediaLine($$); } } @@ -596,6 +606,9 @@ media: | MEDIA_SYM maybe_space '{' maybe_space block_rule_list save_block { $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5); } + | MEDIA_SYM maybe_space ';' { + $$ = 0; + } ; medium: @@ -607,7 +620,7 @@ medium: keyframes: WEBKIT_KEYFRAMES_SYM maybe_space keyframe_name maybe_space '{' maybe_space keyframes_rule '}' { $$ = $7; - $7->setNameInternal($3); + $7->setName($3); } ; @@ -621,13 +634,13 @@ keyframes_rule: | keyframes_rule keyframe_rule maybe_space { $$ = $1; if ($2) - $$->append($2); + $$->parserAppendKeyframe($2); } ; keyframe_rule: key_list maybe_space '{' maybe_space declaration_list '}' { - $$ = static_cast<CSSParser*>(parser)->createKeyframeRule($1); + $$ = static_cast<CSSParser*>(parser)->createKeyframe($1); } ; @@ -988,8 +1001,7 @@ element_name: IDENT { CSSParserString& str = $1; CSSParser* p = static_cast<CSSParser*>(parser); - Document* doc = p->findDocument(); - if (doc && doc->isHTMLDocument()) + if (p->m_context.isHTMLDocument) str.lower(); $$ = str; } @@ -1020,7 +1032,7 @@ specifier: CSSParser* p = static_cast<CSSParser*>(parser); $$ = p->createFloatingSelector(); $$->setMatch(CSSSelector::Id); - if (!p->m_strict) + if (p->m_context.mode == CSSQuirksMode) $1.lower(); $$->setValue($1); } @@ -1031,7 +1043,7 @@ specifier: CSSParser* p = static_cast<CSSParser*>(parser); $$ = p->createFloatingSelector(); $$->setMatch(CSSSelector::Id); - if (!p->m_strict) + if (p->m_context.mode == CSSQuirksMode) $1.lower(); $$->setValue($1); } @@ -1046,7 +1058,7 @@ class: CSSParser* p = static_cast<CSSParser*>(parser); $$ = p->createFloatingSelector(); $$->setMatch(CSSSelector::Class); - if (!p->m_strict) + if (p->m_context.mode == CSSQuirksMode) $2.lower(); $$->setValue($2); } @@ -1056,8 +1068,7 @@ attr_name: IDENT maybe_space { CSSParserString& str = $1; CSSParser* p = static_cast<CSSParser*>(parser); - Document* doc = p->findDocument(); - if (doc && doc->isHTMLDocument()) + if (p->m_context.isHTMLDocument) str.lower(); $$ = str; } @@ -1301,7 +1312,7 @@ declaration: if ($1 && $4) { p->m_valueList = p->sinkFloatingValueList($4); int oldParsedProperties = p->m_parsedProperties.size(); - $$ = p->parseValue($1, $5); + $$ = p->parseValue(static_cast<CSSPropertyID>($1), $5); if (!$$) p->rollbackLastProperties(p->m_parsedProperties.size() - oldParsedProperties); else @@ -1467,9 +1478,12 @@ unary_term: $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_REMS; CSSParser* p = static_cast<CSSParser*>(parser); - if (Document* doc = p->findDocument()) - doc->setUsesRemUnits(true); + if (p->m_styleSheet) + p->m_styleSheet->parserSetUsesRemUnits(true); } + | VW maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_VW; } + | VH maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_VH; } + | VMIN maybe_space { $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_VMIN; } ; function: diff --git a/Source/WebCore/css/CSSImageSetValue.cpp b/Source/WebCore/css/CSSImageSetValue.cpp new file mode 100644 index 000000000..7917e99a7 --- /dev/null +++ b/Source/WebCore/css/CSSImageSetValue.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2012 Apple 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 INC. AND ITS 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 APPLE INC. OR ITS 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 "CSSImageSetValue.h" + +#if ENABLE(CSS_IMAGE_SET) + +#include "CSSImageValue.h" +#include "CSSPrimitiveValue.h" +#include "CachedResourceLoader.h" +#include "Document.h" +#include "Page.h" +#include "StyleCachedImageSet.h" +#include "StylePendingImage.h" + +namespace WebCore { + +CSSImageSetValue::CSSImageSetValue() + : CSSValueList(ImageSetClass, CommaSeparator) + , m_accessedBestFitImage(false) + , m_scaleFactor(1) +{ +} + +CSSImageSetValue::~CSSImageSetValue() +{ +} + +void CSSImageSetValue::fillImageSet() +{ + size_t length = this->length(); + size_t i = 0; + while (i < length) { + CSSValue* imageValue = item(i); + ASSERT(imageValue->isImageValue()); + String imageURL = static_cast<CSSImageValue*>(imageValue)->url(); + + ++i; + ASSERT(i < length); + CSSValue* scaleFactorValue = item(i); + ASSERT(scaleFactorValue->isPrimitiveValue()); + float scaleFactor = static_cast<CSSPrimitiveValue*>(scaleFactorValue)->getFloatValue(); + + ImageWithScale image; + image.imageURL = imageURL; + image.scaleFactor = scaleFactor; + m_imagesInSet.append(image); + ++i; + } + + // Sort the images so that they are stored in order from lowest resolution to highest. + std::sort(m_imagesInSet.begin(), m_imagesInSet.end(), CSSImageSetValue::compareByScaleFactor); +} + +CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor() +{ + ImageWithScale image; + size_t numberOfImages = m_imagesInSet.size(); + for (size_t i = 0; i < numberOfImages; ++i) { + image = m_imagesInSet.at(i); + if (image.scaleFactor >= m_scaleFactor) + return image; + } + return image; +} + +StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* loader) +{ + ASSERT(loader); + + Document* document = loader->document(); + if (Page* page = document->page()) + m_scaleFactor = page->deviceScaleFactor(); + else + m_scaleFactor = 1; + + if (!m_imagesInSet.size()) + fillImageSet(); + + if (!m_accessedBestFitImage) { + // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here. + // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(), + // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698 + ImageWithScale image = bestImageForScaleFactor(); + ResourceRequest request(loader->document()->completeURL(image.imageURL)); + if (CachedImage* cachedImage = loader->requestImage(request)) { + m_imageSet = StyleCachedImageSet::create(cachedImage, image.scaleFactor, this); + m_accessedBestFitImage = true; + } + } + + return (m_imageSet && m_imageSet->isCachedImageSet()) ? static_cast<StyleCachedImageSet*>(m_imageSet.get()) : 0; +} + +StyleImage* CSSImageSetValue::cachedOrPendingImageSet(Document* document) +{ + if (!m_imageSet) + m_imageSet = StylePendingImage::create(this); + else if (document && !m_imageSet->isPendingImage()) { + float deviceScaleFactor = 1; + if (Page* page = document->page()) + deviceScaleFactor = page->deviceScaleFactor(); + + // If the deviceScaleFactor has changed, we may not have the best image loaded, so we have to re-assess. + if (deviceScaleFactor != m_scaleFactor) { + m_accessedBestFitImage = false; + m_imageSet = StylePendingImage::create(this); + } + } + + return m_imageSet.get(); +} + +String CSSImageSetValue::customCssText() const +{ + return "-webkit-image-set(" + CSSValueList::customCssText() + ")"; +} + +CSSImageSetValue::CSSImageSetValue(const CSSImageSetValue& cloneFrom) + : CSSValueList(cloneFrom) + , m_accessedBestFitImage(false) + , m_scaleFactor(1) +{ + // Non-CSSValueList data is not accessible through CSS OM, no need to clone. +} + +PassRefPtr<CSSImageSetValue> CSSImageSetValue::cloneForCSSOM() const +{ + return adoptRef(new CSSImageSetValue(*this)); +} + +} // namespace WebCore + +#endif // ENABLE(CSS_IMAGE_SET) diff --git a/Source/WebCore/css/CSSImageSetValue.h b/Source/WebCore/css/CSSImageSetValue.h new file mode 100644 index 000000000..404d3f9ee --- /dev/null +++ b/Source/WebCore/css/CSSImageSetValue.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 Apple 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 INC. AND ITS 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 APPLE INC. OR ITS 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 CSSImageSetValue_h +#define CSSImageSetValue_h + +#if ENABLE(CSS_IMAGE_SET) + +#include "CSSValueList.h" + +namespace WebCore { + +class CachedResourceLoader; +class Document; +class StyleCachedImageSet; +class StyleImage; + +class CSSImageSetValue : public CSSValueList { +public: + + static PassRefPtr<CSSImageSetValue> create() + { + return adoptRef(new CSSImageSetValue()); + } + ~CSSImageSetValue(); + + StyleCachedImageSet* cachedImageSet(CachedResourceLoader*); + + // Returns a StyleCachedImageSet if the best fit image has been cached already, otherwise a StylePendingImage. + StyleImage* cachedOrPendingImageSet(Document*); + + String customCssText() const; + + bool isPending() const { return !m_accessedBestFitImage; } + + struct ImageWithScale { + String imageURL; + float scaleFactor; + }; + + PassRefPtr<CSSImageSetValue> cloneForCSSOM() const; + +protected: + ImageWithScale bestImageForScaleFactor(); + +private: + CSSImageSetValue(); + CSSImageSetValue(const CSSImageSetValue& cloneFrom); + + void fillImageSet(); + static inline bool compareByScaleFactor(ImageWithScale first, ImageWithScale second) { return first.scaleFactor < second.scaleFactor; } + + RefPtr<StyleImage> m_imageSet; + bool m_accessedBestFitImage; + + // This represents the scale factor that we used to find the best fit image. It does not necessarily + // correspond to the scale factor of the best fit image. + float m_scaleFactor; + + Vector<ImageWithScale> m_imagesInSet; +}; + +} // namespace WebCore + +#endif // ENABLE(CSS_IMAGE_SET) + +#endif // CSSImageSetValue_h diff --git a/Source/WebCore/css/CSSImageValue.cpp b/Source/WebCore/css/CSSImageValue.cpp index 8437f3ec0..db56bd428 100644 --- a/Source/WebCore/css/CSSImageValue.cpp +++ b/Source/WebCore/css/CSSImageValue.cpp @@ -22,6 +22,7 @@ #include "CSSImageValue.h" #include "CSSCursorImageValue.h" +#include "CSSParser.h" #include "CSSValueKeywords.h" #include "Document.h" #include "MemoryCache.h" @@ -33,25 +34,22 @@ namespace WebCore { CSSImageValue::CSSImageValue(ClassType classType, const String& url) - : CSSPrimitiveValue(classType, url, CSS_URI) + : CSSValue(classType) + , m_url(url) , m_accessedImage(false) { } -CSSImageValue::CSSImageValue() - : CSSPrimitiveValue(ImageClass, CSSValueNone) - , m_accessedImage(true) -{ -} - CSSImageValue::CSSImageValue(const String& url) - : CSSPrimitiveValue(ImageClass, url, CSS_URI) + : CSSValue(ImageClass) + , m_url(url) , m_accessedImage(false) { } CSSImageValue::CSSImageValue(const String& url, StyleImage* image) - : CSSPrimitiveValue(ImageClass, url, CSS_URI) + : CSSValue(ImageClass) + , m_url(url) , m_image(image) , m_accessedImage(true) { @@ -63,9 +61,6 @@ CSSImageValue::~CSSImageValue() StyleImage* CSSImageValue::cachedOrPendingImage() { - if (getIdent() == CSSValueNone) - return 0; - if (!m_image) m_image = StylePendingImage::create(this); @@ -76,7 +71,7 @@ StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader) { if (isCursorImageValue()) return static_cast<CSSCursorImageValue*>(this)->cachedImage(loader); - return cachedImage(loader, getStringValue()); + return cachedImage(loader, m_url); } StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const String& url) @@ -107,4 +102,17 @@ void CSSImageValue::clearCachedImage() m_accessedImage = false; } +String CSSImageValue::customCssText() const +{ + return "url(" + quoteCSSURLIfNeeded(m_url) + ")"; +} + +PassRefPtr<CSSValue> CSSImageValue::cloneForCSSOM() const +{ + // NOTE: We expose CSSImageValues as URI primitive values in CSSOM to maintain old behavior. + RefPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_url, CSSPrimitiveValue::CSS_URI); + uriValue->setCSSOMSafe(); + return uriValue.release(); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSImageValue.h b/Source/WebCore/css/CSSImageValue.h index 82e34de4d..5b2ce4760 100644 --- a/Source/WebCore/css/CSSImageValue.h +++ b/Source/WebCore/css/CSSImageValue.h @@ -1,6 +1,6 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,7 +21,7 @@ #ifndef CSSImageValue_h #define CSSImageValue_h -#include "CSSPrimitiveValue.h" +#include "CSSValue.h" #include <wtf/RefPtr.h> namespace WebCore { @@ -30,9 +30,8 @@ class CachedResourceLoader; class StyleCachedImage; class StyleImage; -class CSSImageValue : public CSSPrimitiveValue { +class CSSImageValue : public CSSValue { public: - static PassRefPtr<CSSImageValue> create() { return adoptRef(new CSSImageValue); } static PassRefPtr<CSSImageValue> create(const String& url) { return adoptRef(new CSSImageValue(url)); } static PassRefPtr<CSSImageValue> create(const String& url, StyleImage* image) { return adoptRef(new CSSImageValue(url, image)); } ~CSSImageValue(); @@ -41,6 +40,12 @@ public: // Returns a StyleCachedImage if the image is cached already, otherwise a StylePendingImage. StyleImage* cachedOrPendingImage(); + const String& url() { return m_url; } + + String customCssText() const; + + PassRefPtr<CSSValue> cloneForCSSOM() const; + protected: CSSImageValue(ClassType, const String& url); @@ -49,10 +54,10 @@ protected: void clearCachedImage(); private: - CSSImageValue(); explicit CSSImageValue(const String& url); - explicit CSSImageValue(const String& url, StyleImage*); + CSSImageValue(const String& url, StyleImage*); + String m_url; RefPtr<StyleImage> m_image; bool m_accessedImage; }; diff --git a/Source/WebCore/css/CSSImportRule.cpp b/Source/WebCore/css/CSSImportRule.cpp index 20d7706b3..f9d14671b 100644 --- a/Source/WebCore/css/CSSImportRule.cpp +++ b/Source/WebCore/css/CSSImportRule.cpp @@ -25,101 +25,73 @@ #include "CachedCSSStyleSheet.h" #include "CachedResourceLoader.h" #include "Document.h" +#include "MediaList.h" #include "SecurityOrigin.h" #include "Settings.h" #include <wtf/StdLibExtras.h> +#include <wtf/text/StringBuilder.h> namespace WebCore { -CSSImportRule::CSSImportRule(CSSStyleSheet* parent, const String& href, PassRefPtr<MediaList> media) - : CSSRule(parent, CSSRule::IMPORT_RULE) +PassRefPtr<StyleRuleImport> StyleRuleImport::create(const String& href, PassRefPtr<MediaQuerySet> media) +{ + return adoptRef(new StyleRuleImport(href, media)); +} + +StyleRuleImport::StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet> media) + : StyleRuleBase(Import, 0) + , m_parentStyleSheet(0) , m_styleSheetClient(this) , m_strHref(href) - , m_lstMedia(media) + , m_mediaQueries(media) , m_cachedSheet(0) , m_loading(false) { - ASSERT(parent); - if (m_lstMedia) - m_lstMedia->setParentStyleSheet(parent); - else - m_lstMedia = MediaList::create(parent, String()); + if (!m_mediaQueries) + m_mediaQueries = MediaQuerySet::create(String()); } -CSSImportRule::~CSSImportRule() +StyleRuleImport::~StyleRuleImport() { - if (m_lstMedia) - m_lstMedia->setParentStyleSheet(0); if (m_styleSheet) m_styleSheet->clearOwnerRule(); if (m_cachedSheet) m_cachedSheet->removeClient(&m_styleSheetClient); } -void CSSImportRule::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet) +void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* cachedStyleSheet) { if (m_styleSheet) m_styleSheet->clearOwnerRule(); - m_styleSheet = CSSStyleSheet::create(this, href, baseURL, charset); - - bool crossOriginCSS = false; - bool validMIMEType = false; - CSSStyleSheet* parent = parentStyleSheet(); - bool strict = !parent || parent->useStrictParsing(); - bool enforceMIMEType = strict; - Document* document = parent ? parent->findDocument() : 0; - bool needsSiteSpecificQuirks = document && document->settings() && document->settings()->needsSiteSpecificQuirks(); - -#ifdef BUILDING_ON_LEOPARD - if (enforceMIMEType && needsSiteSpecificQuirks) { - // Covers both http and https, with or without "www." - if (baseURL.string().contains("mcafee.com/japan/", false)) - enforceMIMEType = false; - } -#endif - - String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType); - m_styleSheet->parseString(sheetText, strict); - - if (!document || !document->securityOrigin()->canRequest(baseURL)) - crossOriginCSS = true; - - if (crossOriginCSS && !validMIMEType && !m_styleSheet->hasSyntacticallyValidCSSHeader()) - m_styleSheet = CSSStyleSheet::create(this, href, baseURL, charset); - - if (strict && needsSiteSpecificQuirks) { - // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>. - DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css")); - DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n")); - // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet, - // while the other lacks the second trailing newline. - if (baseURL.string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText) - && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) { - ASSERT(m_styleSheet->length() == 1); - ExceptionCode ec; - m_styleSheet->deleteRule(0, ec); - } - } + + CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : CSSStrictMode; + context.charset = charset; + if (!baseURL.isNull()) + context.baseURL = baseURL; + + m_styleSheet = StyleSheetInternal::create(this, href, baseURL, context); + + Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : 0; + m_styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document ? document->securityOrigin() : 0); m_loading = false; - if (parent) { - parent->notifyLoadedSheet(sheet); - parent->checkLoaded(); + if (m_parentStyleSheet) { + m_parentStyleSheet->notifyLoadedSheet(cachedStyleSheet); + m_parentStyleSheet->checkLoaded(); } } -bool CSSImportRule::isLoading() const +bool StyleRuleImport::isLoading() const { return m_loading || (m_styleSheet && m_styleSheet->isLoading()); } -void CSSImportRule::requestStyleSheet() +void StyleRuleImport::requestStyleSheet() { - CSSStyleSheet* parentSheet = parentStyleSheet(); - if (!parentSheet) + if (!m_parentStyleSheet) return; - Document* document = parentSheet->findDocument(); + Document* document = m_parentStyleSheet->singleOwnerDocument(); if (!document) return; @@ -128,55 +100,81 @@ void CSSImportRule::requestStyleSheet() return; String absHref = m_strHref; - if (!parentSheet->finalURL().isNull()) + if (!m_parentStyleSheet->finalURL().isNull()) // use parent styleheet's URL as the base URL - absHref = KURL(parentSheet->finalURL(), m_strHref).string(); + absHref = KURL(m_parentStyleSheet->finalURL(), m_strHref).string(); // Check for a cycle in our import chain. If we encounter a stylesheet // in our parent chain with the same URL, then just bail. - CSSStyleSheet* rootSheet = parentSheet; - for (CSSStyleSheet* sheet = parentSheet; sheet; sheet = sheet->parentStyleSheet()) { - // FIXME: This is wrong if the finalURL was updated via document::updateBaseURL. - if (absHref == sheet->finalURL().string()) + StyleSheetInternal* rootSheet = m_parentStyleSheet; + for (StyleSheetInternal* sheet = m_parentStyleSheet; sheet; sheet = sheet->parentStyleSheet()) { + if (absHref == sheet->finalURL().string() || absHref == sheet->originalURL()) return; rootSheet = sheet; } ResourceRequest request(document->completeURL(absHref)); - if (parentSheet->isUserStyleSheet()) - m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, parentSheet->charset()); + if (m_parentStyleSheet->isUserStyleSheet()) + m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, m_parentStyleSheet->charset()); else - m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, parentSheet->charset()); + m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, m_parentStyleSheet->charset()); if (m_cachedSheet) { // if the import rule is issued dynamically, the sheet may be // removed from the pending sheet count, so let the doc know // the sheet being imported is pending. - if (parentSheet && parentSheet->loadCompleted() && rootSheet == parentSheet) - parentSheet->startLoadingDynamicSheet(); + if (m_parentStyleSheet && m_parentStyleSheet->loadCompleted() && rootSheet == m_parentStyleSheet) + m_parentStyleSheet->startLoadingDynamicSheet(); m_loading = true; m_cachedSheet->addClient(&m_styleSheetClient); } } -String CSSImportRule::cssText() const +CSSImportRule::CSSImportRule(StyleRuleImport* importRule, CSSStyleSheet* parent) + : CSSRule(parent, CSSRule::IMPORT_RULE) + , m_importRule(importRule) { - String result = "@import url(\""; - result += m_strHref; - result += "\")"; +} - if (m_lstMedia) { - result += " "; - result += m_lstMedia->mediaText(); - } - result += ";"; +CSSImportRule::~CSSImportRule() +{ + if (m_styleSheetCSSOMWrapper) + m_styleSheetCSSOMWrapper->clearOwnerRule(); + if (m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper->clearParentRule(); +} - return result; +MediaList* CSSImportRule::media() const +{ + if (!m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper = MediaList::create(m_importRule->mediaQueries(), const_cast<CSSImportRule*>(this)); + return m_mediaCSSOMWrapper.get(); } -void CSSImportRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +String CSSImportRule::cssText() const { - if (m_styleSheet) - addSubresourceURL(urls, m_styleSheet->baseURL()); + StringBuilder result; + result.append("@import url(\""); + result.append(m_importRule->href()); + result.append("\")"); + + if (m_importRule->mediaQueries()) { + result.append(' '); + result.append(m_importRule->mediaQueries()->mediaText()); + } + result.append(';'); + + return result.toString(); +} + +CSSStyleSheet* CSSImportRule::styleSheet() const +{ + if (!m_importRule->styleSheet()) + return 0; + + if (!m_styleSheetCSSOMWrapper) + m_styleSheetCSSOMWrapper = CSSStyleSheet::create(m_importRule->styleSheet(), const_cast<CSSImportRule*>(this)); + return m_styleSheetCSSOMWrapper.get(); } + } // namespace WebCore diff --git a/Source/WebCore/css/CSSImportRule.h b/Source/WebCore/css/CSSImportRule.h index ad15087ba..ef2fd4287 100644 --- a/Source/WebCore/css/CSSImportRule.h +++ b/Source/WebCore/css/CSSImportRule.h @@ -25,64 +25,85 @@ #include "CSSRule.h" #include "CachedResourceHandle.h" #include "CachedStyleSheetClient.h" -#include "MediaList.h" #include "PlatformString.h" +#include "StyleRule.h" namespace WebCore { class CachedCSSStyleSheet; class MediaList; +class MediaQuerySet; +class StyleSheetInternal; -class CSSImportRule : public CSSRule { +class StyleRuleImport : public StyleRuleBase { public: - static PassRefPtr<CSSImportRule> create(CSSStyleSheet* parent, const String& href, PassRefPtr<MediaList> media) - { - return adoptRef(new CSSImportRule(parent, href, media)); - } + static PassRefPtr<StyleRuleImport> create(const String& href, PassRefPtr<MediaQuerySet>); - ~CSSImportRule(); + ~StyleRuleImport(); + + StyleSheetInternal* parentStyleSheet() const { return m_parentStyleSheet; } + void setParentStyleSheet(StyleSheetInternal* sheet) { ASSERT(sheet); m_parentStyleSheet = sheet; } + void clearParentStyleSheet() { m_parentStyleSheet = 0; } String href() const { return m_strHref; } - MediaList* media() const { return m_lstMedia.get(); } - CSSStyleSheet* styleSheet() const { return m_styleSheet.get(); } + StyleSheetInternal* styleSheet() const { return m_styleSheet.get(); } - String cssText() const; - - // Not part of the CSSOM bool isLoading() const; - - void addSubresourceStyleURLs(ListHashSet<KURL>& urls); + MediaQuerySet* mediaQueries() { return m_mediaQueries.get(); } void requestStyleSheet(); private: // NOTE: We put the CachedStyleSheetClient in a member instead of inheriting from it - // to avoid adding a vptr to CSSImportRule. + // to avoid adding a vptr to StyleRuleImport. class ImportedStyleSheetClient : public CachedStyleSheetClient { public: - ImportedStyleSheetClient(CSSImportRule* ownerRule) : m_ownerRule(ownerRule) { } + ImportedStyleSheetClient(StyleRuleImport* ownerRule) : m_ownerRule(ownerRule) { } virtual ~ImportedStyleSheetClient() { } virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet) { m_ownerRule->setCSSStyleSheet(href, baseURL, charset, sheet); } private: - CSSImportRule* m_ownerRule; + StyleRuleImport* m_ownerRule; }; void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*); friend class ImportedStyleSheetClient; - CSSImportRule(CSSStyleSheet* parent, const String& href, PassRefPtr<MediaList>); + StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet>); + + StyleSheetInternal* m_parentStyleSheet; ImportedStyleSheetClient m_styleSheetClient; String m_strHref; - RefPtr<MediaList> m_lstMedia; - RefPtr<CSSStyleSheet> m_styleSheet; + RefPtr<MediaQuerySet> m_mediaQueries; + RefPtr<StyleSheetInternal> m_styleSheet; CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet; bool m_loading; }; +class CSSImportRule : public CSSRule { +public: + static PassRefPtr<CSSImportRule> create(StyleRuleImport* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSImportRule(rule, sheet)); } + + ~CSSImportRule(); + + String href() const { return m_importRule->href(); } + MediaList* media() const; + CSSStyleSheet* styleSheet() const; + + String cssText() const; + +private: + CSSImportRule(StyleRuleImport*, CSSStyleSheet*); + + RefPtr<StyleRuleImport> m_importRule; + + mutable RefPtr<MediaList> m_mediaCSSOMWrapper; + mutable RefPtr<CSSStyleSheet> m_styleSheetCSSOMWrapper; +}; + } // namespace WebCore #endif // CSSImportRule_h diff --git a/Source/WebCore/css/CSSMediaRule.cpp b/Source/WebCore/css/CSSMediaRule.cpp index baf19b69a..a6ee351f7 100644 --- a/Source/WebCore/css/CSSMediaRule.cpp +++ b/Source/WebCore/css/CSSMediaRule.cpp @@ -1,7 +1,7 @@ /** * (C) 1999-2003 Lars Knoll (knoll@kde.org) * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2002, 2005, 2006, 2012 Apple Computer, Inc. * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) * * This library is free software; you can redistribute it and/or @@ -24,50 +24,45 @@ #include "CSSMediaRule.h" #include "CSSParser.h" +#include "CSSRuleList.h" #include "ExceptionCode.h" +#include "StyleRule.h" +#include <wtf/text/StringBuilder.h> namespace WebCore { -CSSMediaRule::CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList> media, PassRefPtr<CSSRuleList> rules) +CSSMediaRule::CSSMediaRule(StyleRuleMedia* mediaRule, CSSStyleSheet* parent) : CSSRule(parent, CSSRule::MEDIA_RULE) - , m_lstMedia(media) - , m_lstCSSRules(rules) + , m_mediaRule(mediaRule) + , m_childRuleCSSOMWrappers(mediaRule->childRules().size()) { - m_lstMedia->setParentStyleSheet(parent); - int length = m_lstCSSRules->length(); - for (int i = 0; i < length; i++) - m_lstCSSRules->item(i)->setParentRule(this); } CSSMediaRule::~CSSMediaRule() { - if (m_lstMedia) - m_lstMedia->setParentStyleSheet(0); + ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); - int length = m_lstCSSRules->length(); - for (int i = 0; i < length; i++) - m_lstCSSRules->item(i)->setParentRule(0); + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->setParentRule(0); + } + if (m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper->clearParentRule(); } -unsigned CSSMediaRule::append(CSSRule* rule) +unsigned CSSMediaRule::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec) { - if (!rule) - return 0; - - rule->setParentRule(this); - return m_lstCSSRules->insertRule(rule, m_lstCSSRules->length()); -} + ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); -unsigned CSSMediaRule::insertRule(const String& rule, unsigned index, ExceptionCode& ec) -{ - if (index > m_lstCSSRules->length()) { + if (index > m_mediaRule->childRules().size()) { // INDEX_SIZE_ERR: Raised if the specified index is not a valid insertion point. ec = INDEX_SIZE_ERR; return 0; } - CSSParser p(useStrictParsing()); - RefPtr<CSSRule> newRule = p.parseRule(parentStyleSheet(), rule); + CSSParser parser(parserContext()); + CSSStyleSheet* styleSheet = parentStyleSheet(); + RefPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->internal() : 0, ruleString); if (!newRule) { // SYNTAX_ERR: Raised if the specified rule has a syntax error and is unparsable. ec = SYNTAX_ERR; @@ -85,27 +80,31 @@ unsigned CSSMediaRule::insertRule(const String& rule, unsigned index, ExceptionC ec = HIERARCHY_REQUEST_ERR; return 0; } + m_mediaRule->wrapperInsertRule(index, newRule); - newRule->setParentRule(this); - unsigned returnedIndex = m_lstCSSRules->insertRule(newRule.get(), index); + m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); if (CSSStyleSheet* styleSheet = parentStyleSheet()) styleSheet->styleSheetChanged(); - return returnedIndex; + return index; } void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec) { - if (index >= m_lstCSSRules->length()) { + ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); + + if (index >= m_mediaRule->childRules().size()) { // INDEX_SIZE_ERR: Raised if the specified index does not correspond to a // rule in the media rule list. ec = INDEX_SIZE_ERR; return; } + m_mediaRule->wrapperRemoveRule(index); - m_lstCSSRules->item(index)->setParentRule(0); - m_lstCSSRules->deleteRule(index); + if (m_childRuleCSSOMWrappers[index]) + m_childRuleCSSOMWrappers[index]->setParentRule(0); + m_childRuleCSSOMWrappers.remove(index); if (CSSStyleSheet* styleSheet = parentStyleSheet()) styleSheet->styleSheetChanged(); @@ -113,18 +112,55 @@ void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec) String CSSMediaRule::cssText() const { - String result = "@media "; - if (m_lstMedia) { - result += m_lstMedia->mediaText(); - result += " "; + StringBuilder result; + result.append("@media "); + if (m_mediaRule->mediaQueries()) { + result.append(m_mediaRule->mediaQueries()->mediaText()); + result.append(' '); + } + result.append("{ \n"); + + unsigned size = length(); + for (unsigned i = 0; i < size; ++i) { + result.append(" "); + result.append(item(i)->cssText()); + result.append('\n'); } - result += "{ \n"; - if (m_lstCSSRules) - result += m_lstCSSRules->rulesText(); + result.append('}'); + return result.toString(); +} + +MediaList* CSSMediaRule::media() const +{ + if (!m_mediaRule->mediaQueries()) + return 0; + if (!m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper = MediaList::create(m_mediaRule->mediaQueries(), const_cast<CSSMediaRule*>(this)); + return m_mediaCSSOMWrapper.get(); +} + +unsigned CSSMediaRule::length() const +{ + return m_mediaRule->childRules().size(); +} - result += "}"; - return result; +CSSRule* CSSMediaRule::item(unsigned index) const +{ + if (index >= length()) + return 0; + ASSERT(m_childRuleCSSOMWrappers.size() == m_mediaRule->childRules().size()); + RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index]; + if (!rule) + rule = m_mediaRule->childRules()[index]->createCSSOMWrapper(const_cast<CSSMediaRule*>(this)); + return rule.get(); +} + +CSSRuleList* CSSMediaRule::cssRules() const +{ + if (!m_ruleListCSSOMWrapper) + m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSMediaRule>(const_cast<CSSMediaRule*>(this))); + return m_ruleListCSSOMWrapper.get(); } } // namespace WebCore diff --git a/Source/WebCore/css/CSSMediaRule.h b/Source/WebCore/css/CSSMediaRule.h index a591192a9..1aa544252 100644 --- a/Source/WebCore/css/CSSMediaRule.h +++ b/Source/WebCore/css/CSSMediaRule.h @@ -24,38 +24,40 @@ #define CSSMediaRule_h #include "CSSRule.h" -#include "CSSRuleList.h" #include "MediaList.h" #include "PlatformString.h" // needed so bindings will compile namespace WebCore { class CSSRuleList; +class StyleRuleMedia; class CSSMediaRule : public CSSRule { public: - static PassRefPtr<CSSMediaRule> create(CSSStyleSheet* parent, PassRefPtr<MediaList> media, PassRefPtr<CSSRuleList> rules) - { - return adoptRef(new CSSMediaRule(parent, media, rules)); - } + static PassRefPtr<CSSMediaRule> create(StyleRuleMedia* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSMediaRule(rule, sheet)); } + ~CSSMediaRule(); - MediaList* media() const { return m_lstMedia.get(); } - CSSRuleList* cssRules() { return m_lstCSSRules.get(); } + MediaList* media() const; + CSSRuleList* cssRules() const; unsigned insertRule(const String& rule, unsigned index, ExceptionCode&); void deleteRule(unsigned index, ExceptionCode&); String cssText() const; - - // Not part of the CSSOM - unsigned append(CSSRule*); + + // For CSSRuleList + unsigned length() const; + CSSRule* item(unsigned index) const; private: - CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList>, PassRefPtr<CSSRuleList>); + CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*); + + RefPtr<StyleRuleMedia> m_mediaRule; - RefPtr<MediaList> m_lstMedia; - RefPtr<CSSRuleList> m_lstCSSRules; + mutable RefPtr<MediaList> m_mediaCSSOMWrapper; + mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers; + mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper; }; } // namespace WebCore diff --git a/Source/WebCore/css/CSSNamespace.h b/Source/WebCore/css/CSSNamespace.h index 92638f20e..992b97fa0 100644 --- a/Source/WebCore/css/CSSNamespace.h +++ b/Source/WebCore/css/CSSNamespace.h @@ -1,55 +1 @@ -/* - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * 1999 Waldo Bastian (bastian@kde.org) - * Copyright (C) 2004, 2006, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef CSSNamespace_h -#define CSSNamespace_h - -#include <wtf/text/AtomicString.h> - -namespace WebCore { - - struct CSSNamespace { - WTF_MAKE_NONCOPYABLE(CSSNamespace); WTF_MAKE_FAST_ALLOCATED; - public: - AtomicString prefix; - AtomicString uri; - OwnPtr<CSSNamespace> parent; - - CSSNamespace(const AtomicString& prefix, const AtomicString& uri, PassOwnPtr<CSSNamespace> parent) - : prefix(prefix) - , uri(uri) - , parent(parent) - { - } - - CSSNamespace* namespaceForPrefix(const AtomicString& prefix) - { - for (CSSNamespace* candidate = this; candidate; candidate = candidate->parent.get()) { - if (candidate->prefix == prefix) - return candidate; - } - return 0; - } - }; - -} // namespace WebCore - -#endif // CSSNamespace_h +// FIXME: Remove this file. diff --git a/Source/WebCore/css/CSSPageRule.cpp b/Source/WebCore/css/CSSPageRule.cpp index 3858d3a54..88a089954 100644 --- a/Source/WebCore/css/CSSPageRule.cpp +++ b/Source/WebCore/css/CSSPageRule.cpp @@ -25,25 +25,36 @@ #include "CSSParser.h" #include "CSSSelector.h" #include "Document.h" +#include "PropertySetCSSStyleDeclaration.h" #include "StylePropertySet.h" +#include "StyleRule.h" #include <wtf/Vector.h> namespace WebCore { -CSSPageRule::CSSPageRule(CSSStyleSheet* parent) +CSSPageRule::CSSPageRule(StyleRulePage* pageRule, CSSStyleSheet* parent) : CSSRule(parent, CSSRule::PAGE_RULE) + , m_pageRule(pageRule) { } CSSPageRule::~CSSPageRule() { - m_style->clearParentRule(this); + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->clearParentRule(); +} + +CSSStyleDeclaration* CSSPageRule::style() const +{ + if (!m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_pageRule->properties(), const_cast<CSSPageRule*>(this)); + return m_propertiesCSSOMWrapper.get(); } String CSSPageRule::selectorText() const { String text = "@page"; - const CSSSelector* selector = this->selector(); + const CSSSelector* selector = m_pageRule->selector(); if (selector) { String pageSpecification = selector->selectorText(); if (!pageSpecification.isEmpty() && pageSpecification != starAtom) @@ -56,29 +67,29 @@ void CSSPageRule::setSelectorText(const String& selectorText) { Document* doc = 0; if (CSSStyleSheet* styleSheet = parentStyleSheet()) - doc = styleSheet->findDocument(); + doc = styleSheet->ownerDocument(); if (!doc) return; - CSSParser p; + CSSParser parser(parserContext()); CSSSelectorList selectorList; - p.parseSelector(selectorText, doc, selectorList); + parser.parseSelector(selectorText, selectorList); if (!selectorList.first()) return; String oldSelectorText = this->selectorText(); - m_selectorList.adopt(selectorList); + m_pageRule->wrapperAdoptSelectorList(selectorList); if (this->selectorText() == oldSelectorText) return; - doc->styleSelectorChanged(DeferRecalcStyle); + doc->styleResolverChanged(DeferRecalcStyle); } String CSSPageRule::cssText() const { String result = selectorText(); result += " { "; - result += m_style->asText(); + result += m_pageRule->properties()->asText(); result += "}"; return result; } diff --git a/Source/WebCore/css/CSSPageRule.h b/Source/WebCore/css/CSSPageRule.h index c837274fd..69a578d75 100644 --- a/Source/WebCore/css/CSSPageRule.h +++ b/Source/WebCore/css/CSSPageRule.h @@ -23,42 +23,35 @@ #define CSSPageRule_h #include "CSSRule.h" -#include "CSSSelectorList.h" -#include "StylePropertySet.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> namespace WebCore { -class CSSSelector; -class CSSSelectorList; +class CSSStyleDeclaration; +class CSSStyleSheet; +class StyleRulePage; +class StyleRuleCSSStyleDeclaration; class CSSPageRule : public CSSRule { public: - static PassRefPtr<CSSPageRule> create(CSSStyleSheet* parent) - { - return adoptRef(new CSSPageRule(parent)); - } + static PassRefPtr<CSSPageRule> create(StyleRulePage* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSPageRule(rule, sheet)); } + ~CSSPageRule(); - CSSStyleDeclaration* style() const { return m_style->ensureRuleCSSStyleDeclaration(this); } + CSSStyleDeclaration* style() const; String selectorText() const; void setSelectorText(const String&); String cssText() const; - const CSSSelector* selector() const { return m_selectorList.first(); } - StylePropertySet* properties() const { return m_style.get(); } - - void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); } - void setDeclaration(PassRefPtr<StylePropertySet> style) { m_style = style; } - private: - CSSPageRule(CSSStyleSheet* parent); + CSSPageRule(StyleRulePage*, CSSStyleSheet*); + + RefPtr<StyleRulePage> m_pageRule; - RefPtr<StylePropertySet> m_style; - CSSSelectorList m_selectorList; + mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper; }; } // namespace WebCore diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 3dc4bc912..3eef56cf6 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -1,10 +1,11 @@ /* * Copyright (C) 2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * Copyright (C) 2008 Eric Seidel <eric@webkit.org> * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,14 +29,15 @@ #include "CSSAspectRatioValue.h" #include "CSSBorderImage.h" #include "CSSCanvasValue.h" -#include "CSSCharsetRule.h" #include "CSSCrossfadeValue.h" #include "CSSCursorImageValue.h" -#include "CSSFlexValue.h" #include "CSSFontFaceRule.h" #include "CSSFontFaceSrcValue.h" #include "CSSFunctionValue.h" #include "CSSGradientValue.h" +#if ENABLE(CSS_IMAGE_SET) +#include "CSSImageSetValue.h" +#endif #include "CSSImageValue.h" #include "CSSImportRule.h" #include "CSSInheritedValue.h" @@ -45,10 +47,8 @@ #include "CSSPageRule.h" #include "CSSPrimitiveValue.h" #include "CSSProperty.h" -#include "CSSPropertyNames.h" #include "CSSPropertySourceData.h" #include "CSSReflectValue.h" -#include "CSSRuleList.h" #include "CSSSelector.h" #include "CSSStyleRule.h" #include "CSSStyleSheet.h" @@ -71,10 +71,13 @@ #include "Pair.h" #include "Rect.h" #include "RenderTheme.h" +#include "RuntimeEnabledFeatures.h" #include "Settings.h" #include "ShadowValue.h" #include "StylePropertySet.h" +#include "StylePropertyShorthand.h" #include "StyleRule.h" +#include "TextEncoding.h" #if ENABLE(CSS_FILTERS) #include "WebKitCSSFilterValue.h" #endif @@ -171,20 +174,57 @@ static bool hasPrefix(const char* string, unsigned length, const char* prefix) } return false; } + +const CSSParserContext& strictCSSParserContext() +{ + DEFINE_STATIC_LOCAL(CSSParserContext, strictContext, (CSSStrictMode)); + return strictContext; +} + +CSSParserContext::CSSParserContext(CSSParserMode mode, const KURL& baseURL) + : baseURL(baseURL) + , mode(mode) + , isHTMLDocument(false) + , isCSSCustomFilterEnabled(false) + , isCSSRegionsEnabled(false) + , needsSiteSpecificQuirks(false) + , enforcesCSSMIMETypeInNoQuirksMode(true) +{ +} -inline void CSSParser::ensureCSSValuePool() +CSSParserContext::CSSParserContext(Document* document, const KURL& baseURL, const String& charset) + : baseURL(baseURL.isNull() ? document->baseURL() : baseURL) + , charset(charset) + , mode(document->inQuirksMode() ? CSSQuirksMode : CSSStrictMode) + , isHTMLDocument(document->isHTMLDocument()) + , isCSSCustomFilterEnabled(document->settings() ? document->settings()->isCSSCustomFilterEnabled() : false) + , isCSSRegionsEnabled(document->cssRegionsEnabled()) + , needsSiteSpecificQuirks(document->settings() ? document->settings()->needsSiteSpecificQuirks() : false) + , enforcesCSSMIMETypeInNoQuirksMode(!document->settings() || document->settings()->enforceCSSMIMETypeInNoQuirksMode()) { - if (!m_cssValuePool) - m_cssValuePool = CSSValuePool::create(); } -CSSParser::CSSParser(bool strictParsing) - : m_strict(strictParsing) +bool operator==(const CSSParserContext& a, const CSSParserContext& b) +{ + return a.baseURL == b.baseURL + && a.charset == b.charset + && a.mode == b.mode + && a.isHTMLDocument == b.isHTMLDocument + && a.isCSSCustomFilterEnabled == b.isCSSCustomFilterEnabled + && a.isCSSRegionsEnabled == b.isCSSRegionsEnabled + && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks + && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode; +} + +CSSParser::CSSParser(const CSSParserContext& context) + : m_context(context) , m_important(false) - , m_id(0) + , m_id(CSSPropertyInvalid) , m_styleSheet(0) + , m_selectorListForParseSelector(0) + , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES) , m_inParseShorthand(0) - , m_currentShorthand(0) + , m_currentShorthand(CSSPropertyInvalid) , m_implicitShorthand(false) , m_hasFontFaceOnlyValues(false) , m_hadSyntacticallyValidCSSRule(false) @@ -197,6 +237,7 @@ CSSParser::CSSParser(bool strictParsing) , m_currentRuleData(0) , m_parsingMode(NormalMode) , m_currentCharacter(0) + , m_tokenStart(0) , m_token(0) , m_lineNumber(0) , m_lastSelectorLineNumber(0) @@ -257,7 +298,7 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char resetRuleBodyMarks(); } -void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int startLineNumber, StyleRuleRangeMap* ruleRangeMap) +void CSSParser::parseSheet(StyleSheetInternal* sheet, const String& string, int startLineNumber, StyleRuleRangeMap* ruleRangeMap) { setStyleSheet(sheet); m_defaultNamespace = starAtom; // Reset the default namespace. @@ -275,7 +316,7 @@ void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int start m_rule = 0; } -PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string) +PassRefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetInternal* sheet, const String& string) { setStyleSheet(sheet); m_allowNamespaceDeclarations = false; @@ -284,7 +325,7 @@ PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& str return m_rule.release(); } -PassRefPtr<WebKitCSSKeyframeRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string) +PassRefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetInternal* sheet, const String& string) { setStyleSheet(sheet); setupParser("@-webkit-keyframe-rule{ ", string, "} "); @@ -292,7 +333,7 @@ PassRefPtr<WebKitCSSKeyframeRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sh return m_keyframe.release(); } -static inline bool isColorPropertyID(int propertyId) +static inline bool isColorPropertyID(CSSPropertyID propertyId) { switch (propertyId) { case CSSPropertyColor: @@ -319,10 +360,10 @@ static inline bool isColorPropertyID(int propertyId) } } -static bool parseColorValue(StylePropertySet* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet) +static bool parseColorValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) { - if (!string.length()) - return false; + ASSERT(!string.isEmpty()); + bool strict = isStrictParserMode(cssParserMode); if (!isColorPropertyID(propertyId)) return false; CSSParserString cssString; @@ -339,29 +380,20 @@ static bool parseColorValue(StylePropertySet* declaration, int propertyId, const validPrimitive = true; } - Document* document = contextStyleSheet->findDocument(); if (validPrimitive) { - RefPtr<CSSValue> value; - if (document) - value = document->cssValuePool()->createIdentifierValue(valueID); - else - value = CSSPrimitiveValue::createIdentifier(valueID); + RefPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID); declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); return true; } RGBA32 color; if (!CSSParser::fastParseColor(color, string, strict && string[0] != '#')) return false; - RefPtr<CSSValue> value; - if (document) - value = document->cssValuePool()->createColorValue(color); - else - value = CSSPrimitiveValue::createColor(color); + RefPtr<CSSValue> value = cssValuePool().createColorValue(color); declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); return true; } -static inline bool isSimpleLengthPropertyID(int propertyId, bool& acceptsNegativeNumbers) +static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acceptsNegativeNumbers) { switch (propertyId) { case CSSPropertyFontSize: @@ -381,10 +413,12 @@ static inline bool isSimpleLengthPropertyID(int propertyId, bool& acceptsNegativ case CSSPropertyWebkitPaddingBefore: case CSSPropertyWebkitPaddingEnd: case CSSPropertyWebkitPaddingStart: + acceptsNegativeNumbers = false; + return true; case CSSPropertyWebkitWrapMargin: case CSSPropertyWebkitWrapPadding: acceptsNegativeNumbers = false; - return true; + return RuntimeEnabledFeatures::cssExclusionsEnabled(); case CSSPropertyBottom: case CSSPropertyLeft: case CSSPropertyMarginBottom: @@ -405,14 +439,13 @@ static inline bool isSimpleLengthPropertyID(int propertyId, bool& acceptsNegativ } } -static bool parseSimpleLengthValue(StylePropertySet* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet) +static bool parseSimpleLengthValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode) { + ASSERT(!string.isEmpty()); bool acceptsNegativeNumbers; + bool strict = isStrictParserMode(cssParserMode); unsigned length = string.length(); - if (!length) - return false; - double number; bool ok; CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER; @@ -469,41 +502,497 @@ static bool parseSimpleLengthValue(StylePropertySet* declaration, int propertyId if (number < 0 && !acceptsNegativeNumbers) return false; - Document* document = contextStyleSheet->findDocument(); + RefPtr<CSSValue> value = cssValuePool().createValue(number, unit); + declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); + return true; +} + +static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID) +{ + if (!valueID) + return false; + + switch (propertyId) { + case CSSPropertyBorderCollapse: // collapse | separate | inherit + if (valueID == CSSValueCollapse || valueID == CSSValueSeparate) + return true; + break; + case CSSPropertyBorderTopStyle: // <border-style> | inherit + case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed | + case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset + case CSSPropertyBorderLeftStyle: + case CSSPropertyWebkitBorderAfterStyle: + case CSSPropertyWebkitBorderBeforeStyle: + case CSSPropertyWebkitBorderEndStyle: + case CSSPropertyWebkitBorderStartStyle: + case CSSPropertyWebkitColumnRuleStyle: + if (valueID >= CSSValueNone && valueID <= CSSValueDouble) + return true; + break; + case CSSPropertyBoxSizing: + if (valueID == CSSValueBorderBox || valueID == CSSValueContentBox) + return true; + break; + case CSSPropertyCaptionSide: // top | bottom | left | right | inherit + if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom) + return true; + break; + case CSSPropertyClear: // none | left | right | both | inherit + if (valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth) + return true; + break; + case CSSPropertyDirection: // ltr | rtl | inherit + if (valueID == CSSValueLtr || valueID == CSSValueRtl) + return true; + break; + case CSSPropertyDisplay: + // inline | block | list-item | run-in | inline-block | table | + // inline-table | table-row-group | table-header-group | table-footer-group | table-row | + // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit + // -webkit-flexbox | -webkit-inline-flexbox | -webkit-grid | -webkit-inline-grid + if ((valueID >= CSSValueInline && valueID <= CSSValueWebkitInlineFlexbox) || valueID == CSSValueNone) + return true; +#if ENABLE(CSS_GRID_LAYOUT) + if (valueID == CSSValueWebkitGrid || valueID == CSSValueWebkitInlineGrid) + return true; +#endif + break; + case CSSPropertyEmptyCells: // show | hide | inherit + if (valueID == CSSValueShow || valueID == CSSValueHide) + return true; + break; + case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none) + if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter) + return true; + break; + case CSSPropertyFontStyle: // normal | italic | oblique | inherit + if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique) + return true; + break; + case CSSPropertyImageRendering: // auto | optimizeContrast + if (valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast) + return true; + break; + case CSSPropertyListStylePosition: // inside | outside | inherit + if (valueID == CSSValueInside || valueID == CSSValueOutside) + return true; + break; + case CSSPropertyListStyleType: + // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in + // for the list of supported list-style-types. + if ((valueID >= CSSValueDisc && valueID <= CSSValueKatakanaIroha) || valueID == CSSValueNone) + return true; + break; + case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto | inherit + if (valueID == CSSValueAuto || valueID == CSSValueNone || (valueID >= CSSValueInset && valueID <= CSSValueDouble)) + return true; + break; + case CSSPropertyOverflowX: + case CSSPropertyOverflowY: // visible | hidden | scroll | auto | marquee | overlay | inherit + if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitMarquee) + return true; + break; + case CSSPropertyPointerEvents: + // none | visiblePainted | visibleFill | visibleStroke | visible | + // painted | fill | stroke | auto | all | inherit + if (valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID >= CSSValueVisiblepainted && valueID <= CSSValueStroke)) + return true; + break; + case CSSPropertyPosition: // static | relative | absolute | fixed | inherit + if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed) + return true; + break; + case CSSPropertyResize: // none | both | horizontal | vertical | auto + if (valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto) + return true; + break; + case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit + if (valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation) + return true; + break; + case CSSPropertyTableLayout: // auto | fixed | inherit + if (valueID == CSSValueAuto || valueID == CSSValueFixed) + return true; + break; + case CSSPropertyTextLineThroughMode: + case CSSPropertyTextOverlineMode: + case CSSPropertyTextUnderlineMode: + if (valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace) + return true; + break; + case CSSPropertyTextLineThroughStyle: + case CSSPropertyTextOverlineStyle: + case CSSPropertyTextUnderlineStyle: + if (valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave) + return true; + break; + case CSSPropertyTextOverflow: // clip | ellipsis + if (valueID == CSSValueClip || valueID == CSSValueEllipsis) + return true; + break; + case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision + if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision) + return true; + break; + case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit + if ((valueID >= CSSValueCapitalize && valueID <= CSSValueLowercase) || valueID == CSSValueNone) + return true; + break; + case CSSPropertyVisibility: // visible | hidden | collapse | inherit + if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse) + return true; + break; + case CSSPropertyWebkitAppearance: + if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone) + return true; + break; + case CSSPropertyWebkitBackfaceVisibility: + if (valueID == CSSValueVisible || valueID == CSSValueHidden) + return true; + break; + case CSSPropertyWebkitBorderFit: + if (valueID == CSSValueBorder || valueID == CSSValueLines) + return true; + break; + case CSSPropertyWebkitBoxAlign: + if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline) + return true; + break; + case CSSPropertyWebkitBoxDirection: + if (valueID == CSSValueNormal || valueID == CSSValueReverse) + return true; + break; + case CSSPropertyWebkitBoxLines: + if (valueID == CSSValueSingle || valueID == CSSValueMultiple) + return true; + break; + case CSSPropertyWebkitBoxOrient: + if (valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis) + return true; + break; + case CSSPropertyWebkitBoxPack: + if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify) + return true; + break; + case CSSPropertyWebkitColorCorrection: + if (valueID == CSSValueSrgb || valueID == CSSValueDefault) + return true; + break; + case CSSPropertyWebkitFlexAlign: + if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) + return true; + break; + case CSSPropertyWebkitFlexDirection: + if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse) + return true; + break; + case CSSPropertyWebkitFlexItemAlign: + if (valueID == CSSValueAuto || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch) + return true; + break; + case CSSPropertyWebkitFlexLinePack: + if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify || valueID == CSSValueDistribute || valueID == CSSValueStretch) + return true; + break; + case CSSPropertyWebkitFlexPack: + if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify || valueID == CSSValueDistribute) + return true; + break; + case CSSPropertyWebkitFlexWrap: + if (valueID == CSSValueNone || valueID == CSSValueWrap || valueID == CSSValueWrapReverse) + return true; + break; + case CSSPropertyWebkitFontKerning: + if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone) + return true; + break; + case CSSPropertyWebkitFontSmoothing: + if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased) + return true; + break; + case CSSPropertyWebkitHyphens: + if (valueID == CSSValueNone || valueID == CSSValueManual || valueID == CSSValueAuto) + return true; + break; + case CSSPropertyWebkitLineAlign: + if (valueID == CSSValueNone || valueID == CSSValueEdges) + return true; + break; + case CSSPropertyWebkitLineBreak: // normal | after-white-space + if (valueID == CSSValueNormal || valueID == CSSValueAfterWhiteSpace) + return true; + break; + case CSSPropertyWebkitLineSnap: + if (valueID == CSSValueNone || valueID == CSSValueBaseline || valueID == CSSValueContain) + return true; + break; + case CSSPropertyWebkitMarginAfterCollapse: + case CSSPropertyWebkitMarginBeforeCollapse: + case CSSPropertyWebkitMarginBottomCollapse: + case CSSPropertyWebkitMarginTopCollapse: + if (valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard) + return true; + break; + case CSSPropertyWebkitMarqueeDirection: + if (valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown + || valueID == CSSValueUp || valueID == CSSValueAuto) + return true; + break; + case CSSPropertyWebkitMarqueeStyle: + if (valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate) + return true; + break; + case CSSPropertyWebkitMatchNearestMailBlockquoteColor: // normal | match + if (valueID == CSSValueNormal || valueID == CSSValueMatch) + return true; + break; + case CSSPropertyWebkitNbspMode: // normal | space + if (valueID == CSSValueNormal || valueID == CSSValueSpace) + return true; + break; +#if ENABLE(OVERFLOW_SCROLLING) + case CSSPropertyWebkitOverflowScrolling: + if (valueID == CSSValueAuto || valueID == CSSValueTouch) + return true; + break; +#endif + case CSSPropertyWebkitPrintColorAdjust: + if (valueID == CSSValueExact || valueID == CSSValueEconomy) + return true; + break; + case CSSPropertyWebkitRtlOrdering: + if (valueID == CSSValueLogical || valueID == CSSValueVisual) + return true; + break; + case CSSPropertyWebkitTextCombine: + if (valueID == CSSValueNone || valueID == CSSValueHorizontal) + return true; + break; + case CSSPropertyWebkitTextEmphasisPosition: + if (valueID == CSSValueOver || valueID == CSSValueUnder) + return true; + break; + case CSSPropertyWebkitTextSecurity: + // disc | circle | square | none | inherit + if (valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone) + return true; + break; + case CSSPropertyWebkitTextSizeAdjust: + if (valueID == CSSValueAuto || valueID == CSSValueNone) + return true; + break; + case CSSPropertyWebkitTransformStyle: + if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d) + return true; + break; + case CSSPropertyWebkitUserDrag: // auto | none | element + if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement) + return true; + break; + case CSSPropertyWebkitUserModify: // read-only | read-write + if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly) + return true; + break; + case CSSPropertyWebkitUserSelect: // auto | none | text + if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText) + return true; + break; + case CSSPropertyWebkitWrapFlow: + if (!RuntimeEnabledFeatures::cssExclusionsEnabled()) + return false; + if (valueID == CSSValueAuto || valueID == CSSValueBoth || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueMaximum || valueID == CSSValueClear) + return true; + break; + case CSSPropertyWebkitWrapThrough: + if (!RuntimeEnabledFeatures::cssExclusionsEnabled()) + return false; + if (valueID == CSSValueWrap || valueID == CSSValueNone) + return true; + break; + case CSSPropertyWebkitWritingMode: + if (valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt) + return true; + break; + case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit + if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap) + return true; + break; + case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension) + if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord) + return true; + break; + case CSSPropertyWordWrap: // normal | break-word + if (valueID == CSSValueNormal || valueID == CSSValueBreakWord) + return true; + break; + default: + ASSERT_NOT_REACHED(); + return false; + } + return false; +} + +static inline bool isKeywordPropertyID(CSSPropertyID propertyId) +{ + switch (propertyId) { + case CSSPropertyBorderBottomStyle: + case CSSPropertyBorderCollapse: + case CSSPropertyBorderLeftStyle: + case CSSPropertyBorderRightStyle: + case CSSPropertyBorderTopStyle: + case CSSPropertyBoxSizing: + case CSSPropertyCaptionSide: + case CSSPropertyClear: + case CSSPropertyDirection: + case CSSPropertyDisplay: + case CSSPropertyEmptyCells: + case CSSPropertyFloat: + case CSSPropertyFontStyle: + case CSSPropertyImageRendering: + case CSSPropertyListStylePosition: + case CSSPropertyListStyleType: + case CSSPropertyOutlineStyle: + case CSSPropertyOverflowX: + case CSSPropertyOverflowY: + case CSSPropertyPointerEvents: + case CSSPropertyPosition: + case CSSPropertyResize: + case CSSPropertySpeak: + case CSSPropertyTableLayout: + case CSSPropertyTextLineThroughMode: + case CSSPropertyTextLineThroughStyle: + case CSSPropertyTextOverflow: + case CSSPropertyTextOverlineMode: + case CSSPropertyTextOverlineStyle: + case CSSPropertyTextRendering: + case CSSPropertyTextTransform: + case CSSPropertyTextUnderlineMode: + case CSSPropertyTextUnderlineStyle: + case CSSPropertyVisibility: + case CSSPropertyWebkitAppearance: + case CSSPropertyWebkitBackfaceVisibility: + case CSSPropertyWebkitBorderAfterStyle: + case CSSPropertyWebkitBorderBeforeStyle: + case CSSPropertyWebkitBorderEndStyle: + case CSSPropertyWebkitBorderFit: + case CSSPropertyWebkitBorderStartStyle: + case CSSPropertyWebkitBoxAlign: + case CSSPropertyWebkitBoxDirection: + case CSSPropertyWebkitBoxLines: + case CSSPropertyWebkitBoxOrient: + case CSSPropertyWebkitBoxPack: + case CSSPropertyWebkitColorCorrection: + case CSSPropertyWebkitColumnRuleStyle: + case CSSPropertyWebkitFlexAlign: + case CSSPropertyWebkitFlexDirection: + case CSSPropertyWebkitFlexItemAlign: + case CSSPropertyWebkitFlexLinePack: + case CSSPropertyWebkitFlexPack: + case CSSPropertyWebkitFlexWrap: + case CSSPropertyWebkitFontKerning: + case CSSPropertyWebkitFontSmoothing: + case CSSPropertyWebkitHyphens: + case CSSPropertyWebkitLineAlign: + case CSSPropertyWebkitLineBreak: + case CSSPropertyWebkitLineSnap: + case CSSPropertyWebkitMarginAfterCollapse: + case CSSPropertyWebkitMarginBeforeCollapse: + case CSSPropertyWebkitMarginBottomCollapse: + case CSSPropertyWebkitMarginTopCollapse: + case CSSPropertyWebkitMarqueeDirection: + case CSSPropertyWebkitMarqueeStyle: + case CSSPropertyWebkitMatchNearestMailBlockquoteColor: + case CSSPropertyWebkitNbspMode: +#if ENABLE(OVERFLOW_SCROLLING) + case CSSPropertyWebkitOverflowScrolling: +#endif + case CSSPropertyWebkitPrintColorAdjust: + case CSSPropertyWebkitRtlOrdering: + case CSSPropertyWebkitTextCombine: + case CSSPropertyWebkitTextEmphasisPosition: + case CSSPropertyWebkitTextSecurity: + case CSSPropertyWebkitTextSizeAdjust: + case CSSPropertyWebkitTransformStyle: + case CSSPropertyWebkitUserDrag: + case CSSPropertyWebkitUserModify: + case CSSPropertyWebkitUserSelect: + case CSSPropertyWebkitWrapFlow: + case CSSPropertyWebkitWrapThrough: + case CSSPropertyWebkitWritingMode: + case CSSPropertyWhiteSpace: + case CSSPropertyWordBreak: + case CSSPropertyWordWrap: + return true; + default: + return false; + } +} + +static bool parseKeywordValue(StylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important) +{ + ASSERT(!string.isEmpty()); + + if (!isKeywordPropertyID(propertyId)) + return false; + + CSSParserString cssString; + cssString.characters = const_cast<UChar*>(string.characters()); + cssString.length = string.length(); + int valueID = cssValueKeywordID(cssString); + + if (!valueID) + return false; + RefPtr<CSSValue> value; - if (document) - value = document->cssValuePool()->createValue(number, unit); + if (valueID == CSSValueInherit) + value = cssValuePool().createInheritedValue(); + else if (valueID == CSSValueInitial) + value = cssValuePool().createExplicitInitialValue(); + else if (isValidKeywordPropertyAndValue(propertyId, valueID)) + value = cssValuePool().createIdentifierValue(valueID); else - value = CSSPrimitiveValue::create(number, unit); + return false; + declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important)); return true; } -PassRefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string, CSSStyleSheet* contextStyleSheet) +PassRefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string) { + if (string.isEmpty()) + return 0; RefPtr<StylePropertySet> dummyStyle = StylePropertySet::create(); - if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, false, contextStyleSheet)) + if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, CSSQuirksMode, 0)) return 0; return static_pointer_cast<CSSValueList>(dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily)); } -bool CSSParser::parseValue(StylePropertySet* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet) +bool CSSParser::parseValue(StylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetInternal* contextStyleSheet) { - if (parseSimpleLengthValue(declaration, propertyId, string, important, strict, contextStyleSheet)) + ASSERT(!string.isEmpty()); + if (parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode)) + return true; + if (parseColorValue(declaration, propertyID, string, important, cssParserMode)) return true; - if (parseColorValue(declaration, propertyId, string, important, strict, contextStyleSheet)) + if (parseKeywordValue(declaration, propertyID, string, important)) return true; - CSSParser parser(strict); - return parser.parseValue(declaration, propertyId, string, important, contextStyleSheet); + + CSSParserContext context(cssParserMode); + if (contextStyleSheet) { + context = contextStyleSheet->parserContext(); + context.mode = cssParserMode; + } + CSSParser parser(context); + return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet); } -bool CSSParser::parseValue(StylePropertySet* declaration, int propertyId, const String& string, bool important, CSSStyleSheet* contextStyleSheet) +bool CSSParser::parseValue(StylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, StyleSheetInternal* contextStyleSheet) { setStyleSheet(contextStyleSheet); setupParser("@-webkit-value{", string, "} "); - m_id = propertyId; + m_id = propertyID; m_important = important; cssyyparse(this); @@ -530,7 +1019,7 @@ bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) if (fastParseColor(color, string, strict)) return true; - CSSParser parser(true); + CSSParser parser(CSSStrictMode); // In case the fast-path parser didn't understand the color, try the full parser. if (!parser.parseColor(string)) @@ -550,10 +1039,6 @@ bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict) bool CSSParser::parseColor(const String& string) { - // This function may be called without a stylesheet set on the parser, so we need to - // make sure that we have a CSSValuePool or we'll crash below cssyyparse(). - ensureCSSValuePool(); - setupParser("@-webkit-decls{color:", string, "} "); cssyyparse(this); m_rule = 0; @@ -577,10 +1062,9 @@ bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document* return true; } -void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorList& selectorList) +void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList) { - RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc); - + RefPtr<StyleSheetInternal> dummyStyleSheet = StyleSheetInternal::create(); setStyleSheet(dummyStyleSheet.get()); m_selectorListForParseSelector = &selectorList; @@ -594,7 +1078,7 @@ void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorLi ASSERT(dummyStyleSheet->hasOneRef()); } -bool CSSParser::parseDeclaration(StylePropertySet* declaration, const String& string, RefPtr<CSSStyleSourceData>* styleSourceData, CSSStyleSheet* contextStyleSheet) +bool CSSParser::parseDeclaration(StylePropertySet* declaration, const String& string, RefPtr<CSSStyleSourceData>* styleSourceData, StyleSheetInternal* contextStyleSheet) { // Length of the "@-webkit-decls{" prefix. static const unsigned prefixLength = 15; @@ -637,10 +1121,10 @@ bool CSSParser::parseDeclaration(StylePropertySet* declaration, const String& st return ok; } -bool CSSParser::parseMediaQuery(MediaList* queries, const String& string) +PassOwnPtr<MediaQuery> CSSParser::parseMediaQuery(const String& string) { if (string.isEmpty()) - return true; + return nullptr; ASSERT(!m_mediaQuery); @@ -649,16 +1133,10 @@ bool CSSParser::parseMediaQuery(MediaList* queries, const String& string) setupParser("@-webkit-mediaquery ", string, "} "); cssyyparse(this); - bool ok = false; - if (m_mediaQuery) { - ok = true; - queries->appendMediaQuery(m_mediaQuery.release()); - } - - return ok; + return m_mediaQuery.release(); } -void CSSParser::addProperty(int propId, PassRefPtr<CSSValue> value, bool important, bool implicit) +void CSSParser::addProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit) { m_parsedProperties.append(CSSProperty(propId, value, important, m_currentShorthand, m_implicitShorthand || implicit)); } @@ -677,18 +1155,23 @@ void CSSParser::clearProperties() m_hasFontFaceOnlyValues = false; } -void CSSParser::setStyleSheet(CSSStyleSheet* styleSheet) +void CSSParser::setStyleSheet(StyleSheetInternal* styleSheet) { m_styleSheet = styleSheet; - Document* document = findDocument(); - m_cssValuePool = document ? document->cssValuePool() : CSSValuePool::create(); } -Document* CSSParser::findDocument() const +KURL CSSParser::completeURL(const CSSParserContext& context, const String& url) { - if (!m_styleSheet) - return 0; - return m_styleSheet->findDocument(); + if (url.isNull()) + return KURL(); + if (context.charset.isEmpty()) + return KURL(context.baseURL, url); + return KURL(context.baseURL, url, context.charset); +} + +KURL CSSParser::completeURL(const String& url) const +{ + return completeURL(m_context, url); } bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags) @@ -729,7 +1212,13 @@ bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags) return b; } -bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict) +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); +} + +bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode) { if (isCalculation(value)) return validCalculationUnit(value, unitflags); @@ -738,7 +1227,7 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict) switch (value->unit) { case CSSPrimitiveValue::CSS_NUMBER: b = (unitflags & FNumber); - if (!b && ((unitflags & (FLength | FAngle | FTime)) && (!value->fValue || !strict))) { + if (!b && shouldAcceptUnitLessValues(value, unitflags, cssParserMode)) { value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX : ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS); b = true; @@ -759,6 +1248,9 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, bool strict) case CSSPrimitiveValue::CSS_IN: case CSSPrimitiveValue::CSS_PT: case CSSPrimitiveValue::CSS_PC: + case CSSPrimitiveValue::CSS_VW: + case CSSPrimitiveValue::CSS_VH: + case CSSPrimitiveValue::CSS_VMIN: b = (unitflags & FLength); break; case CSSPrimitiveValue::CSS_MS: @@ -790,14 +1282,15 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSP } ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) - || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS)); - return cssValuePool()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); + || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS) + || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMIN)); + return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); } inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveStringValue(CSSParserValue* value) { ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT); - return cssValuePool()->createValue(value->string, CSSPrimitiveValue::CSS_STRING); + return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING); } static int unitFromString(CSSParserValue* value) @@ -839,13 +1332,25 @@ static int unitFromString(CSSParserValue* value) return CSSPrimitiveValue::CSS_HZ; if (equal(value->string, "kHz")) return CSSPrimitiveValue::CSS_KHZ; + if (equal(value->string, "vw")) + return CSSPrimitiveValue::CSS_VW; + if (equal(value->string, "vh")) + return CSSPrimitiveValue::CSS_VH; + if (equal(value->string, "vmin")) + return CSSPrimitiveValue::CSS_VMIN; return 0; } +static inline bool isComma(CSSParserValue* value) +{ + return value && value->unit == CSSParserValue::Operator && value->iValue == ','; +} + + void CSSParser::checkForOrphanedUnits() { - if (m_strict || inShorthand()) + if (inStrictMode() || inShorthand()) return; // The purpose of this code is to implement the WinIE quirk that allows unit types to be separated from their numeric values @@ -874,16 +1379,18 @@ void CSSParser::checkForOrphanedUnits() } } -inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int id, CSSParserValue* value) +inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int identifier, CSSParserValue* value) { - if (id) - return cssValuePool()->createIdentifierValue(id); + if (identifier) + return cssValuePool().createIdentifierValue(identifier); if (value->unit == CSSPrimitiveValue::CSS_STRING) return createPrimitiveStringValue(value); if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) return createPrimitiveNumericValue(value); if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS) return createPrimitiveNumericValue(value); + if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMIN) + return createPrimitiveNumericValue(value); if (value->unit >= CSSParserValue::Q_EMS) return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS); if (isCalculation(value)) @@ -892,7 +1399,7 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int id, CSSP return 0; } -bool CSSParser::parseValue(int propId, bool important) +bool CSSParser::parseValue(CSSPropertyID propId, bool important) { if (!m_valueList) return false; @@ -917,20 +1424,29 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueInherit) { if (num != 1) return false; - addProperty(propId, cssValuePool()->createInheritedValue(), important); + addProperty(propId, cssValuePool().createInheritedValue(), important); return true; } else if (id == CSSValueInitial) { if (num != 1) return false; - addProperty(propId, cssValuePool()->createExplicitInitialValue(), important); + addProperty(propId, cssValuePool().createExplicitInitialValue(), important); + return true; + } + + if (isKeywordPropertyID(propId)) { + if (!isValidKeywordPropertyAndValue(propId, id)) + return false; + if (m_valueList->next() && !inShorthand()) + return false; + addProperty(propId, cssValuePool().createIdentifierValue(id), important); return true; } bool validPrimitive = false; RefPtr<CSSValue> parsedValue; - switch (static_cast<CSSPropertyID>(propId)) { + switch (propId) { /* The comment to the left defines all valid value of this properties as defined * in CSS 2, Appendix F. Property index */ @@ -961,7 +1477,7 @@ bool CSSParser::parseValue(int propId, bool important) switch (value->id) { case CSSValueBidiOverride: case CSSValueWebkitIsolate: - list->append(cssValuePool()->createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); break; default: isValid = false; @@ -975,14 +1491,6 @@ bool CSSParser::parseValue(int propId, bool important) } break; - case CSSPropertyPosition: // static | relative | absolute | fixed | inherit - if (id == CSSValueStatic - || id == CSSValueRelative - || id == CSSValueAbsolute - || id == CSSValueFixed) - validPrimitive = true; - break; - case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit case CSSPropertyPageBreakBefore: case CSSPropertyWebkitColumnBreakAfter: @@ -1004,51 +1512,20 @@ bool CSSParser::parseValue(int propId, bool important) validPrimitive = (propId == CSSPropertyWebkitRegionBreakInside) ? cssRegionsEnabled() : true; break; - case CSSPropertyEmptyCells: // show | hide | inherit - if (id == CSSValueShow - || id == CSSValueHide) - validPrimitive = true; - break; - case CSSPropertyContent: // [ <string> | <uri> | <counter> | attr(X) | open-quote | // close-quote | no-open-quote | no-close-quote ]+ | inherit return parseContent(propId, important); - case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit - if (id == CSSValueNormal - || id == CSSValuePre - || id == CSSValuePreWrap - || id == CSSValuePreLine - || id == CSSValueNowrap) - validPrimitive = true; - break; - case CSSPropertyClip: // <shape> | auto | inherit if (id == CSSValueAuto) validPrimitive = true; else if (value->unit == CSSParserValue::Function) - return parseShape(propId, important); + return parseClipShape(propId, important); break; /* Start of supported CSS properties with validation. This is needed for parseShorthand to work * correctly and allows optimization in WebCore::applyRule(..) */ - case CSSPropertyCaptionSide: // top | bottom | left | right | inherit - if (id == CSSValueLeft || id == CSSValueRight || - id == CSSValueTop || id == CSSValueBottom) - validPrimitive = true; - break; - - case CSSPropertyBorderCollapse: // collapse | separate | inherit - if (id == CSSValueCollapse || id == CSSValueSeparate) - validPrimitive = true; - break; - - case CSSPropertyVisibility: // visible | hidden | collapse | inherit - if (id == CSSValueVisible || id == CSSValueHidden || id == CSSValueCollapse) - validPrimitive = true; - break; - case CSSPropertyOverflow: { ShorthandScope scope(this, propId); if (num != 1 || !parseValue(CSSPropertyOverflowX, important)) @@ -1057,59 +1534,6 @@ bool CSSParser::parseValue(int propId, bool important) addProperty(CSSPropertyOverflowY, value, important); return true; } - case CSSPropertyOverflowX: - case CSSPropertyOverflowY: // visible | hidden | scroll | auto | marquee | overlay | inherit - if (id == CSSValueVisible || id == CSSValueHidden || id == CSSValueScroll || id == CSSValueAuto || - id == CSSValueOverlay || id == CSSValueWebkitMarquee) - validPrimitive = true; - break; - - case CSSPropertyListStylePosition: // inside | outside | inherit - if (id == CSSValueInside || id == CSSValueOutside) - validPrimitive = true; - break; - - case CSSPropertyListStyleType: - // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in - // for the list of supported list-style-types. - if ((id >= CSSValueDisc && id <= CSSValueKatakanaIroha) || id == CSSValueNone) - validPrimitive = true; - break; - - case CSSPropertyDisplay: - // inline | block | list-item | run-in | inline-block | table | - // inline-table | table-row-group | table-header-group | table-footer-group | table-row | - // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit - // -webkit-flexbox | -webkit-inline-flexbox | -webkit-grid | -webkit-inline-grid - if ((id >= CSSValueInline && id <= CSSValueWebkitInlineFlexbox) || id == CSSValueNone) - validPrimitive = true; -#if ENABLE(CSS_GRID_LAYOUT) - if (id == CSSValueWebkitGrid || id == CSSValueWebkitInlineGrid) - validPrimitive = true; -#endif - break; - - case CSSPropertyDirection: // ltr | rtl | inherit - if (id == CSSValueLtr || id == CSSValueRtl) - validPrimitive = true; - break; - - case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit - if ((id >= CSSValueCapitalize && id <= CSSValueLowercase) || id == CSSValueNone) - validPrimitive = true; - break; - - case CSSPropertyFloat: // left | right | none | positioned | center (for buggy CSS, maps to none) - if (id == CSSValueLeft || id == CSSValueRight - || id == CSSValueNone || id == CSSValueCenter || id == CSSValueWebkitPositioned) - validPrimitive = true; - break; - - case CSSPropertyClear: // none | left | right | both | inherit - if (id == CSSValueNone || id == CSSValueLeft - || id == CSSValueRight || id == CSSValueBoth) - validPrimitive = true; - break; case CSSPropertyTextAlign: // left | right | center | justify | webkit_left | webkit_right | webkit_center | webkit_match_parent | @@ -1119,41 +1543,23 @@ bool CSSParser::parseValue(int propId, bool important) validPrimitive = true; break; - case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto | inherit - if (id == CSSValueAuto || id == CSSValueNone || (id >= CSSValueInset && id <= CSSValueDouble)) - validPrimitive = true; - break; - - case CSSPropertyBorderTopStyle: //// <border-style> | inherit - case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed | - case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset - case CSSPropertyBorderLeftStyle: - case CSSPropertyWebkitBorderStartStyle: - case CSSPropertyWebkitBorderEndStyle: - case CSSPropertyWebkitBorderBeforeStyle: - case CSSPropertyWebkitBorderAfterStyle: - case CSSPropertyWebkitColumnRuleStyle: - if (id >= CSSValueNone && id <= CSSValueDouble) - validPrimitive = true; - break; - - case CSSPropertyFontWeight: // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit + case CSSPropertyFontWeight: { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit + if (m_valueList->size() != 1) + return false; return parseFontWeight(important); - + } case CSSPropertyBorderSpacing: { - const int properties[2] = { CSSPropertyWebkitBorderHorizontalSpacing, - CSSPropertyWebkitBorderVerticalSpacing }; if (num == 1) { ShorthandScope scope(this, CSSPropertyBorderSpacing); - if (!parseValue(properties[0], important)) + if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important)) return false; CSSValue* value = m_parsedProperties.last().value(); - addProperty(properties[1], value, important); + addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important); return true; } else if (num == 2) { ShorthandScope scope(this, CSSPropertyBorderSpacing); - if (!parseValue(properties[0], important) || !parseValue(properties[1], important)) + if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important)) return false; return true; } @@ -1161,7 +1567,7 @@ bool CSSParser::parseValue(int propId, bool important) } case CSSPropertyWebkitBorderHorizontalSpacing: case CSSPropertyWebkitBorderVerticalSpacing: - validPrimitive = validUnit(value, FLength | FNonNeg, m_strict); + validPrimitive = validUnit(value, FLength | FNonNeg); break; case CSSPropertyOutlineColor: // <color> | invert | inherit // Outline color has "invert" as additional keyword. @@ -1194,7 +1600,7 @@ bool CSSParser::parseValue(int propId, bool important) else if (id == CSSValueCurrentcolor) validPrimitive = true; else if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || - (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && !m_strict)) { + (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) { validPrimitive = true; } else { parsedValue = parseColor(); @@ -1227,13 +1633,10 @@ bool CSSParser::parseValue(int propId, bool important) if (nrcoords == 2) hotSpot = IntPoint(coords[0], coords[1]); - if (!uri.isNull() && m_styleSheet) { - // FIXME: The completeURL call should be done when using the CSSCursorImageValue, - // not when creating it. - list->append(CSSCursorImageValue::create(m_styleSheet->completeURL(uri), hotSpot)); - } + if (!uri.isNull()) + list->append(CSSCursorImageValue::create(completeURL(uri), hotSpot)); - if ((m_strict && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ','))) + if ((inStrictMode() && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ','))) return false; value = m_valueList->next(); // comma } @@ -1241,20 +1644,24 @@ bool CSSParser::parseValue(int propId, bool important) if (!value) { // no value after url list (MSIE 5 compatibility) if (list->length() != 1) return false; - } else if (!m_strict && value->id == CSSValueHand) // MSIE 5 compatibility :/ - list->append(cssValuePool()->createIdentifierValue(CSSValuePointer)); - else if (value && ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)) - list->append(cssValuePool()->createIdentifierValue(value->id)); + } else if (inQuirksMode() && value->id == CSSValueHand) // MSIE 5 compatibility :/ + list->append(cssValuePool().createIdentifierValue(CSSValuePointer)); + else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone) + list->append(cssValuePool().createIdentifierValue(value->id)); m_valueList->next(); parsedValue = list.release(); break; + } else if (value) { + id = value->id; + if (inQuirksMode() && value->id == CSSValueHand) { // MSIE 5 compatibility :/ + id = CSSValuePointer; + validPrimitive = true; + } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone) + validPrimitive = true; + } else { + ASSERT_NOT_REACHED(); + return false; } - id = value->id; - if (!m_strict && value->id == CSSValueHand) { // MSIE 5 compatibility :/ - id = CSSValuePointer; - validPrimitive = true; - } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone) - validPrimitive = true; break; } @@ -1287,7 +1694,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitMaskRepeatY: { RefPtr<CSSValue> val1; RefPtr<CSSValue> val2; - int propId1, propId2; + CSSPropertyID propId1, propId2; bool result = false; if (parseFillProperty(propId, propId1, propId2, val1, val2)) { OwnPtr<ShorthandScope> shorthandScope; @@ -1309,21 +1716,25 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyBorderImageSource: case CSSPropertyWebkitMaskBoxImageSource: if (id == CSSValueNone) { - parsedValue = CSSImageValue::create(); + parsedValue = cssValuePool().createIdentifierValue(CSSValueNone); m_valueList->next(); } else if (value->unit == CSSPrimitiveValue::CSS_URI) { - if (m_styleSheet) { - // FIXME: The completeURL call should be done when using the CSSImageValue, - // not when creating it. - parsedValue = CSSImageValue::create(m_styleSheet->completeURL(value->string)); - m_valueList->next(); - } + parsedValue = CSSImageValue::create(completeURL(value->string)); + m_valueList->next(); } else if (isGeneratedImageValue(value)) { if (parseGeneratedImage(m_valueList.get(), parsedValue)) m_valueList->next(); else return false; } +#if ENABLE(CSS_IMAGE_SET) + else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) { + parsedValue = parseImageSet(m_valueList.get()); + if (!parsedValue) + return false; + m_valueList->next(); + } +#endif break; case CSSPropertyWebkitTextStrokeWidth: @@ -1340,7 +1751,7 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick) validPrimitive = true; else - validPrimitive = validUnit(value, FLength | FNonNeg, m_strict); + validPrimitive = validUnit(value, FLength | FNonNeg); break; case CSSPropertyLetterSpacing: // normal | <length> | inherit @@ -1348,26 +1759,11 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueNormal) validPrimitive = true; else - validPrimitive = validUnit(value, FLength, m_strict); - break; - - case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension) - if (id == CSSValueNormal || id == CSSValueBreakAll || id == CSSValueBreakWord) - validPrimitive = true; - break; - - case CSSPropertyWordWrap: // normal | break-word - if (id == CSSValueNormal || id == CSSValueBreakWord) - validPrimitive = true; - break; - case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit - if (id == CSSValueNone || id == CSSValueNormal || id == CSSValueSpellOut || id == CSSValueDigits - || id == CSSValueLiteralPunctuation || id == CSSValueNoPunctuation) - validPrimitive = true; + validPrimitive = validUnit(value, FLength); break; case CSSPropertyTextIndent: // <length> | <percentage> | inherit - validPrimitive = (!id && validUnit(value, FLength | FPercent, m_strict)); + validPrimitive = (!id && validUnit(value, FLength | FPercent)); break; case CSSPropertyPaddingTop: //// <padding-width> | inherit @@ -1378,7 +1774,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitPaddingEnd: case CSSPropertyWebkitPaddingBefore: case CSSPropertyWebkitPaddingAfter: - validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg, m_strict)); + validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg)); break; case CSSPropertyMaxHeight: // <length> | <percentage> | none | inherit @@ -1397,21 +1793,11 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) validPrimitive = true; else - validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg, m_strict)); + validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg)); break; case CSSPropertyFontSize: - // <absolute-size> | <relative-size> | <length> | <percentage> | inherit - if (id >= CSSValueXxSmall && id <= CSSValueLarger) - validPrimitive = true; - else - validPrimitive = (validUnit(value, FLength | FPercent | FNonNeg, m_strict)); - break; - - case CSSPropertyFontStyle: // normal | italic | oblique | inherit - if (id == CSSValueNormal || id == CSSValueItalic || id == CSSValueOblique) - validPrimitive = true; - break; + return parseFontSize(important); case CSSPropertyFontVariant: // normal | small-caps | inherit return parseFontVariant(important); @@ -1423,7 +1809,7 @@ bool CSSParser::parseValue(int propId, bool important) if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle) validPrimitive = true; else - validPrimitive = (!id && validUnit(value, FLength | FPercent, m_strict)); + validPrimitive = (!id && validUnit(value, FLength | FPercent)); break; case CSSPropertyHeight: // <length> | <percentage> | auto | inherit @@ -1432,11 +1818,9 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitLogicalHeight: if (id == CSSValueAuto || id == CSSValueIntrinsic || id == CSSValueMinIntrinsic) validPrimitive = true; - else if (!id && validUnit(value, FLength | FPercent | FNonNeg, m_strict)) + else if (!id && validUnit(value, FLength | FPercent | FNonNeg)) // ### handle multilength case where we allow relative units validPrimitive = true; - else if (value->unit == CSSParserValue::Function) - return parseFlex(propId, important); break; case CSSPropertyBottom: // <length> | <percentage> | auto | inherit @@ -1454,7 +1838,7 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = (!id && validUnit(value, FLength | FPercent, m_strict)); + validPrimitive = (!id && validUnit(value, FLength | FPercent)); break; case CSSPropertyZIndex: // auto | <integer> | inherit @@ -1466,15 +1850,11 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyOrphans: // <integer> | inherit case CSSPropertyWidows: // <integer> | inherit // ### not supported later on - validPrimitive = (!id && validUnit(value, FInteger, false)); + validPrimitive = (!id && validUnit(value, FInteger, CSSQuirksMode)); break; - case CSSPropertyLineHeight: // normal | <number> | <length> | <percentage> | inherit - if (id == CSSValueNormal) - validPrimitive = true; - else - validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict)); - break; + case CSSPropertyLineHeight: + return parseLineHeight(important); case CSSPropertyCounterIncrement: // [ <identifier> <integer>? ]+ | none | inherit if (id != CSSValueNone) return parseCounter(propId, 1, important); @@ -1507,7 +1887,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSValueUnderline: case CSSValueOverline: case CSSValueLineThrough: - list->append(cssValuePool()->createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); break; default: isValid = false; @@ -1525,12 +1905,7 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument) validPrimitive = true; else - validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, true)); - break; - - case CSSPropertyTableLayout: // auto | fixed | inherit - if (id == CSSValueAuto || id == CSSValueFixed) - validPrimitive = true; + validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, CSSStrictMode)); break; case CSSPropertySrc: // Only used within @font-face, so cannot use inherit | initial or be !important. This is a list of urls or local references. @@ -1540,10 +1915,6 @@ bool CSSParser::parseValue(int propId, bool important) return parseFontFaceUnicodeRange(); /* CSS3 properties */ - case CSSPropertyWebkitAppearance: - if ((id >= CSSValueCheckbox && id <= CSSValueTextarea) || id == CSSValueNone) - validPrimitive = true; - break; case CSSPropertyBorderImage: { RefPtr<CSSValue> result; @@ -1600,14 +1971,14 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyBorderBottomRightRadius: { if (num != 1 && num != 2) return false; - validPrimitive = validUnit(value, FLength | FPercent | FNonNeg, m_strict); + validPrimitive = validUnit(value, FLength | FPercent | FNonNeg); if (!validPrimitive) return false; RefPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(value); RefPtr<CSSPrimitiveValue> parsedValue2; if (num == 2) { value = m_valueList->next(); - validPrimitive = validUnit(value, FLength | FPercent | FNonNeg, m_strict); + validPrimitive = validUnit(value, FLength | FPercent | FNonNeg); if (!validPrimitive) return false; parsedValue2 = createPrimitiveNumericValue(value); @@ -1615,7 +1986,7 @@ bool CSSParser::parseValue(int propId, bool important) parsedValue2 = parsedValue1; RefPtr<Pair> pair = Pair::create(parsedValue1.release(), parsedValue2.release()); - RefPtr<CSSPrimitiveValue> val = cssValuePool()->createValue(pair.release()); + RefPtr<CSSPrimitiveValue> val = cssValuePool().createValue(pair.release()); addProperty(propId, val.release(), important); return true; } @@ -1625,7 +1996,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitBorderRadius: return parseBorderRadius(propId, important); case CSSPropertyOutlineOffset: - validPrimitive = validUnit(value, FLength | FPercent, m_strict); + validPrimitive = validUnit(value, FLength | FPercent); break; case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3 case CSSPropertyBoxShadow: @@ -1649,43 +2020,14 @@ bool CSSParser::parseValue(int propId, bool important) return parseReflect(propId, important); break; case CSSPropertyOpacity: - validPrimitive = validUnit(value, FNumber, m_strict); - break; - case CSSPropertyWebkitBoxAlign: - if (id == CSSValueStretch || id == CSSValueStart || id == CSSValueEnd || - id == CSSValueCenter || id == CSSValueBaseline) - validPrimitive = true; - break; - case CSSPropertyWebkitBoxDirection: - if (id == CSSValueNormal || id == CSSValueReverse) - validPrimitive = true; - break; - case CSSPropertyWebkitBoxLines: - if (id == CSSValueSingle || id == CSSValueMultiple) - validPrimitive = true; - break; - case CSSPropertyWebkitBoxOrient: - if (id == CSSValueHorizontal || id == CSSValueVertical || - id == CSSValueInlineAxis || id == CSSValueBlockAxis) - validPrimitive = true; - break; - case CSSPropertyWebkitBoxPack: - if (id == CSSValueStart || id == CSSValueEnd || - id == CSSValueCenter || id == CSSValueJustify) - validPrimitive = true; + validPrimitive = validUnit(value, FNumber); break; case CSSPropertyWebkitBoxFlex: - validPrimitive = validUnit(value, FNumber, m_strict); + validPrimitive = validUnit(value, FNumber); break; case CSSPropertyWebkitBoxFlexGroup: case CSSPropertyWebkitBoxOrdinalGroup: - validPrimitive = validUnit(value, FInteger | FNonNeg, true); - break; - case CSSPropertyBoxSizing: - validPrimitive = id == CSSValueBorderBox || id == CSSValueContentBox; - break; - case CSSPropertyWebkitColorCorrection: - validPrimitive = id == CSSValueSrgb || id == CSSValueDefault; + validPrimitive = validUnit(value, FInteger | FNonNeg, CSSStrictMode); break; #if ENABLE(CSS_FILTERS) case CSSPropertyWebkitFilter: @@ -1701,62 +2043,39 @@ bool CSSParser::parseValue(int propId, bool important) } break; #endif + case CSSPropertyWebkitFlex: + if (id == CSSValueNone) + validPrimitive = true; + else + parsedValue = parseFlex(m_valueList.get()); + break; case CSSPropertyWebkitFlexOrder: - if (validUnit(value, FInteger, true)) { + if (validUnit(value, FInteger, CSSStrictMode)) { // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set. - parsedValue = cssValuePool()->createValue(max(static_cast<double>(std::numeric_limits<int>::min() + 2), value->fValue), + parsedValue = cssValuePool().createValue(max(static_cast<double>(std::numeric_limits<int>::min() + 2), value->fValue), static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); m_valueList->next(); } break; - case CSSPropertyWebkitFlexPack: - validPrimitive = id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueJustify || id == CSSValueDistribute; - break; - case CSSPropertyWebkitFlexAlign: - validPrimitive = id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueBaseline || id == CSSValueStretch; - break; - case CSSPropertyWebkitFlexItemAlign: - validPrimitive = id == CSSValueAuto || id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueBaseline || id == CSSValueStretch; - break; - case CSSPropertyWebkitFlexDirection: - validPrimitive = id == CSSValueRow || id == CSSValueRowReverse || id == CSSValueColumn || id == CSSValueColumnReverse; - break; - case CSSPropertyWebkitFlexWrap: - validPrimitive = id == CSSValueNone || id == CSSValueWrap || id == CSSValueWrapReverse; - break; - case CSSPropertyWebkitMarquee: { - const int properties[5] = { CSSPropertyWebkitMarqueeDirection, CSSPropertyWebkitMarqueeIncrement, - CSSPropertyWebkitMarqueeRepetition, - CSSPropertyWebkitMarqueeStyle, CSSPropertyWebkitMarqueeSpeed }; - return parseShorthand(propId, properties, 5, important); - } - case CSSPropertyWebkitMarqueeDirection: - if (id == CSSValueForwards || id == CSSValueBackwards || id == CSSValueAhead || - id == CSSValueReverse || id == CSSValueLeft || id == CSSValueRight || id == CSSValueDown || - id == CSSValueUp || id == CSSValueAuto) - validPrimitive = true; - break; + case CSSPropertyWebkitMarquee: + return parseShorthand(propId, webkitMarqueeShorthand(), important); case CSSPropertyWebkitMarqueeIncrement: if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium) validPrimitive = true; else - validPrimitive = validUnit(value, FLength | FPercent, m_strict); - break; - case CSSPropertyWebkitMarqueeStyle: - if (id == CSSValueNone || id == CSSValueSlide || id == CSSValueScroll || id == CSSValueAlternate) - validPrimitive = true; + validPrimitive = validUnit(value, FLength | FPercent); break; case CSSPropertyWebkitMarqueeRepetition: if (id == CSSValueInfinite) validPrimitive = true; else - validPrimitive = validUnit(value, FInteger | FNonNeg, m_strict); + validPrimitive = validUnit(value, FInteger | FNonNeg); break; case CSSPropertyWebkitMarqueeSpeed: if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast) validPrimitive = true; else - validPrimitive = validUnit(value, FTime | FInteger | FNonNeg, m_strict); + validPrimitive = validUnit(value, FTime | FInteger | FNonNeg); break; case CSSPropertyWebkitFlowInto: if (!cssRegionsEnabled()) @@ -1770,23 +2089,6 @@ bool CSSParser::parseValue(int propId, bool important) if (cssRegionsEnabled() && (id == CSSValueAuto || id == CSSValueBreak)) validPrimitive = true; break; - - case CSSPropertyWebkitUserDrag: // auto | none | element - if (id == CSSValueAuto || id == CSSValueNone || id == CSSValueElement) - validPrimitive = true; - break; - case CSSPropertyWebkitUserModify: // read-only | read-write - if (id == CSSValueReadOnly || id == CSSValueReadWrite || id == CSSValueReadWritePlaintextOnly) - validPrimitive = true; - break; - case CSSPropertyWebkitUserSelect: // auto | none | text - if (id == CSSValueAuto || id == CSSValueNone || id == CSSValueText) - validPrimitive = true; - break; - case CSSPropertyTextOverflow: // clip | ellipsis - if (id == CSSValueClip || id == CSSValueEllipsis) - validPrimitive = true; - break; case CSSPropertyWebkitTransform: if (id == CSSValueNone) validPrimitive = true; @@ -1806,7 +2108,7 @@ bool CSSParser::parseValue(int propId, bool important) RefPtr<CSSValue> val1; RefPtr<CSSValue> val2; RefPtr<CSSValue> val3; - int propId1, propId2, propId3; + CSSPropertyID propId1, propId2, propId3; if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) { addProperty(propId1, val1.release(), important); if (val2) @@ -1817,24 +2119,12 @@ bool CSSParser::parseValue(int propId, bool important) } return false; } - case CSSPropertyWebkitTransformStyle: - if (value->id == CSSValueFlat || value->id == CSSValuePreserve3d) - validPrimitive = true; - break; - case CSSPropertyWebkitBackfaceVisibility: - if (value->id == CSSValueVisible || value->id == CSSValueHidden) - validPrimitive = true; - break; - case CSSPropertyWebkitPrintColorAdjust: - if (value->id == CSSValueExact || value->id == CSSValueEconomy) - validPrimitive = true; - break; case CSSPropertyWebkitPerspective: if (id == CSSValueNone) validPrimitive = true; else { // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property. - if (validUnit(value, FNumber | FLength | FNonNeg, m_strict)) { + if (validUnit(value, FNumber | FLength | FNonNeg)) { RefPtr<CSSValue> val = createPrimitiveNumericValue(value); if (val) { addProperty(propId, val.release(), important); @@ -1849,7 +2139,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitPerspectiveOriginY: { RefPtr<CSSValue> val1; RefPtr<CSSValue> val2; - int propId1, propId2; + CSSPropertyID propId1, propId2; if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) { addProperty(propId1, val1.release(), important); if (val2) @@ -1884,54 +2174,26 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitGridColumn: case CSSPropertyWebkitGridRow: - validPrimitive = id == CSSValueAuto || validUnit(value, FInteger, m_strict); + validPrimitive = id == CSSValueAuto || validUnit(value, FInteger); break; #endif case CSSPropertyWebkitMarginCollapse: { - const int properties[2] = { CSSPropertyWebkitMarginBeforeCollapse, - CSSPropertyWebkitMarginAfterCollapse }; if (num == 1) { ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse); - if (!parseValue(properties[0], important)) + if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important)) return false; CSSValue* value = m_parsedProperties.last().value(); - addProperty(properties[1], value, important); + addProperty(webkitMarginCollapseShorthand().properties()[1], value, important); return true; } else if (num == 2) { ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse); - if (!parseValue(properties[0], important) || !parseValue(properties[1], important)) + if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important)) return false; return true; } return false; } - case CSSPropertyWebkitMarginBeforeCollapse: - case CSSPropertyWebkitMarginAfterCollapse: - case CSSPropertyWebkitMarginTopCollapse: - case CSSPropertyWebkitMarginBottomCollapse: - if (id == CSSValueCollapse || id == CSSValueSeparate || id == CSSValueDiscard) - validPrimitive = true; - break; - case CSSPropertyTextLineThroughMode: - case CSSPropertyTextOverlineMode: - case CSSPropertyTextUnderlineMode: - if (id == CSSValueContinuous || id == CSSValueSkipWhiteSpace) - validPrimitive = true; - break; - case CSSPropertyTextLineThroughStyle: - case CSSPropertyTextOverlineStyle: - case CSSPropertyTextUnderlineStyle: - if (id == CSSValueNone || id == CSSValueSolid || id == CSSValueDouble || - id == CSSValueDashed || id == CSSValueDotDash || id == CSSValueDotDotDash || - id == CSSValueWave) - validPrimitive = true; - break; - case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision - if (id == CSSValueAuto || id == CSSValueOptimizespeed || id == CSSValueOptimizelegibility - || id == CSSValueGeometricprecision) - validPrimitive = true; - break; case CSSPropertyTextLineThroughWidth: case CSSPropertyTextOverlineWidth: case CSSPropertyTextUnderlineWidth: @@ -1939,23 +2201,19 @@ bool CSSParser::parseValue(int propId, bool important) id == CSSValueMedium || id == CSSValueThick) validPrimitive = true; else - validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent, m_strict); - break; - case CSSPropertyResize: // none | both | horizontal | vertical | auto - if (id == CSSValueNone || id == CSSValueBoth || id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto) - validPrimitive = true; + validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent); break; case CSSPropertyWebkitColumnCount: if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = !id && validUnit(value, FInteger | FNonNeg, false); + validPrimitive = !id && validUnit(value, FInteger | FNonNeg, CSSQuirksMode); break; case CSSPropertyWebkitColumnGap: // normal | <length> if (id == CSSValueNormal) validPrimitive = true; else - validPrimitive = validUnit(value, FLength | FNonNeg, m_strict); + validPrimitive = validUnit(value, FLength | FNonNeg); break; case CSSPropertyWebkitColumnAxis: if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto) @@ -1965,24 +2223,13 @@ bool CSSParser::parseValue(int propId, bool important) if (id == CSSValueAll) validPrimitive = true; else - validPrimitive = validUnit(value, FNumber | FNonNeg, m_strict) && value->fValue == 1; + validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1; break; case CSSPropertyWebkitColumnWidth: // auto | <length> if (id == CSSValueAuto) validPrimitive = true; else // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property. - validPrimitive = validUnit(value, FLength, true); - break; - case CSSPropertyPointerEvents: - // none | visiblePainted | visibleFill | visibleStroke | visible | - // painted | fill | stroke | auto | all | inherit - if (id == CSSValueVisible || id == CSSValueNone || id == CSSValueAll || id == CSSValueAuto || - (id >= CSSValueVisiblepainted && id <= CSSValueStroke)) - validPrimitive = true; - break; - case CSSPropertyImageRendering: // auto | optimizeContrast - if (id == CSSValueAuto || id == CSSValueWebkitOptimizeContrast) - validPrimitive = true; + validPrimitive = validUnit(value, FLength, CSSStrictMode); break; // End of CSS3 properties @@ -1991,34 +2238,11 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitLineClamp: // When specifying number of lines, don't allow 0 as a valid value // When specifying either type of unit, require non-negative integers - validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, false)); - break; - case CSSPropertyWebkitTextSizeAdjust: - if (id == CSSValueAuto || id == CSSValueNone) - validPrimitive = true; - break; - case CSSPropertyWebkitRtlOrdering: - if (id == CSSValueLogical || id == CSSValueVisual) - validPrimitive = true; + validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, CSSQuirksMode)); break; case CSSPropertyWebkitFontSizeDelta: // <length> - validPrimitive = validUnit(value, FLength, m_strict); - break; - - case CSSPropertyWebkitNbspMode: // normal | space - if (id == CSSValueNormal || id == CSSValueSpace) - validPrimitive = true; - break; - - case CSSPropertyWebkitLineBreak: // normal | after-white-space - if (id == CSSValueNormal || id == CSSValueAfterWhiteSpace) - validPrimitive = true; - break; - - case CSSPropertyWebkitMatchNearestMailBlockquoteColor: // normal | match - if (id == CSSValueNormal || id == CSSValueMatch) - validPrimitive = true; + validPrimitive = validUnit(value, FLength); break; case CSSPropertyWebkitHighlight: @@ -2026,11 +2250,6 @@ bool CSSParser::parseValue(int propId, bool important) validPrimitive = true; break; - case CSSPropertyWebkitHyphens: - if (id == CSSValueNone || id == CSSValueManual || id == CSSValueAuto) - validPrimitive = true; - break; - case CSSPropertyWebkitHyphenateCharacter: if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING) validPrimitive = true; @@ -2038,12 +2257,12 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitHyphenateLimitBefore: case CSSPropertyWebkitHyphenateLimitAfter: - if (id == CSSValueAuto || validUnit(value, FInteger | FNonNeg, true)) + if (id == CSSValueAuto || validUnit(value, FInteger | FNonNeg, CSSStrictMode)) validPrimitive = true; break; case CSSPropertyWebkitHyphenateLimitLines: - if (id == CSSValueNoLimit || validUnit(value, FInteger | FNonNeg, true)) + if (id == CSSValueNoLimit || validUnit(value, FInteger | FNonNeg, CSSStrictMode)) validPrimitive = true; break; @@ -2053,41 +2272,16 @@ bool CSSParser::parseValue(int propId, bool important) else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { String lineGridValue = String(value->string); if (!lineGridValue.isEmpty()) { - addProperty(propId, cssValuePool()->createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, cssValuePool().createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important); return true; } } break; - case CSSPropertyWebkitLineSnap: - if (id == CSSValueNone || id == CSSValueBaseline || id == CSSValueContain) - validPrimitive = true; - break; - case CSSPropertyWebkitLineAlign: - if (id == CSSValueNone || id == CSSValueEdges) - validPrimitive = true; - break; case CSSPropertyWebkitLocale: if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING) validPrimitive = true; break; - case CSSPropertyWebkitBorderFit: - if (id == CSSValueBorder || id == CSSValueLines) - validPrimitive = true; - break; - - case CSSPropertyWebkitTextSecurity: - // disc | circle | square | none | inherit - if (id == CSSValueDisc || id == CSSValueCircle || id == CSSValueSquare|| id == CSSValueNone) - validPrimitive = true; - break; - - case CSSPropertyWebkitFontSmoothing: - if (id == CSSValueAuto || id == CSSValueNone - || id == CSSValueAntialiased || id == CSSValueSubpixelAntialiased) - validPrimitive = true; - break; - #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: // <dashboard-region> | <dashboard-region> if (value->unit == CSSParserValue::Function || id == CSSValueNone) @@ -2099,7 +2293,7 @@ bool CSSParser::parseValue(int propId, bool important) #if ENABLE(TOUCH_EVENTS) case CSSPropertyWebkitTapHighlightColor: if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu - || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && !m_strict)) { + || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) { validPrimitive = true; } else { parsedValue = parseColor(); @@ -2109,25 +2303,18 @@ bool CSSParser::parseValue(int propId, bool important) break; #endif -#if ENABLE(OVERFLOW_SCROLLING) - case CSSPropertyWebkitOverflowScrolling: - if (id == CSSValueAuto || id == CSSValueTouch) - validPrimitive = true; - break; -#endif - /* shorthand properties */ case CSSPropertyBackground: { // Position must come before color in this array because a plain old "0" is a legal color // in quirks mode but it's usually the X coordinate of a position. // FIXME: Add CSSPropertyBackgroundSize to the shorthand. - const int properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, + const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin, CSSPropertyBackgroundClip, CSSPropertyBackgroundColor }; return parseFillShorthand(propId, properties, 7, important); } case CSSPropertyWebkitMask: { - const int properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, + const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, CSSPropertyWebkitMaskAttachment, CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip }; return parseFillShorthand(propId, properties, 6, important); @@ -2135,115 +2322,54 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyBorder: // [ 'border-width' || 'border-style' || <color> ] | inherit { - const int properties[3] = { CSSPropertyBorderWidth, CSSPropertyBorderStyle, - CSSPropertyBorderColor }; - if (parseShorthand(propId, properties, 3, important)) { + if (parseShorthand(propId, borderAbridgedShorthand(), important)) { // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as // though a value of none was specified for the image. - addProperty(CSSPropertyBorderImage, cssValuePool()->createImplicitInitialValue(), important); + addProperty(CSSPropertyBorderImage, cssValuePool().createImplicitInitialValue(), important); return true; } return false; } case CSSPropertyBorderTop: // [ 'border-top-width' || 'border-style' || <color> ] | inherit - { - const int properties[3] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle, - CSSPropertyBorderTopColor}; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, borderTopShorthand(), important); case CSSPropertyBorderRight: // [ 'border-right-width' || 'border-style' || <color> ] | inherit - { - const int properties[3] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle, - CSSPropertyBorderRightColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, borderRightShorthand(), important); case CSSPropertyBorderBottom: // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit - { - const int properties[3] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle, - CSSPropertyBorderBottomColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, borderBottomShorthand(), important); case CSSPropertyBorderLeft: // [ 'border-left-width' || 'border-style' || <color> ] | inherit - { - const int properties[3] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle, - CSSPropertyBorderLeftColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, borderLeftShorthand(), important); case CSSPropertyWebkitBorderStart: - { - const int properties[3] = { CSSPropertyWebkitBorderStartWidth, CSSPropertyWebkitBorderStartStyle, - CSSPropertyWebkitBorderStartColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, webkitBorderStartShorthand(), important); case CSSPropertyWebkitBorderEnd: - { - const int properties[3] = { CSSPropertyWebkitBorderEndWidth, CSSPropertyWebkitBorderEndStyle, - CSSPropertyWebkitBorderEndColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, webkitBorderEndShorthand(), important); case CSSPropertyWebkitBorderBefore: - { - const int properties[3] = { CSSPropertyWebkitBorderBeforeWidth, CSSPropertyWebkitBorderBeforeStyle, - CSSPropertyWebkitBorderBeforeColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, webkitBorderBeforeShorthand(), important); case CSSPropertyWebkitBorderAfter: - { - const int properties[3] = { CSSPropertyWebkitBorderAfterWidth, CSSPropertyWebkitBorderAfterStyle, - CSSPropertyWebkitBorderAfterColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, webkitBorderAfterShorthand(), important); case CSSPropertyOutline: // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit - { - const int properties[3] = { CSSPropertyOutlineWidth, CSSPropertyOutlineStyle, - CSSPropertyOutlineColor }; - return parseShorthand(propId, properties, 3, important); - } + return parseShorthand(propId, outlineShorthand(), important); case CSSPropertyBorderColor: // <color>{1,4} | inherit - { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, - CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return parse4Values(propId, properties, important); - } + return parse4Values(propId, borderColorShorthand().properties(), important); case CSSPropertyBorderWidth: // <border-width>{1,4} | inherit - { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, - CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return parse4Values(propId, properties, important); - } + return parse4Values(propId, borderWidthShorthand().properties(), important); case CSSPropertyBorderStyle: // <border-style>{1,4} | inherit - { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, - CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return parse4Values(propId, properties, important); - } + return parse4Values(propId, borderStyleShorthand().properties(), important); case CSSPropertyMargin: // <margin-width>{1,4} | inherit - { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, - CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return parse4Values(propId, properties, important); - } + return parse4Values(propId, marginShorthand().properties(), important); case CSSPropertyPadding: // <padding-width>{1,4} | inherit - { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, - CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return parse4Values(propId, properties, important); - } + return parse4Values(propId, paddingShorthand().properties(), important); case CSSPropertyWebkitFlexFlow: - { - const int properties[] = { CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap }; - return parseShorthand(propId, properties, 2, important); - } + return parseShorthand(propId, webkitFlexFlowShorthand(), important); case CSSPropertyFont: // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit @@ -2253,24 +2379,13 @@ bool CSSParser::parseValue(int propId, bool important) return parseFont(important); break; case CSSPropertyListStyle: - { - const int properties[3] = { CSSPropertyListStyleType, CSSPropertyListStylePosition, - CSSPropertyListStyleImage }; - return parseShorthand(propId, properties, 3, important); - } - case CSSPropertyWebkitColumns: { - const int properties[2] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount }; - return parseShorthand(propId, properties, 2, important); - } - case CSSPropertyWebkitColumnRule: { - const int properties[3] = { CSSPropertyWebkitColumnRuleWidth, CSSPropertyWebkitColumnRuleStyle, - CSSPropertyWebkitColumnRuleColor }; - return parseShorthand(propId, properties, 3, important); - } - case CSSPropertyWebkitTextStroke: { - const int properties[2] = { CSSPropertyWebkitTextStrokeWidth, CSSPropertyWebkitTextStrokeColor }; - return parseShorthand(propId, properties, 2, important); - } + return parseShorthand(propId, listStyleShorthand(), important); + case CSSPropertyWebkitColumns: + return parseShorthand(propId, webkitColumnsShorthand(), important); + case CSSPropertyWebkitColumnRule: + return parseShorthand(propId, webkitColumnRuleShorthand(), important); + case CSSPropertyWebkitTextStroke: + return parseShorthand(propId, webkitTextStrokeShorthand(), important); case CSSPropertyWebkitAnimation: return parseAnimationShorthand(important); case CSSPropertyWebkitTransition: @@ -2285,25 +2400,8 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyTextUnderline: return false; // CSS Text Layout Module Level 3: Vertical writing support - case CSSPropertyWebkitWritingMode: - if (id >= CSSValueHorizontalTb && id <= CSSValueHorizontalBt) - validPrimitive = true; - break; - - case CSSPropertyWebkitTextCombine: - if (id == CSSValueNone || id == CSSValueHorizontal) - validPrimitive = true; - break; - - case CSSPropertyWebkitTextEmphasis: { - const int properties[] = { CSSPropertyWebkitTextEmphasisStyle, CSSPropertyWebkitTextEmphasisColor }; - return parseShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important); - } - - case CSSPropertyWebkitTextEmphasisPosition: - if (id == CSSValueOver || id == CSSValueUnder) - validPrimitive = true; - break; + case CSSPropertyWebkitTextEmphasis: + return parseShorthand(propId, webkitTextEmphasisShorthand(), important); case CSSPropertyWebkitTextEmphasisStyle: return parseTextEmphasisStyle(important); @@ -2327,11 +2425,6 @@ bool CSSParser::parseValue(int propId, bool important) return parseFontFeatureSettings(important); break; - case CSSPropertyWebkitFontKerning: - if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueNone) - validPrimitive = true; - break; - case CSSPropertyWebkitFontVariantLigatures: if (id == CSSValueNormal) validPrimitive = true; @@ -2339,30 +2432,111 @@ bool CSSParser::parseValue(int propId, bool important) return parseFontVariantLigatures(important); break; - case CSSPropertyWebkitWrapShapeInside: - case CSSPropertyWebkitWrapShapeOutside: + case CSSPropertyWebkitShapeInside: + case CSSPropertyWebkitShapeOutside: + if (!RuntimeEnabledFeatures::cssExclusionsEnabled()) + return false; if (id == CSSValueAuto) validPrimitive = true; else if (value->unit == CSSParserValue::Function) - return parseWrapShape((propId == CSSPropertyWebkitWrapShapeInside), important); - break; - case CSSPropertyWebkitWrapFlow: - if (id == CSSValueAuto || id == CSSValueBoth || id == CSSValueLeft || id == CSSValueRight || id == CSSValueMaximum || id == CSSValueClear) - validPrimitive = true; - break; - - case CSSPropertyWebkitWrapThrough: - if (id == CSSValueWrap || id == CSSValueNone) - validPrimitive = true; + return parseExclusionShape((propId == CSSPropertyWebkitShapeInside), important); break; case CSSPropertyWebkitWrapMargin: case CSSPropertyWebkitWrapPadding: - validPrimitive = (!id && validUnit(value, FLength | FNonNeg, m_strict)); + validPrimitive = (RuntimeEnabledFeatures::cssExclusionsEnabled() && !id && validUnit(value, FLength | FNonNeg)); break; - case CSSPropertyWebkitWrap: { - const int properties[] = { CSSPropertyWebkitWrapFlow, CSSPropertyWebkitWrapMargin, CSSPropertyWebkitWrapPadding }; - return parseShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important); - } + case CSSPropertyWebkitWrap: + return RuntimeEnabledFeatures::cssExclusionsEnabled() && parseShorthand(propId, webkitWrapShorthand(), important); + case CSSPropertyBorderBottomStyle: + case CSSPropertyBorderCollapse: + case CSSPropertyBorderLeftStyle: + case CSSPropertyBorderRightStyle: + case CSSPropertyBorderTopStyle: + case CSSPropertyBoxSizing: + case CSSPropertyCaptionSide: + case CSSPropertyClear: + case CSSPropertyDirection: + case CSSPropertyDisplay: + case CSSPropertyEmptyCells: + case CSSPropertyFloat: + case CSSPropertyFontStyle: + case CSSPropertyImageRendering: + case CSSPropertyListStylePosition: + case CSSPropertyListStyleType: + case CSSPropertyOutlineStyle: + case CSSPropertyOverflowX: + case CSSPropertyOverflowY: + case CSSPropertyPointerEvents: + case CSSPropertyPosition: + case CSSPropertyResize: + case CSSPropertySpeak: + case CSSPropertyTableLayout: + case CSSPropertyTextLineThroughMode: + case CSSPropertyTextLineThroughStyle: + case CSSPropertyTextOverflow: + case CSSPropertyTextOverlineMode: + case CSSPropertyTextOverlineStyle: + case CSSPropertyTextRendering: + case CSSPropertyTextTransform: + case CSSPropertyTextUnderlineMode: + case CSSPropertyTextUnderlineStyle: + case CSSPropertyVisibility: + case CSSPropertyWebkitAppearance: + case CSSPropertyWebkitBackfaceVisibility: + case CSSPropertyWebkitBorderAfterStyle: + case CSSPropertyWebkitBorderBeforeStyle: + case CSSPropertyWebkitBorderEndStyle: + case CSSPropertyWebkitBorderFit: + case CSSPropertyWebkitBorderStartStyle: + case CSSPropertyWebkitBoxAlign: + case CSSPropertyWebkitBoxDirection: + case CSSPropertyWebkitBoxLines: + case CSSPropertyWebkitBoxOrient: + case CSSPropertyWebkitBoxPack: + case CSSPropertyWebkitColorCorrection: + case CSSPropertyWebkitColumnRuleStyle: + case CSSPropertyWebkitFlexAlign: + case CSSPropertyWebkitFlexDirection: + case CSSPropertyWebkitFlexItemAlign: + case CSSPropertyWebkitFlexLinePack: + case CSSPropertyWebkitFlexPack: + case CSSPropertyWebkitFlexWrap: + case CSSPropertyWebkitFontKerning: + case CSSPropertyWebkitFontSmoothing: + case CSSPropertyWebkitHyphens: + case CSSPropertyWebkitLineAlign: + case CSSPropertyWebkitLineBreak: + case CSSPropertyWebkitLineSnap: + case CSSPropertyWebkitMarginAfterCollapse: + case CSSPropertyWebkitMarginBeforeCollapse: + case CSSPropertyWebkitMarginBottomCollapse: + case CSSPropertyWebkitMarginTopCollapse: + case CSSPropertyWebkitMarqueeDirection: + case CSSPropertyWebkitMarqueeStyle: + case CSSPropertyWebkitMatchNearestMailBlockquoteColor: + case CSSPropertyWebkitNbspMode: +#if ENABLE(OVERFLOW_SCROLLING) + case CSSPropertyWebkitOverflowScrolling: +#endif + case CSSPropertyWebkitPrintColorAdjust: + case CSSPropertyWebkitRtlOrdering: + case CSSPropertyWebkitTextCombine: + case CSSPropertyWebkitTextEmphasisPosition: + case CSSPropertyWebkitTextSecurity: + case CSSPropertyWebkitTextSizeAdjust: + case CSSPropertyWebkitTransformStyle: + case CSSPropertyWebkitUserDrag: + case CSSPropertyWebkitUserModify: + case CSSPropertyWebkitUserSelect: + case CSSPropertyWebkitWrapFlow: + case CSSPropertyWebkitWrapThrough: + case CSSPropertyWebkitWritingMode: + case CSSPropertyWhiteSpace: + case CSSPropertyWordBreak: + case CSSPropertyWordWrap: + // These properties should be handled before in isValidKeywordPropertyAndValue(). + ASSERT_NOT_REACHED(); + return false; #if ENABLE(SVG) default: return parseSVGValue(propId, important); @@ -2400,11 +2574,11 @@ void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval) lval = rval; } -static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue, CSSValuePool* cssValuePool) +static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue) { if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) { - cssValue = cssValuePool->createIdentifierValue(parserValue->id); + cssValue = cssValuePool().createIdentifierValue(parserValue->id); return true; } return false; @@ -2412,7 +2586,7 @@ static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& c const int cMaxFillProperties = 9; -bool CSSParser::parseFillShorthand(int propId, const int* properties, int numProperties, bool important) +bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important) { ASSERT(numProperties <= cMaxFillProperties); if (numProperties > cMaxFillProperties) @@ -2440,14 +2614,14 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro return false; if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) { - addFillValue(values[i], cssValuePool()->createImplicitInitialValue()); + addFillValue(values[i], cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) - addFillValue(positionYValue, cssValuePool()->createImplicitInitialValue()); + addFillValue(positionYValue, cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat) - addFillValue(repeatYValue, cssValuePool()->createImplicitInitialValue()); + addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue()); if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) { // If background-origin wasn't present, then reset background-clip also. - addFillValue(clipValue, cssValuePool()->createImplicitInitialValue()); + addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); } } parsedProperty[i] = false; @@ -2461,7 +2635,7 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro if (!parsedProperty[i]) { RefPtr<CSSValue> val1; RefPtr<CSSValue> val2; - int propId1, propId2; + CSSPropertyID propId1, propId2; CSSParserValue* parserValue = m_valueList->current(); if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) { parsedProperty[i] = found = true; @@ -2472,10 +2646,10 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro addFillValue(repeatYValue, val2.release()); if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) { // Reparse the value as a clip, and see if we succeed. - if (parseBackgroundClip(parserValue, val1, cssValuePool())) + if (parseBackgroundClip(parserValue, val1)) addFillValue(clipValue, val1.release()); // The property parsed successfully. else - addFillValue(clipValue, cssValuePool()->createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead. + addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead. } if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) { // Update clipValue @@ -2496,14 +2670,14 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro for (i = 0; i < numProperties; i++) { // Fill in any remaining properties with the initial value. if (!parsedProperty[i]) { - addFillValue(values[i], cssValuePool()->createImplicitInitialValue()); + addFillValue(values[i], cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition) - addFillValue(positionYValue, cssValuePool()->createImplicitInitialValue()); + addFillValue(positionYValue, cssValuePool().createImplicitInitialValue()); if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat) - addFillValue(repeatYValue, cssValuePool()->createImplicitInitialValue()); + addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue()); if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin)) { // If background-origin wasn't present, then reset background-clip also. - addFillValue(clipValue, cssValuePool()->createImplicitInitialValue()); + addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); } } if (properties[i] == CSSPropertyBackgroundPosition) { @@ -2557,22 +2731,14 @@ void CSSParser::addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> r bool CSSParser::parseAnimationShorthand(bool important) { - const int properties[] = { CSSPropertyWebkitAnimationName, - CSSPropertyWebkitAnimationDuration, - CSSPropertyWebkitAnimationTimingFunction, - CSSPropertyWebkitAnimationDelay, - CSSPropertyWebkitAnimationIterationCount, - CSSPropertyWebkitAnimationDirection, - CSSPropertyWebkitAnimationFillMode }; - const int numProperties = WTF_ARRAY_LENGTH(properties); - + const unsigned numProperties = webkitAnimationShorthand().length(); ShorthandScope scope(this, CSSPropertyWebkitAnimation); - bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary - RefPtr<CSSValue> values[numProperties]; + bool parsedProperty[] = { false, false, false, false, false, false, false }; + RefPtr<CSSValue> values[7]; - int i; - int initialParsedPropertyIndex = 0; + unsigned i; + unsigned initialParsedPropertyIndex = 0; while (m_valueList->current()) { CSSParserValue* val = m_valueList->current(); if (val->unit == CSSParserValue::Operator && val->iValue == ',') { @@ -2581,7 +2747,7 @@ bool CSSParser::parseAnimationShorthand(bool important) m_valueList->next(); for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool()->createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); parsedProperty[i] = false; } if (!m_valueList->current()) @@ -2592,7 +2758,7 @@ bool CSSParser::parseAnimationShorthand(bool important) for (i = initialParsedPropertyIndex; !found && i < numProperties; ++i) { if (!parsedProperty[i]) { RefPtr<CSSValue> val; - if (parseAnimationProperty(properties[i], val)) { + if (parseAnimationProperty(webkitAnimationShorthand().properties()[i], val)) { parsedProperty[i] = found = true; initialParsedPropertyIndex = 1; addAnimationValue(values[i], val.release()); @@ -2609,30 +2775,26 @@ bool CSSParser::parseAnimationShorthand(bool important) // Fill in any remaining properties with the initial value. for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool()->createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); } // Now add all of the properties we found. for (i = 0; i < numProperties; i++) - addProperty(properties[i], values[i].release(), important); + addProperty(webkitAnimationShorthand().properties()[i], values[i].release(), important); return true; } bool CSSParser::parseTransitionShorthand(bool important) { - const int properties[] = { CSSPropertyWebkitTransitionProperty, - CSSPropertyWebkitTransitionDuration, - CSSPropertyWebkitTransitionTimingFunction, - CSSPropertyWebkitTransitionDelay }; - const int numProperties = WTF_ARRAY_LENGTH(properties); + const unsigned numProperties = webkitTransitionShorthand().length(); ShorthandScope scope(this, CSSPropertyWebkitTransition); - bool parsedProperty[numProperties] = { false }; // compiler will repeat false as necessary - RefPtr<CSSValue> values[numProperties]; + bool parsedProperty[] = { false, false, false, false }; + RefPtr<CSSValue> values[4]; - int i; + unsigned i; while (m_valueList->current()) { CSSParserValue* val = m_valueList->current(); if (val->unit == CSSParserValue::Operator && val->iValue == ',') { @@ -2640,7 +2802,7 @@ bool CSSParser::parseTransitionShorthand(bool important) m_valueList->next(); for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool()->createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); parsedProperty[i] = false; } if (!m_valueList->current()) @@ -2651,7 +2813,7 @@ bool CSSParser::parseTransitionShorthand(bool important) for (i = 0; !found && i < numProperties; ++i) { if (!parsedProperty[i]) { RefPtr<CSSValue> val; - if (parseAnimationProperty(properties[i], val)) { + if (parseAnimationProperty(webkitTransitionShorthand().properties()[i], val)) { parsedProperty[i] = found = true; addAnimationValue(values[i], val.release()); } @@ -2667,17 +2829,17 @@ bool CSSParser::parseTransitionShorthand(bool important) // Fill in any remaining properties with the initial value. for (i = 0; i < numProperties; ++i) { if (!parsedProperty[i]) - addAnimationValue(values[i], cssValuePool()->createImplicitInitialValue()); + addAnimationValue(values[i], cssValuePool().createImplicitInitialValue()); } // Now add all of the properties we found. for (i = 0; i < numProperties; i++) - addProperty(properties[i], values[i].release(), important); + addProperty(webkitTransitionShorthand().properties()[i], values[i].release(), important); return true; } -bool CSSParser::parseShorthand(int propId, const int *properties, int numProperties, bool important) +bool CSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important) { // We try to match as many properties as possible // We set up an array of booleans to mark which property has been found, @@ -2685,14 +2847,14 @@ bool CSSParser::parseShorthand(int propId, const int *properties, int numPropert ShorthandScope scope(this, propId); bool found = false; - int propertiesParsed = 0; - bool fnd[6]= { false, false, false, false, false, false }; // 6 is enough size. + unsigned propertiesParsed = 0; + bool propertyFound[6]= { false, false, false, false, false, false }; // 6 is enough size. while (m_valueList->current()) { found = false; - for (int propIndex = 0; !found && propIndex < numProperties; ++propIndex) { - if (!fnd[propIndex] && parseValue(properties[propIndex], important)) { - fnd[propIndex] = found = true; + for (unsigned propIndex = 0; !found && propIndex < shorthand.length(); ++propIndex) { + if (!propertyFound[propIndex] && parseValue(shorthand.properties()[propIndex], important)) { + propertyFound[propIndex] = found = true; propertiesParsed++; } } @@ -2703,20 +2865,28 @@ bool CSSParser::parseShorthand(int propId, const int *properties, int numPropert return false; } - if (propertiesParsed == numProperties) + if (propertiesParsed == shorthand.length()) return true; // Fill in any remaining properties with the initial value. ImplicitScope implicitScope(this, PropertyImplicit); - for (int i = 0; i < numProperties; ++i) { - if (!fnd[i]) - addProperty(properties[i], cssValuePool()->createImplicitInitialValue(), important); + const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization(); + for (unsigned i = 0; i < shorthand.length(); ++i) { + if (propertyFound[i]) + continue; + + if (propertiesForInitialization) { + const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]); + for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex) + addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important); + } else + addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important); } return true; } -bool CSSParser::parse4Values(int propId, const int *properties, bool important) +bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties, bool important) { /* From the CSS 2 specs, 8.3 * If there is only one value, it applies to all sides. If there are two values, the top and @@ -2775,7 +2945,7 @@ bool CSSParser::parse4Values(int propId, const int *properties, bool important) } // auto | <identifier> -bool CSSParser::parsePage(int propId, bool important) +bool CSSParser::parsePage(CSSPropertyID propId, bool important) { ASSERT(propId == CSSPropertyPage); @@ -2787,7 +2957,7 @@ bool CSSParser::parsePage(int propId, bool important) return false; if (value->id == CSSValueAuto) { - addProperty(propId, cssValuePool()->createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return true; } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) { addProperty(propId, createPrimitiveStringValue(value), important); @@ -2797,7 +2967,7 @@ bool CSSParser::parsePage(int propId, bool important) } // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ] -bool CSSParser::parseSize(int propId, bool important) +bool CSSParser::parseSize(CSSPropertyID propId, bool important) { ASSERT(propId == CSSPropertySize); @@ -2832,14 +3002,14 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV switch (value->id) { case CSSValueAuto: if (prevParamType == None) { - parsedValues->append(cssValuePool()->createIdentifierValue(value->id)); + parsedValues->append(cssValuePool().createIdentifierValue(value->id)); return Auto; } return None; case CSSValueLandscape: case CSSValuePortrait: if (prevParamType == None || prevParamType == PageSize) { - parsedValues->append(cssValuePool()->createIdentifierValue(value->id)); + parsedValues->append(cssValuePool().createIdentifierValue(value->id)); return Orientation; } return None; @@ -2853,13 +3023,13 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV case CSSValueLetter: if (prevParamType == None || prevParamType == Orientation) { // Normalize to Page Size then Orientation order by prepending. - // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (CSSStyleSelector::applyPageSizeProperty). - parsedValues->prepend(cssValuePool()->createIdentifierValue(value->id)); + // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty). + parsedValues->prepend(cssValuePool().createIdentifierValue(value->id)); return PageSize; } return None; case 0: - if (validUnit(value, FLength | FNonNeg, m_strict) && (prevParamType == None || prevParamType == Length)) { + if (validUnit(value, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) { parsedValues->append(createPrimitiveNumericValue(value)); return Length; } @@ -2871,7 +3041,7 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV // [ <string> <string> ]+ | inherit | none // inherit and none are handled in parseValue. -bool CSSParser::parseQuotes(int propId, bool important) +bool CSSParser::parseQuotes(CSSPropertyID propId, bool important) { RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); while (CSSParserValue* val = m_valueList->current()) { @@ -2894,17 +3064,15 @@ bool CSSParser::parseQuotes(int propId, bool important) // [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit // in CSS 2.1 this got somewhat reduced: // [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit -bool CSSParser::parseContent(int propId, bool important) +bool CSSParser::parseContent(CSSPropertyID propId, bool important) { RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); while (CSSParserValue* val = m_valueList->current()) { RefPtr<CSSValue> parsedValue; - if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) { + if (val->unit == CSSPrimitiveValue::CSS_URI) { // url - // FIXME: The completeURL call should be done when using the CSSImageValue, - // not when creating it. - parsedValue = CSSImageValue::create(m_styleSheet->completeURL(val->string)); + parsedValue = CSSImageValue::create(completeURL(val->string)); } else if (val->unit == CSSParserValue::Function) { // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...) CSSParserValueList* args = val->function->args.get(); @@ -2922,6 +3090,12 @@ bool CSSParser::parseContent(int propId, bool important) parsedValue = parseCounterContent(args, true); if (!parsedValue) return false; +#if ENABLE(CSS_IMAGE_SET) + } else if (equalIgnoringCase(val->function->name, "-webkit-image-set(")) { + parsedValue = parseImageSet(m_valueList.get()); + if (!parsedValue) + return false; +#endif } else if (isGeneratedImageValue(val)) { if (!parseGeneratedImage(m_valueList.get(), parsedValue)) return false; @@ -2943,7 +3117,7 @@ bool CSSParser::parseContent(int propId, bool important) case CSSValueNoCloseQuote: case CSSValueNone: case CSSValueNormal: - parsedValue = cssValuePool()->createIdentifierValue(val->id); + parsedValue = cssValuePool().createIdentifierValue(val->id); } } else if (val->unit == CSSPrimitiveValue::CSS_STRING) { parsedValue = createPrimitiveStringValue(val); @@ -2980,38 +3154,42 @@ PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args) if (attrName[0] == '-') return 0; - Document* document = findDocument(); - if (document && document->isHTMLDocument()) + if (m_context.isHTMLDocument) attrName = attrName.lower(); - return cssValuePool()->createValue(attrName, CSSPrimitiveValue::CSS_ATTR); + return cssValuePool().createValue(attrName, CSSPrimitiveValue::CSS_ATTR); } PassRefPtr<CSSValue> CSSParser::parseBackgroundColor() { int id = m_valueList->current()->id; if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor || - (id >= CSSValueGrey && id < CSSValueWebkitText && !m_strict)) - return cssValuePool()->createIdentifierValue(id); + (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode())) + return cssValuePool().createIdentifierValue(id); return parseColor(); } bool CSSParser::parseFillImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value) { if (valueList->current()->id == CSSValueNone) { - value = CSSImageValue::create(); + value = cssValuePool().createIdentifierValue(CSSValueNone); return true; } if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) { - // FIXME: The completeURL call should be done when using the CSSImageValue, - // not when creating it. - if (m_styleSheet) - value = CSSImageValue::create(m_styleSheet->completeURL(valueList->current()->string)); + value = CSSImageValue::create(completeURL(valueList->current()->string)); return true; } if (isGeneratedImageValue(valueList->current())) return parseGeneratedImage(valueList, value); + +#if ENABLE(CSS_IMAGE_SET) + if (valueList->current()->unit == CSSParserValue::Function && equalIgnoringCase(valueList->current()->function->name, "-webkit-image-set(")) { + value = parseImageSet(m_valueList.get()); + if (value) + return true; + } +#endif return false; } @@ -3025,9 +3203,9 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionX(CSSParserValueList* valueList percent = 100; else if (id == CSSValueCenter) percent = 50; - return cssValuePool()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } - if (validUnit(valueList->current(), FPercent | FLength, m_strict)) + if (validUnit(valueList->current(), FPercent | FLength)) return createPrimitiveNumericValue(valueList->current()); return 0; } @@ -3041,9 +3219,9 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionY(CSSParserValueList* valueList percent = 100; else if (id == CSSValueCenter) percent = 50; - return cssValuePool()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } - if (validUnit(valueList->current(), FPercent | FLength, m_strict)) + if (validUnit(valueList->current(), FPercent | FLength)) return createPrimitiveNumericValue(valueList->current()); return 0; } @@ -3074,9 +3252,9 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionComponent(CSSParserValueList* v cumulativeFlags |= AmbiguousFillPosition; individualFlag = AmbiguousFillPosition; } - return cssValuePool()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } - if (validUnit(valueList->current(), FPercent | FLength, m_strict)) { + if (validUnit(valueList->current(), FPercent | FLength)) { if (!cumulativeFlags) { cumulativeFlags |= XFillPosition; individualFlag = XFillPosition; @@ -3111,7 +3289,7 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue value = valueList->next(); // First check for the comma. If so, we are finished parsing this value or value pair. - if (value && value->unit == CSSParserValue::Operator && value->iValue == ',') + if (isComma(value)) value = 0; if (value) { @@ -3131,7 +3309,7 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue // is simply 50%. This is our default. // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center). // For left/right/center, the default of 50% in the y is still correct. - value2 = cssValuePool()->createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE); + value2 = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE); if (value1Flag == YFillPosition || value2Flag == XFillPosition) value1.swap(value2); @@ -3139,78 +3317,73 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2) { - CSSParserValue* value = m_valueList->current(); - int id = m_valueList->current()->id; if (id == CSSValueRepeatX) { m_implicitShorthand = true; - value1 = cssValuePool()->createIdentifierValue(CSSValueRepeat); - value2 = cssValuePool()->createIdentifierValue(CSSValueNoRepeat); + value1 = cssValuePool().createIdentifierValue(CSSValueRepeat); + value2 = cssValuePool().createIdentifierValue(CSSValueNoRepeat); m_valueList->next(); return; } if (id == CSSValueRepeatY) { m_implicitShorthand = true; - value1 = cssValuePool()->createIdentifierValue(CSSValueNoRepeat); - value2 = cssValuePool()->createIdentifierValue(CSSValueRepeat); + value1 = cssValuePool().createIdentifierValue(CSSValueNoRepeat); + value2 = cssValuePool().createIdentifierValue(CSSValueRepeat); m_valueList->next(); return; } if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) - value1 = cssValuePool()->createIdentifierValue(id); + value1 = cssValuePool().createIdentifierValue(id); else { value1 = 0; return; } - value = m_valueList->next(); - - // First check for the comma. If so, we are finished parsing this value or value pair. - if (value && value->unit == CSSParserValue::Operator && value->iValue == ',') - value = 0; - - if (value) - id = m_valueList->current()->id; + CSSParserValue* value = m_valueList->next(); - if (value && (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)) { - value2 = cssValuePool()->createIdentifierValue(id); - m_valueList->next(); - } else { - // If only one value was specified, value2 is the same as value1. - m_implicitShorthand = true; - value2 = cssValuePool()->createIdentifierValue(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent()); + // Parse the second value if one is available + if (value && !isComma(value)) { + id = value->id; + if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) { + value2 = cssValuePool().createIdentifierValue(id); + m_valueList->next(); + return; + } } + + // If only one value was specified, value2 is the same as value1. + m_implicitShorthand = true; + value2 = cssValuePool().createIdentifierValue(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent()); } -PassRefPtr<CSSValue> CSSParser::parseFillSize(int propId, bool& allowComma) +PassRefPtr<CSSValue> CSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma) { allowComma = true; CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueContain || value->id == CSSValueCover) - return cssValuePool()->createIdentifierValue(value->id); + return cssValuePool().createIdentifierValue(value->id); RefPtr<CSSPrimitiveValue> parsedValue1; if (value->id == CSSValueAuto) - parsedValue1 = cssValuePool()->createIdentifierValue(CSSValueAuto); + parsedValue1 = cssValuePool().createIdentifierValue(CSSValueAuto); else { - if (!validUnit(value, FLength | FPercent, m_strict)) + if (!validUnit(value, FLength | FPercent)) return 0; parsedValue1 = createPrimitiveNumericValue(value); } - CSSPropertyID property = static_cast<CSSPropertyID>(propId); RefPtr<CSSPrimitiveValue> parsedValue2; if ((value = m_valueList->next())) { if (value->unit == CSSParserValue::Operator && value->iValue == ',') allowComma = false; else if (value->id != CSSValueAuto) { - if (!validUnit(value, FLength | FPercent, m_strict)) + if (!validUnit(value, FLength | FPercent)) return 0; parsedValue2 = createPrimitiveNumericValue(value); } - } else if (!parsedValue2 && property == CSSPropertyWebkitBackgroundSize) { + } else if (!parsedValue2 && propId == CSSPropertyWebkitBackgroundSize) { // For backwards compatibility we set the second value to the first if it is omitted. // We only need to do this for -webkit-background-size. It should be safe to let masks match // the real property. @@ -3219,10 +3392,10 @@ PassRefPtr<CSSValue> CSSParser::parseFillSize(int propId, bool& allowComma) if (!parsedValue2) return parsedValue1; - return cssValuePool()->createValue(Pair::create(parsedValue1.release(), parsedValue2.release())); + return cssValuePool().createValue(Pair::create(parsedValue1.release(), parsedValue2.release())); } -bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, +bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>& retValue1, RefPtr<CSSValue>& retValue2) { RefPtr<CSSValueList> values; @@ -3255,7 +3428,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, RefPtr<CSSValue> currValue2; if (allowComma) { - if (val->unit != CSSParserValue::Operator || val->iValue != ',') + if (!isComma(val)) return false; m_valueList->next(); allowComma = false; @@ -3270,7 +3443,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, case CSSPropertyBackgroundAttachment: case CSSPropertyWebkitMaskAttachment: if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) { - currValue = cssValuePool()->createIdentifierValue(val->id); + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; @@ -3289,17 +3462,17 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox || ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) && (val->id == CSSValueText || val->id == CSSValueWebkitText))) { - currValue = cssValuePool()->createIdentifierValue(val->id); + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; case CSSPropertyBackgroundClip: - if (parseBackgroundClip(val, currValue, cssValuePool())) + if (parseBackgroundClip(val, currValue)) m_valueList->next(); break; case CSSPropertyBackgroundOrigin: if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) { - currValue = cssValuePool()->createIdentifierValue(val->id); + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; @@ -3325,7 +3498,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, case CSSPropertyWebkitBackgroundComposite: case CSSPropertyWebkitMaskComposite: if ((val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) || val->id == CSSValueHighlight) { - currValue = cssValuePool()->createIdentifierValue(val->id); + currValue = cssValuePool().createIdentifierValue(val->id); m_valueList->next(); } break; @@ -3342,6 +3515,8 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, m_valueList->next(); break; } + default: + break; } if (!currValue) return false; @@ -3391,7 +3566,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, PassRefPtr<CSSValue> CSSParser::parseAnimationDelay() { CSSParserValue* value = m_valueList->current(); - if (validUnit(value, FTime, m_strict)) + if (validUnit(value, FTime)) return createPrimitiveNumericValue(value); return 0; } @@ -3400,14 +3575,14 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDirection() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse) - return cssValuePool()->createIdentifierValue(value->id); + return cssValuePool().createIdentifierValue(value->id); return 0; } PassRefPtr<CSSValue> CSSParser::parseAnimationDuration() { CSSParserValue* value = m_valueList->current(); - if (validUnit(value, FTime | FNonNeg, m_strict)) + if (validUnit(value, FTime | FNonNeg)) return createPrimitiveNumericValue(value); return 0; } @@ -3416,7 +3591,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth) - return cssValuePool()->createIdentifierValue(value->id); + return cssValuePool().createIdentifierValue(value->id); return 0; } @@ -3424,8 +3599,8 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueInfinite) - return cssValuePool()->createIdentifierValue(value->id); - if (validUnit(value, FInteger | FNonNeg, m_strict)) + return cssValuePool().createIdentifierValue(value->id); + if (validUnit(value, FNumber | FNonNeg)) return createPrimitiveNumericValue(value); return 0; } @@ -3435,7 +3610,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationName() CSSParserValue* value = m_valueList->current(); if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) { if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value->string, "none"))) { - return cssValuePool()->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); } else { return createPrimitiveStringValue(value); } @@ -3447,7 +3622,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueRunning || value->id == CSSValuePaused) - return cssValuePool()->createIdentifierValue(value->id); + return cssValuePool().createIdentifierValue(value->id); return 0; } @@ -3458,11 +3633,11 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationProperty() return 0; int result = cssPropertyID(value->string); if (result) - return cssValuePool()->createIdentifierValue(result); + return cssValuePool().createIdentifierValue(result); if (equalIgnoringCase(value->string, "all")) - return cssValuePool()->createIdentifierValue(CSSValueAll); + return cssValuePool().createIdentifierValue(CSSValueAll); if (equalIgnoringCase(value->string, "none")) - return cssValuePool()->createIdentifierValue(CSSValueNone); + return cssValuePool().createIdentifierValue(CSSValueNone); return 0; } @@ -3472,29 +3647,30 @@ bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<C // now get z if (m_valueList->current()) { - if (validUnit(m_valueList->current(), FLength, m_strict)) { + if (validUnit(m_valueList->current(), FLength)) { value3 = createPrimitiveNumericValue(m_valueList->current()); m_valueList->next(); return true; } return false; } + value3 = cssValuePool().createImplicitInitialValue(); return true; } bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result) { CSSParserValue* v = args->current(); - if (!validUnit(v, FNumber, m_strict)) + if (!validUnit(v, FNumber)) return false; result = v->fValue; v = args->next(); if (!v) // The last number in the function has no comma after it, so we're done. return true; - if (v->unit != CSSParserValue::Operator && v->iValue != ',') + if (!isComma(v)) return false; - v = args->next(); + args->next(); return true; } @@ -3503,7 +3679,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction() CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd) - return cssValuePool()->createIdentifierValue(value->id); + return cssValuePool().createIdentifierValue(value->id); // We must be a function. if (value->unit != CSSParserValue::Function) @@ -3521,7 +3697,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction() bool stepAtStart = false; CSSParserValue* v = args->current(); - if (!validUnit(v, FInteger, m_strict)) + if (!validUnit(v, FInteger)) return 0; numSteps = clampToInteger(v->fValue); if (numSteps < 1) @@ -3530,7 +3706,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction() if (v) { // There is a comma so we need to parse the second value - if (v->unit != CSSParserValue::Operator && v->iValue != ',') + if (!isComma(v)) return 0; v = args->next(); if (v->id != CSSValueStart && v->id != CSSValueEnd) @@ -3564,7 +3740,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction() return 0; } -bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result) +bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& result) { RefPtr<CSSValueList> values; CSSParserValue* val; @@ -3576,7 +3752,7 @@ bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result) while ((val = m_valueList->current())) { RefPtr<CSSValue> currValue; if (allowComma) { - if (val->unit != CSSParserValue::Operator || val->iValue != ',') + if (!isComma(val)) return false; m_valueList->next(); allowComma = false; @@ -3631,6 +3807,9 @@ bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result) if (currValue) m_valueList->next(); break; + default: + ASSERT_NOT_REACHED(); + return false; } if (!currValue) @@ -3667,24 +3846,24 @@ bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result) } #if ENABLE(CSS_GRID_LAYOUT) -bool CSSParser::parseGridTrackList(int propId, bool important) +bool CSSParser::parseGridTrackList(CSSPropertyID propId, bool important) { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNone) { if (m_valueList->next()) return false; - addProperty(propId, cssValuePool()->createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return true; } RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); while (value) { - bool valid = validUnit(value, FLength | FPercent, m_strict) || value->id == CSSValueAuto; + bool valid = validUnit(value, FLength | FPercent) || value->id == CSSValueAuto; if (!valid) return false; - RefPtr<CSSPrimitiveValue> primitiveValue = value->id == CSSValueAuto ? cssValuePool()->createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(value); + RefPtr<CSSPrimitiveValue> primitiveValue = value->id == CSSValueAuto ? cssValuePool().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(value); values->append(primitiveValue.release()); value = m_valueList->next(); } @@ -3711,7 +3890,7 @@ static CSSParserValue* skipCommaInDashboardRegion(CSSParserValueList *args) return args->current(); } -bool CSSParser::parseDashboardRegions(int propId, bool important) +bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) { bool valid = true; @@ -3720,7 +3899,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) if (value->id == CSSValueNone) { if (m_valueList->next()) return false; - addProperty(propId, cssValuePool()->createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return valid; } @@ -3790,7 +3969,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) if (numArgs == DASHBOARD_REGION_SHORT_NUM_PARAMETERS || numArgs == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) { // This originally used CSSValueInvalid by accident. It might be more logical to use something else. - RefPtr<CSSPrimitiveValue> amount = cssValuePool()->createIdentifierValue(CSSValueInvalid); + RefPtr<CSSPrimitiveValue> amount = cssValuePool().createIdentifierValue(CSSValueInvalid); region->setTop(amount); region->setRight(amount); @@ -3803,12 +3982,12 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) arg = args->next(); arg = skipCommaInDashboardRegion(args); - valid = arg->id == CSSValueAuto || validUnit(arg, FLength, m_strict); + valid = arg->id == CSSValueAuto || validUnit(arg, FLength); if (!valid) break; RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ? - cssValuePool()->createIdentifierValue(CSSValueAuto) : + cssValuePool().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(arg); if (i == 0) @@ -3829,7 +4008,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) } if (valid) - addProperty(propId, cssValuePool()->createValue(firstRegion.release()), important); + addProperty(propId, cssValuePool().createValue(firstRegion.release()), important); return valid; } @@ -3851,7 +4030,7 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo RefPtr<CSSPrimitiveValue> separator; if (!counters) - separator = cssValuePool()->createValue(String(), CSSPrimitiveValue::CSS_STRING); + separator = cssValuePool().createValue(String(), CSSPrimitiveValue::CSS_STRING); else { i = args->next(); if (i->unit != CSSParserValue::Operator || i->iValue != ',') @@ -3867,7 +4046,7 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo RefPtr<CSSPrimitiveValue> listStyle; i = args->next(); if (!i) // Make the list style default decimal - listStyle = cssValuePool()->createIdentifierValue(CSSValueDecimal); + listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal); else { if (i->unit != CSSParserValue::Operator || i->iValue != ',') return 0; @@ -3882,13 +4061,13 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo else return 0; - listStyle = cssValuePool()->createIdentifierValue(listStyleID); + listStyle = cssValuePool().createIdentifierValue(listStyleID); } - return cssValuePool()->createValue(Counter::create(identifier.release(), listStyle.release(), separator.release())); + return cssValuePool().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release())); } -bool CSSParser::parseShape(int propId, bool important) +bool CSSParser::parseClipShape(CSSPropertyID propId, bool important) { CSSParserValue* value = m_valueList->current(); CSSParserValueList* args = value->function->args.get(); @@ -3904,11 +4083,11 @@ bool CSSParser::parseShape(int propId, bool important) int i = 0; CSSParserValue* a = args->current(); while (a) { - valid = a->id == CSSValueAuto || validUnit(a, FLength, m_strict); + valid = a->id == CSSValueAuto || validUnit(a, FLength); if (!valid) break; RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ? - cssValuePool()->createIdentifierValue(CSSValueAuto) : + cssValuePool().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(a); if (i == 0) rect->setTop(length); @@ -3930,14 +4109,14 @@ bool CSSParser::parseShape(int propId, bool important) i++; } if (valid) { - addProperty(propId, cssValuePool()->createValue(rect.release()), important); + addProperty(propId, cssValuePool().createValue(rect.release()), important); m_valueList->next(); return true; } return false; } -PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeRect(CSSParserValueList* args) +PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeRectangle(CSSParserValueList* args) { ASSERT(args); @@ -3945,12 +4124,12 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeRect(CSSParserValueList* args) if (args->size() != 7 && args->size() != 9 && args->size() != 11) return 0; - RefPtr<CSSWrapShapeRect> shape = CSSWrapShapeRect::create(); + RefPtr<CSSWrapShapeRectangle> shape = CSSWrapShapeRectangle::create(); unsigned argumentNumber = 0; CSSParserValue* argument = args->current(); while (argument) { - if (!validUnit(argument, FLength, m_strict)) + if (!validUnit(argument, FLength)) return 0; RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); @@ -3990,7 +4169,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeRect(CSSParserValueList* args) return shape; } -PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeCircle(CSSParserValueList* args) +PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeCircle(CSSParserValueList* args) { ASSERT(args); @@ -4003,7 +4182,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeCircle(CSSParserValueList* arg unsigned argumentNumber = 0; CSSParserValue* argument = args->current(); while (argument) { - if (!validUnit(argument, FLength, m_strict)) + if (!validUnit(argument, FLength)) return 0; RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); @@ -4034,7 +4213,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeCircle(CSSParserValueList* arg return shape; } -PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeEllipse(CSSParserValueList* args) +PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeEllipse(CSSParserValueList* args) { ASSERT(args); @@ -4046,7 +4225,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeEllipse(CSSParserValueList* ar unsigned argumentNumber = 0; CSSParserValue* argument = args->current(); while (argument) { - if (!validUnit(argument, FLength, m_strict)) + if (!validUnit(argument, FLength)) return 0; RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument); @@ -4080,7 +4259,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapeEllipse(CSSParserValueList* ar return shape; } -PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapePolygon(CSSParserValueList* args) +PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapePolygon(CSSParserValueList* args) { ASSERT(args); @@ -4094,29 +4273,24 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapePolygon(CSSParserValueList* ar if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) { shape->setWindRule(argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO); - CSSParserValue* comma = args->next(); - if (!comma || comma->unit != CSSParserValue::Operator || comma->iValue != ',') + if (!isComma(args->next())) return 0; argument = args->next(); size -= 2; } - // <length>, <length> ... <length>, <length> -> each pair has 3 elements - if (!size || (size % 3)) + // <length> <length>, ... <length> <length> -> each pair has 3 elements except the last one + if (!size || (size % 3) - 2) return 0; CSSParserValue* argumentX = argument; while (argumentX) { - if (!validUnit(argumentX, FLength, m_strict)) - return 0; - - CSSParserValue* comma = args->next(); - if (!comma || comma->unit != CSSParserValue::Operator || comma->iValue != ',') + if (!validUnit(argumentX, FLength)) return 0; CSSParserValue* argumentY = args->next(); - if (!argumentY || !validUnit(argumentY, FLength, m_strict)) + if (!argumentY || !validUnit(argumentY, FLength)) return 0; RefPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentX); @@ -4124,13 +4298,19 @@ PassRefPtr<CSSWrapShape> CSSParser::parseWrapShapePolygon(CSSParserValueList* ar shape->appendPoint(xLength.release(), yLength.release()); - argumentX = args->next(); + CSSParserValue* commaOrNull = args->next(); + if (!commaOrNull) + argumentX = 0; + else if (!isComma(commaOrNull)) + return 0; + else + argumentX = args->next(); } return shape; } -bool CSSParser::parseWrapShape(bool shapeInside, bool important) +bool CSSParser::parseExclusionShape(bool shapeInside, bool important) { CSSParserValue* value = m_valueList->current(); CSSParserValueList* args = value->function->args.get(); @@ -4140,17 +4320,17 @@ bool CSSParser::parseWrapShape(bool shapeInside, bool important) RefPtr<CSSWrapShape> shape; - if (equalIgnoringCase(value->function->name, "rect(")) - shape = parseWrapShapeRect(args); + if (equalIgnoringCase(value->function->name, "rectangle(")) + shape = parseExclusionShapeRectangle(args); else if (equalIgnoringCase(value->function->name, "circle(")) - shape = parseWrapShapeCircle(args); + shape = parseExclusionShapeCircle(args); else if (equalIgnoringCase(value->function->name, "ellipse(")) - shape = parseWrapShapeEllipse(args); + shape = parseExclusionShapeEllipse(args); else if (equalIgnoringCase(value->function->name, "polygon(")) - shape = parseWrapShapePolygon(args); + shape = parseExclusionShapePolygon(args); if (shape) { - addProperty(shapeInside ? CSSPropertyWebkitWrapShapeInside : CSSPropertyWebkitWrapShapeOutside, cssValuePool()->createValue(shape.release()), important); + addProperty(shapeInside ? CSSPropertyWebkitShapeInside : CSSPropertyWebkitShapeOutside, cssValuePool().createValue(shape.release()), important); m_valueList->next(); return true; } @@ -4161,111 +4341,50 @@ bool CSSParser::parseWrapShape(bool shapeInside, bool important) // [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family' bool CSSParser::parseFont(bool important) { - bool valid = true; - bool styleImplicit = true; - bool variantImplicit = true; - bool weightImplicit = true; - bool lineHeightImplicit = true; - int valueOrdinal = 0; - - CSSParserValue *value = m_valueList->current(); - RefPtr<FontValue> font = FontValue::create(); - // Optional font-style, font-variant and font-weight. - while (value) { - int id = value->id; - if (id == CSSValueInitial || id == CSSValueInherit) + // Let's check if there is an inherit or initial somewhere in the shorthand. + for (unsigned i = 0; i < m_valueList->size(); ++i) { + if (m_valueList->valueAt(i)->id == CSSValueInherit || m_valueList->valueAt(i)->id == CSSValueInitial) return false; - if (id) { - if (id == CSSValueNormal) { - // It's the initial value for all three, so mark the corresponding longhand as explicit. - switch (valueOrdinal) { - case 0: - styleImplicit = false; - break; - case 1: - variantImplicit = false; - break; - case 2: - weightImplicit = false; - break; - } - } else if (id == CSSValueItalic || id == CSSValueOblique) { - if (font->style) - return false; - font->style = cssValuePool()->createIdentifierValue(id); - styleImplicit = false; - } else if (id == CSSValueSmallCaps) { - if (font->variant) - return false; - font->variant = cssValuePool()->createIdentifierValue(id); - variantImplicit = false; - } else if (id >= CSSValueBold && id <= CSSValueLighter) { - if (font->weight) - return false; - font->weight = cssValuePool()->createIdentifierValue(id); - weightImplicit = false; - } else - valid = false; - } else if (!font->weight && validUnit(value, FInteger | FNonNeg, true)) { - int weight = static_cast<int>(value->fValue); - int val = 0; - if (weight == 100) - val = CSSValue100; - else if (weight == 200) - val = CSSValue200; - else if (weight == 300) - val = CSSValue300; - else if (weight == 400) - val = CSSValue400; - else if (weight == 500) - val = CSSValue500; - else if (weight == 600) - val = CSSValue600; - else if (weight == 700) - val = CSSValue700; - else if (weight == 800) - val = CSSValue800; - else if (weight == 900) - val = CSSValue900; + } - if (val) { - font->weight = cssValuePool()->createIdentifierValue(val); - weightImplicit = false; - } else - valid = false; - } else { - valid = false; - } - if (!valid) + ShorthandScope scope(this, CSSPropertyFont); + // Optional font-style, font-variant and font-weight. + bool fontStyleParsed = false; + bool fontVariantParsed = false; + bool fontWeightParsed = false; + CSSParserValue* value; + while ((value = m_valueList->current())) { + if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id)) { + addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(value->id), important); + fontStyleParsed = true; + } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->id == CSSValueSmallCaps)) { + // Font variant in the shorthand is particular, it only accepts normal or small-caps. + addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(value->id), important); + fontVariantParsed = true; + } else if (!fontWeightParsed && parseFontWeight(important)) + fontWeightParsed = true; + else break; - value = m_valueList->next(); - ++valueOrdinal; + m_valueList->next(); } - if (!value) - return false; - if (value->id == CSSValueInitial || value->id == CSSValueInherit) + if (!value) return false; - // Set undefined values to default. - if (!font->style) - font->style = cssValuePool()->createIdentifierValue(CSSValueNormal); - if (!font->variant) - font->variant = cssValuePool()->createIdentifierValue(CSSValueNormal); - if (!font->weight) - font->weight = cssValuePool()->createIdentifierValue(CSSValueNormal); + if (!fontStyleParsed) + addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); + if (!fontVariantParsed) + addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); + if (!fontWeightParsed) + addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); // Now a font size _must_ come. // <absolute-size> | <relative-size> | <length> | <percentage> | inherit - if (value->id >= CSSValueXxSmall && value->id <= CSSValueLarger) - font->size = cssValuePool()->createIdentifierValue(value->id); - else if (validUnit(value, FLength | FPercent | FNonNeg, m_strict)) - font->size = createPrimitiveNumericValue(value); - value = m_valueList->next(); - if (!font->size || !value) + if (!parseFontSize(important)) return false; - if (value->id == CSSValueInitial || value->id == CSSValueInherit) + value = m_valueList->current(); + if (!value) return false; if (value->unit == CSSParserValue::Operator && value->iValue == '/') { @@ -4273,51 +4392,31 @@ bool CSSParser::parseFont(bool important) value = m_valueList->next(); if (!value) return false; - if (value->id == CSSValueNormal) { - // Default value, just mark the property as explicit. - lineHeightImplicit = false; - } else if (validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict)) { - font->lineHeight = createPrimitiveNumericValue(value); - lineHeightImplicit = false; - } else - return false; - value = m_valueList->next(); - if (!value) + if (!parseLineHeight(important)) return false; - } - - if (value->id == CSSValueInitial || value->id == CSSValueInherit) - return false; - - if (!font->lineHeight) - font->lineHeight = cssValuePool()->createIdentifierValue(CSSValueNormal); + } else + addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true); // Font family must come now. - font->family = parseFontFamily(); - - if (m_valueList->current() || !font->family) + RefPtr<CSSValue> parsedFamilyValue = parseFontFamily(); + if (!parsedFamilyValue) return false; - ShorthandScope scope(this, CSSPropertyFont); - addProperty(CSSPropertyFontFamily, font->family, important); - addProperty(CSSPropertyFontSize, font->size, important); - addProperty(CSSPropertyFontStyle, font->style, important, styleImplicit); - addProperty(CSSPropertyFontVariant, font->variant, important, variantImplicit); - addProperty(CSSPropertyFontWeight, font->weight, important, weightImplicit); - addProperty(CSSPropertyLineHeight, font->lineHeight, important, lineHeightImplicit); + addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important); // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their initial values // but we don't seem to support them at the moment. They should also be added here once implemented. + if (m_valueList->current()) + return false; return true; } class FontFamilyValueBuilder { public: - FontFamilyValueBuilder(CSSValueList* list, CSSValuePool* pool) + FontFamilyValueBuilder(CSSValueList* list) : m_list(list) - , m_cssValuePool(pool) { } @@ -4332,14 +4431,13 @@ public: { if (m_builder.isEmpty()) return; - m_list->append(m_cssValuePool->createFontFamilyValue(m_builder.toString())); + m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString())); m_builder.clear(); } private: StringBuilder m_builder; CSSValueList* m_list; - CSSValuePool* m_cssValuePool; }; PassRefPtr<CSSValueList> CSSParser::parseFontFamily() @@ -4347,7 +4445,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily() RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); CSSParserValue* value = m_valueList->current(); - FontFamilyValueBuilder familyBuilder(list.get(), cssValuePool()); + FontFamilyValueBuilder familyBuilder(list.get()); bool inFamily = false; while (value) { @@ -4364,7 +4462,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily() if (inFamily) familyBuilder.add(value->string); else if (nextValBreaksFont || !nextValIsFontName) - list->append(cssValuePool()->createIdentifierValue(value->id)); + list->append(cssValuePool().createIdentifierValue(value->id)); else { familyBuilder.commit(); familyBuilder.add(value->string); @@ -4374,12 +4472,12 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily() // Strings never share in a family name. inFamily = false; familyBuilder.commit(); - list->append(cssValuePool()->createFontFamilyValue(value->string)); + list->append(cssValuePool().createFontFamilyValue(value->string)); } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) { if (inFamily) familyBuilder.add(value->string); else if (nextValBreaksFont || !nextValIsFontName) - list->append(cssValuePool()->createFontFamilyValue(value->string)); + list->append(cssValuePool().createFontFamilyValue(value->string)); else { familyBuilder.commit(); familyBuilder.add(value->string); @@ -4409,6 +4507,36 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily() return list.release(); } +bool CSSParser::parseLineHeight(bool important) +{ + CSSParserValue* value = m_valueList->current(); + int id = value->id; + bool validPrimitive = false; + // normal | <number> | <length> | <percentage> | inherit + if (id == CSSValueNormal) + validPrimitive = true; + else + validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg)); + if (validPrimitive && (!m_valueList->next() || inShorthand())) + addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, value), important); + return validPrimitive; +} + +bool CSSParser::parseFontSize(bool important) +{ + CSSParserValue* value = m_valueList->current(); + int id = value->id; + bool validPrimitive = false; + // <absolute-size> | <relative-size> | <length> | <percentage> | inherit + if (id >= CSSValueXxSmall && id <= CSSValueLarger) + validPrimitive = true; + else + validPrimitive = validUnit(value, FLength | FPercent | FNonNeg); + if (validPrimitive && (!m_valueList->next() || inShorthand())) + addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), important); + return validPrimitive; +} + bool CSSParser::parseFontVariant(bool important) { RefPtr<CSSValueList> values; @@ -4421,12 +4549,12 @@ bool CSSParser::parseFontVariant(bool important) if (!expectComma) { expectComma = true; if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps) - parsedValue = cssValuePool()->createIdentifierValue(val->id); + parsedValue = cssValuePool().createIdentifierValue(val->id); else if (val->id == CSSValueAll && !values) { // 'all' is only allowed in @font-face and with no other values. Make a value list to // indicate that we are in the @font-face case. values = CSSValueList::createCommaSeparated(); - parsedValue = cssValuePool()->createIdentifierValue(val->id); + parsedValue = cssValuePool().createIdentifierValue(val->id); } } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { expectComma = false; @@ -4458,28 +4586,24 @@ bool CSSParser::parseFontVariant(bool important) bool CSSParser::parseFontWeight(bool important) { - if (m_valueList->size() != 1) - return false; - CSSParserValue* value = m_valueList->current(); if ((value->id >= CSSValueNormal) && (value->id <= CSSValue900)) { - addProperty(CSSPropertyFontWeight, cssValuePool()->createIdentifierValue(value->id), important); + addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important); return true; } - if (validUnit(value, FInteger | FNonNeg, false)) { + if (validUnit(value, FInteger | FNonNeg, CSSQuirksMode)) { int weight = static_cast<int>(value->fValue); - if (!(weight % 100) && weight >= 100 && weight <= 900) - addProperty(CSSPropertyFontWeight, cssValuePool()->createIdentifierValue(CSSValue100 + weight / 100 - 1), important); - return true; + if (!(weight % 100) && weight >= 100 && weight <= 900) { + addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValue100 + weight / 100 - 1), important); + return true; + } } return false; } bool CSSParser::parseFontFaceSrcURI(CSSValueList* valueList) { - // FIXME: The completeURL call should be done when using the CSSFontFaceSrcValue, - // not when creating it. - RefPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(m_styleSheet->completeURL(m_valueList->current()->string))); + RefPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(completeURL(m_valueList->current()->string))); CSSParserValue* value = m_valueList->next(); if (!value) { @@ -4541,7 +4665,7 @@ bool CSSParser::parseFontFaceSrc() RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated()); while (CSSParserValue* value = m_valueList->current()) { - if (value->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) { + if (value->unit == CSSPrimitiveValue::CSS_URI) { if (!parseFontFaceSrcURI(values.get())) return false; } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "local(")) { @@ -4985,9 +5109,9 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo CSSParserValue* v = args->current(); Units unitType = FUnknown; // Get the first value and its type - if (validUnit(v, FInteger, true)) + if (validUnit(v, FInteger, CSSStrictMode)) unitType = FInteger; - else if (validUnit(v, FPercent, true)) + else if (validUnit(v, FPercent, CSSStrictMode)) unitType = FPercent; else return false; @@ -4998,7 +5122,7 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; v = args->next(); - if (!validUnit(v, unitType, true)) + if (!validUnit(v, unitType, CSSStrictMode)) return false; colorArray[i] = colorIntFromValue(v); } @@ -5007,7 +5131,7 @@ bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, boo if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; v = args->next(); - if (!validUnit(v, FNumber, true)) + if (!validUnit(v, FNumber, CSSStrictMode)) return false; const double value = parsedDouble(v, ReleaseParsedCalcValue); // Convert the floating pointer number of alpha to an integer in the range [0, 256), @@ -5027,7 +5151,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo CSSParserValueList* args = value->function->args.get(); CSSParserValue* v = args->current(); // Get the first value - if (!validUnit(v, FNumber, true)) + if (!validUnit(v, FNumber, CSSStrictMode)) return false; // normalize the Hue value and change it to be between 0 and 1.0 colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0; @@ -5036,7 +5160,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; v = args->next(); - if (!validUnit(v, FPercent, true)) + if (!validUnit(v, FPercent, CSSStrictMode)) return false; colorArray[i] = max(0.0, min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0 } @@ -5045,7 +5169,7 @@ bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bo if (v->unit != CSSParserValue::Operator && v->iValue != ',') return false; v = args->next(); - if (!validUnit(v, FNumber, true)) + if (!validUnit(v, FNumber, CSSStrictMode)) return false; colorArray[3] = max(0.0, min(1.0, parsedDouble(v, ReleaseParsedCalcValue))); } @@ -5057,20 +5181,21 @@ PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value) RGBA32 c = Color::transparent; if (!parseColorFromValue(value ? value : m_valueList->current(), c)) return 0; - return cssValuePool()->createColorValue(c); + return cssValuePool().createColorValue(c); } bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c) { - if (!m_strict && value->unit == CSSPrimitiveValue::CSS_NUMBER && - value->fValue >= 0. && value->fValue < 1000000.) { + if (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_NUMBER + && value->fValue >= 0. && value->fValue < 1000000.) { String str = String::format("%06d", static_cast<int>((value->fValue+.5))); - if (!fastParseColor(c, str, m_strict)) + // FIXME: This should be strict parsing for SVG as well. + if (!fastParseColor(c, str, inStrictMode())) return false; } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR || value->unit == CSSPrimitiveValue::CSS_IDENT || - (!m_strict && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) { - if (!fastParseColor(c, value->string, m_strict && value->unit == CSSPrimitiveValue::CSS_IDENT)) + (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) { + if (!fastParseColor(c, value->string, inStrictMode() && value->unit == CSSPrimitiveValue::CSS_IDENT)) return false; } else if (value->unit == CSSParserValue::Function && value->function->args != 0 && @@ -5202,7 +5327,7 @@ struct ShadowParseContext { void commitStyle(CSSParserValue* v) { - style = m_parser->cssValuePool()->createIdentifierValue(v->id); + style = cssValuePool().createIdentifierValue(v->id); allowStyle = false; if (allowX) allowBreak = false; @@ -5233,9 +5358,9 @@ struct ShadowParseContext { bool allowBreak; }; -PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, int propId) +PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propId) { - ShadowParseContext context(static_cast<CSSPropertyID>(propId), this); + ShadowParseContext context(propId, this); CSSParserValue* val; while ((val = valueList->current())) { // Check for a comma break first. @@ -5246,12 +5371,12 @@ PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, i return 0; #if ENABLE(SVG) // -webkit-svg-shadow does not support multiple values. - if (static_cast<CSSPropertyID>(propId) == CSSPropertyWebkitSvgShadow) + if (propId == CSSPropertyWebkitSvgShadow) return 0; #endif // The value is good. Commit it. context.commitValue(); - } else if (validUnit(val, FLength, true)) { + } else if (validUnit(val, FLength, CSSStrictMode)) { // We required a length and didn't get one. Invalid. if (!context.allowLength()) return 0; @@ -5267,12 +5392,12 @@ PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, i // The only other type of value that's ok is a color value. RefPtr<CSSPrimitiveValue> parsedColor; bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu - || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && !m_strict) + || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && inQuirksMode()) || val->id == CSSValueCurrentcolor); if (isColor) { if (!context.allowColor) return 0; - parsedColor = cssValuePool()->createIdentifierValue(val->id); + parsedColor = cssValuePool().createIdentifierValue(val->id); } if (!parsedColor) @@ -5298,7 +5423,7 @@ PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, i return 0; } -bool CSSParser::parseReflect(int propId, bool important) +bool CSSParser::parseReflect(CSSPropertyID propId, bool important) { // box-reflect: <direction> <offset> <mask> @@ -5326,9 +5451,9 @@ bool CSSParser::parseReflect(int propId, bool important) val = m_valueList->next(); RefPtr<CSSPrimitiveValue> offset; if (!val) - offset = cssValuePool()->createValue(0, CSSPrimitiveValue::CSS_PX); + offset = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); else { - if (!validUnit(val, FLength | FPercent, m_strict)) + if (!validUnit(val, FLength | FPercent)) return false; offset = createPrimitiveNumericValue(val); } @@ -5347,36 +5472,33 @@ bool CSSParser::parseReflect(int propId, bool important) return true; } -bool CSSParser::parseFlex(int propId, bool important) +PassRefPtr<CSSValue> CSSParser::parseFlex(CSSParserValueList* args) { - CSSParserValue* value = m_valueList->current(); - CSSParserValueList* args = value->function->args.get(); - if (!equalIgnoringCase(value->function->name, "-webkit-flex(") || !args || !args->size() || args->size() > 3 || m_valueList->next()) - return false; - + if (!args || !args->size() || args->size() > 3) + return 0; static const double unsetValue = -1; double positiveFlex = unsetValue; double negativeFlex = unsetValue; RefPtr<CSSPrimitiveValue> preferredSize; while (CSSParserValue* arg = args->current()) { - if (validUnit(arg, FNumber | FNonNeg, m_strict)) { + if (validUnit(arg, FNumber | FNonNeg)) { if (positiveFlex == unsetValue) positiveFlex = arg->fValue; else if (negativeFlex == unsetValue) negativeFlex = arg->fValue; else if (!arg->fValue) { // flex() only allows a preferred size of 0 (sans units) if the positive and negative flex values have already been set. - preferredSize = cssValuePool()->createValue(0, CSSPrimitiveValue::CSS_PX); + preferredSize = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); } else { // We only allow 3 numbers without units if the last value is 0. E.g., flex(1 1 1) is invalid. - return false; + return 0; } - } else if (!preferredSize && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg, m_strict))) + } else if (!preferredSize && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg))) preferredSize = parseValidPrimitive(arg->id, arg); else { // Not a valid arg for flex(). - return false; + return 0; } args->next(); } @@ -5386,11 +5508,13 @@ bool CSSParser::parseFlex(int propId, bool important) if (negativeFlex == unsetValue) negativeFlex = 0; if (!preferredSize) - preferredSize = cssValuePool()->createValue(0, CSSPrimitiveValue::CSS_PX); + preferredSize = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX); - RefPtr<CSSFlexValue> flex = CSSFlexValue::create(clampToFloat(positiveFlex), clampToFloat(negativeFlex), preferredSize); - addProperty(propId, flex.release(), important); - return true; + RefPtr<CSSValueList> flex = CSSValueList::createSpaceSeparated(); + flex->append(cssValuePool().createValue(clampToFloat(positiveFlex), CSSPrimitiveValue::CSS_NUMBER)); + flex->append(cssValuePool().createValue(clampToFloat(negativeFlex), CSSPrimitiveValue::CSS_NUMBER)); + flex->append(preferredSize); + return flex; } struct BorderImageParseContext { @@ -5489,12 +5613,12 @@ struct BorderImageParseContext { commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important); } - void commitBorderImageProperty(int propId, CSSParser* parser, PassRefPtr<CSSValue> value, bool important) + void commitBorderImageProperty(CSSPropertyID propId, CSSParser* parser, PassRefPtr<CSSValue> value, bool important) { if (value) parser->addProperty(propId, value, important); else - parser->addProperty(propId, parser->cssValuePool()->createImplicitInitialValue(), important, true); + parser->addProperty(propId, cssValuePool().createImplicitInitialValue(), important, true); } bool m_canAdvance; @@ -5516,7 +5640,7 @@ struct BorderImageParseContext { RefPtr<CSSValue> m_repeat; }; -bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result, bool important) +bool CSSParser::parseBorderImage(CSSPropertyID propId, RefPtr<CSSValue>& result, bool important) { ShorthandScope scope(this, propId); BorderImageParseContext context; @@ -5527,18 +5651,24 @@ bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result, bool impo context.commitSlash(); if (!context.canAdvance() && context.allowImage()) { - if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) { - // FIXME: The completeURL call should be done when using the CSSImageValue, - // not when creating it. - context.commitImage(CSSImageValue::create(m_styleSheet->completeURL(val->string))); - } else if (isGeneratedImageValue(val)) { + if (val->unit == CSSPrimitiveValue::CSS_URI) + context.commitImage(CSSImageValue::create(completeURL(val->string))); + else if (isGeneratedImageValue(val)) { RefPtr<CSSValue> value; if (parseGeneratedImage(m_valueList.get(), value)) context.commitImage(value); else return false; +#if ENABLE(CSS_IMAGE_SET) + } else if (val->unit == CSSParserValue::Function && equalIgnoringCase(val->function->name, "-webkit-image-set(")) { + RefPtr<CSSValue> value = parseImageSet(m_valueList.get()); + if (value) + context.commitImage(value); + else + return false; +#endif } else if (val->id == CSSValueNone) - context.commitImage(CSSImageValue::create()); + context.commitImage(cssValuePool().createIdentifierValue(CSSValueNone)); } if (!context.canAdvance() && context.allowImageSlice()) { @@ -5594,14 +5724,14 @@ bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result) RefPtr<CSSPrimitiveValue> secondValue; CSSParserValue* val = m_valueList->current(); if (isBorderImageRepeatKeyword(val->id)) - firstValue = cssValuePool()->createIdentifierValue(val->id); + firstValue = cssValuePool().createIdentifierValue(val->id); else return false; val = m_valueList->next(); if (val) { if (isBorderImageRepeatKeyword(val->id)) - secondValue = cssValuePool()->createIdentifierValue(val->id); + secondValue = cssValuePool().createIdentifierValue(val->id); else if (!inShorthand()) { // If we're not parsing a shorthand then we are invalid. return false; @@ -5613,7 +5743,7 @@ bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result) } else secondValue = firstValue; - result = cssValuePool()->createValue(Pair::create(firstValue, secondValue)); + result = cssValuePool().createValue(Pair::create(firstValue, secondValue)); return true; } @@ -5680,7 +5810,7 @@ public: quad->setLeft(m_left); // Make our new border image value now. - return CSSBorderImageSliceValue::create(m_parser->cssValuePool()->createValue(quad.release()), m_fill); + return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), m_fill); } private: @@ -5698,13 +5828,13 @@ private: bool m_fill; }; -bool CSSParser::parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValue>& result) +bool CSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtr<CSSBorderImageSliceValue>& result) { BorderImageSliceParseContext context(this); CSSParserValue* val; while ((val = m_valueList->current())) { // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet. - if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, true)) { + if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, CSSStrictMode)) { context.commitNumber(val); } else if (context.allowFill() && val->id == CSSValueFill) context.commitFill(); @@ -5751,7 +5881,7 @@ public: { RefPtr<CSSPrimitiveValue> val; if (v->id == CSSValueAuto) - val = m_parser->cssValuePool()->createIdentifierValue(v->id); + val = cssValuePool().createIdentifierValue(v->id); else val = m_parser->createPrimitiveNumericValue(v); @@ -5797,7 +5927,7 @@ public: quad->setLeft(m_left); // Make our new value now. - return m_parser->cssValuePool()->createValue(quad.release()); + return cssValuePool().createValue(quad.release()); } private: @@ -5817,7 +5947,7 @@ bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr<CSSPrimitiveValue> BorderImageQuadParseContext context(this); CSSParserValue* val; while ((val = m_valueList->current())) { - if (context.allowNumber() && (validUnit(val, validUnits, true) || val->id == CSSValueAuto)) { + if (context.allowNumber() && (validUnit(val, validUnits, CSSStrictMode) || val->id == CSSValueAuto)) { context.commitNumber(val); } else if (!inShorthand()) { // If we're not parsing a shorthand then we are invalid. @@ -5860,7 +5990,7 @@ static void completeBorderRadii(RefPtr<CSSPrimitiveValue> radii[4]) radii[3] = radii[1]; } -bool CSSParser::parseBorderRadius(int propId, bool important) +bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important) { unsigned num = m_valueList->size(); if (num > 9) @@ -5887,7 +6017,7 @@ bool CSSParser::parseBorderRadius(int propId, bool important) if (i - indexAfterSlash >= 4) return false; - if (!validUnit(value, FLength | FPercent | FNonNeg, m_strict)) + if (!validUnit(value, FLength | FPercent | FNonNeg)) return false; RefPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value); @@ -5912,10 +6042,10 @@ bool CSSParser::parseBorderRadius(int propId, bool important) completeBorderRadii(radii[1]); ImplicitScope implicitScope(this, PropertyImplicit); - addProperty(CSSPropertyBorderTopLeftRadius, cssValuePool()->createValue(Pair::create(radii[0][0].release(), radii[1][0].release())), important); - addProperty(CSSPropertyBorderTopRightRadius, cssValuePool()->createValue(Pair::create(radii[0][1].release(), radii[1][1].release())), important); - addProperty(CSSPropertyBorderBottomRightRadius, cssValuePool()->createValue(Pair::create(radii[0][2].release(), radii[1][2].release())), important); - addProperty(CSSPropertyBorderBottomLeftRadius, cssValuePool()->createValue(Pair::create(radii[0][3].release(), radii[1][3].release())), important); + addProperty(CSSPropertyBorderTopLeftRadius, cssValuePool().createValue(Pair::create(radii[0][0].release(), radii[1][0].release())), important); + addProperty(CSSPropertyBorderTopRightRadius, cssValuePool().createValue(Pair::create(radii[0][1].release(), radii[1][1].release())), important); + addProperty(CSSPropertyBorderBottomRightRadius, cssValuePool().createValue(Pair::create(radii[0][2].release(), radii[1][2].release())), important); + addProperty(CSSPropertyBorderBottomLeftRadius, cssValuePool().createValue(Pair::create(radii[0][3].release(), radii[1][3].release())), important); return true; } @@ -5923,7 +6053,7 @@ bool CSSParser::parseAspectRatio(bool important) { unsigned num = m_valueList->size(); if (num == 1 && m_valueList->valueAt(0)->id == CSSValueNone) { - addProperty(CSSPropertyWebkitAspectRatio, cssValuePool()->createIdentifierValue(CSSValueNone), important); + addProperty(CSSPropertyWebkitAspectRatio, cssValuePool().createIdentifierValue(CSSValueNone), important); return true; } @@ -5937,7 +6067,7 @@ bool CSSParser::parseAspectRatio(bool important) if (op->unit != CSSParserValue::Operator || op->iValue != '/') return false; - if (!validUnit(lvalue, FNumber | FNonNeg, m_strict) || !validUnit(rvalue, FNumber | FNonNeg, m_strict)) + if (!validUnit(lvalue, FNumber | FNonNeg) || !validUnit(rvalue, FNumber | FNonNeg)) return false; if (!lvalue->fValue || !rvalue->fValue) @@ -5948,7 +6078,7 @@ bool CSSParser::parseAspectRatio(bool important) return true; } -bool CSSParser::parseCounter(int propId, int defaultValue, bool important) +bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important) { enum { ID, VAL } state = ID; @@ -5973,8 +6103,8 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important) m_valueList->next(); } - list->append(cssValuePool()->createValue(Pair::create(counterName.release(), - cssValuePool()->createValue(i, CSSPrimitiveValue::CSS_NUMBER)))); + list->append(cssValuePool().createValue(Pair::create(counterName.release(), + cssValuePool().createValue(i, CSSPrimitiveValue::CSS_NUMBER)))); state = ID; continue; } @@ -5991,20 +6121,20 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important) } // This should go away once we drop support for -webkit-gradient -static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal) { RefPtr<CSSPrimitiveValue> result; if (a->unit == CSSPrimitiveValue::CSS_IDENT) { if ((equalIgnoringCase(a->string, "left") && horizontal) || (equalIgnoringCase(a->string, "top") && !horizontal)) - result = cssValuePool->createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE); + result = cssValuePool().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE); else if ((equalIgnoringCase(a->string, "right") && horizontal) || (equalIgnoringCase(a->string, "bottom") && !horizontal)) - result = cssValuePool->createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE); + result = cssValuePool().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE); else if (equalIgnoringCase(a->string, "center")) - result = cssValuePool->createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE); + result = cssValuePool().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE); } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - result = cssValuePool->createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit)); + result = cssValuePool().createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit)); return result; } @@ -6029,13 +6159,13 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS return false; if (equalIgnoringCase(a->function->name, "from(")) - stop.m_position = p->cssValuePool()->createValue(0, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER); else - stop.m_position = p->cssValuePool()->createValue(1, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER); int id = args->current()->id; if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) - stop.m_color = p->cssValuePool()->createIdentifierValue(id); + stop.m_color = cssValuePool().createIdentifierValue(id); else stop.m_color = p->parseColor(args->current()); if (!stop.m_color) @@ -6049,9 +6179,9 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS CSSParserValue* stopArg = args->current(); if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - stop.m_position = p->cssValuePool()->createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER); else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER) - stop.m_position = p->cssValuePool()->createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = cssValuePool().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER); else return false; @@ -6062,7 +6192,7 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS stopArg = args->next(); int id = stopArg->id; if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) - stop.m_color = p->cssValuePool()->createIdentifierValue(id); + stop.m_color = cssValuePool().createIdentifierValue(id); else stop.m_color = p->parseColor(stopArg); if (!stop.m_color) @@ -6103,7 +6233,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS // Comma. a = args->next(); - if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; // Next comes the starting point for the gradient as an x y pair. There is no @@ -6112,7 +6242,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS a = args->next(); if (!a) return false; - RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true, cssValuePool()); + RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true); if (!point) return false; result->setFirstX(point.release()); @@ -6121,14 +6251,14 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS a = args->next(); if (!a) return false; - point = parseDeprecatedGradientPoint(a, false, cssValuePool()); + point = parseDeprecatedGradientPoint(a, false); if (!point) return false; result->setFirstY(point.release()); // Comma after the first point. a = args->next(); - if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; // For radial gradients only, we now expect a numeric radius. @@ -6140,7 +6270,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS // Comma after the first radius. a = args->next(); - if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; } @@ -6149,7 +6279,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS a = args->next(); if (!a) return false; - point = parseDeprecatedGradientPoint(a, true, cssValuePool()); + point = parseDeprecatedGradientPoint(a, true); if (!point) return false; result->setSecondX(point.release()); @@ -6158,7 +6288,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS a = args->next(); if (!a) return false; - point = parseDeprecatedGradientPoint(a, false, cssValuePool()); + point = parseDeprecatedGradientPoint(a, false); if (!point) return false; result->setSecondY(point.release()); @@ -6167,7 +6297,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS if (gradientType == CSSRadialGradient) { // Comma after the second point. a = args->next(); - if (!a || a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; a = args->next(); @@ -6180,7 +6310,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS a = args->next(); while (a) { // Look for the comma before the next stop. - if (a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; // Now examine the stop itself. @@ -6202,7 +6332,7 @@ bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CS return true; } -static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal, CSSValuePool* cssValuePool) +static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal) { if (a->unit != CSSPrimitiveValue::CSS_IDENT) return 0; @@ -6219,14 +6349,14 @@ static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, boo default: return 0; } - return cssValuePool->createIdentifierValue(a->id); + return cssValuePool().createIdentifierValue(a->id); } static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value) { int id = value->id; if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor) - return p->cssValuePool()->createIdentifierValue(id); + return cssValuePool().createIdentifierValue(id); return p->parseColor(value); } @@ -6246,10 +6376,10 @@ bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSVal bool expectComma = false; // Look for angle. - if (validUnit(a, FAngle, true)) { + if (validUnit(a, FAngle, CSSStrictMode)) { result->setAngle(createPrimitiveNumericValue(a)); - a = args->next(); + args->next(); expectComma = true; } else { // Look one or two optional keywords that indicate a side or corner. @@ -6257,15 +6387,14 @@ bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSVal RefPtr<CSSPrimitiveValue> location; bool isHorizontal = false; - if ((location = valueFromSideKeyword(a, isHorizontal, cssValuePool()))) { + if ((location = valueFromSideKeyword(a, isHorizontal))) { if (isHorizontal) startX = location; else startY = location; - a = args->next(); - if (a) { - if ((location = valueFromSideKeyword(a, isHorizontal, cssValuePool()))) { + if ((a = args->next())) { + if ((location = valueFromSideKeyword(a, isHorizontal))) { if (isHorizontal) { if (startX) return false; @@ -6276,7 +6405,7 @@ bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSVal startY = location; } - a = args->next(); + args->next(); } } @@ -6284,7 +6413,7 @@ bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSVal } if (!startX && !startY) - startY = cssValuePool()->createIdentifierValue(CSSValueTop); + startY = cssValuePool().createIdentifierValue(CSSValueTop); result->setFirstX(startX.release()); result->setFirstY(startY.release()); @@ -6327,7 +6456,7 @@ bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSVal if (centerX || centerY) { // Comma - if (a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; a = args->next(); @@ -6356,7 +6485,7 @@ bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSVal switch (a->id) { case CSSValueCircle: case CSSValueEllipse: - shapeValue = cssValuePool()->createIdentifierValue(a->id); + shapeValue = cssValuePool().createIdentifierValue(a->id); foundValue = true; break; case CSSValueClosestSide: @@ -6365,7 +6494,7 @@ bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSVal case CSSValueFarthestCorner: case CSSValueContain: case CSSValueCover: - sizeValue = cssValuePool()->createIdentifierValue(a->id); + sizeValue = cssValuePool().createIdentifierValue(a->id); foundValue = true; break; } @@ -6387,7 +6516,7 @@ bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSVal RefPtr<CSSPrimitiveValue> verticalSize; if (!shapeValue && !sizeValue) { - if (validUnit(a, FLength | FPercent, m_strict)) { + if (validUnit(a, FLength | FPercent)) { horizontalSize = createPrimitiveNumericValue(a); a = args->next(); if (!a) @@ -6396,7 +6525,7 @@ bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSVal expectComma = true; } - if (validUnit(a, FLength | FPercent, m_strict)) { + if (validUnit(a, FLength | FPercent)) { verticalSize = createPrimitiveNumericValue(a); a = args->next(); @@ -6428,7 +6557,7 @@ bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradie while (a) { // Look for the comma before the next stop. if (expectComma) { - if (a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; a = valueList->next(); @@ -6444,7 +6573,7 @@ bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradie a = valueList->next(); if (a) { - if (validUnit(a, FLength | FPercent, m_strict)) { + if (validUnit(a, FLength | FPercent)) { stop.m_position = createPrimitiveNumericValue(a); a = valueList->next(); } @@ -6521,7 +6650,7 @@ bool CSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>& a = args->next(); // Skip a comma - if (a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; a = args->next(); @@ -6531,7 +6660,7 @@ bool CSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>& a = args->next(); // Skip a comma - if (a->unit != CSSParserValue::Operator || a->iValue != ',') + if (!isComma(a)) return false; a = args->next(); @@ -6541,9 +6670,9 @@ bool CSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>& return false; if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - percentage = cssValuePool()->createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER); + percentage = cssValuePool().createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER); else if (a->unit == CSSPrimitiveValue::CSS_NUMBER) - percentage = cssValuePool()->createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER); + percentage = cssValuePool().createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER); else return false; @@ -6571,6 +6700,58 @@ bool CSSParser::parseCanvas(CSSParserValueList* valueList, RefPtr<CSSValue>& can return true; } +#if ENABLE(CSS_IMAGE_SET) +PassRefPtr<CSSValue> CSSParser::parseImageSet(CSSParserValueList* valueList) +{ + CSSParserValue* function = valueList->current(); + + if (function->unit != CSSParserValue::Function) + return 0; + + CSSParserValueList* functionArgs = valueList->current()->function->args.get(); + if (!functionArgs || !functionArgs->size() || !functionArgs->current()) + return 0; + + RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create(); + + CSSParserValue* arg = functionArgs->current(); + while (arg) { + if (arg->unit != CSSPrimitiveValue::CSS_URI) + return 0; + + RefPtr<CSSImageValue> image = CSSImageValue::create(completeURL(arg->string)); + imageSet->append(image); + + arg = functionArgs->next(); + if (!arg || arg->unit != CSSPrimitiveValue::CSS_DIMENSION) + return 0; + + double imageScaleFactor = 0; + const String& string = arg->string; + const UChar* current = string.characters(); + const UChar* end = current + string.length(); + parseDouble(current, end, 'x', imageScaleFactor); + if (imageScaleFactor <= 0) + return 0; + imageSet->append(cssValuePool().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER)); + + // If there are no more arguments, we're done. + arg = functionArgs->next(); + if (!arg) + break; + + // If there are more arguments, they should be after a comma. + if (!isComma(arg)) + return 0; + + // Skip the comma and move on to the next argument. + arg = functionArgs->next(); + } + + return imageSet; +} +#endif + class TransformOperationInfo { public: TransformOperationInfo(const CSSParserString& name) @@ -6702,21 +6883,21 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform() if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) { // 4th param of rotate3d() is an angle rather than a bare number, validate it as such - if (!validUnit(a, FAngle, true)) + if (!validUnit(a, FAngle, CSSStrictMode)) return 0; } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation && argNumber == 2) { // 3rd param of translate3d() cannot be a percentage - if (!validUnit(a, FLength, true)) + if (!validUnit(a, FLength, CSSStrictMode)) return 0; } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation && argNumber == 0) { // 1st param of translateZ() cannot be a percentage - if (!validUnit(a, FLength, true)) + if (!validUnit(a, FLength, CSSStrictMode)) return 0; } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && argNumber == 0) { // 1st param of perspective() must be a non-negative number (deprecated) or length. - if (!validUnit(a, FNumber | FLength | FNonNeg, true)) + if (!validUnit(a, FNumber | FLength | FNonNeg, CSSStrictMode)) return 0; - } else if (!validUnit(a, unit, true)) + } else if (!validUnit(a, unit, CSSStrictMode)) return 0; // Add the value to the current transform operation. @@ -6772,7 +6953,7 @@ static void filterInfoForName(const CSSParserString& name, WebKitCSSFilterValue: static bool acceptCommaOperator(CSSParserValueList* argsList) { if (CSSParserValue* arg = argsList->current()) { - if (arg->unit != CSSParserValue::Operator || arg->iValue != ',') + if (!isComma(arg)) return false; argsList->next(); } @@ -6819,9 +7000,9 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseCustomFilter(CSSParserValue* va while ((arg = argsList->current())) { RefPtr<CSSValue> value; if (arg->id == CSSValueNone) - value = cssValuePool()->createIdentifierValue(CSSValueNone); + value = cssValuePool().createIdentifierValue(CSSValueNone); else if (arg->unit == CSSPrimitiveValue::CSS_URI) { - KURL shaderURL = m_styleSheet ? m_styleSheet->completeURL(arg->string) : KURL(); + KURL shaderURL = completeURL(arg->string); value = WebKitCSSShaderValue::create(shaderURL.string()); hadAtLeastOneCustomShader = true; } @@ -6840,13 +7021,13 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseCustomFilter(CSSParserValue* va RefPtr<CSSValueList> meshSizeList = CSSValueList::createSpaceSeparated(); while ((arg = argsList->current())) { - if (!validUnit(arg, FInteger | FNonNeg, true)) + if (!validUnit(arg, FInteger | FNonNeg, CSSStrictMode)) break; int integerValue = clampToInteger(arg->fValue); // According to the specification we can only accept positive non-zero values. if (integerValue < 1) return 0; - meshSizeList->append(cssValuePool()->createValue(integerValue, CSSPrimitiveValue::CSS_NUMBER)); + meshSizeList->append(cssValuePool().createValue(integerValue, CSSPrimitiveValue::CSS_NUMBER)); argsList->next(); } @@ -6855,12 +7036,12 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseCustomFilter(CSSParserValue* va if ((arg = argsList->current()) && (arg->id == CSSValueBorderBox || arg->id == CSSValuePaddingBox || arg->id == CSSValueContentBox || arg->id == CSSValueFilterBox)) { - meshSizeList->append(cssValuePool()->createIdentifierValue(arg->id)); + meshSizeList->append(cssValuePool().createIdentifierValue(arg->id)); argsList->next(); } if ((arg = argsList->current()) && arg->id == CSSValueDetached) { - meshSizeList->append(cssValuePool()->createIdentifierValue(arg->id)); + meshSizeList->append(cssValuePool().createIdentifierValue(arg->id)); argsList->next(); } @@ -6891,11 +7072,11 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseCustomFilter(CSSParserValue* va RefPtr<CSSValueList> paramValueList = CSSValueList::createSpaceSeparated(); while ((arg = argsList->current())) { // If we hit a comma it means we finished this parameter's values. - if (arg->unit == CSSParserValue::Operator && arg->iValue == ',') + if (isComma(arg)) break; - if (!validUnit(arg, FNumber, true)) + if (!validUnit(arg, FNumber, CSSStrictMode)) return 0; - paramValueList->append(cssValuePool()->createValue(arg->fValue, CSSPrimitiveValue::CSS_NUMBER)); + paramValueList->append(cssValuePool().createValue(arg->fValue, CSSPrimitiveValue::CSS_NUMBER)); argsList->next(); } if (!paramValueList->length() || paramValueList->length() > 4) @@ -6931,7 +7112,7 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse if (args->size()) { CSSParserValue* value = args->current(); - if (!validUnit(value, FNumber | FPercent | FNonNeg, true)) + if (!validUnit(value, FNumber | FPercent | FNonNeg, CSSStrictMode)) return 0; double amount = value->fValue; @@ -6944,7 +7125,7 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse return 0; } - filterValue->append(cssValuePool()->createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); + filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); } break; } @@ -6955,7 +7136,7 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse if (args->size()) { CSSParserValue* value = args->current(); - if (!validUnit(value, FNumber | FPercent, true)) + if (!validUnit(value, FNumber | FPercent, CSSStrictMode)) return 0; double amount = value->fValue; @@ -6964,7 +7145,7 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse if (amount < minAllowed || amount > maxAllowed) return 0; - filterValue->append(cssValuePool()->createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); + filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); } break; } @@ -6975,7 +7156,7 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse if (args->size()) { CSSParserValue* argument = args->current(); - if (!validUnit(argument, FAngle, true)) + if (!validUnit(argument, FAngle, CSSStrictMode)) return 0; filterValue->append(createPrimitiveNumericValue(argument)); @@ -6989,7 +7170,7 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse if (args->size()) { CSSParserValue* argument = args->current(); - if (!validUnit(argument, FLength | FNonNeg, true)) + if (!validUnit(argument, FLength | FNonNeg, CSSStrictMode)) return 0; filterValue->append(createPrimitiveNumericValue(argument)); @@ -7028,7 +7209,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFilter() if (value->unit == CSSPrimitiveValue::CSS_URI) { RefPtr<WebKitCSSFilterValue> referenceFilterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation); list->append(referenceFilterValue); - referenceFilterValue->append(cssValuePool()->createValue(value->string, CSSPrimitiveValue::CSS_STRING)); + referenceFilterValue->append(cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING)); } else { const CSSParserString name = value->function->name; unsigned maximumArgumentCount = 1; @@ -7041,11 +7222,8 @@ PassRefPtr<CSSValueList> CSSParser::parseFilter() #if ENABLE(CSS_SHADERS) if (filterType == WebKitCSSFilterValue::CustomFilterOperation) { // Make sure parsing fails if custom filters are disabled. - if (Document* document = findDocument()) { - Settings* settings = document->settings(); - if (!settings || !settings->isCSSCustomFilterEnabled()) - return 0; - } + if (!m_context.isCSSCustomFilterEnabled) + return 0; RefPtr<WebKitCSSFilterValue> filterValue = parseCustomFilter(value); if (!filterValue) @@ -7081,18 +7259,12 @@ static bool validFlowName(const String& flowName) bool CSSParser::cssRegionsEnabled() const { - if (Document* document = findDocument()) - return document->cssRegionsEnabled(); - - return false; + return m_context.isCSSRegionsEnabled; } -bool CSSParser::parseFlowThread(const String& flowName, Document* doc) +bool CSSParser::parseFlowThread(const String& flowName) { - ASSERT(doc); - ASSERT(doc->cssRegionsEnabled()); - - RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc); + RefPtr<StyleSheetInternal> dummyStyleSheet = StyleSheetInternal::create(); setStyleSheet(dummyStyleSheet.get()); setupParser("@-webkit-decls{-webkit-flow-into:", flowName, "}"); @@ -7104,7 +7276,7 @@ bool CSSParser::parseFlowThread(const String& flowName, Document* doc) } // none | <ident> -bool CSSParser::parseFlowThread(int propId, bool important) +bool CSSParser::parseFlowThread(CSSPropertyID propId, bool important) { ASSERT(propId == CSSPropertyWebkitFlowInto); ASSERT(cssRegionsEnabled()); @@ -7120,7 +7292,7 @@ bool CSSParser::parseFlowThread(int propId, bool important) return false; if (value->id == CSSValueNone) { - addProperty(propId, cssValuePool()->createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); return true; } @@ -7128,15 +7300,15 @@ bool CSSParser::parseFlowThread(int propId, bool important) if (!inputProperty.isEmpty()) { if (!validFlowName(inputProperty)) return false; - addProperty(propId, cssValuePool()->createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, cssValuePool().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); } else - addProperty(propId, cssValuePool()->createIdentifierValue(CSSValueNone), important); + addProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important); return true; } // -webkit-flow-from: none | <ident> -bool CSSParser::parseRegionThread(int propId, bool important) +bool CSSParser::parseRegionThread(CSSPropertyID propId, bool important) { ASSERT(propId == CSSPropertyWebkitFlowFrom); ASSERT(cssRegionsEnabled()); @@ -7152,21 +7324,21 @@ bool CSSParser::parseRegionThread(int propId, bool important) return false; if (value->id == CSSValueNone) - addProperty(propId, cssValuePool()->createIdentifierValue(value->id), important); + addProperty(propId, cssValuePool().createIdentifierValue(value->id), important); else { String inputProperty = String(value->string); if (!inputProperty.isEmpty()) { if (!validFlowName(inputProperty)) return false; - addProperty(propId, cssValuePool()->createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, cssValuePool().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important); } else - addProperty(propId, cssValuePool()->createIdentifierValue(CSSValueNone), important); + addProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important); } return true; } -bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3) +bool CSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3) { propId1 = propId; propId2 = propId; @@ -7196,18 +7368,21 @@ bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int break; } case CSSPropertyWebkitTransformOriginZ: { - if (validUnit(m_valueList->current(), FLength, m_strict)) + if (validUnit(m_valueList->current(), FLength)) value = createPrimitiveNumericValue(m_valueList->current()); if (value) m_valueList->next(); break; } + default: + ASSERT_NOT_REACHED(); + return false; } return value; } -bool CSSParser::parsePerspectiveOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2) +bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2) { propId1 = propId; propId2 = propId; @@ -7232,6 +7407,9 @@ bool CSSParser::parsePerspectiveOrigin(int propId, int& propId1, int& propId2, R m_valueList->next(); break; } + default: + ASSERT_NOT_REACHED(); + return false; } return value; @@ -7256,7 +7434,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->id == CSSValueNone) { if (fill || shape || (valueListSize != 1 && !inShorthand())) return false; - addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool()->createIdentifierValue(CSSValueNone), important); + addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool().createIdentifierValue(CSSValueNone), important); m_valueList->next(); return true; } @@ -7264,11 +7442,11 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->id == CSSValueOpen || value->id == CSSValueFilled) { if (fill) return false; - fill = cssValuePool()->createIdentifierValue(value->id); + fill = cssValuePool().createIdentifierValue(value->id); } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) { if (shape) return false; - shape = cssValuePool()->createIdentifierValue(value->id); + shape = cssValuePool().createIdentifierValue(value->id); } else if (!inShorthand()) return false; else @@ -7341,7 +7519,7 @@ bool CSSParser::parseFontFeatureTag(CSSValueList* settings) CSSParserValue* value = m_valueList->current(); // Feature tag name comes first - if (value->unit != CSSPrimitiveValue::CSS_STRING && value->unit != CSSPrimitiveValue::CSS_IDENT) + if (value->unit != CSSPrimitiveValue::CSS_STRING) return false; if (value->string.length != tagNameLength) return false; @@ -7374,7 +7552,7 @@ bool CSSParser::parseFontFeatureTag(CSSValueList* settings) bool CSSParser::parseFontFeatureSettings(bool important) { if (m_valueList->size() == 1 && m_valueList->current()->id == CSSValueNormal) { - RefPtr<CSSPrimitiveValue> normalValue = cssValuePool()->createIdentifierValue(CSSValueNormal); + RefPtr<CSSPrimitiveValue> normalValue = cssValuePool().createIdentifierValue(CSSValueNormal); m_valueList->next(); addProperty(CSSPropertyWebkitFontFeatureSettings, normalValue.release(), important); return true; @@ -7387,7 +7565,7 @@ bool CSSParser::parseFontFeatureSettings(bool important) // If the list isn't parsed fully, the current value should be comma. value = m_valueList->current(); - if (value && !(value->unit == CSSParserValue::Operator && value->iValue == ',')) + if (value && !isComma(value)) return false; } if (settings->length()) { @@ -7414,21 +7592,21 @@ bool CSSParser::parseFontVariantLigatures(bool important) if (sawCommonLigaturesValue) return false; sawCommonLigaturesValue = true; - ligatureValues->append(cssValuePool()->createIdentifierValue(value->id)); + ligatureValues->append(cssValuePool().createIdentifierValue(value->id)); break; case CSSValueNoDiscretionaryLigatures: case CSSValueDiscretionaryLigatures: if (sawDiscretionaryLigaturesValue) return false; sawDiscretionaryLigaturesValue = true; - ligatureValues->append(cssValuePool()->createIdentifierValue(value->id)); + ligatureValues->append(cssValuePool().createIdentifierValue(value->id)); break; case CSSValueNoHistoricalLigatures: case CSSValueHistoricalLigatures: if (sawHistoricalLigaturesValue) return false; sawHistoricalLigaturesValue = true; - ligatureValues->append(cssValuePool()->createIdentifierValue(value->id)); + ligatureValues->append(cssValuePool().createIdentifierValue(value->id)); break; default: return false; @@ -7714,8 +7892,12 @@ inline UChar* CSSParser::checkAndSkipString(UChar* currentCharacter, UChar quote // String parsing is successful. return currentCharacter + 1; } - if (UNLIKELY(*currentCharacter <= '\r' && (!*currentCharacter || *currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) { - // String parsing is failed for character '\0', '\n', '\f' or '\r'. + if (UNLIKELY(!*currentCharacter)) { + // String parsing is successful up to end of input. + return currentCharacter; + } + if (UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) { + // String parsing is failed for character '\n', '\f' or '\r'. return 0; } @@ -7746,14 +7928,20 @@ void CSSParser::parseEscape(UChar*& result) unicode = (unicode << 4) + toASCIIHexValue(*m_currentCharacter++); } while (--length && isASCIIHexDigit(*m_currentCharacter)); - // Characters above 0xffff are not handled. - if (unicode > 0xffff) + // Characters above 0x10ffff are not handled. + if (unicode > 0x10ffff) unicode = 0xfffd; // Optional space after the escape sequence. if (isHTMLSpace(*m_currentCharacter)) ++m_currentCharacter; - *result = unicode; + + // Replace unicode with a surrogate pairs when it is bigger than 0xffff + if (U16_LENGTH(unicode) == 2) { + *result++ = U16_LEAD(unicode); + *result = U16_TRAIL(unicode); + } else + *result = unicode; } else *result = *m_currentCharacter++; ++result; @@ -7783,6 +7971,10 @@ inline void CSSParser::parseString(UChar*& result, UChar quote) ++m_currentCharacter; return; } + if (UNLIKELY(!*m_currentCharacter)) { + // String parsing is done, but don't advance pointer if at the end of input. + return; + } ASSERT(*m_currentCharacter > '\r' || (*m_currentCharacter < '\n' && *m_currentCharacter) || *m_currentCharacter == '\v'); if (LIKELY(m_currentCharacter[0] != '\\')) @@ -8050,6 +8242,16 @@ inline void CSSParser::detectNumberToken(UChar* type, int length) && isASCIIAlphaCaselessEqual(type[2], 'r') && isASCIIAlphaCaselessEqual(type[3], 'n')) m_token = TURNS; return; + case 'v': + if (length == 2) { + if (isASCIIAlphaCaselessEqual(type[1], 'w')) + m_token = VW; + else if (isASCIIAlphaCaselessEqual(type[1], 'h')) + m_token = VH; + } else if (length == 4 && isASCIIAlphaCaselessEqual(type[1], 'm') + && isASCIIAlphaCaselessEqual(type[2], 'i') && isASCIIAlphaCaselessEqual(type[3], 'n')) + m_token = VMIN; + return; default: if (type[0] == '_' && length == 5 && type[1] == '_' && isASCIIAlphaCaselessEqual(type[2], 'q') @@ -8324,16 +8526,17 @@ restartAfterComment: m_token = NTH; yylval->string.length = m_currentCharacter - m_tokenStart; } - } else if (result - m_tokenStart == 2 && m_tokenStart[1] == '-') { + } else if (result - m_tokenStart >= 2 && m_tokenStart[1] == '-') { // String "n-" is IDENT but "n-1" is NTH. - // Speculatively decrease m_currentCharacter to detect an nth-child token. - m_currentCharacter--; + // Set m_currentCharacter to '-' to continue parsing. + UChar* nextCharacter = result; + m_currentCharacter = m_tokenStart + 1; if (parseNthChildExtra()) { m_token = NTH; yylval->string.length = m_currentCharacter - m_tokenStart; } else { // Revert the change to m_currentCharacter if unsuccessful. - m_currentCharacter++; + m_currentCharacter = nextCharacter; } } } @@ -8423,16 +8626,17 @@ restartAfterComment: m_token = NTH; result = m_currentCharacter; } - } else if (result - m_tokenStart == 3 && m_tokenStart[2] == '-') { + } else if (result - m_tokenStart >= 3 && m_tokenStart[2] == '-') { // String "-n-" is IDENT but "-n-1" is NTH. - // Speculatively decrease m_currentCharacter to detect an nth-child token. - m_currentCharacter--; + // Set m_currentCharacter to second '-' of '-n-' to continue parsing. + UChar* nextCharacter = result; + m_currentCharacter = m_tokenStart + 2; if (parseNthChildExtra()) { m_token = NTH; - yylval->string.length = m_currentCharacter - m_tokenStart; + result = m_currentCharacter; } else { // Revert the change to m_currentCharacter if unsuccessful. - m_currentCharacter++; + m_currentCharacter = nextCharacter; } } } @@ -8778,74 +8982,64 @@ PassOwnPtr<MediaQuery> CSSParser::sinkFloatingMediaQuery(MediaQuery* query) return m_floatingMediaQuery.release(); } -MediaList* CSSParser::createMediaList() +MediaQuerySet* CSSParser::createMediaQuerySet() { - RefPtr<MediaList> list = MediaList::create(); - MediaList* result = list.get(); - m_parsedMediaLists.append(list.release()); + RefPtr<MediaQuerySet> queries = MediaQuerySet::create(); + MediaQuerySet* result = queries.get(); + m_parsedMediaQuerySets.append(queries.release()); return result; } -CSSRule* CSSParser::createCharsetRule(const CSSParserString& charset) +StyleRuleBase* CSSParser::createImportRule(const CSSParserString& url, MediaQuerySet* media) { - if (!m_styleSheet) + if (!media || !m_allowImportRules) return 0; - RefPtr<CSSCharsetRule> rule = CSSCharsetRule::create(m_styleSheet, charset); - CSSCharsetRule* result = rule.get(); + RefPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media); + StyleRuleImport* result = rule.get(); m_parsedRules.append(rule.release()); return result; } -CSSRule* CSSParser::createImportRule(const CSSParserString& url, MediaList* media) +StyleRuleBase* CSSParser::createMediaRule(MediaQuerySet* media, RuleList* rules) { - if (!media || !m_styleSheet || !m_allowImportRules) - return 0; - RefPtr<CSSImportRule> rule = CSSImportRule::create(m_styleSheet, url, media); - CSSImportRule* result = rule.get(); - m_parsedRules.append(rule.release()); - return result; -} - -CSSRule* CSSParser::createMediaRule(MediaList* media, CSSRuleList* rules) -{ - if (!media || !rules || !m_styleSheet) + if (!media || !rules) return 0; m_allowImportRules = m_allowNamespaceDeclarations = false; - RefPtr<CSSMediaRule> rule = CSSMediaRule::create(m_styleSheet, media, rules); - CSSMediaRule* result = rule.get(); + RefPtr<StyleRuleMedia> rule = StyleRuleMedia::create(media, *rules); + StyleRuleMedia* result = rule.get(); m_parsedRules.append(rule.release()); return result; } -CSSRuleList* CSSParser::createRuleList() +CSSParser::RuleList* CSSParser::createRuleList() { - RefPtr<CSSRuleList> list = CSSRuleList::create(); - CSSRuleList* listPtr = list.get(); + OwnPtr<RuleList> list = adoptPtr(new RuleList); + RuleList* listPtr = list.get(); m_parsedRuleLists.append(list.release()); return listPtr; } -WebKitCSSKeyframesRule* CSSParser::createKeyframesRule() +StyleRuleKeyframes* CSSParser::createKeyframesRule() { m_allowImportRules = m_allowNamespaceDeclarations = false; - RefPtr<WebKitCSSKeyframesRule> rule = WebKitCSSKeyframesRule::create(m_styleSheet); - WebKitCSSKeyframesRule* rulePtr = rule.get(); + RefPtr<StyleRuleKeyframes> rule = StyleRuleKeyframes::create(); + StyleRuleKeyframes* rulePtr = rule.get(); m_parsedRules.append(rule.release()); return rulePtr; } -CSSRule* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors) +StyleRuleBase* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors) { - CSSStyleRule* result = 0; + StyleRule* result = 0; markRuleBodyEnd(); if (selectors) { m_allowImportRules = m_allowNamespaceDeclarations = false; - RefPtr<CSSStyleRule> rule = CSSStyleRule::create(m_styleSheet, m_lastSelectorLineNumber); - rule->styleRule()->adoptSelectorVector(*selectors); + RefPtr<StyleRule> rule = StyleRule::create(m_lastSelectorLineNumber); + rule->parserAdoptSelectorVector(*selectors); if (m_hasFontFaceOnlyValues) deleteFontFaceOnlyValues(); - rule->styleRule()->setProperties(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_strict)); + rule->setProperties(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_context.mode)); result = rule.get(); m_parsedRules.append(rule.release()); if (m_ruleRangeMap) { @@ -8864,16 +9058,14 @@ CSSRule* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selector return result; } -CSSRule* CSSParser::createFontFaceRule() +StyleRuleBase* CSSParser::createFontFaceRule() { m_allowImportRules = m_allowNamespaceDeclarations = false; for (unsigned i = 0; i < m_parsedProperties.size(); ++i) { CSSProperty& property = m_parsedProperties[i]; - if (property.id() == CSSPropertyFontVariant && property.value()->isPrimitiveValue()) { - RefPtr<CSSValue> value = property.m_value.release(); - property.m_value = CSSValueList::createCommaSeparated(); - static_cast<CSSValueList*>(property.value())->append(value.release()); - } else if (property.id() == CSSPropertyFontFamily && (!property.value()->isValueList() || static_cast<CSSValueList*>(property.value())->length() != 1)) { + if (property.id() == CSSPropertyFontVariant && property.value()->isPrimitiveValue()) + property.wrapValueInCommaSeparatedList(); + else if (property.id() == CSSPropertyFontFamily && (!property.value()->isValueList() || static_cast<CSSValueList*>(property.value())->length() != 1)) { // Unlike font-family property, font-family descriptor in @font-face rule // has to be a value list with exactly one family name. It cannot have a // have 'initial' value and cannot 'inherit' from parent. @@ -8882,10 +9074,10 @@ CSSRule* CSSParser::createFontFaceRule() return 0; } } - RefPtr<CSSFontFaceRule> rule = CSSFontFaceRule::create(m_styleSheet); - rule->setDeclaration(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_strict)); + RefPtr<StyleRuleFontFace> rule = StyleRuleFontFace::create(); + rule->setProperties(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_context.mode)); clearProperties(); - CSSFontFaceRule* result = rule.get(); + StyleRuleFontFace* result = rule.get(); m_parsedRules.append(rule.release()); return result; } @@ -8895,7 +9087,9 @@ void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri if (!m_styleSheet || !m_allowNamespaceDeclarations) return; m_allowImportRules = false; - m_styleSheet->addNamespace(this, prefix, uri); + m_styleSheet->parserAddNamespace(prefix, uri); + if (prefix.isEmpty() && !uri.isNull()) + m_defaultNamespace = uri; } void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers) @@ -8944,17 +9138,17 @@ CSSParserSelector* CSSParser::updateSpecifiers(CSSParserSelector* specifiers, CS return specifiers; } -CSSRule* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector) +StyleRuleBase* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector) { // FIXME: Margin at-rules are ignored. m_allowImportRules = m_allowNamespaceDeclarations = false; - CSSPageRule* pageRule = 0; + StyleRulePage* pageRule = 0; if (pageSelector) { - RefPtr<CSSPageRule> rule = CSSPageRule::create(m_styleSheet); + RefPtr<StyleRulePage> rule = StyleRulePage::create(); Vector<OwnPtr<CSSParserSelector> > selectorVector; selectorVector.append(pageSelector); - rule->adoptSelectorVector(selectorVector); - rule->setDeclaration(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_strict)); + rule->parserAdoptSelectorVector(selectorVector); + rule->setProperties(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_context.mode)); pageRule = rule.get(); m_parsedRules.append(rule.release()); } @@ -8968,22 +9162,22 @@ void CSSParser::setReusableRegionSelectorVector(Vector<OwnPtr<CSSParserSelector> m_reusableRegionSelectorVector.swap(*selectors); } -CSSRule* CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, CSSRuleList* rules) +StyleRuleBase* CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules) { if (!cssRegionsEnabled() || !regionSelector || !rules) return 0; m_allowImportRules = m_allowNamespaceDeclarations = false; - RefPtr<WebKitCSSRegionRule> regionRule = WebKitCSSRegionRule::create(m_styleSheet, regionSelector, rules); + RefPtr<StyleRuleRegion> regionRule = StyleRuleRegion::create(regionSelector, *rules); - WebKitCSSRegionRule* result = regionRule.get(); + StyleRuleRegion* result = regionRule.get(); m_parsedRules.append(regionRule.release()); return result; } -CSSRule* CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */) +StyleRuleBase* CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */) { // FIXME: Implement margin at-rule here, using: // - marginBox: margin box @@ -9018,7 +9212,7 @@ void CSSParser::deleteFontFaceOnlyValues() } } -WebKitCSSKeyframeRule* CSSParser::createKeyframeRule(CSSParserValueList* keys) +StyleKeyframe* CSSParser::createKeyframe(CSSParserValueList* keys) { // Create a key string from the passed keys String keyString; @@ -9030,14 +9224,14 @@ WebKitCSSKeyframeRule* CSSParser::createKeyframeRule(CSSParserValueList* keys) keyString += "%"; } - RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create(m_styleSheet); + RefPtr<StyleKeyframe> keyframe = StyleKeyframe::create(); keyframe->setKeyText(keyString); - keyframe->setDeclaration(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_strict)); + keyframe->setProperties(StylePropertySet::create(m_parsedProperties.data(), m_parsedProperties.size(), m_context.mode)); clearProperties(); - WebKitCSSKeyframeRule* keyframePtr = keyframe.get(); - m_parsedRules.append(keyframe.release()); + StyleKeyframe* keyframePtr = keyframe.get(); + m_parsedKeyframes.append(keyframe.release()); return keyframePtr; } @@ -9053,7 +9247,7 @@ void CSSParser::updateLastSelectorLineAndPosition() markRuleBodyStart(); } -void CSSParser::updateLastMediaLine(MediaList* media) +void CSSParser::updateLastMediaLine(MediaQuerySet* media) { media->setLastLine(m_lineNumber); } @@ -9115,9 +9309,9 @@ void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed) const unsigned end = m_propertyRange.end; ASSERT(start < end); String propertyString = String(m_dataStart.get() + start, end - start).stripWhiteSpace(); - if (propertyString.endsWith(";", true)) + if (propertyString.endsWith(';')) propertyString = propertyString.left(propertyString.length() - 1); - size_t colonIndex = propertyString.find(":"); + size_t colonIndex = propertyString.find(':'); ASSERT(colonIndex != notFound); String name = propertyString.left(colonIndex).stripWhiteSpace(); @@ -9129,25 +9323,26 @@ void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed) resetPropertyMarks(); } -static int cssPropertyID(const UChar* propertyName, unsigned length) +static CSSPropertyID cssPropertyID(const UChar* propertyName, unsigned length) { if (!length) - return 0; + return CSSPropertyInvalid; if (length > maxCSSPropertyNameLength) - return 0; + return CSSPropertyInvalid; char buffer[maxCSSPropertyNameLength + 1 + 1]; // 1 to turn "apple"/"khtml" into "webkit", 1 for null character for (unsigned i = 0; i != length; ++i) { UChar c = propertyName[i]; if (c == 0 || c >= 0x7F) - return 0; // illegal character + return CSSPropertyInvalid; // illegal character buffer[i] = toASCIILower(c); } buffer[length] = '\0'; const char* name = buffer; if (buffer[0] == '-') { +#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES) // If the prefix is -apple- or -khtml-, change it to -webkit-. // This makes the string one character longer. if (hasPrefix(buffer, length, "-apple-") || hasPrefix(buffer, length, "-khtml-")) { @@ -9155,21 +9350,22 @@ static int cssPropertyID(const UChar* propertyName, unsigned length) memcpy(buffer, "-webkit", 7); ++length; } +#endif #if PLATFORM(IOS) cssPropertyNameIOSAliasing(buffer, name, length); #endif } const Property* hashTableEntry = findProperty(name, length); - return hashTableEntry ? hashTableEntry->id : 0; + return hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid; } -int cssPropertyID(const String& string) +CSSPropertyID cssPropertyID(const String& string) { return cssPropertyID(string.characters(), string.length()); } -int cssPropertyID(const CSSParserString& string) +CSSPropertyID cssPropertyID(const CSSParserString& string) { return cssPropertyID(string.characters, string.length); } diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h index 45c5a4425..2c5a27ab8 100644 --- a/Source/WebCore/css/CSSParser.h +++ b/Source/WebCore/css/CSSParser.h @@ -25,8 +25,10 @@ #include "CSSCalculationValue.h" #include "CSSGradientValue.h" +#include "CSSParserMode.h" #include "CSSParserValues.h" #include "CSSProperty.h" +#include "CSSPropertyNames.h" #include "CSSPropertySourceData.h" #include "CSSSelector.h" #include "Color.h" @@ -45,52 +47,49 @@ namespace WebCore { class CSSBorderImageSliceValue; class CSSPrimitiveValue; -class CSSValuePool; class CSSProperty; -class CSSRule; -class CSSRuleList; class CSSSelectorList; -class CSSStyleSheet; class CSSValue; class CSSValueList; class CSSWrapShape; class Document; -class MediaList; class MediaQueryExp; +class MediaQuerySet; +class StyleKeyframe; class StylePropertySet; +class StylePropertyShorthand; +class StyleRuleBase; +class StyleRuleKeyframes; +class StyleKeyframe; +class StyleSheetInternal; class StyledElement; -class WebKitCSSKeyframeRule; -class WebKitCSSKeyframesRule; class CSSParser { public: - CSSParser(bool strictParsing = true); + CSSParser(const CSSParserContext&); + ~CSSParser(); - void parseSheet(CSSStyleSheet*, const String&, int startLineNumber = 0, StyleRuleRangeMap* ruleRangeMap = 0); - PassRefPtr<CSSRule> parseRule(CSSStyleSheet*, const String&); - PassRefPtr<WebKitCSSKeyframeRule> parseKeyframeRule(CSSStyleSheet*, const String&); - static bool parseValue(StylePropertySet*, int propId, const String&, bool important, bool strict, CSSStyleSheet* contextStyleSheet); + void parseSheet(StyleSheetInternal*, const String&, int startLineNumber = 0, StyleRuleRangeMap* = 0); + PassRefPtr<StyleRuleBase> parseRule(StyleSheetInternal*, const String&); + PassRefPtr<StyleKeyframe> parseKeyframeRule(StyleSheetInternal*, const String&); + static bool parseValue(StylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetInternal*); static bool parseColor(RGBA32& color, const String&, bool strict = false); static bool parseSystemColor(RGBA32& color, const String&, Document*); - static PassRefPtr<CSSValueList> parseFontFaceValue(const AtomicString&, CSSStyleSheet* contextStyleSheet); - PassRefPtr<CSSPrimitiveValue> parseValidPrimitive(int propId, CSSParserValue*); - bool parseDeclaration(StylePropertySet*, const String&, RefPtr<CSSStyleSourceData>*, CSSStyleSheet* contextStyleSheet); - bool parseMediaQuery(MediaList*, const String&); - - Document* findDocument() const; - - CSSValuePool* cssValuePool() const { return m_cssValuePool.get(); } + static PassRefPtr<CSSValueList> parseFontFaceValue(const AtomicString&); + PassRefPtr<CSSPrimitiveValue> parseValidPrimitive(int ident, CSSParserValue*); + bool parseDeclaration(StylePropertySet*, const String&, RefPtr<CSSStyleSourceData>*, StyleSheetInternal* contextStyleSheet); + PassOwnPtr<MediaQuery> parseMediaQuery(const String&); - void addProperty(int propId, PassRefPtr<CSSValue>, bool important, bool implicit = false); + void addProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false); void rollbackLastProperties(int num); bool hasProperties() const { return !m_parsedProperties.isEmpty(); } - bool parseValue(int propId, bool important); - bool parseShorthand(int propId, const int* properties, int numProperties, bool important); - bool parse4Values(int propId, const int* properties, bool important); - bool parseContent(int propId, bool important); - bool parseQuotes(int propId, bool important); + bool parseValue(CSSPropertyID, bool important); + bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important); + bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important); + bool parseContent(CSSPropertyID, bool important); + bool parseQuotes(CSSPropertyID, bool important); PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args); @@ -105,10 +104,10 @@ public: void parseFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&); void parseFillRepeat(RefPtr<CSSValue>&, RefPtr<CSSValue>&); - PassRefPtr<CSSValue> parseFillSize(int propId, bool &allowComma); + PassRefPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma); - bool parseFillProperty(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&); - bool parseFillShorthand(int propId, const int* properties, int numProperties, bool important); + bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&); + bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important); void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval); @@ -126,64 +125,66 @@ public: bool parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&); bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result); - bool parseAnimationProperty(int propId, RefPtr<CSSValue>&); + bool parseAnimationProperty(CSSPropertyID, RefPtr<CSSValue>&); bool parseTransitionShorthand(bool important); bool parseAnimationShorthand(bool important); #if ENABLE(CSS_GRID_LAYOUT) - bool parseGridTrackList(int propId, bool important); + bool parseGridTrackList(CSSPropertyID, bool important); #endif - bool parseDashboardRegions(int propId, bool important); + bool parseDashboardRegions(CSSPropertyID, bool important); - bool parseShape(int propId, bool important); + bool parseClipShape(CSSPropertyID, bool important); - bool parseWrapShape(bool shapeInside, bool important); - PassRefPtr<CSSWrapShape> parseWrapShapeRect(CSSParserValueList* args); - PassRefPtr<CSSWrapShape> parseWrapShapeCircle(CSSParserValueList* args); - PassRefPtr<CSSWrapShape> parseWrapShapeEllipse(CSSParserValueList* args); - PassRefPtr<CSSWrapShape> parseWrapShapePolygon(CSSParserValueList* args); + bool parseExclusionShape(bool shapeInside, bool important); + PassRefPtr<CSSWrapShape> parseExclusionShapeRectangle(CSSParserValueList* args); + PassRefPtr<CSSWrapShape> parseExclusionShapeCircle(CSSParserValueList* args); + PassRefPtr<CSSWrapShape> parseExclusionShapeEllipse(CSSParserValueList* args); + PassRefPtr<CSSWrapShape> parseExclusionShapePolygon(CSSParserValueList* args); bool parseFont(bool important); PassRefPtr<CSSValueList> parseFontFamily(); - bool parseCounter(int propId, int defaultValue, bool important); + bool parseCounter(CSSPropertyID, int defaultValue, bool important); PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters); bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha); bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha); PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0); bool parseColorFromValue(CSSParserValue*, RGBA32&); - void parseSelector(const String&, Document* doc, CSSSelectorList&); + void parseSelector(const String&, CSSSelectorList&); static bool fastParseColor(RGBA32&, const String&, bool strict); + bool parseLineHeight(bool important); + bool parseFontSize(bool important); bool parseFontVariant(bool important); bool parseFontWeight(bool important); bool parseFontFaceSrc(); bool parseFontFaceUnicodeRange(); #if ENABLE(SVG) - bool parseSVGValue(int propId, bool important); + bool parseSVGValue(CSSPropertyID propId, bool important); PassRefPtr<CSSValue> parseSVGPaint(); PassRefPtr<CSSValue> parseSVGColor(); PassRefPtr<CSSValue> parseSVGStrokeDasharray(); #endif // CSS3 Parsing Routines (for properties specific to CSS3) - PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, int propId); - bool parseBorderImage(int propId, RefPtr<CSSValue>&, bool important = false); + PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID); + bool parseBorderImage(CSSPropertyID, RefPtr<CSSValue>&, bool important = false); bool parseBorderImageRepeat(RefPtr<CSSValue>&); - bool parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValue>&); + bool parseBorderImageSlice(CSSPropertyID, RefPtr<CSSBorderImageSliceValue>&); bool parseBorderImageWidth(RefPtr<CSSPrimitiveValue>&); bool parseBorderImageOutset(RefPtr<CSSPrimitiveValue>&); - bool parseBorderRadius(int propId, bool important); + bool parseBorderRadius(CSSPropertyID, bool important); bool parseAspectRatio(bool important); - bool parseReflect(int propId, bool important); + bool parseReflect(CSSPropertyID, bool important); - bool parseFlex(int propId, bool important); + PassRefPtr<CSSValue> parseFlex(CSSParserValueList* args); // Image generators bool parseCanvas(CSSParserValueList*, RefPtr<CSSValue>&); @@ -195,6 +196,10 @@ public: bool parseCrossfade(CSSParserValueList*, RefPtr<CSSValue>&); +#if ENABLE(CSS_IMAGE_SET) + PassRefPtr<CSSValue> parseImageSet(CSSParserValueList*); +#endif + #if ENABLE(CSS_FILTERS) PassRefPtr<CSSValueList> parseFilter(); PassRefPtr<WebKitCSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, WebKitCSSFilterValue::FilterOperationType); @@ -204,8 +209,8 @@ public: #endif PassRefPtr<CSSValueList> parseTransform(); - bool parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&); - bool parsePerspectiveOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&); + bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&); + bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&); bool parseTextEmphasisStyle(bool important); @@ -216,9 +221,9 @@ public: bool parseFontFeatureSettings(bool important); bool cssRegionsEnabled() const; - bool parseFlowThread(const String& flowName, Document*); - bool parseFlowThread(int propId, bool important); - bool parseRegionThread(int propId, bool important); + bool parseFlowThread(const String& flowName); + bool parseFlowThread(CSSPropertyID, bool important); + bool parseRegionThread(CSSPropertyID, bool important); bool parseFontVariantLigatures(bool important); @@ -238,18 +243,19 @@ public: CSSParserValue& sinkFloatingValue(CSSParserValue&); - MediaList* createMediaList(); - CSSRule* createCharsetRule(const CSSParserString&); - CSSRule* createImportRule(const CSSParserString&, MediaList*); - WebKitCSSKeyframeRule* createKeyframeRule(CSSParserValueList*); - WebKitCSSKeyframesRule* createKeyframesRule(); - CSSRule* createMediaRule(MediaList*, CSSRuleList*); - CSSRuleList* createRuleList(); - CSSRule* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors); - CSSRule* createFontFaceRule(); - CSSRule* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector); - CSSRule* createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, CSSRuleList* rules); - CSSRule* createMarginAtRule(CSSSelector::MarginBoxType marginBox); + MediaQuerySet* createMediaQuerySet(); + StyleRuleBase* createImportRule(const CSSParserString&, MediaQuerySet*); + StyleKeyframe* createKeyframe(CSSParserValueList*); + StyleRuleKeyframes* createKeyframesRule(); + + typedef Vector<RefPtr<StyleRuleBase> > RuleList; + StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*); + RuleList* createRuleList(); + StyleRuleBase* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors); + StyleRuleBase* createFontFaceRule(); + StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector); + StyleRuleBase* createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules); + StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType); void startDeclarationsForMarginBox(); void endDeclarationsForMarginBox(); @@ -273,26 +279,26 @@ public: Vector<OwnPtr<CSSParserSelector> >* reusableRegionSelectorVector() { return &m_reusableRegionSelectorVector; } void updateLastSelectorLineAndPosition(); - void updateLastMediaLine(MediaList*); + void updateLastMediaLine(MediaQuerySet*); void clearProperties(); - bool m_strict; + CSSParserContext m_context; + bool m_important; - int m_id; - CSSStyleSheet* m_styleSheet; - RefPtr<CSSRule> m_rule; - RefPtr<WebKitCSSKeyframeRule> m_keyframe; + CSSPropertyID m_id; + StyleSheetInternal* m_styleSheet; + RefPtr<StyleRuleBase> m_rule; + RefPtr<StyleKeyframe> m_keyframe; OwnPtr<MediaQuery> m_mediaQuery; OwnPtr<CSSParserValueList> m_valueList; Vector<CSSProperty, 256> m_parsedProperties; CSSSelectorList* m_selectorListForParseSelector; - RefPtr<CSSValuePool> m_cssValuePool; unsigned m_numParsedPropertiesBeforeMarginBox; int m_inParseShorthand; - int m_currentShorthand; + CSSPropertyID m_currentShorthand; bool m_implicitShorthand; bool m_hasFontFaceOnlyValues; @@ -321,7 +327,9 @@ public: PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*); PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*); - + + static KURL completeURL(const CSSParserContext&, const String& url); + private: inline bool isIdentifierStart(); @@ -340,8 +348,12 @@ private: inline void detectDashToken(int); inline void detectAtToken(int, bool); - void setStyleSheet(CSSStyleSheet*); - void ensureCSSValuePool(); + void setStyleSheet(StyleSheetInternal*); + + inline bool inStrictMode() const { return m_context.mode == CSSStrictMode || m_context.mode == SVGAttributeMode; } + inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; } + + KURL completeURL(const String& url) const; void recheckAtKeyword(const UChar* str, int len); @@ -356,7 +368,7 @@ private: bool isGeneratedImageValue(CSSParserValue*) const; bool parseGeneratedImage(CSSParserValueList*, RefPtr<CSSValue>&); - bool parseValue(StylePropertySet*, int propId, const String&, bool important, CSSStyleSheet* contextStyleSheet); + bool parseValue(StylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetInternal* contextStyleSheet); enum SizeParameterType { None, @@ -366,8 +378,8 @@ private: Orientation, }; - bool parsePage(int propId, bool important); - bool parseSize(int propId, bool important); + bool parsePage(CSSPropertyID propId, bool important); + bool parseSize(CSSPropertyID propId, bool important); SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType); bool parseFontFaceSrcURI(CSSValueList*); @@ -392,9 +404,10 @@ private: bool m_allowImportRules; bool m_allowNamespaceDeclarations; - Vector<RefPtr<CSSRule> > m_parsedRules; - Vector<RefPtr<MediaList> > m_parsedMediaLists; - Vector<RefPtr<CSSRuleList> > m_parsedRuleLists; + Vector<RefPtr<StyleRuleBase> > m_parsedRules; + Vector<RefPtr<StyleKeyframe> > m_parsedKeyframes; + Vector<RefPtr<MediaQuerySet> > m_parsedMediaQuerySets; + Vector<OwnPtr<RuleList> > m_parsedRuleLists; HashSet<CSSParserSelector*> m_floatingSelectors; HashSet<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors; HashSet<CSSParserValueList*> m_floatingValueLists; @@ -429,7 +442,11 @@ private: } bool validCalculationUnit(CSSParserValue*, Units); - bool validUnit(CSSParserValue*, Units, bool strict); + + bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode); + + inline bool validUnit(CSSParserValue* value, Units unitflags) { return validUnit(value, unitflags, m_context.mode); } + bool validUnit(CSSParserValue*, Units, CSSParserMode); bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&); int colorIntFromValue(CSSParserValue*); @@ -447,8 +464,8 @@ private: #endif }; -int cssPropertyID(const CSSParserString&); -int cssPropertyID(const String&); +CSSPropertyID cssPropertyID(const CSSParserString&); +CSSPropertyID cssPropertyID(const String&); int cssValueKeywordID(const CSSParserString&); #if PLATFORM(IOS) void cssPropertyNameIOSAliasing(const char* propertyName, const char*& propertyNameAlias, unsigned& newLength); @@ -457,7 +474,7 @@ void cssPropertyNameIOSAliasing(const char* propertyName, const char*& propertyN class ShorthandScope { WTF_MAKE_FAST_ALLOCATED; public: - ShorthandScope(CSSParser* parser, int propId) : m_parser(parser) + ShorthandScope(CSSParser* parser, CSSPropertyID propId) : m_parser(parser) { if (!(m_parser->m_inParseShorthand++)) m_parser->m_currentShorthand = propId; @@ -465,7 +482,7 @@ public: ~ShorthandScope() { if (!(--m_parser->m_inParseShorthand)) - m_parser->m_currentShorthand = 0; + m_parser->m_currentShorthand = CSSPropertyInvalid; } private: diff --git a/Source/WebCore/css/CSSParserMode.h b/Source/WebCore/css/CSSParserMode.h new file mode 100644 index 000000000..4e74f8c2e --- /dev/null +++ b/Source/WebCore/css/CSSParserMode.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * Copyright (C) 2012 Apple 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 THE COPYRIGHT HOLDER “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 HOLDER 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 CSSParserMode_h +#define CSSParserMode_h + +#include "KURL.h" + +namespace WebCore { + +class Document; + +enum CSSParserMode { + CSSQuirksMode, + CSSStrictMode, + // SVG should always be in strict mode. For SVG attributes, the rules differ to strict sometimes. + SVGAttributeMode +}; + +inline CSSParserMode strictToCSSParserMode(bool inStrictMode) +{ + return inStrictMode ? CSSStrictMode : CSSQuirksMode; +} + +inline bool isStrictParserMode(CSSParserMode cssParserMode) +{ + return cssParserMode == CSSStrictMode || cssParserMode == SVGAttributeMode; +} + +struct CSSParserContext { + CSSParserContext(CSSParserMode, const KURL& baseURL = KURL()); + CSSParserContext(Document*, const KURL& baseURL = KURL(), const String& charset = emptyString()); + + KURL baseURL; + String charset; + CSSParserMode mode; + bool isHTMLDocument; + bool isCSSCustomFilterEnabled; + bool isCSSRegionsEnabled; + bool needsSiteSpecificQuirks; + bool enforcesCSSMIMETypeInNoQuirksMode; +}; + +bool operator==(const CSSParserContext&, const CSSParserContext&); +inline bool operator!=(const CSSParserContext& a, const CSSParserContext& b) { return !(a == b); } + +const CSSParserContext& strictCSSParserContext(); + +}; + +#endif // CSSParserMode_h diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index 9d213dcdd..704a42d2a 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -77,6 +77,9 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit case CSSPrimitiveValue:: CSS_REMS: case CSSPrimitiveValue:: CSS_S: case CSSPrimitiveValue:: CSS_TURN: + case CSSPrimitiveValue:: CSS_VW: + case CSSPrimitiveValue:: CSS_VH: + case CSSPrimitiveValue:: CSS_VMIN: return true; case CSSPrimitiveValue:: CSS_ATTR: case CSSPrimitiveValue:: CSS_COUNTER: @@ -130,6 +133,10 @@ static CSSPrimitiveValue::UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes case CSSPrimitiveValue::CSS_HZ: case CSSPrimitiveValue::CSS_KHZ: return CSSPrimitiveValue::UFrequency; + case CSSPrimitiveValue::CSS_VW: + case CSSPrimitiveValue::CSS_VH: + case CSSPrimitiveValue::CSS_VMIN: + return CSSPrimitiveValue::UViewportPercentageLength; default: return CSSPrimitiveValue::UOther; } @@ -190,11 +197,6 @@ static const AtomicString& valueOrPropertyName(int valueOrPropertyID) return nullAtom; } -CSSPrimitiveValue::CSSPrimitiveValue() - : CSSValue(PrimitiveClass) -{ -} - CSSPrimitiveValue::CSSPrimitiveValue(int ident) : CSSValue(PrimitiveClass) { @@ -202,13 +204,6 @@ CSSPrimitiveValue::CSSPrimitiveValue(int ident) m_value.ident = ident; } -CSSPrimitiveValue::CSSPrimitiveValue(ClassType classType, int ident) - : CSSValue(classType) -{ - m_primitiveUnitType = CSS_IDENT; - m_value.ident = ident; -} - CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type) : CSSValue(PrimitiveClass) { @@ -226,14 +221,6 @@ CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type) } -CSSPrimitiveValue::CSSPrimitiveValue(ClassType classType, const String& str, UnitTypes type) - : CSSValue(classType) -{ - m_primitiveUnitType = type; - if ((m_value.string = str.impl())) - m_value.string->ref(); -} - CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color) : CSSValue(PrimitiveClass) { @@ -266,6 +253,18 @@ CSSPrimitiveValue::CSSPrimitiveValue(const Length& length) ASSERT(isfinite(length.percent())); m_value.num = length.percent(); break; + case ViewportPercentageWidth: + m_primitiveUnitType = CSS_VW; + m_value.num = length.viewportPercentageLength(); + break; + case ViewportPercentageHeight: + m_primitiveUnitType = CSS_VH; + m_value.num = length.viewportPercentageLength(); + break; + case ViewportPercentageMin: + m_primitiveUnitType = CSS_VMIN; + m_value.num = length.viewportPercentageLength(); + break; case Calculated: case Relative: case Undefined: @@ -333,41 +332,69 @@ CSSPrimitiveValue::~CSSPrimitiveValue() void CSSPrimitiveValue::cleanup() { switch (m_primitiveUnitType) { - case CSS_STRING: - case CSS_URI: - case CSS_ATTR: - case CSS_PARSER_HEXCOLOR: - if (m_value.string) - m_value.string->deref(); - break; - case CSS_COUNTER: - m_value.counter->deref(); - break; - case CSS_RECT: - m_value.rect->deref(); - break; - case CSS_QUAD: - m_value.quad->deref(); - break; - case CSS_PAIR: - m_value.pair->deref(); - break; + case CSS_STRING: + case CSS_URI: + case CSS_ATTR: + case CSS_COUNTER_NAME: + case CSS_PARSER_HEXCOLOR: + if (m_value.string) + m_value.string->deref(); + break; + case CSS_COUNTER: + m_value.counter->deref(); + break; + case CSS_RECT: + m_value.rect->deref(); + break; + case CSS_QUAD: + m_value.quad->deref(); + break; + case CSS_PAIR: + m_value.pair->deref(); + break; #if ENABLE(DASHBOARD_SUPPORT) - case CSS_DASHBOARD_REGION: - if (m_value.region) - m_value.region->deref(); - break; + case CSS_DASHBOARD_REGION: + if (m_value.region) + m_value.region->deref(); + break; #endif - case CSS_CALC: - m_value.calc->deref(); - break; - case CSS_SHAPE: - m_value.shape->deref(); - break; - default: - break; + case CSS_CALC: + m_value.calc->deref(); + break; + case CSS_SHAPE: + m_value.shape->deref(); + break; + case CSS_NUMBER: + case CSS_PARSER_INTEGER: + case CSS_PERCENTAGE: + case CSS_EMS: + case CSS_EXS: + case CSS_REMS: + case CSS_PX: + case CSS_CM: + case CSS_MM: + case CSS_IN: + case CSS_PT: + case CSS_PC: + case CSS_DEG: + case CSS_RAD: + case CSS_GRAD: + case CSS_MS: + case CSS_S: + case CSS_HZ: + case CSS_KHZ: + case CSS_TURN: + case CSS_VW: + case CSS_VH: + case CSS_VMIN: + case CSS_IDENT: + case CSS_RGBCOLOR: + case CSS_DIMENSION: + case CSS_UNKNOWN: + case CSS_PARSER_OPERATOR: + case CSS_PARSER_IDENTIFIER: + break; } - m_primitiveUnitType = 0; if (m_hasCachedCSSText) { cssTextCache().remove(this); @@ -394,28 +421,31 @@ double CSSPrimitiveValue::computeDegrees() template<> int CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize) { - return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); + return roundForImpreciseConversion<int>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); } template<> unsigned CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize) { - return roundForImpreciseConversion<unsigned, UINT_MAX, 0>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); + return roundForImpreciseConversion<unsigned>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); } template<> Length CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize) { - // FIXME: Length.h no longer expects 28 bit integers, so these bounds should be INT_MAX and INT_MIN - return Length(roundForImpreciseConversion<int, intMaxForLength, intMinForLength>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), Fixed); +#if ENABLE(SUBPIXEL_LAYOUT) + return Length(static_cast<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), Fixed); +#else + return Length(roundForImpreciseConversion<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), Fixed); +#endif } template<> short CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize) { - return roundForImpreciseConversion<short, SHRT_MAX, SHRT_MIN>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); + return roundForImpreciseConversion<short>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); } template<> unsigned short CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize) { - return roundForImpreciseConversion<unsigned short, USHRT_MAX, 0>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); + return roundForImpreciseConversion<unsigned short>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)); } template<> float CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize) @@ -595,6 +625,8 @@ CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(Uni return CSS_DEG; case UFrequency: return CSS_HZ; + case UViewportPercentageLength: + return CSS_UNKNOWN; // Cannot convert between numbers and relative lengths. default: return CSS_UNKNOWN; } @@ -1015,6 +1047,15 @@ String CSSPrimitiveValue::customCssText() const case CSS_SHAPE: text = m_value.shape->cssText(); break; + case CSS_VW: + text = formatNumber(m_value.num) + "vw"; + break; + case CSS_VH: + text = formatNumber(m_value.num) + "vh"; + break; + case CSS_VMIN: + text = formatNumber(m_value.num) + "vmin"; + break; } ASSERT(!cssTextCache().contains(this)); @@ -1023,10 +1064,113 @@ String CSSPrimitiveValue::customCssText() const return text; } -void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetInternal* styleSheet) { if (m_primitiveUnitType == CSS_URI) addSubresourceURL(urls, styleSheet->completeURL(m_value.string)); } +Length CSSPrimitiveValue::viewportPercentageLength() +{ + ASSERT(isViewportPercentageLength()); + Length viewportLength; + switch (m_primitiveUnitType) { + case CSS_VW: + viewportLength = Length(getDoubleValue(), ViewportPercentageWidth); + break; + case CSS_VH: + viewportLength = Length(getDoubleValue(), ViewportPercentageHeight); + break; + case CSS_VMIN: + viewportLength = Length(getDoubleValue(), ViewportPercentageMin); + break; + default: + break; + } + return viewportLength; +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const +{ + RefPtr<CSSPrimitiveValue> result; + + switch (m_primitiveUnitType) { + case CSS_STRING: + case CSS_URI: + case CSS_ATTR: + case CSS_COUNTER_NAME: + result = CSSPrimitiveValue::create(m_value.string, static_cast<UnitTypes>(m_primitiveUnitType)); + break; + case CSS_COUNTER: + result = CSSPrimitiveValue::create(m_value.counter->cloneForCSSOM()); + break; + case CSS_RECT: + result = CSSPrimitiveValue::create(m_value.rect->cloneForCSSOM()); + break; + case CSS_QUAD: + result = CSSPrimitiveValue::create(m_value.quad->cloneForCSSOM()); + break; + case CSS_PAIR: + // Pair is not exposed to the CSSOM, no need for a deep clone. + result = CSSPrimitiveValue::create(m_value.pair); + break; +#if ENABLE(DASHBOARD_SUPPORT) + case CSS_DASHBOARD_REGION: + // DashboardRegion is not exposed to the CSSOM, no need for a deep clone. + result = CSSPrimitiveValue::create(m_value.region); + break; +#endif + case CSS_CALC: + // CSSCalcValue is not exposed to the CSSOM, no need for a deep clone. + result = CSSPrimitiveValue::create(m_value.calc); + break; + case CSS_SHAPE: + // CSSShapeValue is not exposed to the CSSOM, no need for a deep clone. + result = CSSPrimitiveValue::create(m_value.shape); + break; + case CSS_NUMBER: + case CSS_PARSER_INTEGER: + case CSS_PERCENTAGE: + case CSS_EMS: + case CSS_EXS: + case CSS_REMS: + case CSS_PX: + case CSS_CM: + case CSS_MM: + case CSS_IN: + case CSS_PT: + case CSS_PC: + case CSS_DEG: + case CSS_RAD: + case CSS_GRAD: + case CSS_MS: + case CSS_S: + case CSS_HZ: + case CSS_KHZ: + case CSS_TURN: + case CSS_VW: + case CSS_VH: + case CSS_VMIN: + result = CSSPrimitiveValue::create(m_value.num, static_cast<UnitTypes>(m_primitiveUnitType)); + break; + case CSS_IDENT: + result = CSSPrimitiveValue::createIdentifier(m_value.ident); + break; + case CSS_RGBCOLOR: + result = CSSPrimitiveValue::createColor(m_value.rgbcolor); + break; + case CSS_DIMENSION: + case CSS_UNKNOWN: + case CSS_PARSER_OPERATOR: + case CSS_PARSER_IDENTIFIER: + case CSS_PARSER_HEXCOLOR: + ASSERT_NOT_REACHED(); + break; + } + if (result) + result->setCSSOMSafe(); + + return result; +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSPrimitiveValue.h b/Source/WebCore/css/CSSPrimitiveValue.h index 13e576a3e..78f5cd90e 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.h +++ b/Source/WebCore/css/CSSPrimitiveValue.h @@ -42,13 +42,24 @@ class CSSWrapShape; struct Length; -template<typename T, T max, T min> inline T roundForImpreciseConversion(double value) +// Dimension calculations are imprecise, often resulting in values of e.g. +// 44.99998. We need to go ahead and round if we're really close to the next +// integer value. +template<typename T> inline T roundForImpreciseConversion(double value) { - // Dimension calculations are imprecise, often resulting in values of e.g. - // 44.99998. We need to go ahead and round if we're really close to the - // next integer value. value += (value < 0) ? -0.01 : +0.01; - return ((value > max) || (value < min)) ? 0 : static_cast<T>(value); + return ((value > std::numeric_limits<T>::max()) || (value < std::numeric_limits<T>::min())) ? 0 : static_cast<T>(value); +} + +template<> inline float roundForImpreciseConversion(double value) +{ + double ceiledValue = ceil(value); + double proximityToNextInt = ceiledValue - value; + if (proximityToNextInt <= 0.01 && value > 0) + return static_cast<float>(ceiledValue); + if (proximityToNextInt >= 0.99 && value < 0) + return static_cast<float>(floor(value)); + return static_cast<float>(value); } class CSSPrimitiveValue : public CSSValue { @@ -80,6 +91,10 @@ public: CSS_COUNTER = 23, CSS_RECT = 24, CSS_RGBCOLOR = 25, + // From CSS Values and Units. Viewport-percentage Lengths (vw/vh/vmin). + CSS_VW = 26, + CSS_VH = 27, + CSS_VMIN = 28, CSS_PAIR = 100, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.) CSS_DASHBOARD_REGION = 101, // FIXME: Dashboard region should not be a primitive value. CSS_UNICODE_RANGE = 102, @@ -118,6 +133,7 @@ public: UAngle, UTime, UFrequency, + UViewportPercentageLength, UOther }; @@ -153,6 +169,7 @@ public: bool isCalculated() const { return m_primitiveUnitType == CSS_CALC; } bool isCalculatedPercentageWithNumber() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_NUMBER; } bool isCalculatedPercentageWithLength() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_LENGTH; } + bool isViewportPercentageLength() const { return m_primitiveUnitType >= CSS_VW && m_primitiveUnitType <= CSS_VMIN; } static PassRefPtr<CSSPrimitiveValue> createIdentifier(int identifier) { return adoptRef(new CSSPrimitiveValue(identifier)); } static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); } @@ -266,14 +283,14 @@ public: bool isQuirkValue() { return m_isQuirkValue; } - void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetInternal*); -protected: - CSSPrimitiveValue(ClassType, int ident); - CSSPrimitiveValue(ClassType, const String&, UnitTypes); + Length viewportPercentageLength(); + + PassRefPtr<CSSPrimitiveValue> cloneForCSSOM() const; + void setCSSOMSafe() { m_isCSSOMSafe = true; } private: - CSSPrimitiveValue(); // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and identifier cases. CSSPrimitiveValue(int ident); CSSPrimitiveValue(unsigned color); // RGB value @@ -298,10 +315,6 @@ private: static void create(unsigned); // compile-time guard template<typename T> operator T*(); // compile-time guard - static PassRefPtr<CSSPrimitiveValue> createUncachedIdentifier(int identifier); - static PassRefPtr<CSSPrimitiveValue> createUncachedColor(unsigned rgbValue); - static PassRefPtr<CSSPrimitiveValue> createUncached(double value, UnitTypes type); - static UnitTypes canonicalUnitTypeForCategory(UnitCategory category); void init(PassRefPtr<Counter>); diff --git a/Source/WebCore/css/CSSPrimitiveValue.idl b/Source/WebCore/css/CSSPrimitiveValue.idl index 517aba226..6c637c9ab 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.idl +++ b/Source/WebCore/css/CSSPrimitiveValue.idl @@ -48,7 +48,10 @@ module css { const unsigned short CSS_COUNTER = 23; const unsigned short CSS_RECT = 24; const unsigned short CSS_RGBCOLOR = 25; - + const unsigned short CSS_VW = 26; + const unsigned short CSS_VH = 27; + const unsigned short CSS_VMIN = 28; + readonly attribute unsigned short primitiveType; [ObjCLegacyUnnamedParameters] void setFloatValue(in [Optional=DefaultIsUndefined] unsigned short unitType, diff --git a/Source/WebCore/css/CSSPrimitiveValueMappings.h b/Source/WebCore/css/CSSPrimitiveValueMappings.h index 7d88cec32..d607713a0 100644 --- a/Source/WebCore/css/CSSPrimitiveValueMappings.h +++ b/Source/WebCore/css/CSSPrimitiveValueMappings.h @@ -30,13 +30,15 @@ #ifndef CSSPrimitiveValueMappings_h #define CSSPrimitiveValueMappings_h -#include "ColorSpace.h" +#include "CSSCalculationValue.h" #include "CSSPrimitiveValue.h" +#include "ColorSpace.h" #include "CSSValueKeywords.h" #include "FontDescription.h" #include "FontSmoothingMode.h" #include "GraphicsTypes.h" #include "Length.h" +#include "LineClampValue.h" #include "Path.h" #include "RenderStyleConstants.h" #include "SVGRenderStyleDefs.h" @@ -86,13 +88,6 @@ template<> inline CSSPrimitiveValue::operator unsigned short() const return 0; } -template<> inline CSSPrimitiveValue::CSSPrimitiveValue(int i) - : CSSValue(PrimitiveClass) -{ - m_primitiveUnitType = CSS_NUMBER; - m_value.num = static_cast<double>(i); -} - template<> inline CSSPrimitiveValue::operator int() const { if (m_primitiveUnitType == CSS_NUMBER) @@ -102,13 +97,6 @@ template<> inline CSSPrimitiveValue::operator int() const return 0; } -template<> inline CSSPrimitiveValue::CSSPrimitiveValue(unsigned i) - : CSSValue(PrimitiveClass) -{ - m_primitiveUnitType = CSS_NUMBER; - m_value.num = static_cast<double>(i); -} - template<> inline CSSPrimitiveValue::operator unsigned() const { if (m_primitiveUnitType == CSS_NUMBER) @@ -135,6 +123,25 @@ template<> inline CSSPrimitiveValue::operator float() const return 0.0f; } +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineClampValue i) + : CSSValue(PrimitiveClass) +{ + m_primitiveUnitType = i.isPercentage() ? CSS_PERCENTAGE : CSS_NUMBER; + m_value.num = static_cast<double>(i.value()); +} + +template<> inline CSSPrimitiveValue::operator LineClampValue() const +{ + if (m_primitiveUnitType == CSS_NUMBER) + return LineClampValue(clampTo<int>(m_value.num), LineClampLineCount); + + if (m_primitiveUnitType == CSS_PERCENTAGE) + return LineClampValue(clampTo<int>(m_value.num), LineClampPercentage); + + ASSERT_NOT_REACHED(); + return LineClampValue(); +} + template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnSpan columnSpan) : CSSValue(PrimitiveClass) { @@ -361,16 +368,14 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ControlPart e) case ListboxPart: m_value.ident = CSSValueListbox; break; - case ListButtonPart: -#if ENABLE(DATALIST) - m_value.ident = CSSValueListButton; -#endif - break; case ListItemPart: m_value.ident = CSSValueListitem; break; - case MediaFullscreenButtonPart: - m_value.ident = CSSValueMediaFullscreenButton; + case MediaEnterFullscreenButtonPart: + m_value.ident = CSSValueMediaEnterFullscreenButton; + break; + case MediaExitFullscreenButtonPart: + m_value.ident = CSSValueMediaExitFullscreenButton; break; case MediaPlayButtonPart: m_value.ident = CSSValueMediaPlayButton; @@ -1289,6 +1294,53 @@ template<> inline CSSPrimitiveValue::operator EFlexDirection() const } } +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexLinePack e) + : CSSValue(PrimitiveClass) +{ + m_primitiveUnitType = CSS_IDENT; + switch (e) { + case LinePackStart: + m_value.ident = CSSValueStart; + break; + case LinePackEnd: + m_value.ident = CSSValueEnd; + break; + case LinePackCenter: + m_value.ident = CSSValueCenter; + break; + case LinePackJustify: + m_value.ident = CSSValueJustify; + break; + case LinePackDistribute: + m_value.ident = CSSValueDistribute; + break; + case LinePackStretch: + m_value.ident = CSSValueStretch; + break; + } +} + +template<> inline CSSPrimitiveValue::operator EFlexLinePack() const +{ + switch (m_value.ident) { + case CSSValueStart: + return LinePackStart; + case CSSValueEnd: + return LinePackEnd; + case CSSValueCenter: + return LinePackCenter; + case CSSValueJustify: + return LinePackJustify; + case CSSValueDistribute: + return LinePackDistribute; + case CSSValueStretch: + return LinePackStretch; + default: + ASSERT_NOT_REACHED(); + return LinePackStretch; + } +} + template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFlexWrap e) : CSSValue(PrimitiveClass) { @@ -1335,9 +1387,6 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFloat e) case RightFloat: m_value.ident = CSSValueRight; break; - case PositionedFloat: - m_value.ident = CSSValueWebkitPositioned; - break; } } @@ -1351,8 +1400,6 @@ template<> inline CSSPrimitiveValue::operator EFloat() const case CSSValueNone: case CSSValueCenter: // Non-standard CSS value return NoFloat; - case CSSValueWebkitPositioned: - return PositionedFloat; default: ASSERT_NOT_REACHED(); return NoFloat; @@ -3647,11 +3694,11 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WrapFlow wrapFlow) case WrapFlowBoth: m_value.ident = CSSValueBoth; break; - case WrapFlowLeft: - m_value.ident = CSSValueLeft; + case WrapFlowStart: + m_value.ident = CSSValueStart; break; - case WrapFlowRight: - m_value.ident = CSSValueRight; + case WrapFlowEnd: + m_value.ident = CSSValueEnd; break; case WrapFlowMaximum: m_value.ident = CSSValueMaximum; @@ -3669,10 +3716,10 @@ template<> inline CSSPrimitiveValue::operator WrapFlow() const return WrapFlowAuto; case CSSValueBoth: return WrapFlowBoth; - case CSSValueLeft: - return WrapFlowLeft; - case CSSValueRight: - return WrapFlowRight; + case CSSValueStart: + return WrapFlowStart; + case CSSValueEnd: + return WrapFlowEnd; case CSSValueMaximum: return WrapFlowMaximum; case CSSValueClear: @@ -3710,18 +3757,35 @@ template<> inline CSSPrimitiveValue::operator WrapThrough() const } } -enum LengthConversion { UnsupportedConversion = 0, FixedConversion = 1, AutoConversion = 2, PercentConversion = 4, FractionConversion = 8}; +enum LengthConversion { + AnyConversion = ~0, + FixedIntegerConversion = 1 << 0, + FixedFloatConversion = 1 << 1, + AutoConversion = 1 << 2, + PercentConversion = 1 << 3, + FractionConversion = 1 << 4, + CalculatedConversion = 1 << 5, + ViewportPercentageConversion = 1 << 6 +}; + template<int supported> Length CSSPrimitiveValue::convertToLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier, bool computingFontSize) { - if ((supported & FixedConversion) && isLength()) + if ((supported & (FixedIntegerConversion | FixedFloatConversion)) && isFontRelativeLength() && (!style || !rootStyle)) + return Length(Undefined); + if ((supported & FixedIntegerConversion) && isLength()) return computeLength<Length>(style, rootStyle, multiplier, computingFontSize); + if ((supported & FixedFloatConversion) && isLength()) + return Length(computeLength<double>(style, rootStyle, multiplier), Fixed); if ((supported & PercentConversion) && isPercentage()) return Length(getDoubleValue(), Percent); if ((supported & FractionConversion) && isNumber()) return Length(getDoubleValue() * 100.0, Percent); if ((supported & AutoConversion) && getIdent() == CSSValueAuto) return Length(Auto); - ASSERT_NOT_REACHED(); + if ((supported & CalculatedConversion) && isCalculated()) + return Length(cssCalcValue()->toCalcValue(style, rootStyle, multiplier)); + if ((supported & ViewportPercentageConversion) && isViewportPercentageLength()) + return viewportPercentageLength(); return Length(Undefined); } diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp index 01e7077bf..ad8797aec 100644 --- a/Source/WebCore/css/CSSProperty.cpp +++ b/Source/WebCore/css/CSSProperty.cpp @@ -21,40 +21,55 @@ #include "config.h" #include "CSSProperty.h" -#include "CSSPropertyNames.h" +#include "CSSValueList.h" #include "PlatformString.h" #include "RenderStyleConstants.h" +#include "StylePropertyShorthand.h" namespace WebCore { +struct SameSizeAsCSSProperty { + uint32_t bitfields; + void* value; +}; + +COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small); + String CSSProperty::cssText() const { - return String(getPropertyName(static_cast<CSSPropertyID>(id()))) + ": " + m_value->cssText() + (isImportant() ? " !important" : "") + "; "; + return String(getPropertyName(id())) + ": " + m_value->cssText() + (isImportant() ? " !important" : "") + "; "; +} + +void CSSProperty::wrapValueInCommaSeparatedList() +{ + RefPtr<CSSValue> value = m_value.release(); + m_value = CSSValueList::createCommaSeparated(); + static_cast<CSSValueList*>(m_value.get())->append(value.release()); } enum LogicalBoxSide { BeforeSide, EndSide, AfterSide, StartSide }; enum PhysicalBoxSide { TopSide, RightSide, BottomSide, LeftSide }; -static int resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const int* properties) +static CSSPropertyID resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand) { if (direction == LTR) { if (writingMode == TopToBottomWritingMode) { // The common case. The logical and physical box sides match. // Left = Start, Right = End, Before = Top, After = Bottom - return properties[logicalSide]; + return shorthand.properties()[logicalSide]; } if (writingMode == BottomToTopWritingMode) { // Start = Left, End = Right, Before = Bottom, After = Top. switch (logicalSide) { case StartSide: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; case EndSide: - return properties[RightSide]; + return shorthand.properties()[RightSide]; case BeforeSide: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; default: - return properties[TopSide]; + return shorthand.properties()[TopSide]; } } @@ -62,26 +77,26 @@ static int resolveToPhysicalProperty(TextDirection direction, WritingMode writin // Start = Top, End = Bottom, Before = Left, After = Right. switch (logicalSide) { case StartSide: - return properties[TopSide]; + return shorthand.properties()[TopSide]; case EndSide: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; case BeforeSide: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; default: - return properties[RightSide]; + return shorthand.properties()[RightSide]; } } // Start = Top, End = Bottom, Before = Right, After = Left switch (logicalSide) { case StartSide: - return properties[TopSide]; + return shorthand.properties()[TopSide]; case EndSide: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; case BeforeSide: - return properties[RightSide]; + return shorthand.properties()[RightSide]; default: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; } } @@ -89,13 +104,13 @@ static int resolveToPhysicalProperty(TextDirection direction, WritingMode writin // Start = Right, End = Left, Before = Top, After = Bottom switch (logicalSide) { case StartSide: - return properties[RightSide]; + return shorthand.properties()[RightSide]; case EndSide: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; case BeforeSide: - return properties[TopSide]; + return shorthand.properties()[TopSide]; default: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; } } @@ -103,13 +118,13 @@ static int resolveToPhysicalProperty(TextDirection direction, WritingMode writin // Start = Right, End = Left, Before = Bottom, After = Top switch (logicalSide) { case StartSide: - return properties[RightSide]; + return shorthand.properties()[RightSide]; case EndSide: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; case BeforeSide: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; default: - return properties[TopSide]; + return shorthand.properties()[TopSide]; } } @@ -117,159 +132,118 @@ static int resolveToPhysicalProperty(TextDirection direction, WritingMode writin // Start = Bottom, End = Top, Before = Left, After = Right switch (logicalSide) { case StartSide: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; case EndSide: - return properties[TopSide]; + return shorthand.properties()[TopSide]; case BeforeSide: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; default: - return properties[RightSide]; + return shorthand.properties()[RightSide]; } } // Start = Bottom, End = Top, Before = Right, After = Left switch (logicalSide) { case StartSide: - return properties[BottomSide]; + return shorthand.properties()[BottomSide]; case EndSide: - return properties[TopSide]; + return shorthand.properties()[TopSide]; case BeforeSide: - return properties[RightSide]; + return shorthand.properties()[RightSide]; default: - return properties[LeftSide]; + return shorthand.properties()[LeftSide]; } } enum LogicalExtent { LogicalWidth, LogicalHeight }; -static int resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const int* properties) +static CSSPropertyID resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const CSSPropertyID* properties) { if (writingMode == TopToBottomWritingMode || writingMode == BottomToTopWritingMode) return properties[logicalSide]; return logicalSide == LogicalWidth ? properties[1] : properties[0]; } -int CSSProperty::resolveDirectionAwareProperty(int propertyID, TextDirection direction, WritingMode writingMode) +static const StylePropertyShorthand& borderDirections() { - switch (static_cast<CSSPropertyID>(propertyID)) { - case CSSPropertyWebkitMarginEnd: { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return resolveToPhysicalProperty(direction, writingMode, EndSide, properties); - } - case CSSPropertyWebkitMarginStart: { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return resolveToPhysicalProperty(direction, writingMode, StartSide, properties); - } - case CSSPropertyWebkitMarginBefore: { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties); - } - case CSSPropertyWebkitMarginAfter: { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties); - } - case CSSPropertyWebkitPaddingEnd: { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return resolveToPhysicalProperty(direction, writingMode, EndSide, properties); - } - case CSSPropertyWebkitPaddingStart: { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return resolveToPhysicalProperty(direction, writingMode, StartSide, properties); - } - case CSSPropertyWebkitPaddingBefore: { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties); - } - case CSSPropertyWebkitPaddingAfter: { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties); - } - case CSSPropertyWebkitBorderEnd: { - const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; - return resolveToPhysicalProperty(direction, writingMode, EndSide, properties); - } - case CSSPropertyWebkitBorderStart: { - const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; - return resolveToPhysicalProperty(direction, writingMode, StartSide, properties); - } - case CSSPropertyWebkitBorderBefore: { - const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; - return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties); - } - case CSSPropertyWebkitBorderAfter: { - const int properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; - return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties); - } - case CSSPropertyWebkitBorderEndColor: { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return resolveToPhysicalProperty(direction, writingMode, EndSide, properties); - } - case CSSPropertyWebkitBorderStartColor: { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return resolveToPhysicalProperty(direction, writingMode, StartSide, properties); - } - case CSSPropertyWebkitBorderBeforeColor: { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties); - } - case CSSPropertyWebkitBorderAfterColor: { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties); - } - case CSSPropertyWebkitBorderEndStyle: { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return resolveToPhysicalProperty(direction, writingMode, EndSide, properties); - } - case CSSPropertyWebkitBorderStartStyle: { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return resolveToPhysicalProperty(direction, writingMode, StartSide, properties); - } - case CSSPropertyWebkitBorderBeforeStyle: { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties); - } - case CSSPropertyWebkitBorderAfterStyle: { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties); - } - case CSSPropertyWebkitBorderEndWidth: { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return resolveToPhysicalProperty(direction, writingMode, EndSide, properties); - } - case CSSPropertyWebkitBorderStartWidth: { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return resolveToPhysicalProperty(direction, writingMode, StartSide, properties); - } - case CSSPropertyWebkitBorderBeforeWidth: { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return resolveToPhysicalProperty(direction, writingMode, BeforeSide, properties); - } - case CSSPropertyWebkitBorderAfterWidth: { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return resolveToPhysicalProperty(direction, writingMode, AfterSide, properties); - } + static const CSSPropertyID properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderDirections, (properties, WTF_ARRAY_LENGTH(properties))); + return borderDirections; +} + +CSSPropertyID CSSProperty::resolveDirectionAwareProperty(CSSPropertyID propertyID, TextDirection direction, WritingMode writingMode) +{ + switch (propertyID) { + case CSSPropertyWebkitMarginEnd: + return resolveToPhysicalProperty(direction, writingMode, EndSide, marginShorthand()); + case CSSPropertyWebkitMarginStart: + return resolveToPhysicalProperty(direction, writingMode, StartSide, marginShorthand()); + case CSSPropertyWebkitMarginBefore: + return resolveToPhysicalProperty(direction, writingMode, BeforeSide, marginShorthand()); + case CSSPropertyWebkitMarginAfter: + return resolveToPhysicalProperty(direction, writingMode, AfterSide, marginShorthand()); + case CSSPropertyWebkitPaddingEnd: + return resolveToPhysicalProperty(direction, writingMode, EndSide, paddingShorthand()); + case CSSPropertyWebkitPaddingStart: + return resolveToPhysicalProperty(direction, writingMode, StartSide, paddingShorthand()); + case CSSPropertyWebkitPaddingBefore: + return resolveToPhysicalProperty(direction, writingMode, BeforeSide, paddingShorthand()); + case CSSPropertyWebkitPaddingAfter: + return resolveToPhysicalProperty(direction, writingMode, AfterSide, paddingShorthand()); + case CSSPropertyWebkitBorderEnd: + return resolveToPhysicalProperty(direction, writingMode, EndSide, borderDirections()); + case CSSPropertyWebkitBorderStart: + return resolveToPhysicalProperty(direction, writingMode, StartSide, borderDirections()); + case CSSPropertyWebkitBorderBefore: + return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderDirections()); + case CSSPropertyWebkitBorderAfter: + return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderDirections()); + case CSSPropertyWebkitBorderEndColor: + return resolveToPhysicalProperty(direction, writingMode, EndSide, borderColorShorthand()); + case CSSPropertyWebkitBorderStartColor: + return resolveToPhysicalProperty(direction, writingMode, StartSide, borderColorShorthand()); + case CSSPropertyWebkitBorderBeforeColor: + return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderColorShorthand()); + case CSSPropertyWebkitBorderAfterColor: + return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderColorShorthand()); + case CSSPropertyWebkitBorderEndStyle: + return resolveToPhysicalProperty(direction, writingMode, EndSide, borderStyleShorthand()); + case CSSPropertyWebkitBorderStartStyle: + return resolveToPhysicalProperty(direction, writingMode, StartSide, borderStyleShorthand()); + case CSSPropertyWebkitBorderBeforeStyle: + return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderStyleShorthand()); + case CSSPropertyWebkitBorderAfterStyle: + return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderStyleShorthand()); + case CSSPropertyWebkitBorderEndWidth: + return resolveToPhysicalProperty(direction, writingMode, EndSide, borderWidthShorthand()); + case CSSPropertyWebkitBorderStartWidth: + return resolveToPhysicalProperty(direction, writingMode, StartSide, borderWidthShorthand()); + case CSSPropertyWebkitBorderBeforeWidth: + return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderWidthShorthand()); + case CSSPropertyWebkitBorderAfterWidth: + return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderWidthShorthand()); case CSSPropertyWebkitLogicalWidth: { - const int properties[2] = { CSSPropertyWidth, CSSPropertyHeight }; + const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight }; return resolveToPhysicalProperty(writingMode, LogicalWidth, properties); } case CSSPropertyWebkitLogicalHeight: { - const int properties[2] = { CSSPropertyWidth, CSSPropertyHeight }; + const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight }; return resolveToPhysicalProperty(writingMode, LogicalHeight, properties); } case CSSPropertyWebkitMinLogicalWidth: { - const int properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight }; + const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight }; return resolveToPhysicalProperty(writingMode, LogicalWidth, properties); } case CSSPropertyWebkitMinLogicalHeight: { - const int properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight }; + const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight }; return resolveToPhysicalProperty(writingMode, LogicalHeight, properties); } case CSSPropertyWebkitMaxLogicalWidth: { - const int properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight }; + const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight }; return resolveToPhysicalProperty(writingMode, LogicalWidth, properties); } case CSSPropertyWebkitMaxLogicalHeight: { - const int properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight }; + const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight }; return resolveToPhysicalProperty(writingMode, LogicalHeight, properties); } default: @@ -277,9 +251,9 @@ int CSSProperty::resolveDirectionAwareProperty(int propertyID, TextDirection dir } } -bool CSSProperty::isInheritedProperty(unsigned propertyID) +bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) { - switch (static_cast<CSSPropertyID>(propertyID)) { + switch (propertyID) { case CSSPropertyBorderCollapse: case CSSPropertyBorderSpacing: case CSSPropertyCaptionSide: @@ -562,12 +536,14 @@ bool CSSProperty::isInheritedProperty(unsigned propertyID) #if ENABLE(CSS_FILTERS) case CSSPropertyWebkitFilter: #endif + case CSSPropertyWebkitFlex: case CSSPropertyWebkitFlexOrder: case CSSPropertyWebkitFlexPack: case CSSPropertyWebkitFlexAlign: case CSSPropertyWebkitFlexItemAlign: case CSSPropertyWebkitFlexDirection: case CSSPropertyWebkitFlexFlow: + case CSSPropertyWebkitFlexLinePack: case CSSPropertyWebkitFlexWrap: case CSSPropertyWebkitFontSizeDelta: #if ENABLE(CSS_GRID_LAYOUT) @@ -649,8 +625,8 @@ bool CSSProperty::isInheritedProperty(unsigned propertyID) case CSSPropertyWebkitWrapFlow: case CSSPropertyWebkitWrapMargin: case CSSPropertyWebkitWrapPadding: - case CSSPropertyWebkitWrapShapeInside: - case CSSPropertyWebkitWrapShapeOutside: + case CSSPropertyWebkitShapeInside: + case CSSPropertyWebkitShapeOutside: case CSSPropertyWebkitWrapThrough: #if ENABLE(SVG) case CSSPropertyClipPath: diff --git a/Source/WebCore/css/CSSProperty.h b/Source/WebCore/css/CSSProperty.h index d90d31e68..0f99e677f 100644 --- a/Source/WebCore/css/CSSProperty.h +++ b/Source/WebCore/css/CSSProperty.h @@ -21,6 +21,7 @@ #ifndef CSSProperty_h #define CSSProperty_h +#include "CSSPropertyNames.h" #include "CSSValue.h" #include "RenderStyleConstants.h" #include "TextDirection.h" @@ -31,7 +32,7 @@ namespace WebCore { class CSSProperty { public: - CSSProperty(unsigned propID, PassRefPtr<CSSValue> value, bool important = false, int shorthandID = 0, bool implicit = false) + CSSProperty(CSSPropertyID propID, PassRefPtr<CSSValue> value, bool important = false, CSSPropertyID shorthandID = CSSPropertyInvalid, bool implicit = false) : m_id(propID) , m_shorthandID(shorthandID) , m_important(important) @@ -41,8 +42,8 @@ public: { } - int id() const { return m_id; } - int shorthandID() const { return m_shorthandID; } + CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_id); } + CSSPropertyID shorthandID() const { return static_cast<CSSPropertyID>(m_shorthandID); } bool isImportant() const { return m_important; } bool isImplicit() const { return m_implicit; } @@ -52,15 +53,18 @@ public: String cssText() const; - static int resolveDirectionAwareProperty(int propertyID, TextDirection, WritingMode); - static bool isInheritedProperty(unsigned propertyID); + void wrapValueInCommaSeparatedList(); + static CSSPropertyID resolveDirectionAwareProperty(CSSPropertyID, TextDirection, WritingMode); + static bool isInheritedProperty(CSSPropertyID); + +private: // Make sure the following fits in 4 bytes. Really. unsigned m_id : 14; unsigned m_shorthandID : 14; // If this property was set as part of a shorthand, gives the shorthand. - bool m_important : 1; - bool m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand. - bool m_inherited : 1; + unsigned m_important : 1; + unsigned m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand. + unsigned m_inherited : 1; RefPtr<CSSValue> m_value; }; diff --git a/Source/WebCore/css/CSSPropertyLonghand.cpp b/Source/WebCore/css/CSSPropertyLonghand.cpp deleted file mode 100644 index 0d03b20bf..000000000 --- a/Source/WebCore/css/CSSPropertyLonghand.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* - * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "CSSPropertyLonghand.h" - -#include "CSSPropertyNames.h" -#include <wtf/HashMap.h> -#include <wtf/StdLibExtras.h> - -namespace WebCore { - -typedef HashMap<int, CSSPropertyLonghand> ShorthandMap; - -static void initShorthandMap(ShorthandMap& shorthandMap) -{ - #define SET_SHORTHAND_MAP_ENTRY(map, propID, array) \ - map.set(propID, CSSPropertyLonghand(array, WTF_ARRAY_LENGTH(array))) - - static const int fontProperties[] = { - CSSPropertyFontFamily, - CSSPropertyFontSize, - CSSPropertyFontStyle, - CSSPropertyFontVariant, - CSSPropertyFontWeight, - CSSPropertyLineHeight - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyFont, fontProperties); - - // Do not change the order of the following four shorthands, and keep them together. - static const int borderProperties[4][3] = { - { CSSPropertyBorderTopColor, CSSPropertyBorderTopStyle, CSSPropertyBorderTopWidth }, - { CSSPropertyBorderRightColor, CSSPropertyBorderRightStyle, CSSPropertyBorderRightWidth }, - { CSSPropertyBorderBottomColor, CSSPropertyBorderBottomStyle, CSSPropertyBorderBottomWidth }, - { CSSPropertyBorderLeftColor, CSSPropertyBorderLeftStyle, CSSPropertyBorderLeftWidth } - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderTop, borderProperties[0]); - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderRight, borderProperties[1]); - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderBottom, borderProperties[2]); - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderLeft, borderProperties[3]); - - shorthandMap.set(CSSPropertyBorder, CSSPropertyLonghand(borderProperties[0], sizeof(borderProperties) / sizeof(borderProperties[0][0]))); - - static const int borderColorProperties[] = { - CSSPropertyBorderTopColor, - CSSPropertyBorderRightColor, - CSSPropertyBorderBottomColor, - CSSPropertyBorderLeftColor - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderColor, borderColorProperties); - - static const int borderImageProperties[] = { - CSSPropertyBorderImageSource, - CSSPropertyBorderImageSlice, - CSSPropertyBorderImageWidth, - CSSPropertyBorderImageOutset, - CSSPropertyBorderImageRepeat - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderImage, borderImageProperties); - - static const int borderStyleProperties[] = { - CSSPropertyBorderTopStyle, - CSSPropertyBorderRightStyle, - CSSPropertyBorderBottomStyle, - CSSPropertyBorderLeftStyle - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderStyle, borderStyleProperties); - - static const int borderWidthProperties[] = { - CSSPropertyBorderTopWidth, - CSSPropertyBorderRightWidth, - CSSPropertyBorderBottomWidth, - CSSPropertyBorderLeftWidth - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderWidth, borderWidthProperties); - - static const int backgroundPositionProperties[] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackgroundPosition, backgroundPositionProperties); - - static const int backgroundRepeatProperties[] = { CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackgroundRepeat, backgroundRepeatProperties); - - static const int borderSpacingProperties[] = { CSSPropertyWebkitBorderHorizontalSpacing, CSSPropertyWebkitBorderVerticalSpacing }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderSpacing, borderSpacingProperties); - - static const int flexFlowProperties[] = { CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitFlexFlow, flexFlowProperties); - - static const int listStyleProperties[] = { - CSSPropertyListStyleImage, - CSSPropertyListStylePosition, - CSSPropertyListStyleType - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyListStyle, listStyleProperties); - - static const int marginProperties[] = { - CSSPropertyMarginTop, - CSSPropertyMarginRight, - CSSPropertyMarginBottom, - CSSPropertyMarginLeft - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyMargin, marginProperties); - - static const int marginCollapseProperties[] = { CSSPropertyWebkitMarginBeforeCollapse, CSSPropertyWebkitMarginAfterCollapse }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMarginCollapse, marginCollapseProperties); - - static const int marqueeProperties[] = { - CSSPropertyWebkitMarqueeDirection, - CSSPropertyWebkitMarqueeIncrement, - CSSPropertyWebkitMarqueeRepetition, - CSSPropertyWebkitMarqueeStyle, - CSSPropertyWebkitMarqueeSpeed - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMarquee, marqueeProperties); - - static const int outlineProperties[] = { - CSSPropertyOutlineColor, - CSSPropertyOutlineOffset, - CSSPropertyOutlineStyle, - CSSPropertyOutlineWidth - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyOutline, outlineProperties); - - static const int paddingProperties[] = { - CSSPropertyPaddingTop, - CSSPropertyPaddingRight, - CSSPropertyPaddingBottom, - CSSPropertyPaddingLeft - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyPadding, paddingProperties); - - static const int webkitWrapProperties[] = { - CSSPropertyWebkitWrapFlow, - CSSPropertyWebkitWrapMargin, - CSSPropertyWebkitWrapPadding - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitWrap, webkitWrapProperties); - - static const int textStrokeProperties[] = { CSSPropertyWebkitTextStrokeColor, CSSPropertyWebkitTextStrokeWidth }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTextStroke, textStrokeProperties); - - static const int backgroundProperties[] = { - CSSPropertyBackgroundAttachment, - CSSPropertyBackgroundClip, - CSSPropertyBackgroundColor, - CSSPropertyBackgroundImage, - CSSPropertyBackgroundOrigin, - CSSPropertyBackgroundPositionX, - CSSPropertyBackgroundPositionY, - CSSPropertyBackgroundRepeatX, - CSSPropertyBackgroundRepeatY - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackground, backgroundProperties); - - static const int columnsProperties[] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitColumns, columnsProperties); - - static const int columnRuleProperties[] = { - CSSPropertyWebkitColumnRuleColor, - CSSPropertyWebkitColumnRuleStyle, - CSSPropertyWebkitColumnRuleWidth - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitColumnRule, columnRuleProperties); - - static const int overflowProperties[] = { CSSPropertyOverflowX, CSSPropertyOverflowY }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyOverflow, overflowProperties); - - static const int borderRadiusProperties[] = { - CSSPropertyBorderTopRightRadius, - CSSPropertyBorderTopLeftRadius, - CSSPropertyBorderBottomLeftRadius, - CSSPropertyBorderBottomRightRadius - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderRadius, borderRadiusProperties); - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitBorderRadius, borderRadiusProperties); - - static const int maskPositionProperties[] = { CSSPropertyWebkitMaskPositionX, CSSPropertyWebkitMaskPositionY }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMaskPosition, maskPositionProperties); - - static const int maskRepeatProperties[] = { CSSPropertyWebkitMaskRepeatX, CSSPropertyWebkitMaskRepeatY }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMaskRepeat, maskRepeatProperties); - - static const int maskProperties[] = { - CSSPropertyWebkitMaskAttachment, - CSSPropertyWebkitMaskClip, - CSSPropertyWebkitMaskImage, - CSSPropertyWebkitMaskOrigin, - CSSPropertyWebkitMaskPositionX, - CSSPropertyWebkitMaskPositionY, - CSSPropertyWebkitMaskRepeatX, - CSSPropertyWebkitMaskRepeatY - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMask, maskProperties); - - static const int animationProperties[] = { - CSSPropertyWebkitAnimationName, - CSSPropertyWebkitAnimationDuration, - CSSPropertyWebkitAnimationTimingFunction, - CSSPropertyWebkitAnimationDelay, - CSSPropertyWebkitAnimationIterationCount, - CSSPropertyWebkitAnimationDirection, - CSSPropertyWebkitAnimationFillMode - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitAnimation, animationProperties); - - static const int transitionProperties[] = { - CSSPropertyWebkitTransitionProperty, - CSSPropertyWebkitTransitionDuration, - CSSPropertyWebkitTransitionTimingFunction, - CSSPropertyWebkitTransitionDelay - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTransition, transitionProperties); - - static const int transformOriginProperties[] = { - CSSPropertyWebkitTransformOriginX, - CSSPropertyWebkitTransformOriginY - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTransformOrigin, transformOriginProperties); - - static const int textEmphasisProperties[] = { - CSSPropertyWebkitTextEmphasisColor, - CSSPropertyWebkitTextEmphasisStyle - }; - SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTextEmphasis, textEmphasisProperties); - - #undef SET_SHORTHAND_MAP_ENTRY -} - -CSSPropertyLonghand longhandForProperty(int propertyID) -{ - DEFINE_STATIC_LOCAL(ShorthandMap, shorthandMap, ()); - if (shorthandMap.isEmpty()) - initShorthandMap(shorthandMap); - - return shorthandMap.get(propertyID); -} - - -} // namespace WebCore diff --git a/Source/WebCore/css/CSSPropertyLonghand.h b/Source/WebCore/css/CSSPropertyLonghand.h deleted file mode 100644 index 9633c025a..000000000 --- a/Source/WebCore/css/CSSPropertyLonghand.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef CSSPropertyLonghand_h -#define CSSPropertyLonghand_h - -namespace WebCore { - -class CSSPropertyLonghand { -public: - CSSPropertyLonghand() - : m_properties(0) - , m_length(0) - { - } - - CSSPropertyLonghand(const int* firstProperty, unsigned numProperties) - : m_properties(firstProperty) - , m_length(numProperties) - { - } - - const int* properties() const { return m_properties; } - unsigned length() const { return m_length; } - -private: - const int* m_properties; - unsigned m_length; -}; - -// Returns an empty list if the property is not a shorthand -CSSPropertyLonghand longhandForProperty(int); - -} // namespace WebCore - -#endif // CSSPropertyLonghand_h diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index 41394466b..aee5c06af 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -255,10 +255,12 @@ z-index #if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS -webkit-filter #endif +-webkit-flex -webkit-flex-align -webkit-flex-direction -webkit-flex-flow -webkit-flex-item-align +-webkit-flex-line-pack -webkit-flex-order -webkit-flex-pack -webkit-flex-wrap @@ -360,8 +362,8 @@ z-index -webkit-flow-into -webkit-flow-from -webkit-region-overflow --webkit-wrap-shape-inside --webkit-wrap-shape-outside +-webkit-shape-inside +-webkit-shape-outside -webkit-wrap-margin -webkit-wrap-padding -webkit-region-break-after diff --git a/Source/WebCore/css/CSSPropertySourceData.h b/Source/WebCore/css/CSSPropertySourceData.h index f20af1af8..5803f94b1 100644 --- a/Source/WebCore/css/CSSPropertySourceData.h +++ b/Source/WebCore/css/CSSPropertySourceData.h @@ -40,7 +40,7 @@ namespace WebCore { -class CSSStyleRule; +class StyleRule; struct SourceRange { SourceRange(); @@ -93,7 +93,7 @@ struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> { SourceRange selectorListRange; RefPtr<CSSStyleSourceData> styleSourceData; }; -typedef HashMap<CSSStyleRule*, RefPtr<CSSRuleSourceData> > StyleRuleRangeMap; +typedef HashMap<StyleRule*, RefPtr<CSSRuleSourceData> > StyleRuleRangeMap; } // namespace WebCore diff --git a/Source/WebCore/css/CSSReflectValue.cpp b/Source/WebCore/css/CSSReflectValue.cpp index 911d110b9..bc786b588 100644 --- a/Source/WebCore/css/CSSReflectValue.cpp +++ b/Source/WebCore/css/CSSReflectValue.cpp @@ -59,7 +59,7 @@ String CSSReflectValue::customCssText() const return result; } -void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetInternal* styleSheet) { if (m_mask) m_mask->addSubresourceStyleURLs(urls, styleSheet); diff --git a/Source/WebCore/css/CSSReflectValue.h b/Source/WebCore/css/CSSReflectValue.h index 5b03efe89..1514775f0 100644 --- a/Source/WebCore/css/CSSReflectValue.h +++ b/Source/WebCore/css/CSSReflectValue.h @@ -49,7 +49,7 @@ public: String customCssText() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetInternal*); private: CSSReflectValue(CSSReflectionDirection direction, PassRefPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask) diff --git a/Source/WebCore/css/CSSRule.h b/Source/WebCore/css/CSSRule.h index 6f9ee410b..5a50645aa 100644 --- a/Source/WebCore/css/CSSRule.h +++ b/Source/WebCore/css/CSSRule.h @@ -69,15 +69,6 @@ public: bool isRegionRule() const { return type() == WEBKIT_REGION_RULE; } bool isImportRule() const { return type() == IMPORT_RULE; } - bool useStrictParsing() const - { - if (parentRule()) - return parentRule()->useStrictParsing(); - if (parentStyleSheet()) - return parentStyleSheet()->useStrictParsing(); - return true; - } - void setParentStyleSheet(CSSStyleSheet* styleSheet) { m_parentIsRule = false; @@ -102,13 +93,6 @@ public: String cssText() const; void setCssText(const String&, ExceptionCode&); - KURL baseURL() const - { - if (CSSStyleSheet* parentSheet = parentStyleSheet()) - return parentSheet->baseURL(); - return KURL(); - } - protected: CSSRule(CSSStyleSheet* parent, Type type) : m_hasCachedSelectorText(false) @@ -126,6 +110,12 @@ protected: bool hasCachedSelectorText() const { return m_hasCachedSelectorText; } void setHasCachedSelectorText(bool hasCachedSelectorText) const { m_hasCachedSelectorText = hasCachedSelectorText; } + const CSSParserContext& parserContext() const + { + CSSStyleSheet* styleSheet = parentStyleSheet(); + return styleSheet ? styleSheet->internal()->parserContext() : strictCSSParserContext(); + } + private: mutable unsigned m_hasCachedSelectorText : 1; unsigned m_parentIsRule : 1; diff --git a/Source/WebCore/css/CSSRuleList.cpp b/Source/WebCore/css/CSSRuleList.cpp index 6b080ef0b..a158d6f2e 100644 --- a/Source/WebCore/css/CSSRuleList.cpp +++ b/Source/WebCore/css/CSSRuleList.cpp @@ -1,7 +1,7 @@ /** * (C) 1999-2003 Lars Knoll (knoll@kde.org) * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2002, 2005, 2006, 2012 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,7 +24,6 @@ #include "CSSRule.h" #include "CSSStyleSheet.h" -#include <wtf/text/StringBuilder.h> namespace WebCore { @@ -32,80 +31,24 @@ CSSRuleList::CSSRuleList() { } -CSSRuleList::CSSRuleList(CSSStyleSheet* styleSheet, bool omitCharsetRules) - : m_styleSheet(styleSheet) -{ - if (styleSheet && omitCharsetRules) { - m_styleSheet = 0; - for (unsigned i = 0; i < styleSheet->length(); ++i) { - CSSRule* rule = styleSheet->item(i); - if (!rule->isCharsetRule()) - append(static_cast<CSSRule*>(rule)); - } - } -} - CSSRuleList::~CSSRuleList() { } -unsigned CSSRuleList::length() const -{ - return m_styleSheet ? m_styleSheet->length() : m_lstCSSRules.size(); -} - -CSSRule* CSSRuleList::item(unsigned index) const -{ - if (m_styleSheet) - return m_styleSheet->item(index); - - if (index < m_lstCSSRules.size()) - return m_lstCSSRules[index].get(); - return 0; +StaticCSSRuleList::StaticCSSRuleList() + : m_refCount(1) +{ } -void CSSRuleList::deleteRule(unsigned index) +StaticCSSRuleList::~StaticCSSRuleList() { - ASSERT(!m_styleSheet); - - if (index >= m_lstCSSRules.size()) - return; - - m_lstCSSRules.remove(index); } -void CSSRuleList::append(CSSRule* rule) -{ - ASSERT(!m_styleSheet); - - if (!rule) - return; - - m_lstCSSRules.append(rule); -} - -unsigned CSSRuleList::insertRule(CSSRule* rule, unsigned index) -{ - ASSERT(!m_styleSheet); - - if (!rule || index > m_lstCSSRules.size()) - return 0; - - m_lstCSSRules.insert(index, rule); - return index; -} - -String CSSRuleList::rulesText() const -{ - StringBuilder result; - - for (unsigned index = 0; index < length(); ++index) { - result.append(" "); - result.append(item(index)->cssText()); - result.append("\n"); - } - - return result.toString(); +void StaticCSSRuleList::deref() +{ + ASSERT(m_refCount); + if (!--m_refCount) + delete this; } } // namespace WebCore diff --git a/Source/WebCore/css/CSSRuleList.h b/Source/WebCore/css/CSSRuleList.h index ea52c8607..c6e75c86e 100644 --- a/Source/WebCore/css/CSSRuleList.h +++ b/Source/WebCore/css/CSSRuleList.h @@ -1,7 +1,7 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2002, 2006 Apple Computer, Inc. + * Copyright (C) 2002, 2006, 2012 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,37 +33,60 @@ namespace WebCore { class CSSRule; class CSSStyleSheet; -class CSSRuleList : public RefCounted<CSSRuleList> { +class CSSRuleList { + WTF_MAKE_NONCOPYABLE(CSSRuleList); WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<CSSRuleList> create(CSSStyleSheet* styleSheet, bool omitCharsetRules = false) - { - return adoptRef(new CSSRuleList(styleSheet, omitCharsetRules)); - } - static PassRefPtr<CSSRuleList> create() - { - return adoptRef(new CSSRuleList); - } - ~CSSRuleList(); + virtual ~CSSRuleList(); - unsigned length() const; - CSSRule* item(unsigned index) const; + virtual void ref() = 0; + virtual void deref() = 0; - // FIXME: Not part of the CSSOM. Only used by @media and @-webkit-keyframes rules. - unsigned insertRule(CSSRule*, unsigned index); - void deleteRule(unsigned index); + virtual unsigned length() const = 0; + virtual CSSRule* item(unsigned index) const = 0; + + virtual CSSStyleSheet* styleSheet() const = 0; + +protected: + CSSRuleList(); +}; - void append(CSSRule*); +class StaticCSSRuleList : public CSSRuleList { +public: + static PassRefPtr<StaticCSSRuleList> create() { return adoptRef(new StaticCSSRuleList()); } - CSSStyleSheet* styleSheet() { return m_styleSheet.get(); } + virtual void ref() { ++m_refCount; } + virtual void deref(); - String rulesText() const; + Vector<RefPtr<CSSRule> >& rules() { return m_rules; } + + virtual CSSStyleSheet* styleSheet() const { return 0; } -private: - CSSRuleList(); - CSSRuleList(CSSStyleSheet*, bool omitCharsetRules); +private: + StaticCSSRuleList(); + ~StaticCSSRuleList(); - RefPtr<CSSStyleSheet> m_styleSheet; - Vector<RefPtr<CSSRule> > m_lstCSSRules; // FIXME: Want to eliminate, but used by IE rules() extension and still used by media rules. + virtual unsigned length() const { return m_rules.size(); } + virtual CSSRule* item(unsigned index) const { return index < m_rules.size() ? m_rules[index].get() : 0; } + + Vector<RefPtr<CSSRule> > m_rules; + unsigned m_refCount; +}; + +// The rule owns the live list. +template <class Rule> +class LiveCSSRuleList : public CSSRuleList { +public: + LiveCSSRuleList(Rule* rule) : m_rule(rule) { } + + virtual void ref() { m_rule->ref(); } + virtual void deref() { m_rule->deref(); } + +private: + virtual unsigned length() const { return m_rule->length(); } + virtual CSSRule* item(unsigned index) const { return m_rule->item(index); } + virtual CSSStyleSheet* styleSheet() const { return m_rule->parentStyleSheet(); } + + Rule* m_rule; }; } // namespace WebCore diff --git a/Source/WebCore/css/CSSSegmentedFontFace.cpp b/Source/WebCore/css/CSSSegmentedFontFace.cpp index f462c24c4..cf9ec9e2e 100644 --- a/Source/WebCore/css/CSSSegmentedFontFace.cpp +++ b/Source/WebCore/css/CSSSegmentedFontFace.cpp @@ -81,6 +81,23 @@ void CSSSegmentedFontFace::appendFontFace(PassRefPtr<CSSFontFace> fontFace) m_fontFaces.append(fontFace); } +static void appendFontDataWithInvalidUnicodeRangeIfLoading(SegmentedFontData* newFontData, const SimpleFontData* faceFontData, const Vector<CSSFontFace::UnicodeRange>& ranges) +{ + if (faceFontData->isLoading()) { + newFontData->appendRange(FontDataRange(0, 0, faceFontData)); + return; + } + + unsigned numRanges = ranges.size(); + if (!numRanges) { + newFontData->appendRange(FontDataRange(0, 0x7FFFFFFF, faceFontData)); + return; + } + + for (unsigned j = 0; j < numRanges; ++j) + newFontData->appendRange(FontDataRange(ranges[j].from(), ranges[j].to(), faceFontData)); +} + FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription) { if (!isValid()) @@ -89,7 +106,7 @@ FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescripti FontTraitsMask desiredTraitsMask = fontDescription.traitsMask(); unsigned hashKey = ((fontDescription.computedPixelSize() + 1) << (FontTraitsMaskWidth + 1)) | ((fontDescription.orientation() == Vertical ? 1 : 0) << FontTraitsMaskWidth) | desiredTraitsMask; - SegmentedFontData*& fontData = m_fontDataTable.add(hashKey, 0).first->second; + SegmentedFontData*& fontData = m_fontDataTable.add(hashKey, 0).iterator->second; if (fontData) return fontData; @@ -104,14 +121,7 @@ FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescripti bool syntheticItalic = !(traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask); if (const SimpleFontData* faceFontData = m_fontFaces[i]->getFontData(fontDescription, syntheticBold, syntheticItalic)) { ASSERT(!faceFontData->isSegmented()); - const Vector<CSSFontFace::UnicodeRange>& ranges = m_fontFaces[i]->ranges(); - unsigned numRanges = ranges.size(); - if (!numRanges) - newFontData->appendRange(FontDataRange(0, 0x7FFFFFFF, faceFontData)); - else { - for (unsigned j = 0; j < numRanges; ++j) - newFontData->appendRange(FontDataRange(ranges[j].from(), ranges[j].to(), faceFontData)); - } + appendFontDataWithInvalidUnicodeRangeIfLoading(newFontData.get(), faceFontData, m_fontFaces[i]->ranges()); } } if (newFontData->numRanges()) { diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp index aee19f6e9..5bc0ee378 100644 --- a/Source/WebCore/css/CSSSelector.cpp +++ b/Source/WebCore/css/CSSSelector.cpp @@ -43,7 +43,7 @@ void CSSSelector::createRareData() if (m_hasRareData) return; // Move the value to the rare data stucture. - m_data.m_rareData = new RareData(adoptRef(m_data.m_value)); + m_data.m_rareData = RareData::create(adoptRef(m_data.m_value)).leakRef(); m_hasRareData = true; } @@ -150,11 +150,6 @@ PseudoId CSSSelector::pseudoId(PseudoType type) case PseudoAnimatingFullScreenTransition: return ANIMATING_FULL_SCREEN_TRANSITION; #endif - - case PseudoInputListButton: -#if ENABLE(DATALIST) - return INPUT_LIST_BUTTON; -#endif case PseudoUnknown: case PseudoEmpty: case PseudoFirstChild: @@ -252,9 +247,6 @@ static HashMap<AtomicStringImpl*, CSSSelector::PseudoType>* nameToPseudoTypeMap( DEFINE_STATIC_LOCAL(AtomicString, focus, ("focus")); DEFINE_STATIC_LOCAL(AtomicString, hover, ("hover")); DEFINE_STATIC_LOCAL(AtomicString, indeterminate, ("indeterminate")); -#if ENABLE(DATALIST) - DEFINE_STATIC_LOCAL(AtomicString, inputListButton, ("-webkit-input-list-button")); -#endif DEFINE_STATIC_LOCAL(AtomicString, lastChild, ("last-child")); DEFINE_STATIC_LOCAL(AtomicString, lastOfType, ("last-of-type")); DEFINE_STATIC_LOCAL(AtomicString, link, ("link")); @@ -322,9 +314,6 @@ static HashMap<AtomicStringImpl*, CSSSelector::PseudoType>* nameToPseudoTypeMap( nameToPseudoType->set(empty.impl(), CSSSelector::PseudoEmpty); nameToPseudoType->set(firstChild.impl(), CSSSelector::PseudoFirstChild); nameToPseudoType->set(fullPageMedia.impl(), CSSSelector::PseudoFullPageMedia); -#if ENABLE(DATALIST) - nameToPseudoType->set(inputListButton.impl(), CSSSelector::PseudoInputListButton); -#endif nameToPseudoType->set(lastChild.impl(), CSSSelector::PseudoLastChild); nameToPseudoType->set(lastOfType.impl(), CSSSelector::PseudoLastOfType); nameToPseudoType->set(onlyChild.impl(), CSSSelector::PseudoOnlyChild); @@ -413,7 +402,6 @@ void CSSSelector::extractPseudoType() const case PseudoFirstLetter: case PseudoFirstLine: compat = true; - case PseudoInputListButton: case PseudoResizer: case PseudoScrollbar: case PseudoScrollbarCorner: diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h index 112d96cea..2e9e5908f 100644 --- a/Source/WebCore/css/CSSSelector.h +++ b/Source/WebCore/css/CSSSelector.h @@ -33,41 +33,13 @@ namespace WebCore { // this class represents a selector for a StyleRule class CSSSelector { - WTF_MAKE_NONCOPYABLE(CSSSelector); WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_FAST_ALLOCATED; public: - CSSSelector() - : m_relation(Descendant) - , m_match(None) - , m_pseudoType(PseudoNotParsed) - , m_parsedNth(false) - , m_isLastInSelectorList(false) - , m_isLastInTagHistory(true) - , m_hasRareData(false) - , m_isForPage(false) - , m_tag(anyQName()) - { - } - - CSSSelector(const QualifiedName& qName) - : m_relation(Descendant) - , m_match(None) - , m_pseudoType(PseudoNotParsed) - , m_parsedNth(false) - , m_isLastInSelectorList(false) - , m_isLastInTagHistory(true) - , m_hasRareData(false) - , m_isForPage(false) - , m_tag(qName) - { - } + CSSSelector(); + CSSSelector(const QualifiedName&); + CSSSelector(const CSSSelector&); - ~CSSSelector() - { - if (m_hasRareData) - delete m_data.m_rareData; - else if (m_data.m_value) - m_data.m_value->deref(); - } + ~CSSSelector(); /** * Re-create selector text from selector's data @@ -172,7 +144,6 @@ namespace WebCore { PseudoSingleButton, PseudoNoButton, PseudoSelection, - PseudoInputListButton, PseudoLeftPage, PseudoRightPage, PseudoFirstPage, @@ -271,10 +242,11 @@ namespace WebCore { unsigned specificityForPage() const; void extractPseudoType() const; - struct RareData { - WTF_MAKE_NONCOPYABLE(RareData); WTF_MAKE_FAST_ALLOCATED; - public: - RareData(PassRefPtr<AtomicStringImpl> value); + // Hide. + CSSSelector& operator=(const CSSSelector&); + + struct RareData : public RefCounted<RareData> { + static PassRefPtr<RareData> create(PassRefPtr<AtomicStringImpl> value) { return adoptRef(new RareData(value)); } ~RareData(); bool parseNth(); @@ -286,6 +258,9 @@ namespace WebCore { QualifiedName m_attribute; // used for attribute selector AtomicString m_argument; // Used for :contains, :lang and :nth-* OwnPtr<CSSSelectorList> m_selectorList; // Used for :-webkit-any and :not + + private: + RareData(PassRefPtr<AtomicStringImpl> value); }; void createRareData(); @@ -370,6 +345,60 @@ inline void move(PassOwnPtr<CSSSelector> from, CSSSelector* to) fastDeleteSkippingDestructor(from.leakPtr()); } +inline CSSSelector::CSSSelector() + : m_relation(Descendant) + , m_match(None) + , m_pseudoType(PseudoNotParsed) + , m_parsedNth(false) + , m_isLastInSelectorList(false) + , m_isLastInTagHistory(true) + , m_hasRareData(false) + , m_isForPage(false) + , m_tag(anyQName()) +{ +} + +inline CSSSelector::CSSSelector(const QualifiedName& qName) + : m_relation(Descendant) + , m_match(None) + , m_pseudoType(PseudoNotParsed) + , m_parsedNth(false) + , m_isLastInSelectorList(false) + , m_isLastInTagHistory(true) + , m_hasRareData(false) + , m_isForPage(false) + , m_tag(qName) +{ +} + +inline CSSSelector::CSSSelector(const CSSSelector& o) + : m_relation(o.m_relation) + , m_match(o.m_match) + , m_pseudoType(o.m_pseudoType) + , m_parsedNth(o.m_parsedNth) + , m_isLastInSelectorList(o.m_isLastInSelectorList) + , m_isLastInTagHistory(o.m_isLastInTagHistory) + , m_hasRareData(o.m_hasRareData) + , m_isForPage(o.m_isForPage) + , m_tag(o.m_tag) +{ + if (o.m_hasRareData) { + m_data.m_rareData = o.m_data.m_rareData; + m_data.m_rareData->ref(); + } else if (o.m_data.m_value) { + m_data.m_value = o.m_data.m_value; + m_data.m_value->ref(); + } +} + +inline CSSSelector::~CSSSelector() +{ + if (m_hasRareData) + m_data.m_rareData->deref(); + else if (m_data.m_value) + m_data.m_value->deref(); +} + } // namespace WebCore #endif // CSSSelector_h diff --git a/Source/WebCore/css/CSSSelectorList.cpp b/Source/WebCore/css/CSSSelectorList.cpp index 80430537a..fb3d1f12f 100644 --- a/Source/WebCore/css/CSSSelectorList.cpp +++ b/Source/WebCore/css/CSSSelectorList.cpp @@ -37,6 +37,22 @@ CSSSelectorList::~CSSSelectorList() deleteSelectors(); } +CSSSelectorList::CSSSelectorList(const CSSSelectorList& o) +{ + CSSSelector* current = o.m_selectorArray; + while (!current->isLastInSelectorList()) + ++current; + unsigned length = (current - o.m_selectorArray) + 1; + if (length == 1) { + // Destructor expects a single selector to be allocated by new, multiple with fastMalloc. + m_selectorArray = new CSSSelector(o.m_selectorArray[0]); + return; + } + m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * length)); + for (unsigned i = 0; i < length; ++i) + new (&m_selectorArray[i]) CSSSelector(o.m_selectorArray[i]); +} + void CSSSelectorList::adopt(CSSSelectorList& list) { deleteSelectors(); diff --git a/Source/WebCore/css/CSSSelectorList.h b/Source/WebCore/css/CSSSelectorList.h index 7d45a6a54..e0aa65c02 100644 --- a/Source/WebCore/css/CSSSelectorList.h +++ b/Source/WebCore/css/CSSSelectorList.h @@ -33,9 +33,11 @@ namespace WebCore { class CSSParserSelector; class CSSSelectorList { - WTF_MAKE_NONCOPYABLE(CSSSelectorList); WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_FAST_ALLOCATED; public: CSSSelectorList() : m_selectorArray(0) { } + CSSSelectorList(const CSSSelectorList&); + ~CSSSelectorList(); void adopt(CSSSelectorList& list); diff --git a/Source/WebCore/css/CSSStyleDeclaration.h b/Source/WebCore/css/CSSStyleDeclaration.h index 50bcef25e..d52f2495c 100644 --- a/Source/WebCore/css/CSSStyleDeclaration.h +++ b/Source/WebCore/css/CSSStyleDeclaration.h @@ -58,6 +58,7 @@ public: // CSSPropertyID versions of the CSSOM functions to support bindings and editing. // Use the non-virtual methods in the concrete subclasses when possible. + // The CSSValue returned by this function should not be exposed to the web as it may be used by multiple documents at the same time. virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) = 0; virtual String getPropertyValueInternal(CSSPropertyID) = 0; virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&) = 0; diff --git a/Source/WebCore/css/CSSStyleRule.cpp b/Source/WebCore/css/CSSStyleRule.cpp index 65da867c5..7357fcf22 100644 --- a/Source/WebCore/css/CSSStyleRule.cpp +++ b/Source/WebCore/css/CSSStyleRule.cpp @@ -26,30 +26,13 @@ #include "CSSSelector.h" #include "CSSStyleSheet.h" #include "Document.h" +#include "PropertySetCSSStyleDeclaration.h" #include "StylePropertySet.h" #include "StyleRule.h" #include <wtf/text/StringBuilder.h> namespace WebCore { -CSSStyleRule::CSSStyleRule(CSSStyleSheet* parent, int line) - : CSSRule(parent, CSSRule::STYLE_RULE) - , m_styleRule(adoptPtr(new StyleRule(line, this))) -{ -} - -CSSStyleRule::~CSSStyleRule() -{ - if (m_styleRule->properties()) - m_styleRule->properties()->clearParentRule(this); - cleanup(); -} - -CSSStyleDeclaration* CSSStyleRule::style() const -{ - return m_styleRule->properties()->ensureRuleCSSStyleDeclaration(this); -} - typedef HashMap<const CSSStyleRule*, String> SelectorTextCache; static SelectorTextCache& selectorTextCache() { @@ -57,14 +40,30 @@ static SelectorTextCache& selectorTextCache() return cache; } -inline void CSSStyleRule::cleanup() +CSSStyleRule::CSSStyleRule(StyleRule* styleRule, CSSStyleSheet* parent) + : CSSRule(parent, CSSRule::STYLE_RULE) + , m_styleRule(styleRule) +{ +} + +CSSStyleRule::~CSSStyleRule() { + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->clearParentRule(); + if (hasCachedSelectorText()) { selectorTextCache().remove(this); setHasCachedSelectorText(false); } } +CSSStyleDeclaration* CSSStyleRule::style() const +{ + if (!m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_styleRule->properties(), const_cast<CSSStyleRule*>(this)); + return m_propertiesCSSOMWrapper.get(); +} + String CSSStyleRule::generateSelectorText() const { StringBuilder builder; @@ -94,28 +93,25 @@ void CSSStyleRule::setSelectorText(const String& selectorText) { Document* doc = 0; if (CSSStyleSheet* styleSheet = parentStyleSheet()) - doc = styleSheet->findDocument(); + doc = styleSheet->ownerDocument(); if (!doc) return; - CSSParser p; + CSSParser p(parserContext()); CSSSelectorList selectorList; - p.parseSelector(selectorText, doc, selectorList); + p.parseSelector(selectorText, selectorList); if (!selectorList.first()) return; String oldSelectorText = this->selectorText(); - m_styleRule->adoptSelectorList(selectorList); + m_styleRule->wrapperAdoptSelectorList(selectorList); if (hasCachedSelectorText()) { ASSERT(selectorTextCache().contains(this)); selectorTextCache().set(this, generateSelectorText()); } - if (this->selectorText() == oldSelectorText) - return; - - doc->styleSelectorChanged(DeferRecalcStyle); + doc->styleResolverChanged(DeferRecalcStyle); } String CSSStyleRule::cssText() const diff --git a/Source/WebCore/css/CSSStyleRule.h b/Source/WebCore/css/CSSStyleRule.h index c71d53ed2..ae03b5887 100644 --- a/Source/WebCore/css/CSSStyleRule.h +++ b/Source/WebCore/css/CSSStyleRule.h @@ -28,16 +28,14 @@ namespace WebCore { -class CSSSelector; class CSSStyleDeclaration; +class StyleRuleCSSStyleDeclaration; class StyleRule; class CSSStyleRule : public CSSRule { public: - static PassRefPtr<CSSStyleRule> create(CSSStyleSheet* parent, int line) - { - return adoptRef(new CSSStyleRule(parent, line)); - } + static PassRefPtr<CSSStyleRule> create(StyleRule* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSStyleRule(rule, sheet)); } + ~CSSStyleRule(); String selectorText() const; @@ -47,15 +45,17 @@ public: String cssText() const; + // FIXME: Not CSSOM. Remove. StyleRule* styleRule() const { return m_styleRule.get(); } private: - CSSStyleRule(CSSStyleSheet* parent, int sourceLine); + CSSStyleRule(StyleRule*, CSSStyleSheet*); - void cleanup(); String generateSelectorText() const; - OwnPtr<StyleRule> m_styleRule; + RefPtr<StyleRule> m_styleRule; + + mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper; }; } // namespace WebCore diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp index 4cd82af22..3852008db 100644 --- a/Source/WebCore/css/CSSStyleSheet.cpp +++ b/Source/WebCore/css/CSSStyleSheet.cpp @@ -1,6 +1,6 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,9 +21,9 @@ #include "config.h" #include "CSSStyleSheet.h" +#include "CSSCharsetRule.h" #include "CSSFontFaceRule.h" #include "CSSImportRule.h" -#include "CSSNamespace.h" #include "CSSParser.h" #include "CSSRuleList.h" #include "CSSStyleRule.h" @@ -31,15 +31,32 @@ #include "Document.h" #include "ExceptionCode.h" #include "HTMLNames.h" +#include "MediaList.h" #include "Node.h" #include "SVGNames.h" #include "SecurityOrigin.h" +#include "StylePropertySet.h" #include "StyleRule.h" -#include "TextEncoding.h" #include <wtf/Deque.h> namespace WebCore { +class StyleSheetCSSRuleList : public CSSRuleList { +public: + StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { } + +private: + virtual void ref() { m_styleSheet->ref(); } + virtual void deref() { m_styleSheet->deref(); } + + virtual unsigned length() const { return m_styleSheet->length(); } + virtual CSSRule* item(unsigned index) const { return m_styleSheet->item(index); } + + virtual CSSStyleSheet* styleSheet() const { return m_styleSheet; } + + CSSStyleSheet* m_styleSheet; +}; + #if !ASSERT_DISABLED static bool isAcceptableCSSStyleSheetParent(Node* parentNode) { @@ -55,182 +72,290 @@ static bool isAcceptableCSSStyleSheetParent(Node* parentNode) } #endif -CSSStyleSheet::CSSStyleSheet(Node* parentNode, const String& href, const KURL& baseURL, const String& charset) - : StyleSheet(parentNode, href, baseURL) - , m_charset(charset) - , m_loadCompleted(false) - , m_strictParsing(false) - , m_isUserStyleSheet(false) - , m_hasSyntacticallyValidCSSHeader(true) - , m_didLoadErrorOccur(false) +// Rough size estimate for the memory cache. +unsigned StyleSheetInternal::estimatedSizeInBytes() const { - ASSERT(isAcceptableCSSStyleSheetParent(parentNode)); + // Note that this does not take into account size of the strings hanging from various objects. + // The assumption is that nearly all of of them are atomic and would exist anyway. + unsigned size = sizeof(*this); + + // FIXME: This ignores the children of media and region rules. + // Most rules are StyleRules. + size += ruleCount() * StyleRule::averageSizeInBytes(); + + for (unsigned i = 0; i < m_importRules.size(); ++i) { + if (StyleSheetInternal* sheet = m_importRules[i]->styleSheet()) + size += sheet->estimatedSizeInBytes(); + } + return size; } -CSSStyleSheet::CSSStyleSheet(CSSImportRule* ownerRule, const String& href, const KURL& baseURL, const String& charset) - : StyleSheet(ownerRule, href, baseURL) - , m_charset(charset) +StyleSheetInternal::StyleSheetInternal(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const CSSParserContext& context) + : m_ownerRule(ownerRule) + , m_originalURL(originalURL) + , m_finalURL(finalURL) , m_loadCompleted(false) - , m_strictParsing(!ownerRule || ownerRule->useStrictParsing()) + , m_isUserStyleSheet(ownerRule && ownerRule->parentStyleSheet() && ownerRule->parentStyleSheet()->isUserStyleSheet()) , m_hasSyntacticallyValidCSSHeader(true) , m_didLoadErrorOccur(false) + , m_usesRemUnits(false) + , m_hasMutated(false) + , m_parserContext(context) { - CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; - m_isUserStyleSheet = parentSheet ? parentSheet->isUserStyleSheet() : false; } -CSSStyleSheet::~CSSStyleSheet() +StyleSheetInternal::StyleSheetInternal(const StyleSheetInternal& o) + : RefCounted<StyleSheetInternal>() + , m_ownerRule(0) + , m_originalURL(o.m_originalURL) + , m_finalURL(o.m_finalURL) + , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule) + , m_importRules(o.m_importRules.size()) + , m_childRules(o.m_childRules.size()) + , m_namespaces(o.m_namespaces) + , m_loadCompleted(true) + , m_isUserStyleSheet(o.m_isUserStyleSheet) + , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) + , m_didLoadErrorOccur(false) + , m_usesRemUnits(o.m_usesRemUnits) + , m_hasMutated(false) + , m_parserContext(o.m_parserContext) { - // For style rules outside the document, .parentStyleSheet can become null even if the style rule - // is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but - // it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection. - for (unsigned i = 0; i < m_children.size(); ++i) { - ASSERT(m_children.at(i)->parentStyleSheet() == this); - m_children.at(i)->setParentStyleSheet(0); - } + ASSERT(o.isCacheable()); + + // FIXME: Copy import rules. + ASSERT(o.m_importRules.isEmpty()); + + for (unsigned i = 0; i < m_childRules.size(); ++i) + m_childRules[i] = o.m_childRules[i]->copy(); } -void CSSStyleSheet::append(PassRefPtr<CSSRule> child) +StyleSheetInternal::~StyleSheetInternal() { - CSSRule* c = child.get(); - m_children.append(child); - if (c->isImportRule()) - static_cast<CSSImportRule*>(c)->requestStyleSheet(); + clearRules(); } -void CSSStyleSheet::remove(unsigned index) +bool StyleSheetInternal::isCacheable() const { - m_children.remove(index); + // FIXME: Support copying import rules. + if (!m_importRules.isEmpty()) + return false; + // This would require dealing with multiple clients for load callbacks. + if (!m_loadCompleted) + return false; + if (m_didLoadErrorOccur) + return false; + // It is not the original sheet anymore. + if (m_hasMutated) + return false; + // If the header is valid we are not going to need to check the SecurityOrigin. + // FIXME: Valid mime type avoids the check too. + if (!m_hasSyntacticallyValidCSSHeader) + return false; + return true; } -unsigned CSSStyleSheet::insertRule(const String& rule, unsigned index, ExceptionCode& ec) +void StyleSheetInternal::parserAppendRule(PassRefPtr<StyleRuleBase> rule) { - ec = 0; - if (index > m_children.size()) { - ec = INDEX_SIZE_ERR; - return 0; - } - CSSParser p(useStrictParsing()); - RefPtr<CSSRule> r = p.parseRule(this, rule); - - if (!r) { - ec = SYNTAX_ERR; - return 0; + ASSERT(!rule->isCharsetRule()); + if (rule->isImportRule()) { + // Parser enforces that @import rules come before anything else except @charset. + ASSERT(m_childRules.isEmpty()); + m_importRules.append(static_cast<StyleRuleImport*>(rule.get())); + m_importRules.last()->setParentStyleSheet(this); + m_importRules.last()->requestStyleSheet(); + return; } + m_childRules.append(rule); +} - // Throw a HIERARCHY_REQUEST_ERR exception if the rule cannot be inserted at the specified index. The best - // example of this is an @import rule inserted after regular rules. - if (index > 0) { - if (r->isImportRule()) { - // Check all the rules that come before this one to make sure they are only @charset and @import rules. - for (unsigned i = 0; i < index; ++i) { - if (!m_children.at(i)->isCharsetRule() && !m_children.at(i)->isImportRule()) { - ec = HIERARCHY_REQUEST_ERR; - return 0; - } - } - } else if (r->isCharsetRule()) { - // The @charset rule has to come first and there can be only one. - ec = HIERARCHY_REQUEST_ERR; - return 0; - } +PassRefPtr<CSSRule> StyleSheetInternal::createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper) +{ + ASSERT(index < ruleCount()); + + unsigned childVectorIndex = index; + if (hasCharsetRule()) { + if (index == 0) + return CSSCharsetRule::create(parentWrapper, m_encodingFromCharsetRule); + --childVectorIndex; } + if (childVectorIndex < m_importRules.size()) + return m_importRules[childVectorIndex]->createCSSOMWrapper(parentWrapper); + + childVectorIndex -= m_importRules.size(); + return m_childRules[childVectorIndex]->createCSSOMWrapper(parentWrapper); +} - CSSRule* c = r.get(); - m_children.insert(index, r.release()); - if (c->isImportRule()) - static_cast<CSSImportRule*>(c)->requestStyleSheet(); - - styleSheetChanged(); - - return index; +unsigned StyleSheetInternal::ruleCount() const +{ + unsigned result = 0; + result += hasCharsetRule() ? 1 : 0; + result += m_importRules.size(); + result += m_childRules.size(); + return result; } -int CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec) +void StyleSheetInternal::clearCharsetRule() { - insertRule(selector + " { " + style + " }", index, ec); + m_encodingFromCharsetRule = String(); +} - // As per Microsoft documentation, always return -1. - return -1; +void StyleSheetInternal::clearRules() +{ + for (unsigned i = 0; i < m_importRules.size(); ++i) { + ASSERT(m_importRules.at(i)->parentStyleSheet() == this); + m_importRules[i]->clearParentStyleSheet(); + } + m_importRules.clear(); + m_childRules.clear(); + clearCharsetRule(); } -int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec) +void StyleSheetInternal::parserSetEncodingFromCharsetRule(const String& encoding) { - return addRule(selector, style, m_children.size(), ec); + // Parser enforces that there is ever only one @charset. + ASSERT(m_encodingFromCharsetRule.isNull()); + m_encodingFromCharsetRule = encoding; } -PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules(bool omitCharsetRules) +bool StyleSheetInternal::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index) { - KURL url = finalURL(); - Document* document = findDocument(); - if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) - return 0; - return CSSRuleList::create(this, omitCharsetRules); + ASSERT(index <= ruleCount()); + // Parser::parseRule doesn't currently allow @charset so we don't need to deal with it. + ASSERT(!rule->isCharsetRule()); + + unsigned childVectorIndex = index; + // m_childRules does not contain @charset which is always in index 0 if it exists. + if (hasCharsetRule()) { + if (childVectorIndex == 0) { + // Nothing can be inserted before @charset. + return false; + } + --childVectorIndex; + } + + if (childVectorIndex < m_importRules.size() || (childVectorIndex == m_importRules.size() && rule->isImportRule())) { + // Inserting non-import rule before @import is not allowed. + if (!rule->isImportRule()) + return false; + m_importRules.insert(childVectorIndex, static_cast<StyleRuleImport*>(rule.get())); + m_importRules[childVectorIndex]->setParentStyleSheet(this); + m_importRules[childVectorIndex]->requestStyleSheet(); + // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded. + styleSheetChanged(); + return true; + } + // Inserting @import rule after a non-import rule is not allowed. + if (rule->isImportRule()) + return false; + childVectorIndex -= m_importRules.size(); + + m_childRules.insert(childVectorIndex, rule); + + styleSheetChanged(); + return true; } -void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec) +void StyleSheetInternal::wrapperDeleteRule(unsigned index) { - if (index >= m_children.size()) { - ec = INDEX_SIZE_ERR; + ASSERT(index < ruleCount()); + + unsigned childVectorIndex = index; + if (hasCharsetRule()) { + if (childVectorIndex == 0) { + clearCharsetRule(); + styleSheetChanged(); + return; + } + --childVectorIndex; + } + if (childVectorIndex < m_importRules.size()) { + m_importRules[childVectorIndex]->clearParentStyleSheet(); + m_importRules.remove(childVectorIndex); + styleSheetChanged(); return; } + childVectorIndex -= m_importRules.size(); - ec = 0; - m_children.at(index)->setParentStyleSheet(0); - m_children.remove(index); + m_childRules.remove(childVectorIndex); styleSheetChanged(); } -void CSSStyleSheet::addNamespace(CSSParser* p, const AtomicString& prefix, const AtomicString& uri) +void StyleSheetInternal::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri) { - if (uri.isNull()) + if (uri.isNull() || prefix.isNull()) return; - - m_namespaces = adoptPtr(new CSSNamespace(prefix, uri, m_namespaces.release())); - - if (prefix.isEmpty()) - // Set the default namespace on the parser so that selectors that omit namespace info will - // be able to pick it up easily. - p->m_defaultNamespace = uri; + m_namespaces.add(prefix, uri); } -const AtomicString& CSSStyleSheet::determineNamespace(const AtomicString& prefix) +const AtomicString& StyleSheetInternal::determineNamespace(const AtomicString& prefix) { if (prefix.isNull()) return nullAtom; // No namespace. If an element/attribute has a namespace, we won't match it. if (prefix == starAtom) return starAtom; // We'll match any namespace. - if (m_namespaces) { - if (CSSNamespace* namespaceForPrefix = m_namespaces->namespaceForPrefix(prefix)) - return namespaceForPrefix->uri; + PrefixNamespaceURIMap::const_iterator it = m_namespaces.find(prefix); + if (it == m_namespaces.end()) + return nullAtom; + return it->second; +} + +void StyleSheetInternal::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin) +{ + // Check to see if we should enforce the MIME type of the CSS resource in strict mode. + // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748> + bool enforceMIMEType = isStrictParserMode(m_parserContext.mode) && m_parserContext.enforcesCSSMIMETypeInNoQuirksMode; + bool hasValidMIMEType = false; + String sheetText = cachedStyleSheet->sheetText(enforceMIMEType, &hasValidMIMEType); + + CSSParser p(parserContext()); + p.parseSheet(this, sheetText, 0); + + // If we're loading a stylesheet cross-origin, and the MIME type is not standard, require the CSS + // to at least start with a syntactically valid CSS rule. + // This prevents an attacker playing games by injecting CSS strings into HTML, XML, JSON, etc. etc. + if (!hasValidMIMEType && !hasSyntacticallyValidCSSHeader()) { + bool isCrossOriginCSS = !securityOrigin || !securityOrigin->canRequest(finalURL()); + if (isCrossOriginCSS) { + clearRules(); + return; + } + } + if (m_parserContext.needsSiteSpecificQuirks && isStrictParserMode(m_parserContext.mode)) { + // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>. + DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css")); + DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n")); + // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet, + // while the other lacks the second trailing newline. + if (finalURL().string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText) + && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) + clearRules(); } - return nullAtom; // Assume we won't match any namespaces. } -bool CSSStyleSheet::parseString(const String &string, bool strict) +bool StyleSheetInternal::parseString(const String& sheetText) { - return parseStringAtLine(string, strict, 0); + return parseStringAtLine(sheetText, 0); } -bool CSSStyleSheet::parseStringAtLine(const String& string, bool strict, int startLineNumber) +bool StyleSheetInternal::parseStringAtLine(const String& sheetText, int startLineNumber) { - setStrictParsing(strict); - CSSParser p(strict); - p.parseSheet(this, string, startLineNumber); + CSSParser p(parserContext()); + p.parseSheet(this, sheetText, startLineNumber); + return true; } -bool CSSStyleSheet::isLoading() +bool StyleSheetInternal::isLoading() const { - for (unsigned i = 0; i < m_children.size(); ++i) { - CSSRule* rule = m_children.at(i).get(); - if (rule->isImportRule() && static_cast<CSSImportRule*>(rule)->isLoading()) + for (unsigned i = 0; i < m_importRules.size(); ++i) { + if (m_importRules[i]->isLoading()) return true; } return false; } -void CSSStyleSheet::checkLoaded() +void StyleSheetInternal::checkLoaded() { if (isLoading()) return; @@ -238,95 +363,306 @@ void CSSStyleSheet::checkLoaded() // Avoid |this| being deleted by scripts that run via // ScriptableDocumentParser::executeScriptsWaitingForStylesheets(). // See <rdar://problem/6622300>. - RefPtr<CSSStyleSheet> protector(this); - if (CSSStyleSheet* styleSheet = parentStyleSheet()) - styleSheet->checkLoaded(); - - RefPtr<Node> owner = ownerNode(); - if (!owner) + RefPtr<StyleSheetInternal> protector(this); + StyleSheetInternal* parentSheet = parentStyleSheet(); + if (parentSheet) { + parentSheet->checkLoaded(); + m_loadCompleted = true; + return; + } + RefPtr<Node> ownerNode = singleOwnerNode(); + if (!ownerNode) { m_loadCompleted = true; - else { - m_loadCompleted = owner->sheetLoaded(); - if (m_loadCompleted) - owner->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); + return; } + m_loadCompleted = ownerNode->sheetLoaded(); + if (m_loadCompleted) + ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); } -void CSSStyleSheet::notifyLoadedSheet(const CachedCSSStyleSheet* sheet) +void StyleSheetInternal::notifyLoadedSheet(const CachedCSSStyleSheet* sheet) { ASSERT(sheet); m_didLoadErrorOccur |= sheet->errorOccurred(); } -void CSSStyleSheet::startLoadingDynamicSheet() +void StyleSheetInternal::startLoadingDynamicSheet() { - if (Node* owner = ownerNode()) + if (Node* owner = singleOwnerNode()) owner->startLoadingDynamicSheet(); } -Node* CSSStyleSheet::findStyleSheetOwnerNode() const +StyleSheetInternal* StyleSheetInternal::rootStyleSheet() const { - for (const CSSStyleSheet* sheet = this; sheet; sheet = sheet->parentStyleSheet()) { - if (Node* ownerNode = sheet->ownerNode()) - return ownerNode; - } - return 0; + const StyleSheetInternal* root = this; + while (root->parentStyleSheet()) + root = root->parentStyleSheet(); + return const_cast<StyleSheetInternal*>(root); } -Document* CSSStyleSheet::findDocument() +Node* StyleSheetInternal::singleOwnerNode() const { - Node* ownerNode = findStyleSheetOwnerNode(); + StyleSheetInternal* root = rootStyleSheet(); + if (root->m_clients.isEmpty()) + return 0; + ASSERT(root->m_clients.size() == 1); + return root->m_clients[0]->ownerNode(); +} +Document* StyleSheetInternal::singleOwnerDocument() const +{ + Node* ownerNode = singleOwnerNode(); return ownerNode ? ownerNode->document() : 0; } -void CSSStyleSheet::styleSheetChanged() +void StyleSheetInternal::styleSheetChanged() { - CSSStyleSheet* rootSheet = this; - while (CSSStyleSheet* parent = rootSheet->parentStyleSheet()) - rootSheet = parent; + m_hasMutated = true; - /* FIXME: We don't need to do everything updateStyleSelector does, - * basically we just need to recreate the document's selector with the - * already existing style sheets. - */ - if (Document* documentToUpdate = rootSheet->findDocument()) - documentToUpdate->styleSelectorChanged(DeferRecalcStyle); + Document* ownerDocument = singleOwnerDocument(); + if (!ownerDocument) + return; + ownerDocument->styleResolverChanged(DeferRecalcStyle); } -KURL CSSStyleSheet::completeURL(const String& url) const +KURL StyleSheetInternal::completeURL(const String& url) const { - // Always return a null URL when passed a null string. - // FIXME: Should we change the KURL constructor to have this behavior? - // See also Document::completeURL(const String&) - if (url.isNull()) - return KURL(); - if (m_charset.isEmpty()) - return KURL(baseURL(), url); - const TextEncoding encoding = TextEncoding(m_charset); - return KURL(baseURL(), url, encoding); + return CSSParser::completeURL(m_parserContext, url); } -void CSSStyleSheet::addSubresourceStyleURLs(ListHashSet<KURL>& urls) +void StyleSheetInternal::addSubresourceStyleURLs(ListHashSet<KURL>& urls) { - Deque<CSSStyleSheet*> styleSheetQueue; + Deque<StyleSheetInternal*> styleSheetQueue; styleSheetQueue.append(this); while (!styleSheetQueue.isEmpty()) { - CSSStyleSheet* styleSheet = styleSheetQueue.takeFirst(); - - for (unsigned i = 0; i < styleSheet->m_children.size(); ++i) { - CSSRule* rule = styleSheet->m_children.at(i).get(); - if (rule->isImportRule()) { - if (CSSStyleSheet* ruleStyleSheet = static_cast<CSSImportRule*>(rule)->styleSheet()) - styleSheetQueue.append(ruleStyleSheet); - static_cast<CSSImportRule*>(rule)->addSubresourceStyleURLs(urls); - } else if (rule->isFontFaceRule()) - static_cast<CSSFontFaceRule*>(rule)->addSubresourceStyleURLs(urls); - else if (rule->isStyleRule() || rule->isPageRule()) - static_cast<CSSStyleRule*>(rule)->styleRule()->addSubresourceStyleURLs(urls, this); + StyleSheetInternal* styleSheet = styleSheetQueue.takeFirst(); + + for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) { + StyleRuleImport* importRule = styleSheet->m_importRules[i].get(); + if (importRule->styleSheet()) { + styleSheetQueue.append(importRule->styleSheet()); + addSubresourceURL(urls, importRule->styleSheet()->baseURL()); + } + } + for (unsigned i = 0; i < styleSheet->m_childRules.size(); ++i) { + StyleRuleBase* rule = styleSheet->m_childRules[i].get(); + if (rule->isStyleRule()) + static_cast<StyleRule*>(rule)->properties()->addSubresourceStyleURLs(urls, this); + else if (rule->isFontFaceRule()) + static_cast<StyleRuleFontFace*>(rule)->properties()->addSubresourceStyleURLs(urls, this); } } } +StyleSheetInternal* StyleSheetInternal::parentStyleSheet() const +{ + return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; +} + +void StyleSheetInternal::registerClient(CSSStyleSheet* sheet) +{ + ASSERT(!m_clients.contains(sheet)); + m_clients.append(sheet); +} + +void StyleSheetInternal::unregisterClient(CSSStyleSheet* sheet) +{ + size_t position = m_clients.find(sheet); + ASSERT(position != notFound); + m_clients.remove(position); +} + +PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const String& encoding) +{ + CSSParserContext parserContext(ownerNode->document(), baseURL, encoding); + RefPtr<StyleSheetInternal> sheet = StyleSheetInternal::create(baseURL.string(), baseURL, parserContext); + return adoptRef(new CSSStyleSheet(sheet.release(), ownerNode)); +} + +CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetInternal> styleSheet, CSSImportRule* ownerRule) + : m_internal(styleSheet) + , m_isDisabled(false) + , m_ownerNode(0) + , m_ownerRule(ownerRule) +{ + m_internal->registerClient(this); +} + +CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetInternal> styleSheet, Node* ownerNode) + : m_internal(styleSheet) + , m_isDisabled(false) + , m_ownerNode(ownerNode) + , m_ownerRule(0) +{ + ASSERT(isAcceptableCSSStyleSheetParent(ownerNode)); + m_internal->registerClient(this); +} + +CSSStyleSheet::~CSSStyleSheet() +{ + // For style rules outside the document, .parentStyleSheet can become null even if the style rule + // is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but + // it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection. + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->setParentStyleSheet(0); + } + if (m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper->clearParentStyleSheet(); + + m_internal->unregisterClient(this); +} + +void CSSStyleSheet::setDisabled(bool disabled) +{ + if (disabled == m_isDisabled) + return; + m_isDisabled = disabled; + Document* owner = ownerDocument(); + if (owner) + owner->styleResolverChanged(DeferRecalcStyle); +} + +void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) +{ + m_mediaQueries = mediaQueries; +} + +unsigned CSSStyleSheet::length() const +{ + return m_internal->ruleCount(); +} + +CSSRule* CSSStyleSheet::item(unsigned index) +{ + unsigned ruleCount = length(); + if (index >= ruleCount) + return 0; + + if (m_childRuleCSSOMWrappers.isEmpty()) + m_childRuleCSSOMWrappers.grow(ruleCount); + ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount); + + RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index]; + if (!cssRule) + cssRule = m_internal->createChildRuleCSSOMWrapper(index, this); + return cssRule.get(); +} + +PassRefPtr<CSSRuleList> CSSStyleSheet::rules() +{ + KURL url = m_internal->finalURL(); + Document* document = ownerDocument(); + if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) + return 0; + // IE behavior. + RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create(); + unsigned ruleCount = length(); + for (unsigned i = 0; i < ruleCount; ++i) { + CSSRule* rule = item(i); + if (rule->isCharsetRule()) + continue; + nonCharsetRules->rules().append(rule); + } + return nonCharsetRules.release(); +} + +unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec) +{ + ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_internal->ruleCount()); + + ec = 0; + if (index > length()) { + ec = INDEX_SIZE_ERR; + return 0; + } + CSSParser p(m_internal->parserContext()); + RefPtr<StyleRuleBase> rule = p.parseRule(m_internal.get(), ruleString); + + if (!rule) { + ec = SYNTAX_ERR; + return 0; + } + bool success = m_internal->wrapperInsertRule(rule, index); + if (!success) { + ec = HIERARCHY_REQUEST_ERR; + return 0; + } + if (!m_childRuleCSSOMWrappers.isEmpty()) + m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); + return index; +} + +void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec) +{ + ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_internal->ruleCount()); + + ec = 0; + if (index >= length()) { + ec = INDEX_SIZE_ERR; + return; + } + m_internal->wrapperDeleteRule(index); + + if (!m_childRuleCSSOMWrappers.isEmpty()) { + if (m_childRuleCSSOMWrappers[index]) + m_childRuleCSSOMWrappers[index]->setParentStyleSheet(0); + m_childRuleCSSOMWrappers.remove(index); + } +} + +int CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec) +{ + insertRule(selector + " { " + style + " }", index, ec); + + // As per Microsoft documentation, always return -1. + return -1; +} + +int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec) +{ + return addRule(selector, style, length(), ec); +} + + +PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules() +{ + KURL url = m_internal->finalURL(); + Document* document = ownerDocument(); + if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url)) + return 0; + if (!m_ruleListCSSOMWrapper) + m_ruleListCSSOMWrapper = adoptPtr(new StyleSheetCSSRuleList(this)); + return m_ruleListCSSOMWrapper.get(); +} + +MediaList* CSSStyleSheet::media() const +{ + if (!m_mediaQueries) + return 0; + + if (!m_mediaCSSOMWrapper) + m_mediaCSSOMWrapper = MediaList::create(m_mediaQueries.get(), const_cast<CSSStyleSheet*>(this)); + return m_mediaCSSOMWrapper.get(); +} + +CSSStyleSheet* CSSStyleSheet::parentStyleSheet() const +{ + return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; +} + +Document* CSSStyleSheet::ownerDocument() const +{ + const CSSStyleSheet* root = this; + while (root->parentStyleSheet()) + root = root->parentStyleSheet(); + return root->ownerNode() ? root->ownerNode()->document() : 0; +} + +void CSSStyleSheet::clearChildRuleCSSOMWrappers() +{ + m_childRuleCSSOMWrappers.clear(); +} + } diff --git a/Source/WebCore/css/CSSStyleSheet.h b/Source/WebCore/css/CSSStyleSheet.h index e73491918..9bd30578b 100644 --- a/Source/WebCore/css/CSSStyleSheet.h +++ b/Source/WebCore/css/CSSStyleSheet.h @@ -1,6 +1,6 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,117 +21,220 @@ #ifndef CSSStyleSheet_h #define CSSStyleSheet_h -#include "CSSRuleList.h" +#include "CSSParserMode.h" #include "StyleSheet.h" +#include <wtf/HashMap.h> +#include <wtf/text/AtomicStringHash.h> namespace WebCore { -struct CSSNamespace; +class CSSCharsetRule; +class CSSImportRule; class CSSParser; class CSSRule; +class CSSRuleList; +class CSSStyleSheet; class CachedCSSStyleSheet; class CachedResourceLoader; class Document; +class MediaQuerySet; +class SecurityOrigin; +class StyleRuleBase; +class StyleRuleImport; typedef int ExceptionCode; -class CSSStyleSheet : public StyleSheet { +class StyleSheetInternal : public RefCounted<StyleSheetInternal> { public: - static PassRefPtr<CSSStyleSheet> create() - { - return adoptRef(new CSSStyleSheet(static_cast<CSSImportRule*>(0), String(), KURL(), String())); - } - static PassRefPtr<CSSStyleSheet> create(Node* ownerNode) - { - return adoptRef(new CSSStyleSheet(ownerNode, String(), KURL(), String())); - } - static PassRefPtr<CSSStyleSheet> create(Node* ownerNode, const String& originalURL, const KURL& finalURL, const String& charset) - { - return adoptRef(new CSSStyleSheet(ownerNode, originalURL, finalURL, charset)); - } - static PassRefPtr<CSSStyleSheet> create(CSSImportRule* ownerRule, const String& originalURL, const KURL& finalURL, const String& charset) + static PassRefPtr<StyleSheetInternal> create(const CSSParserContext& context = CSSParserContext(CSSStrictMode)) { - return adoptRef(new CSSStyleSheet(ownerRule, originalURL, finalURL, charset)); + return adoptRef(new StyleSheetInternal(0, String(), KURL(), context)); } - static PassRefPtr<CSSStyleSheet> createInline(Node* ownerNode, const KURL& finalURL) + static PassRefPtr<StyleSheetInternal> create(const String& originalURL, const KURL& finalURL, const CSSParserContext& context) { - return adoptRef(new CSSStyleSheet(ownerNode, finalURL.string(), finalURL, String())); + return adoptRef(new StyleSheetInternal(0, originalURL, finalURL, context)); } - - virtual ~CSSStyleSheet(); - - CSSStyleSheet* parentStyleSheet() const + static PassRefPtr<StyleSheetInternal> create(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const CSSParserContext& context) { - StyleSheet* parentSheet = StyleSheet::parentStyleSheet(); - ASSERT(!parentSheet || parentSheet->isCSSStyleSheet()); - return static_cast<CSSStyleSheet*>(parentSheet); + return adoptRef(new StyleSheetInternal(ownerRule, originalURL, finalURL, context)); } - PassRefPtr<CSSRuleList> cssRules(bool omitCharsetRules = false); - unsigned insertRule(const String& rule, unsigned index, ExceptionCode&); - void deleteRule(unsigned index, ExceptionCode&); + ~StyleSheetInternal(); + + const CSSParserContext& parserContext() const { return m_parserContext; } - // IE Extensions - PassRefPtr<CSSRuleList> rules() { return cssRules(true); } - int addRule(const String& selector, const String& style, int index, ExceptionCode&); - int addRule(const String& selector, const String& style, ExceptionCode&); - void removeRule(unsigned index, ExceptionCode& ec) { deleteRule(index, ec); } - - void addNamespace(CSSParser*, const AtomicString& prefix, const AtomicString& uri); const AtomicString& determineNamespace(const AtomicString& prefix); void styleSheetChanged(); - virtual bool parseString(const String&, bool strict = true); + void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*); + bool parseString(const String&); + bool parseStringAtLine(const String&, int startLineNumber); - bool parseStringAtLine(const String&, bool strict, int startLineNumber); + bool isCacheable() const; - virtual bool isLoading(); + bool isLoading() const; void checkLoaded(); void startLoadingDynamicSheet(); - Node* findStyleSheetOwnerNode() const; - Document* findDocument(); + StyleSheetInternal* rootStyleSheet() const; + Node* singleOwnerNode() const; + Document* singleOwnerDocument() const; - const String& charset() const { return m_charset; } + const String& charset() const { return m_parserContext.charset; } bool loadCompleted() const { return m_loadCompleted; } KURL completeURL(const String& url) const; void addSubresourceStyleURLs(ListHashSet<KURL>&); - void setStrictParsing(bool b) { m_strictParsing = b; } - bool useStrictParsing() const { return m_strictParsing; } - void setIsUserStyleSheet(bool b) { m_isUserStyleSheet = b; } bool isUserStyleSheet() const { return m_isUserStyleSheet; } void setHasSyntacticallyValidCSSHeader(bool b) { m_hasSyntacticallyValidCSSHeader = b; } bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; } - void append(PassRefPtr<CSSRule>); - void remove(unsigned index); + void parserAddNamespace(const AtomicString& prefix, const AtomicString& uri); + void parserAppendRule(PassRefPtr<StyleRuleBase>); + void parserSetEncodingFromCharsetRule(const String& encoding); + void parserSetUsesRemUnits(bool b) { m_usesRemUnits = b; } - unsigned length() const { return m_children.size(); } - CSSRule* item(unsigned index) { return index < length() ? m_children.at(index).get() : 0; } + void clearRules(); + + // Rules other than @charset and @import. + const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; } + const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; } void notifyLoadedSheet(const CachedCSSStyleSheet*); + + StyleSheetInternal* parentStyleSheet() const; + StyleRuleImport* ownerRule() const { return m_ownerRule; } + void clearOwnerRule() { m_ownerRule = 0; } + + // Note that href is the URL that started the redirect chain that led to + // this style sheet. This property probably isn't useful for much except + // the JavaScript binding (which needs to use this value for security). + String originalURL() const { return m_originalURL; } + + const KURL& finalURL() const { return m_finalURL; } + const KURL& baseURL() const { return m_parserContext.baseURL; } + + unsigned ruleCount() const; + + bool usesRemUnits() const { return m_usesRemUnits; } + + unsigned estimatedSizeInBytes() const; + + bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index); + void wrapperDeleteRule(unsigned index); + + PassRefPtr<CSSRule> createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper); + + PassRefPtr<StyleSheetInternal> copy() const { return adoptRef(new StyleSheetInternal(*this)); } + + void registerClient(CSSStyleSheet*); + void unregisterClient(CSSStyleSheet*); private: - CSSStyleSheet(Node* ownerNode, const String& originalURL, const KURL& finalURL, const String& charset); - CSSStyleSheet(CSSImportRule* ownerRule, const String& originalURL, const KURL& finalURL, const String& charset); + StyleSheetInternal(StyleRuleImport* ownerRule, const String& originalURL, const KURL& baseURL, const CSSParserContext&); + StyleSheetInternal(const StyleSheetInternal&); - virtual bool isCSSStyleSheet() const { return true; } - virtual String type() const { return "text/css"; } + void clearCharsetRule(); + bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); } + + StyleRuleImport* m_ownerRule; + + String m_originalURL; + KURL m_finalURL; + + String m_encodingFromCharsetRule; + Vector<RefPtr<StyleRuleImport> > m_importRules; + Vector<RefPtr<StyleRuleBase> > m_childRules; + typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap; + PrefixNamespaceURIMap m_namespaces; - Vector<RefPtr<CSSRule> > m_children; - OwnPtr<CSSNamespace> m_namespaces; - String m_charset; bool m_loadCompleted : 1; - bool m_strictParsing : 1; bool m_isUserStyleSheet : 1; bool m_hasSyntacticallyValidCSSHeader : 1; bool m_didLoadErrorOccur : 1; + bool m_usesRemUnits : 1; + bool m_hasMutated : 1; + + CSSParserContext m_parserContext; + + Vector<CSSStyleSheet*> m_clients; +}; + +class CSSStyleSheet : public StyleSheet { +public: + static RefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetInternal> sheet, CSSImportRule* ownerRule = 0) + { + return adoptRef(new CSSStyleSheet(sheet, ownerRule)); + } + static RefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetInternal> sheet, Node* ownerNode) + { + return adoptRef(new CSSStyleSheet(sheet, ownerNode)); + } + static PassRefPtr<CSSStyleSheet> createInline(Node*, const KURL&, const String& encoding = String()); + + virtual ~CSSStyleSheet(); + + virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE; + virtual Node* ownerNode() const OVERRIDE { return m_ownerNode; } + virtual MediaList* media() const OVERRIDE; + virtual String href() const OVERRIDE { return m_internal->originalURL(); } + virtual String title() const OVERRIDE { return m_title; } + virtual bool disabled() const OVERRIDE { return m_isDisabled; } + virtual void setDisabled(bool) OVERRIDE; + + PassRefPtr<CSSRuleList> cssRules(); + unsigned insertRule(const String& rule, unsigned index, ExceptionCode&); + void deleteRule(unsigned index, ExceptionCode&); + + // IE Extensions + PassRefPtr<CSSRuleList> rules(); + int addRule(const String& selector, const String& style, int index, ExceptionCode&); + int addRule(const String& selector, const String& style, ExceptionCode&); + void removeRule(unsigned index, ExceptionCode& ec) { deleteRule(index, ec); } + + // For CSSRuleList. + unsigned length() const; + CSSRule* item(unsigned index); + + virtual void clearOwnerNode() OVERRIDE { m_ownerNode = 0; } + virtual CSSImportRule* ownerRule() const OVERRIDE { return m_ownerRule; } + virtual KURL baseURL() const OVERRIDE { return m_internal->baseURL(); } + virtual bool isLoading() const OVERRIDE { return m_internal->isLoading(); } + + void clearOwnerRule() { m_ownerRule = 0; } + void styleSheetChanged() { m_internal->styleSheetChanged(); } + Document* ownerDocument() const; + MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); } + void setMediaQueries(PassRefPtr<MediaQuerySet>); + void setTitle(const String& title) { m_title = title; } + + void clearChildRuleCSSOMWrappers(); + + StyleSheetInternal* internal() const { return m_internal.get(); } + +private: + CSSStyleSheet(PassRefPtr<StyleSheetInternal>, CSSImportRule* ownerRule); + CSSStyleSheet(PassRefPtr<StyleSheetInternal>, Node* ownerNode); + + virtual bool isCSSStyleSheet() const { return true; } + virtual String type() const { return "text/css"; } + + RefPtr<StyleSheetInternal> m_internal; + bool m_isDisabled; + String m_title; + RefPtr<MediaQuerySet> m_mediaQueries; + + Node* m_ownerNode; + CSSImportRule* m_ownerRule; + + mutable RefPtr<MediaList> m_mediaCSSOMWrapper; + mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers; + mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper; }; } // namespace diff --git a/Source/WebCore/css/CSSTimingFunctionValue.h b/Source/WebCore/css/CSSTimingFunctionValue.h index 9958a8c21..e544c5ff0 100644 --- a/Source/WebCore/css/CSSTimingFunctionValue.h +++ b/Source/WebCore/css/CSSTimingFunctionValue.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,20 +31,7 @@ namespace WebCore { -class CSSTimingFunctionValue : public CSSValue { -public: - bool isLinearTimingFunctionValue() const { return classType() == LinearTimingFunctionClass; } - bool isCubicBezierTimingFunctionValue() const { return classType() == CubicBezierTimingFunctionClass; } - bool isStepsTimingFunctionValue() const { return classType() == StepsTimingFunctionClass; } - -protected: - CSSTimingFunctionValue(ClassType classType) - : CSSValue(classType) - { - } -}; - -class CSSLinearTimingFunctionValue : public CSSTimingFunctionValue { +class CSSLinearTimingFunctionValue : public CSSValue { public: static PassRefPtr<CSSLinearTimingFunctionValue> create() { @@ -55,12 +42,12 @@ public: private: CSSLinearTimingFunctionValue() - : CSSTimingFunctionValue(LinearTimingFunctionClass) + : CSSValue(LinearTimingFunctionClass) { } }; -class CSSCubicBezierTimingFunctionValue : public CSSTimingFunctionValue { +class CSSCubicBezierTimingFunctionValue : public CSSValue { public: static PassRefPtr<CSSCubicBezierTimingFunctionValue> create(double x1, double y1, double x2, double y2) { @@ -76,7 +63,7 @@ public: private: CSSCubicBezierTimingFunctionValue(double x1, double y1, double x2, double y2) - : CSSTimingFunctionValue(CubicBezierTimingFunctionClass) + : CSSValue(CubicBezierTimingFunctionClass) , m_x1(x1) , m_y1(y1) , m_x2(x2) @@ -90,7 +77,7 @@ private: double m_y2; }; -class CSSStepsTimingFunctionValue : public CSSTimingFunctionValue { +class CSSStepsTimingFunctionValue : public CSSValue { public: static PassRefPtr<CSSStepsTimingFunctionValue> create(int steps, bool stepAtStart) { @@ -104,7 +91,7 @@ public: private: CSSStepsTimingFunctionValue(int steps, bool stepAtStart) - : CSSTimingFunctionValue(StepsTimingFunctionClass) + : CSSValue(StepsTimingFunctionClass) , m_steps(steps) , m_stepAtStart(stepAtStart) { diff --git a/Source/WebCore/css/CSSValue.cpp b/Source/WebCore/css/CSSValue.cpp index aea4ee4fd..018a26788 100644 --- a/Source/WebCore/css/CSSValue.cpp +++ b/Source/WebCore/css/CSSValue.cpp @@ -33,11 +33,11 @@ #include "CSSCanvasValue.h" #include "CSSCrossfadeValue.h" #include "CSSCursorImageValue.h" -#include "CSSFlexValue.h" #include "CSSFontFaceSrcValue.h" #include "CSSFunctionValue.h" #include "CSSGradientValue.h" #include "CSSImageGeneratorValue.h" +#include "CSSImageSetValue.h" #include "CSSImageValue.h" #include "CSSInheritedValue.h" #include "CSSInitialValue.h" @@ -59,10 +59,27 @@ namespace WebCore { class SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> { - unsigned char bitfields[2]; + uint32_t bitfields; }; COMPILE_ASSERT(sizeof(CSSValue) == sizeof(SameSizeAsCSSValue), CSS_value_should_stay_small); + +class TextCloneCSSValue : public CSSValue { +public: + static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); } + + String cssText() const { return m_cssText; } + +private: + TextCloneCSSValue(ClassType classType, const String& text) + : CSSValue(classType, /*isCSSOMSafe*/ true) + , m_cssText(text) + { + m_isTextClone = true; + } + + String m_cssText; +}; bool CSSValue::isImplicitInitialValue() const { @@ -82,8 +99,11 @@ CSSValue::Type CSSValue::cssValueType() const return CSS_CUSTOM; } -void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetInternal* styleSheet) { + // This should get called for internal instances only. + ASSERT(!isCSSOMSafe()); + if (isPrimitiveValue()) static_cast<CSSPrimitiveValue*>(this)->addSubresourceStyleURLs(urls, styleSheet); else if (isValueList()) @@ -96,6 +116,12 @@ void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSh String CSSValue::cssText() const { + if (m_isTextClone) { + ASSERT(isCSSOMSafe()); + return static_cast<const TextCloneCSSValue*>(this)->cssText(); + } + ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); + switch (classType()) { case AspectRatioClass: return static_cast<const CSSAspectRatioValue*>(this)->customCssText(); @@ -145,10 +171,12 @@ String CSSValue::cssText() const return static_cast<const WebKitCSSTransformValue*>(this)->customCssText(); case LineBoxContainClass: return static_cast<const CSSLineBoxContainValue*>(this)->customCssText(); - case FlexClass: - return static_cast<const CSSFlexValue*>(this)->customCssText(); case CalculationClass: return static_cast<const CSSCalcValue*>(this)->customCssText(); +#if ENABLE(CSS_IMAGE_SET) + case ImageSetClass: + return static_cast<const CSSImageSetValue*>(this)->customCssText(); +#endif #if ENABLE(CSS_FILTERS) case WebKitCSSFilterClass: return static_cast<const WebKitCSSFilterValue*>(this)->customCssText(); @@ -170,6 +198,13 @@ String CSSValue::cssText() const void CSSValue::destroy() { + if (m_isTextClone) { + ASSERT(isCSSOMSafe()); + delete static_cast<TextCloneCSSValue*>(this); + return; + } + ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM()); + switch (classType()) { case AspectRatioClass: delete static_cast<CSSAspectRatioValue*>(this); @@ -243,12 +278,14 @@ void CSSValue::destroy() case LineBoxContainClass: delete static_cast<CSSLineBoxContainValue*>(this); return; - case FlexClass: - delete static_cast<CSSFlexValue*>(this); - return; case CalculationClass: delete static_cast<CSSCalcValue*>(this); return; +#if ENABLE(CSS_IMAGE_SET) + case ImageSetClass: + delete static_cast<CSSImageSetValue*>(this); + return; +#endif #if ENABLE(CSS_FILTERS) case WebKitCSSFilterClass: delete static_cast<WebKitCSSFilterValue*>(this); @@ -271,4 +308,36 @@ void CSSValue::destroy() ASSERT_NOT_REACHED(); } +PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const +{ + switch (classType()) { + case PrimitiveClass: + return static_cast<const CSSPrimitiveValue*>(this)->cloneForCSSOM(); + case ValueListClass: + return static_cast<const CSSValueList*>(this)->cloneForCSSOM(); + case ImageClass: + case CursorImageClass: + return static_cast<const CSSImageValue*>(this)->cloneForCSSOM(); +#if ENABLE(CSS_FILTERS) + case WebKitCSSFilterClass: + return static_cast<const WebKitCSSFilterValue*>(this)->cloneForCSSOM(); +#endif + case WebKitCSSTransformClass: + return static_cast<const WebKitCSSTransformValue*>(this)->cloneForCSSOM(); +#if ENABLE(CSS_IMAGE_SET) + case ImageSetClass: + return static_cast<const CSSImageSetValue*>(this)->cloneForCSSOM(); +#endif +#if ENABLE(SVG) + case SVGColorClass: + return static_cast<const SVGColor*>(this)->cloneForCSSOM(); + case SVGPaintClass: + return static_cast<const SVGPaint*>(this)->cloneForCSSOM(); +#endif + default: + ASSERT(!isSubtypeExposedToCSSOM()); + return TextCloneCSSValue::create(classType(), cssText()); + } +} + } diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h index 66a5943e0..8207c51ef 100644 --- a/Source/WebCore/css/CSSValue.h +++ b/Source/WebCore/css/CSSValue.h @@ -21,6 +21,7 @@ #ifndef CSSValue_h #define CSSValue_h +#include "ExceptionCode.h" #include "KURLHash.h" #include <wtf/ListHashSet.h> #include <wtf/RefCounted.h> @@ -28,10 +29,13 @@ namespace WebCore { -class CSSStyleSheet; - -typedef int ExceptionCode; +class StyleSheetInternal; + +// FIXME: The current CSSValue and subclasses should be turned into internal types (StyleValue). +// The few subtypes that are actually exposed in CSSOM can be seen in the cloneForCSSOM() function. +// They should be handled by separate wrapper classes. +// Please don't expose more CSSValue types to the web. class CSSValue : public RefCounted<CSSValue> { public: enum Type { @@ -56,7 +60,7 @@ public: String cssText() const; void setCssText(const String&, ExceptionCode&) { } // FIXME: Not implemented. - bool isPrimitiveValue() const { return m_classType <= PrimitiveClass; } + bool isPrimitiveValue() const { return m_classType == PrimitiveClass; } bool isValueList() const { return m_classType >= ValueListClass; } bool isAspectRatioValue() const { return m_classType == AspectRatioClass; } @@ -65,16 +69,20 @@ public: bool isFontFeatureValue() const { return m_classType == FontFeatureClass; } bool isFontValue() const { return m_classType == FontClass; } bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; } +#if ENABLE(CSS_IMAGE_SET) + bool isImageSetValue() const { return m_classType == ImageSetClass; } +#endif bool isImageValue() const { return m_classType == ImageClass || m_classType == CursorImageClass; } bool isImplicitInitialValue() const; bool isInheritedValue() const { return m_classType == InheritedClass; } bool isInitialValue() const { return m_classType == InitialClass; } bool isReflectValue() const { return m_classType == ReflectClass; } bool isShadowValue() const { return m_classType == ShadowClass; } - bool isTimingFunctionValue() const { return m_classType >= CubicBezierTimingFunctionClass && m_classType <= StepsTimingFunctionClass; } + bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; } + bool isLinearTimingFunctionValue() const { return m_classType == LinearTimingFunctionClass; } + bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; } bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; } bool isCSSLineBoxContainValue() const { return m_classType == LineBoxContainClass; } - bool isFlexValue() const { return m_classType == FlexClass; } bool isCalculationValue() const {return m_classType == CalculationClass; } #if ENABLE(CSS_FILTERS) bool isWebKitCSSFilterValue() const { return m_classType == WebKitCSSFilterClass; } @@ -86,17 +94,30 @@ public: bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; } bool isSVGPaint() const { return m_classType == SVGPaintClass; } #endif + + bool isCSSOMSafe() const { return m_isCSSOMSafe; } + bool isSubtypeExposedToCSSOM() const + { + return isPrimitiveValue() +#if ENABLE(SVG) + || isSVGColor() +#endif + || isValueList(); + } - void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + PassRefPtr<CSSValue> cloneForCSSOM() const; + + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetInternal*); protected: static const size_t ClassTypeBits = 5; enum ClassType { - // Primitive class types must appear before PrimitiveClass. + PrimitiveClass, + + // Image classes. ImageClass, CursorImageClass, - PrimitiveClass, // Image generator classes. CanvasClass, @@ -124,7 +145,6 @@ protected: ShadowClass, UnicodeRangeClass, LineBoxContainClass, - FlexClass, CalculationClass, #if ENABLE(CSS_FILTERS) && ENABLE(CSS_SHADERS) WebKitCSSShaderClass, @@ -136,6 +156,9 @@ protected: // List class types must appear after ValueListClass. ValueListClass, +#if ENABLE(CSS_IMAGE_SET) + ImageSetClass, +#endif #if ENABLE(CSS_FILTERS) WebKitCSSFilterClass, #endif @@ -152,8 +175,10 @@ protected: ClassType classType() const { return static_cast<ClassType>(m_classType); } - explicit CSSValue(ClassType classType) - : m_primitiveUnitType(0) + explicit CSSValue(ClassType classType, bool isCSSOMSafe = false) + : m_isCSSOMSafe(isCSSOMSafe) + , m_isTextClone(false) + , m_primitiveUnitType(0) , m_hasCachedCSSText(false) , m_isQuirkValue(false) , m_valueListSeparator(SpaceSeparator) @@ -170,18 +195,20 @@ private: void destroy(); protected: + unsigned m_isCSSOMSafe : 1; + unsigned m_isTextClone : 1; // The bits in this section are only used by specific subclasses but kept here // to maximize struct packing. // CSSPrimitiveValue bits: - unsigned char m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes - mutable bool m_hasCachedCSSText : 1; - bool m_isQuirkValue : 1; + unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes + mutable unsigned m_hasCachedCSSText : 1; + unsigned m_isQuirkValue : 1; - unsigned char m_valueListSeparator : ValueListSeparatorBits; + unsigned m_valueListSeparator : ValueListSeparatorBits; private: - unsigned char m_classType : ClassTypeBits; // ClassType + unsigned m_classType : ClassTypeBits; // ClassType }; } // namespace WebCore diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in index a80581f75..46b4c955a 100644 --- a/Source/WebCore/css/CSSValueKeywords.in +++ b/Source/WebCore/css/CSSValueKeywords.in @@ -19,6 +19,7 @@ dotted dashed solid double + // // CSS_PROP_FONT: // @@ -505,6 +506,14 @@ column-reverse // wrap wrap-reverse +// CSS_PROP_FLEX_LINE_PACK +// start +// end +// center +// justify +// distribute +// stretch + // CSS_PROP_MARQUEE_DIRECTION forwards backwards @@ -611,10 +620,10 @@ button-bevel default-button inner-spin-button -webkit-input-speech-button -list-button listbox listitem -media-fullscreen-button +media-enter-fullscreen-button +media-exit-fullscreen-button media-fullscreen-volume-slider media-fullscreen-volume-slider-thumb media-mute-button @@ -867,9 +876,6 @@ off optimizeQuality -webkit-optimize-contrast -// Positioned Floats --webkit-positioned - // -webkit-wrap-shape nonzero evenodd diff --git a/Source/WebCore/css/CSSValueList.cpp b/Source/WebCore/css/CSSValueList.cpp index 07aa789b0..63773919a 100644 --- a/Source/WebCore/css/CSSValueList.cpp +++ b/Source/WebCore/css/CSSValueList.cpp @@ -136,11 +136,25 @@ String CSSValueList::customCssText() const return result.toString(); } -void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const CSSStyleSheet* styleSheet) +void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetInternal* styleSheet) { size_t size = m_values.size(); for (size_t i = 0; i < size; ++i) m_values[i]->addSubresourceStyleURLs(urls, styleSheet); } +CSSValueList::CSSValueList(const CSSValueList& cloneFrom) + : CSSValue(cloneFrom.classType(), /* isCSSOMSafe */ true) +{ + m_valueListSeparator = cloneFrom.m_valueListSeparator; + m_values.resize(cloneFrom.m_values.size()); + for (unsigned i = 0; i < m_values.size(); ++i) + m_values[i] = cloneFrom.m_values[i]->cloneForCSSOM(); +} + +PassRefPtr<CSSValueList> CSSValueList::cloneForCSSOM() const +{ + return adoptRef(new CSSValueList(*this)); +} + } // namespace WebCore diff --git a/Source/WebCore/css/CSSValueList.h b/Source/WebCore/css/CSSValueList.h index 16d195b0d..3d23a6048 100644 --- a/Source/WebCore/css/CSSValueList.h +++ b/Source/WebCore/css/CSSValueList.h @@ -60,10 +60,13 @@ public: String customCssText() const; - void addSubresourceStyleURLs(ListHashSet<KURL>&, const CSSStyleSheet*); + void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetInternal*); + + PassRefPtr<CSSValueList> cloneForCSSOM() const; protected: CSSValueList(ClassType, ValueListSeparator); + CSSValueList(const CSSValueList& cloneFrom); private: explicit CSSValueList(ValueListSeparator); diff --git a/Source/WebCore/css/CSSValuePool.cpp b/Source/WebCore/css/CSSValuePool.cpp index c46c7047c..ce757b933 100644 --- a/Source/WebCore/css/CSSValuePool.cpp +++ b/Source/WebCore/css/CSSValuePool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,18 @@ #include "CSSValuePool.h" #include "CSSParser.h" +#include "CSSStyleSheet.h" #include "CSSValueKeywords.h" #include "CSSValueList.h" namespace WebCore { +CSSValuePool& cssValuePool() +{ + DEFINE_STATIC_LOCAL(CSSValuePool, pool, ()); + return pool; +} + CSSValuePool::CSSValuePool() : m_inheritedValue(CSSInheritedValue::create()) , m_implicitInitialValue(CSSInitialValue::createImplicit()) @@ -39,13 +46,6 @@ CSSValuePool::CSSValuePool() , m_colorTransparent(CSSPrimitiveValue::createColor(Color::transparent)) , m_colorWhite(CSSPrimitiveValue::createColor(Color::white)) , m_colorBlack(CSSPrimitiveValue::createColor(Color::black)) - , m_pixelZero(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX)) - , m_percentZero(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PERCENTAGE)) - , m_numberZero(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER)) -{ -} - -CSSValuePool::~CSSValuePool() { } @@ -54,11 +54,9 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(int ident) if (ident <= 0 || ident >= numCSSValueKeywords) return CSSPrimitiveValue::createIdentifier(ident); - RefPtr<CSSPrimitiveValue> dummyValue; - pair<IdentifierValueCache::iterator, bool> entry = m_identifierValueCache.add(ident, dummyValue); - if (entry.second) - entry.first->second = CSSPrimitiveValue::createIdentifier(ident); - return entry.first->second; + if (!m_identifierValueCache[ident]) + m_identifierValueCache[ident] = CSSPrimitiveValue::createIdentifier(ident); + return m_identifierValueCache[ident]; } PassRefPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue) @@ -78,69 +76,59 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue) m_colorValueCache.clear(); RefPtr<CSSPrimitiveValue> dummyValue; - pair<ColorValueCache::iterator, bool> entry = m_colorValueCache.add(rgbValue, dummyValue); - if (entry.second) - entry.first->second = CSSPrimitiveValue::createColor(rgbValue); - return entry.first->second; + ColorValueCache::AddResult entry = m_colorValueCache.add(rgbValue, dummyValue); + if (entry.isNewEntry) + entry.iterator->second = CSSPrimitiveValue::createColor(rgbValue); + return entry.iterator->second; } PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimitiveValue::UnitTypes type) { - // Small positive integers repeat often. - static const int maximumCacheableValue = 256; - if (value < 0 || value > maximumCacheableValue) + if (value < 0 || value > maximumCacheableIntegerValue) return CSSPrimitiveValue::create(value, type); int intValue = static_cast<int>(value); if (value != intValue) return CSSPrimitiveValue::create(value, type); - IntegerValueCache* cache; + RefPtr<CSSPrimitiveValue>* cache; switch (type) { case CSSPrimitiveValue::CSS_PX: - if (intValue == 0) - return m_pixelZero; - cache = &m_pixelValueCache; + cache = m_pixelValueCache; break; case CSSPrimitiveValue::CSS_PERCENTAGE: - if (intValue == 0) - return m_percentZero; - cache = &m_percentValueCache; + cache = m_percentValueCache; break; case CSSPrimitiveValue::CSS_NUMBER: - if (intValue == 0) - return m_numberZero; - cache = &m_numberValueCache; + cache = m_numberValueCache; break; default: return CSSPrimitiveValue::create(value, type); } - RefPtr<CSSPrimitiveValue> dummyValue; - pair<IntegerValueCache::iterator, bool> entry = cache->add(intValue, dummyValue); - if (entry.second) - entry.first->second = CSSPrimitiveValue::create(value, type); - return entry.first->second; + if (!cache[intValue]) + cache[intValue] = CSSPrimitiveValue::create(value, type); + return cache[intValue]; } PassRefPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName) { - RefPtr<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).first->second; + RefPtr<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).iterator->second; if (!value) value = CSSPrimitiveValue::create(familyName, CSSPrimitiveValue::CSS_STRING); return value; } -PassRefPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& string, CSSStyleSheet* contextStyleSheet) +PassRefPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& string) { // Just wipe out the cache and start rebuilding if it gets too big. const int maximumFontFaceCacheSize = 128; if (m_fontFaceValueCache.size() > maximumFontFaceCacheSize) m_fontFaceValueCache.clear(); - RefPtr<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).first->second; + RefPtr<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).iterator->second; if (!value) - value = CSSParser::parseFontFaceValue(string, contextStyleSheet); + value = CSSParser::parseFontFaceValue(string); return value; } diff --git a/Source/WebCore/css/CSSValuePool.h b/Source/WebCore/css/CSSValuePool.h index ade9fe066..e2ac9d6b8 100644 --- a/Source/WebCore/css/CSSValuePool.h +++ b/Source/WebCore/css/CSSValuePool.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,6 +29,7 @@ #include "CSSInheritedValue.h" #include "CSSInitialValue.h" #include "CSSPrimitiveValue.h" +#include "CSSValueKeywords.h" #include <wtf/text/AtomicStringHash.h> #include <wtf/HashMap.h> #include <wtf/RefPtr.h> @@ -37,12 +38,9 @@ namespace WebCore { class CSSValueList; -class CSSValuePool : public RefCounted<CSSValuePool> { +class CSSValuePool { public: - static PassRefPtr<CSSValuePool> create() { return adoptRef(new CSSValuePool); } - ~CSSValuePool(); - - PassRefPtr<CSSValueList> createFontFaceValue(const AtomicString&, CSSStyleSheet* contextStyleSheet); + PassRefPtr<CSSValueList> createFontFaceValue(const AtomicString&); PassRefPtr<CSSPrimitiveValue> createFontFamilyValue(const String&); PassRefPtr<CSSInheritedValue> createInheritedValue() { return m_inheritedValue; } PassRefPtr<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue; } @@ -60,8 +58,7 @@ private: RefPtr<CSSInitialValue> m_implicitInitialValue; RefPtr<CSSInitialValue> m_explicitInitialValue; - typedef HashMap<int, RefPtr<CSSPrimitiveValue> > IdentifierValueCache; - IdentifierValueCache m_identifierValueCache; + RefPtr<CSSPrimitiveValue> m_identifierValueCache[numCSSValueKeywords]; typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache; ColorValueCache m_colorValueCache; @@ -69,21 +66,23 @@ private: RefPtr<CSSPrimitiveValue> m_colorWhite; RefPtr<CSSPrimitiveValue> m_colorBlack; - typedef HashMap<int, RefPtr<CSSPrimitiveValue> > IntegerValueCache; - RefPtr<CSSPrimitiveValue> m_pixelZero; - RefPtr<CSSPrimitiveValue> m_percentZero; - RefPtr<CSSPrimitiveValue> m_numberZero; - IntegerValueCache m_pixelValueCache; - IntegerValueCache m_percentValueCache; - IntegerValueCache m_numberValueCache; + static const int maximumCacheableIntegerValue = 255; + + RefPtr<CSSPrimitiveValue> m_pixelValueCache[maximumCacheableIntegerValue + 1]; + RefPtr<CSSPrimitiveValue> m_percentValueCache[maximumCacheableIntegerValue + 1]; + RefPtr<CSSPrimitiveValue> m_numberValueCache[maximumCacheableIntegerValue + 1]; typedef HashMap<AtomicString, RefPtr<CSSValueList> > FontFaceValueCache; FontFaceValueCache m_fontFaceValueCache; typedef HashMap<String, RefPtr<CSSPrimitiveValue> > FontFamilyValueCache; FontFamilyValueCache m_fontFamilyValueCache; + + friend CSSValuePool& cssValuePool(); }; +CSSValuePool& cssValuePool(); + } #endif diff --git a/Source/WebCore/css/CSSWrapShapes.cpp b/Source/WebCore/css/CSSWrapShapes.cpp index fff84b95d..49eb3b88c 100644 --- a/Source/WebCore/css/CSSWrapShapes.cpp +++ b/Source/WebCore/css/CSSWrapShapes.cpp @@ -37,14 +37,14 @@ using namespace WTF; namespace WebCore { -String CSSWrapShapeRect::cssText() const +String CSSWrapShapeRectangle::cssText() const { - DEFINE_STATIC_LOCAL(const String, rectParen, ("rect(")); + DEFINE_STATIC_LOCAL(const String, rectangleParen, ("rectangle(")); DEFINE_STATIC_LOCAL(const String, comma, (", ")); StringBuilder result; result.reserveCapacity(32); - result.append(rectParen); + result.append(rectangleParen); result.append(m_left->cssText()); result.append(comma); @@ -122,6 +122,7 @@ String CSSWrapShapePolygon::cssText() const DEFINE_STATIC_LOCAL(const String, polygonParenEvenOdd, ("polygon(evenodd, ")); DEFINE_STATIC_LOCAL(const String, polygonParenNonZero, ("polygon(nonzero, ")); DEFINE_STATIC_LOCAL(const String, comma, (", ")); + DEFINE_STATIC_LOCAL(const String, space, (" ")); StringBuilder result; result.reserveCapacity(32); @@ -134,9 +135,9 @@ String CSSWrapShapePolygon::cssText() const for (unsigned i = 0; i < m_values.size(); i += 2) { if (i) - result.append(' '); + result.append(comma); result.append(m_values.at(i)->cssText()); - result.append(comma); + result.append(space); result.append(m_values.at(i + 1)->cssText()); } diff --git a/Source/WebCore/css/CSSWrapShapes.h b/Source/WebCore/css/CSSWrapShapes.h index 38487b6db..ca37289e5 100644 --- a/Source/WebCore/css/CSSWrapShapes.h +++ b/Source/WebCore/css/CSSWrapShapes.h @@ -41,7 +41,7 @@ namespace WebCore { class CSSWrapShape : public RefCounted<CSSWrapShape> { public: enum Type { - CSS_WRAP_SHAPE_RECT = 1, + CSS_WRAP_SHAPE_RECTANGLE = 1, CSS_WRAP_SHAPE_CIRCLE = 2, CSS_WRAP_SHAPE_ELLIPSE = 3, CSS_WRAP_SHAPE_POLYGON = 4, @@ -58,9 +58,9 @@ protected: CSSWrapShape() { } }; -class CSSWrapShapeRect : public CSSWrapShape { +class CSSWrapShapeRectangle : public CSSWrapShape { public: - static PassRefPtr<CSSWrapShapeRect> create() { return adoptRef(new CSSWrapShapeRect); } + static PassRefPtr<CSSWrapShapeRectangle> create() { return adoptRef(new CSSWrapShapeRectangle); } CSSPrimitiveValue* left() const { return m_left.get(); } CSSPrimitiveValue* top() const { return m_top.get(); } @@ -76,11 +76,11 @@ public: void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; } void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; } - virtual Type type() { return CSS_WRAP_SHAPE_RECT; } + virtual Type type() { return CSS_WRAP_SHAPE_RECTANGLE; } virtual String cssText() const; private: - CSSWrapShapeRect() { } + CSSWrapShapeRectangle() { } RefPtr<CSSPrimitiveValue> m_top; RefPtr<CSSPrimitiveValue> m_left; diff --git a/Source/WebCore/css/Counter.h b/Source/WebCore/css/Counter.h index c5c8176aa..bd3a078a9 100644 --- a/Source/WebCore/css/Counter.h +++ b/Source/WebCore/css/Counter.h @@ -42,6 +42,13 @@ public: void setIdentifier(PassRefPtr<CSSPrimitiveValue> identifier) { m_identifier = identifier; } void setListStyle(PassRefPtr<CSSPrimitiveValue> listStyle) { m_listStyle = listStyle; } void setSeparator(PassRefPtr<CSSPrimitiveValue> separator) { m_separator = separator; } + + PassRefPtr<Counter> cloneForCSSOM() const + { + return create(m_identifier ? m_identifier->cloneForCSSOM() : 0 + , m_listStyle ? m_listStyle->cloneForCSSOM() : 0 + , m_separator ? m_separator->cloneForCSSOM() : 0); + } private: Counter(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle, PassRefPtr<CSSPrimitiveValue> separator) diff --git a/Source/WebCore/css/LengthFunctions.cpp b/Source/WebCore/css/LengthFunctions.cpp new file mode 100644 index 000000000..730a7c97c --- /dev/null +++ b/Source/WebCore/css/LengthFunctions.cpp @@ -0,0 +1,184 @@ +/* + Copyright (C) 1999 Lars Knoll (knoll@kde.org) + Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com) + Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. + Copyright (C) 2012 Motorola Mobility, Inc. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "LengthFunctions.h" + +#include "Length.h" +#include "RenderView.h" + +namespace WebCore { + +int minimumIntValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages) +{ + return static_cast<int>(minimumValueForLength(length, maximumValue, renderView, roundPercentages)); +} + +int intValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages) +{ + return static_cast<int>(valueForLength(length, maximumValue, renderView, roundPercentages)); +} + +LayoutUnit minimumValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages) +{ + switch (length.type()) { + case Fixed: + return length.value(); + case Percent: + if (roundPercentages) + return static_cast<LayoutUnit>(round(maximumValue * length.percent() / 100.0f)); + // Don't remove the extra cast to float. It is needed for rounding on 32-bit Intel machines that use the FPU stack. + return static_cast<LayoutUnit>(static_cast<float>(maximumValue * length.percent() / 100.0f)); + case Calculated: + return length.nonNanCalculatedValue(maximumValue); + case ViewportPercentageWidth: + if (renderView) + return static_cast<LayoutUnit>(renderView->viewportSize().width() * length.viewportPercentageLength() / 100.0f); + return ZERO_LAYOUT_UNIT; + case ViewportPercentageHeight: + if (renderView) + return static_cast<LayoutUnit>(renderView->viewportSize().height() * length.viewportPercentageLength() / 100.0f); + return ZERO_LAYOUT_UNIT; + case ViewportPercentageMin: + if (renderView) { + IntSize viewportSize = renderView->viewportSize(); + return static_cast<LayoutUnit>(std::min(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f); + } + return ZERO_LAYOUT_UNIT; + case Auto: + return ZERO_LAYOUT_UNIT; + case Relative: + case Intrinsic: + case MinIntrinsic: + case Undefined: + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; + } + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; +} + +LayoutUnit valueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages) +{ + switch (length.type()) { + case Fixed: + case Percent: + case Calculated: + case ViewportPercentageWidth: + case ViewportPercentageHeight: + case ViewportPercentageMin: + return minimumValueForLength(length, maximumValue, renderView, roundPercentages); + case Auto: + return maximumValue; + // multiple assertions are used below to provide more useful debug output. + case Relative: + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; + case Intrinsic: + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; + case MinIntrinsic: + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; + case Undefined: + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; + } + ASSERT_NOT_REACHED(); + return ZERO_LAYOUT_UNIT; +} + +// FIXME: when subpixel layout is supported this copy of floatValueForLength() can be removed. See bug 71143. +float floatValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView) +{ + switch (length.type()) { + case Fixed: + return length.getFloatValue(); + case Percent: + return static_cast<float>(maximumValue * length.percent() / 100.0f); + case Auto: + return static_cast<float>(maximumValue); + case Calculated: + return length.nonNanCalculatedValue(maximumValue); + case ViewportPercentageWidth: + if (renderView) + return static_cast<int>(renderView->viewportSize().width() * length.viewportPercentageLength() / 100.0f); + return 0; + case ViewportPercentageHeight: + if (renderView) + return static_cast<int>(renderView->viewportSize().height() * length.viewportPercentageLength() / 100.0f); + return 0; + case ViewportPercentageMin: + if (renderView) { + IntSize viewportSize = renderView->viewportSize(); + return static_cast<int>(std::min(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f); + } + return 0; + case Relative: + case Intrinsic: + case MinIntrinsic: + case Undefined: + ASSERT_NOT_REACHED(); + return 0; + } + ASSERT_NOT_REACHED(); + return 0; +} + +float floatValueForLength(const Length& length, float maximumValue, RenderView* renderView) +{ + switch (length.type()) { + case Fixed: + return length.getFloatValue(); + case Percent: + return static_cast<float>(maximumValue * length.percent() / 100.0f); + case Auto: + return static_cast<float>(maximumValue); + case Calculated: + return length.nonNanCalculatedValue(maximumValue); + case ViewportPercentageWidth: + if (renderView) + return static_cast<int>(renderView->viewportSize().width() * length.viewportPercentageLength() / 100.0f); + return 0; + case ViewportPercentageHeight: + if (renderView) + return static_cast<int>(renderView->viewportSize().height() * length.viewportPercentageLength() / 100.0f); + return 0; + case ViewportPercentageMin: + if (renderView) { + IntSize viewportSize = renderView->viewportSize(); + return static_cast<int>(std::min(viewportSize.width(), viewportSize.height()) * length.viewportPercentageLength() / 100.0f); + } + return 0; + case Relative: + case Intrinsic: + case MinIntrinsic: + case Undefined: + ASSERT_NOT_REACHED(); + return 0; + } + ASSERT_NOT_REACHED(); + return 0; +} + +} // namespace WebCore diff --git a/Source/WebCore/css/LengthFunctions.h b/Source/WebCore/css/LengthFunctions.h new file mode 100644 index 000000000..76c28caff --- /dev/null +++ b/Source/WebCore/css/LengthFunctions.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 1999 Lars Knoll (knoll@kde.org) + Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com) + Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. + Copyright (C) 2012 Motorola Mobility, Inc. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef LengthFunctions_h +#define LengthFunctions_h + +#include "LayoutTypes.h" + +namespace WebCore { + +class RenderView; +struct Length; + +int minimumIntValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false); +int intValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false); +LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false); +LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false); +float floatValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0); +float floatValueForLength(const Length&, float maximumValue, RenderView* = 0); + +} // namespace WebCore + +#endif // LengthFunctions_h diff --git a/Source/WebCore/css/MediaList.cpp b/Source/WebCore/css/MediaList.cpp index e4650c842..57c6eaa1a 100644 --- a/Source/WebCore/css/MediaList.cpp +++ b/Source/WebCore/css/MediaList.cpp @@ -1,6 +1,6 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2006, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2010, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -32,7 +32,7 @@ namespace WebCore { /* MediaList is used to store 3 types of media related entities which mean the same: * Media Queries, Media Types and Media Descriptors. * Currently MediaList always tries to parse media queries and if parsing fails, - * tries to fallback to Media Descriptors if m_fallback flag is set. + * tries to fallback to Media Descriptors if m_fallbackToDescriptor flag is set. * Slight problem with syntax error handling: * CSS 2.1 Spec (http://www.w3.org/TR/CSS21/media.html) * specifies that failing media type parsing is a syntax error @@ -56,21 +56,18 @@ namespace WebCore { * document.styleSheets[0].cssRules[0].media.mediaText = "screen and resolution > 40dpi" will * throw SYNTAX_ERR exception. */ - -MediaList::MediaList(CSSStyleSheet* parentStyleSheet, bool fallbackToDescriptor) - : m_fallback(fallbackToDescriptor) - , m_parentStyleSheet(parentStyleSheet) + +MediaQuerySet::MediaQuerySet() + : m_fallbackToDescriptor(false) , m_lastLine(0) { } -MediaList::MediaList(CSSStyleSheet* parentStyleSheet, const String& media, bool fallbackToDescriptor) - : m_fallback(fallbackToDescriptor) - , m_parentStyleSheet(parentStyleSheet) +MediaQuerySet::MediaQuerySet(const String& mediaString, bool fallbackToDescriptor) + : m_fallbackToDescriptor(fallbackToDescriptor) , m_lastLine(0) { - ExceptionCode ec = 0; - setMediaText(media, ec); + bool success = parse(mediaString); // FIXME: parsing can fail. The problem with failing constructor is that // we would need additional flag saying MediaList is not valid // Parse can fail only when fallbackToDescriptor == false, i.e when HTML4 media descriptor @@ -79,78 +76,129 @@ MediaList::MediaList(CSSStyleSheet* parentStyleSheet, const String& media, bool // for both html and svg, even though svg:style doesn't use media descriptors // Currently the only places where parsing can fail are // creating <svg:style>, creating css media / import rules from js - if (ec) - setMediaText("invalid", ec); + + // FIXME: This doesn't make much sense. + if (!success) + parse("invalid"); } -MediaList::~MediaList() +MediaQuerySet::MediaQuerySet(const MediaQuerySet& o) + : RefCounted<MediaQuerySet>() + , m_fallbackToDescriptor(o.m_fallbackToDescriptor) + , m_lastLine(o.m_lastLine) + , m_queries(o.m_queries.size()) { - deleteAllValues(m_queries); + for (unsigned i = 0; i < m_queries.size(); ++i) + m_queries[i] = o.m_queries[i]->copy(); } -static String parseMediaDescriptor(const String& s) +MediaQuerySet::~MediaQuerySet() { - int len = s.length(); +} +static String parseMediaDescriptor(const String& string) +{ // http://www.w3.org/TR/REC-html40/types.html#type-media-descriptors // "Each entry is truncated just before the first character that isn't a // US ASCII letter [a-zA-Z] (ISO 10646 hex 41-5a, 61-7a), digit [0-9] (hex 30-39), // or hyphen (hex 2d)." - int i; - unsigned short c; - for (i = 0; i < len; ++i) { - c = s[i]; + unsigned length = string.length(); + unsigned i = 0; + for (; i < length; ++i) { + unsigned short c = string[i]; if (! ((c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || (c >= '1' && c <= '9') - || (c == '-'))) + || (c >= 'A' && c <= 'Z') + || (c >= '1' && c <= '9') + || (c == '-'))) break; } - return s.left(i); + return string.left(i); } -void MediaList::deleteMedium(const String& oldMedium, ExceptionCode& ec) +bool MediaQuerySet::parse(const String& mediaString) { - RefPtr<MediaList> tempMediaList = MediaList::create(); - CSSParser p(true); + CSSParser parser(CSSStrictMode); + + Vector<OwnPtr<MediaQuery> > result; + Vector<String> list; + mediaString.split(',', list); + for (unsigned i = 0; i < list.size(); ++i) { + String medium = list[i].stripWhiteSpace(); + if (medium.isEmpty()) { + if (!m_fallbackToDescriptor) + return false; + continue; + } + OwnPtr<MediaQuery> mediaQuery = parser.parseMediaQuery(medium); + if (!mediaQuery) { + if (!m_fallbackToDescriptor) + return false; + String mediaDescriptor = parseMediaDescriptor(medium); + if (mediaDescriptor.isNull()) + continue; + mediaQuery = adoptPtr(new MediaQuery(MediaQuery::None, mediaDescriptor, nullptr)); + } + result.append(mediaQuery.release()); + } + // ",,,," falls straight through, but is not valid unless fallback + if (!m_fallbackToDescriptor && list.isEmpty()) { + String strippedMediaString = mediaString.stripWhiteSpace(); + if (!strippedMediaString.isEmpty()) + return false; + } + m_queries.swap(result); + return true; +} - MediaQuery* oldQuery = 0; - OwnPtr<MediaQuery> createdQuery; +bool MediaQuerySet::add(const String& queryString) +{ + CSSParser parser(CSSStrictMode); - if (p.parseMediaQuery(tempMediaList.get(), oldMedium)) { - if (tempMediaList->m_queries.size() > 0) - oldQuery = tempMediaList->m_queries[0]; - } else if (m_fallback) { - String medium = parseMediaDescriptor(oldMedium); - if (!medium.isNull()) { - createdQuery = adoptPtr(new MediaQuery(MediaQuery::None, medium, nullptr)); - oldQuery = createdQuery.get(); - } + OwnPtr<MediaQuery> parsedQuery = parser.parseMediaQuery(queryString); + if (!parsedQuery && m_fallbackToDescriptor) { + String medium = parseMediaDescriptor(queryString); + if (!medium.isNull()) + parsedQuery = adoptPtr(new MediaQuery(MediaQuery::None, medium, nullptr)); } + if (!parsedQuery) + return false; - // DOM Style Sheets spec doesn't allow SYNTAX_ERR to be thrown in deleteMedium - ec = NOT_FOUND_ERR; - - if (oldQuery) { - for (size_t i = 0; i < m_queries.size(); ++i) { - MediaQuery* a = m_queries[i]; - if (*a == *oldQuery) { - m_queries.remove(i); - delete a; - ec = 0; - break; - } + m_queries.append(parsedQuery.release()); + return true; +} + +bool MediaQuerySet::remove(const String& queryStringToRemove) +{ + CSSParser parser(CSSStrictMode); + + OwnPtr<MediaQuery> parsedQuery = parser.parseMediaQuery(queryStringToRemove); + if (!parsedQuery && m_fallbackToDescriptor) { + String medium = parseMediaDescriptor(queryStringToRemove); + if (!medium.isNull()) + parsedQuery = adoptPtr(new MediaQuery(MediaQuery::None, medium, nullptr)); + } + if (!parsedQuery) + return false; + + for (size_t i = 0; i < m_queries.size(); ++i) { + MediaQuery* query = m_queries[i].get(); + if (*query == *parsedQuery) { + m_queries.remove(i); + return true; } } + return false; +} - if (!ec) - notifyChanged(); +void MediaQuerySet::addMediaQuery(PassOwnPtr<MediaQuery> mediaQuery) +{ + m_queries.append(mediaQuery); } -String MediaList::mediaText() const +String MediaQuerySet::mediaText() const { String text(""); - + bool first = true; for (size_t i = 0; i < m_queries.size(); ++i) { if (!first) @@ -159,91 +207,72 @@ String MediaList::mediaText() const first = false; text += m_queries[i]->cssText(); } - return text; } + +MediaList::MediaList(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet) + : m_mediaQueries(mediaQueries) + , m_parentStyleSheet(parentSheet) + , m_parentRule(0) +{ +} -void MediaList::setMediaText(const String& value, ExceptionCode& ec) +MediaList::MediaList(MediaQuerySet* mediaQueries, CSSRule* parentRule) + : m_mediaQueries(mediaQueries) + , m_parentStyleSheet(0) + , m_parentRule(parentRule) { - RefPtr<MediaList> tempMediaList = MediaList::create(); - CSSParser p(true); +} - Vector<String> list; - value.split(',', list); - Vector<String>::const_iterator end = list.end(); - for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) { - String medium = (*it).stripWhiteSpace(); - if (!medium.isEmpty()) { - if (!p.parseMediaQuery(tempMediaList.get(), medium)) { - if (m_fallback) { - String mediaDescriptor = parseMediaDescriptor(medium); - if (!mediaDescriptor.isNull()) - tempMediaList->m_queries.append(new MediaQuery(MediaQuery::None, mediaDescriptor, nullptr)); - } else { - ec = SYNTAX_ERR; - return; - } - } - } else if (!m_fallback) { - ec = SYNTAX_ERR; - return; - } - } - // ",,,," falls straight through, but is not valid unless fallback - if (!m_fallback && list.begin() == list.end()) { - String s = value.stripWhiteSpace(); - if (!s.isEmpty()) { - ec = SYNTAX_ERR; - return; - } - } +MediaList::~MediaList() +{ +} - ec = 0; - deleteAllValues(m_queries); - m_queries = tempMediaList->m_queries; - tempMediaList->m_queries.clear(); +void MediaList::setMediaText(const String& value, ExceptionCode& ec) +{ + bool success = m_mediaQueries->parse(value); + if (!success) { + ec = SYNTAX_ERR; + return; + } notifyChanged(); } String MediaList::item(unsigned index) const { - if (index < m_queries.size()) { - MediaQuery* query = m_queries[index]; - return query->cssText(); - } - + const Vector<OwnPtr<MediaQuery> >& queries = m_mediaQueries->queryVector(); + if (index < queries.size()) + return queries[index]->cssText(); return String(); } -void MediaList::appendMedium(const String& newMedium, ExceptionCode& ec) +void MediaList::deleteMedium(const String& medium, ExceptionCode& ec) { - ec = INVALID_CHARACTER_ERR; - CSSParser p(true); - if (p.parseMediaQuery(this, newMedium)) { - ec = 0; - } else if (m_fallback) { - String medium = parseMediaDescriptor(newMedium); - if (!medium.isNull()) { - m_queries.append(new MediaQuery(MediaQuery::None, medium, nullptr)); - ec = 0; - } + bool success = m_mediaQueries->remove(medium); + if (!success) { + ec = NOT_FOUND_ERR; + return; } - - if (!ec) - notifyChanged(); + notifyChanged(); } -void MediaList::appendMediaQuery(PassOwnPtr<MediaQuery> mediaQuery) +void MediaList::appendMedium(const String& medium, ExceptionCode& ec) { - m_queries.append(mediaQuery.leakPtr()); + bool success = m_mediaQueries->add(medium); + if (!success) { + // FIXME: Should this really be INVALID_CHARACTER_ERR? + ec = INVALID_CHARACTER_ERR; + return; + } + notifyChanged(); } void MediaList::notifyChanged() { - if (!m_parentStyleSheet) + CSSStyleSheet* parentStyleSheet = m_parentRule ? m_parentRule->parentStyleSheet() : m_parentStyleSheet; + if (!parentStyleSheet) return; - - m_parentStyleSheet->styleSheetChanged(); + parentStyleSheet->styleSheetChanged(); } } diff --git a/Source/WebCore/css/MediaList.h b/Source/WebCore/css/MediaList.h index a0e0fca01..88bdca242 100644 --- a/Source/WebCore/css/MediaList.h +++ b/Source/WebCore/css/MediaList.h @@ -1,6 +1,6 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,80 +21,99 @@ #ifndef MediaList_h #define MediaList_h +#include "ExceptionCode.h" #include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { -class CSSImportRule; class CSSRule; class CSSStyleSheet; +class MediaList; class MediaQuery; -typedef int ExceptionCode; - -class MediaList : public RefCounted<MediaList> { +class MediaQuerySet : public RefCounted<MediaQuerySet> { public: - static PassRefPtr<MediaList> create() + static PassRefPtr<MediaQuerySet> create() { - return adoptRef(new MediaList(0, false)); + return adoptRef(new MediaQuerySet()); } - static PassRefPtr<MediaList> create(CSSStyleSheet* parentSheet, const String& media) + static PassRefPtr<MediaQuerySet> create(const String& mediaString) { - return adoptRef(new MediaList(parentSheet, media, false)); + return adoptRef(new MediaQuerySet(mediaString, false)); } - - static PassRefPtr<MediaList> createAllowingDescriptionSyntax(const String& mediaQueryOrDescription) + static PassRefPtr<MediaQuerySet> createAllowingDescriptionSyntax(const String& mediaString) { - return adoptRef(new MediaList(0, mediaQueryOrDescription, true)); + return adoptRef(new MediaQuerySet(mediaString, true)); } - static PassRefPtr<MediaList> createAllowingDescriptionSyntax(CSSStyleSheet* parentSheet, const String& mediaQueryOrDescription) + ~MediaQuerySet(); + + bool parse(const String&); + bool add(const String&); + bool remove(const String&); + + void addMediaQuery(PassOwnPtr<MediaQuery>); + + const Vector<OwnPtr<MediaQuery> >& queryVector() const { return m_queries; } + + int lastLine() const { return m_lastLine; } + void setLastLine(int lastLine) { m_lastLine = lastLine; } + + String mediaText() const; + + PassRefPtr<MediaQuerySet> copy() const { return adoptRef(new MediaQuerySet(*this)); } + +private: + MediaQuerySet(); + MediaQuerySet(const String& mediaQuery, bool fallbackToDescription); + MediaQuerySet(const MediaQuerySet&); + + unsigned m_fallbackToDescriptor : 1; // true if failed media query parsing should fallback to media description parsing. + signed m_lastLine : 31; + Vector<OwnPtr<MediaQuery> > m_queries; +}; + +class MediaList : public RefCounted<MediaList> { +public: + static PassRefPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet) { - return adoptRef(new MediaList(parentSheet, mediaQueryOrDescription, true)); + return adoptRef(new MediaList(mediaQueries, parentSheet)); } - - static PassRefPtr<MediaList> create(const String& media, bool allowDescriptionSyntax) + static PassRefPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSRule* parentRule) { - return adoptRef(new MediaList(0, media, allowDescriptionSyntax)); + return adoptRef(new MediaList(mediaQueries, parentRule)); } ~MediaList(); - unsigned length() const { return m_queries.size(); } + unsigned length() const { return m_mediaQueries->queryVector().size(); } String item(unsigned index) const; void deleteMedium(const String& oldMedium, ExceptionCode&); void appendMedium(const String& newMedium, ExceptionCode&); - String mediaText() const; - void setMediaText(const String&, ExceptionCode&xo); - - void appendMediaQuery(PassOwnPtr<MediaQuery>); - const Vector<MediaQuery*>& mediaQueries() const { return m_queries; } + String mediaText() const { return m_mediaQueries->mediaText(); } + void setMediaText(const String&, ExceptionCode&); + // Not part of CSSOM. + CSSRule* parentRule() const { return m_parentRule; } CSSStyleSheet* parentStyleSheet() const { return m_parentStyleSheet; } - void setParentStyleSheet(CSSStyleSheet* styleSheet) - { - // MediaList should never be moved between style sheets. - ASSERT(styleSheet == m_parentStyleSheet || !m_parentStyleSheet || !styleSheet); - m_parentStyleSheet = styleSheet; - } - - int lastLine() const { return m_lastLine; } - void setLastLine(int lastLine) { m_lastLine = lastLine; } + void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = 0; } + void clearParentRule() { ASSERT(m_parentRule); m_parentRule = 0; } + const MediaQuerySet* queries() const { return m_mediaQueries.get(); } private: - MediaList(CSSStyleSheet* parentSheet, bool fallbackToDescription); - MediaList(CSSStyleSheet* parentSheet, const String& media, bool fallbackToDescription); + MediaList(); + MediaList(MediaQuerySet*, CSSStyleSheet* parentSheet); + MediaList(MediaQuerySet*, CSSRule* parentRule); void notifyChanged(); - bool m_fallback; // true if failed media query parsing should fallback to media description parsing. - + RefPtr<MediaQuerySet> m_mediaQueries; CSSStyleSheet* m_parentStyleSheet; - Vector<MediaQuery*> m_queries; - int m_lastLine; + CSSRule* m_parentRule; }; } // namespace diff --git a/Source/WebCore/css/MediaQuery.cpp b/Source/WebCore/css/MediaQuery.cpp index 8fa5820df..704c00a59 100644 --- a/Source/WebCore/css/MediaQuery.cpp +++ b/Source/WebCore/css/MediaQuery.cpp @@ -103,6 +103,17 @@ MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtr<Vector< } } +MediaQuery::MediaQuery(const MediaQuery& o) + : m_restrictor(o.m_restrictor) + , m_mediaType(o.m_mediaType) + , m_expressions(adoptPtr(new Vector<OwnPtr<MediaQueryExp> >(o.m_expressions->size()))) + , m_ignored(o.m_ignored) + , m_serializationCache(o.m_serializationCache) +{ + for (unsigned i = 0; i < m_expressions->size(); ++i) + (*m_expressions)[i] = o.m_expressions->at(i)->copy(); +} + MediaQuery::~MediaQuery() { } diff --git a/Source/WebCore/css/MediaQuery.h b/Source/WebCore/css/MediaQuery.h index cb14154df..398e84527 100644 --- a/Source/WebCore/css/MediaQuery.h +++ b/Source/WebCore/css/MediaQuery.h @@ -38,7 +38,7 @@ namespace WebCore { class MediaQueryExp; class MediaQuery { - WTF_MAKE_NONCOPYABLE(MediaQuery); WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_FAST_ALLOCATED; public: enum Restrictor { Only, Not, None @@ -56,7 +56,11 @@ public: String cssText() const; bool ignored() const { return m_ignored; } + PassOwnPtr<MediaQuery> copy() const { return adoptPtr(new MediaQuery(*this)); } + private: + MediaQuery(const MediaQuery&); + Restrictor m_restrictor; String m_mediaType; OwnPtr<ExpressionVector> m_expressions; diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp index c4be4365b..4f045c67a 100644 --- a/Source/WebCore/css/MediaQueryEvaluator.cpp +++ b/Source/WebCore/css/MediaQueryEvaluator.cpp @@ -31,7 +31,6 @@ #include "Chrome.h" #include "ChromeClient.h" #include "CSSPrimitiveValue.h" -#include "CSSStyleSelector.h" #include "CSSValueList.h" #include "FloatRect.h" #include "Frame.h" @@ -43,9 +42,10 @@ #include "MediaQueryExp.h" #include "NodeRenderStyle.h" #include "Page.h" +#include "PlatformScreen.h" #include "RenderView.h" #include "RenderStyle.h" -#include "PlatformScreen.h" +#include "StyleResolver.h" #include <wtf/HashMap.h> #if ENABLE(3D_RENDERING) && USE(ACCELERATED_COMPOSITING) @@ -130,19 +130,19 @@ static bool applyRestrictor(MediaQuery::Restrictor r, bool value) return r == MediaQuery::Not ? !value : value; } -bool MediaQueryEvaluator::eval(const MediaList* mediaList, CSSStyleSelector* styleSelector) const +bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, StyleResolver* styleResolver) const { - if (!mediaList) + if (!querySet) return true; - const Vector<MediaQuery*>& queries = mediaList->mediaQueries(); + const Vector<OwnPtr<MediaQuery> >& queries = querySet->queryVector(); if (!queries.size()) return true; // empty query list evaluates to true // iterate over queries, stop if any of them eval to true (OR semantics) bool result = false; for (size_t i = 0; i < queries.size() && !result; ++i) { - MediaQuery* query = queries.at(i); + MediaQuery* query = queries[i].get(); if (query->ignored()) continue; @@ -154,8 +154,8 @@ bool MediaQueryEvaluator::eval(const MediaList* mediaList, CSSStyleSelector* sty size_t j = 0; for (; j < exps->size(); ++j) { bool exprResult = eval(exps->at(j).get()); - if (styleSelector && exps->at(j)->isViewportDependent()) - styleSelector->addViewportDependentMediaQueryResult(exps->at(j).get(), exprResult); + if (styleResolver && exps->at(j)->isViewportDependent()) + styleResolver->addViewportDependentMediaQueryResult(exps->at(j).get(), exprResult); if (!exprResult) break; } diff --git a/Source/WebCore/css/MediaQueryEvaluator.h b/Source/WebCore/css/MediaQueryEvaluator.h index ba838f207..9eee0f020 100644 --- a/Source/WebCore/css/MediaQueryEvaluator.h +++ b/Source/WebCore/css/MediaQueryEvaluator.h @@ -31,11 +31,11 @@ #include "PlatformString.h" namespace WebCore { -class CSSStyleSelector; class Frame; -class RenderStyle; -class MediaList; class MediaQueryExp; +class MediaQuerySet; +class RenderStyle; +class StyleResolver; /** * Class that evaluates css media queries as defined in @@ -75,7 +75,7 @@ public: bool mediaTypeMatchSpecific(const char* mediaTypeToMatch) const; /** Evaluates a list of media queries */ - bool eval(const MediaList*, CSSStyleSelector* = 0) const; + bool eval(const MediaQuerySet*, StyleResolver* = 0) const; /** Evaluates media query subexpression, ie "and (media-feature: value)" part */ bool eval(const MediaQueryExp*) const; diff --git a/Source/WebCore/css/MediaQueryExp.cpp b/Source/WebCore/css/MediaQueryExp.cpp index 1f5322183..770d88273 100644 --- a/Source/WebCore/css/MediaQueryExp.cpp +++ b/Source/WebCore/css/MediaQueryExp.cpp @@ -59,10 +59,10 @@ inline MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserV // currently accepts only <integer>/<integer> RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - CSSParserValue* value = 0; + CSSParserValue* value = valueList->current(); bool isValid = true; - while ((value = valueList->current()) && isValid) { + while (value && isValid) { if (value->unit == CSSParserValue::Operator && value->iValue == '/') list->append(CSSPrimitiveValue::create("/", CSSPrimitiveValue::CSS_STRING)); else if (value->unit == CSSPrimitiveValue::CSS_NUMBER) diff --git a/Source/WebCore/css/MediaQueryExp.h b/Source/WebCore/css/MediaQueryExp.h index feb61c084..003de02b5 100644 --- a/Source/WebCore/css/MediaQueryExp.h +++ b/Source/WebCore/css/MediaQueryExp.h @@ -70,6 +70,8 @@ public: String serialize() const; + PassOwnPtr<MediaQueryExp> copy() const { return adoptPtr(new MediaQueryExp(*this)); } + private: MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values); diff --git a/Source/WebCore/css/MediaQueryList.cpp b/Source/WebCore/css/MediaQueryList.cpp index aa3ef60d8..4b121d18b 100644 --- a/Source/WebCore/css/MediaQueryList.cpp +++ b/Source/WebCore/css/MediaQueryList.cpp @@ -27,12 +27,12 @@ namespace WebCore { -PassRefPtr<MediaQueryList> MediaQueryList::create(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaList> media, bool matches) +PassRefPtr<MediaQueryList> MediaQueryList::create(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaQuerySet> media, bool matches) { return adoptRef(new MediaQueryList(vector, media, matches)); } -MediaQueryList::MediaQueryList(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaList> media, bool matches) +MediaQueryList::MediaQueryList(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaQuerySet> media, bool matches) : m_matcher(vector) , m_media(media) , m_evaluationRound(m_matcher->evaluationRound()) diff --git a/Source/WebCore/css/MediaQueryList.h b/Source/WebCore/css/MediaQueryList.h index 8ff498859..5601ec787 100644 --- a/Source/WebCore/css/MediaQueryList.h +++ b/Source/WebCore/css/MediaQueryList.h @@ -26,10 +26,10 @@ namespace WebCore { -class MediaList; class MediaQueryListListener; class MediaQueryEvaluator; class MediaQueryMatcher; +class MediaQuerySet; // MediaQueryList interface is specified at http://dev.w3.org/csswg/cssom-view/#the-mediaquerylist-interface // The objects of this class are returned by window.matchMedia. They may be used to @@ -38,7 +38,7 @@ class MediaQueryMatcher; class MediaQueryList : public RefCounted<MediaQueryList> { public: - static PassRefPtr<MediaQueryList> create(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaList>, bool); + static PassRefPtr<MediaQueryList> create(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaQuerySet>, bool); ~MediaQueryList(); String media() const; @@ -50,11 +50,11 @@ public: void evaluate(MediaQueryEvaluator*, bool& notificationNeeded); private: - MediaQueryList(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaList>, bool matches); + MediaQueryList(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaQuerySet>, bool matches); void setMatches(bool); RefPtr<MediaQueryMatcher> m_matcher; - RefPtr<MediaList> m_media; + RefPtr<MediaQuerySet> m_media; unsigned m_evaluationRound; // Indicates if the query has been evaluated after the last style selector change. unsigned m_changeRound; // Used to know if the query has changed in the last style selector change. bool m_matches; diff --git a/Source/WebCore/css/MediaQueryMatcher.cpp b/Source/WebCore/css/MediaQueryMatcher.cpp index a5f35dd77..efd5dedd8 100644 --- a/Source/WebCore/css/MediaQueryMatcher.cpp +++ b/Source/WebCore/css/MediaQueryMatcher.cpp @@ -20,7 +20,6 @@ #include "config.h" #include "MediaQueryMatcher.h" -#include "CSSStyleSelector.h" #include "Document.h" #include "Element.h" #include "Frame.h" @@ -29,6 +28,7 @@ #include "MediaQueryEvaluator.h" #include "MediaQueryList.h" #include "MediaQueryListListener.h" +#include "StyleResolver.h" namespace WebCore { @@ -84,16 +84,16 @@ PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const if (!documentElement) return nullptr; - CSSStyleSelector* styleSelector = m_document->styleSelector(); - if (!styleSelector) + StyleResolver* styleResolver = m_document->styleResolver(); + if (!styleResolver) return nullptr; - RefPtr<RenderStyle> rootStyle = styleSelector->styleForElement(documentElement, 0 /*defaultParent*/, false /*allowSharing*/, true /*resolveForRootDefault*/); + RefPtr<RenderStyle> rootStyle = styleResolver->styleForElement(documentElement, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules); return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame(), rootStyle.get())); } -bool MediaQueryMatcher::evaluate(MediaList* media) +bool MediaQueryMatcher::evaluate(const MediaQuerySet* media) { if (!media) return false; @@ -107,7 +107,7 @@ PassRefPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query) if (!m_document) return 0; - RefPtr<MediaList> media = MediaList::create(query, false); + RefPtr<MediaQuerySet> media = MediaQuerySet::create(query); return MediaQueryList::create(this, media, evaluate(media.get())); } @@ -137,7 +137,7 @@ void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQu } } -void MediaQueryMatcher::styleSelectorChanged() +void MediaQueryMatcher::styleResolverChanged() { ASSERT(m_document); diff --git a/Source/WebCore/css/MediaQueryMatcher.h b/Source/WebCore/css/MediaQueryMatcher.h index 96bbf8337..6eae35f4e 100644 --- a/Source/WebCore/css/MediaQueryMatcher.h +++ b/Source/WebCore/css/MediaQueryMatcher.h @@ -28,10 +28,10 @@ namespace WebCore { class Document; -class MediaList; class MediaQueryList; class MediaQueryListListener; class MediaQueryEvaluator; +class MediaQuerySet; // MediaQueryMatcher class is responsible for keeping a vector of pairs // MediaQueryList x MediaQueryListListener. It is responsible for evaluating the queries @@ -50,8 +50,8 @@ public: PassRefPtr<MediaQueryList> matchMedia(const String&); unsigned evaluationRound() const { return m_evaluationRound; } - void styleSelectorChanged(); - bool evaluate(MediaList*); + void styleResolverChanged(); + bool evaluate(const MediaQuerySet*); private: class Listener { diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp index 428f1957b..b3e6f1d93 100644 --- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp +++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp @@ -23,6 +23,7 @@ #include "PropertySetCSSStyleDeclaration.h" #include "CSSParser.h" +#include "CSSStyleSheet.h" #include "HTMLNames.h" #include "InspectorInstrumentation.h" #include "MutationObserverInterestGroup.h" @@ -118,7 +119,7 @@ bool StyleAttributeMutationScope::s_shouldDeliver = false; #endif } // namespace - + void PropertySetCSSStyleDeclaration::ref() { m_propertySet->ref(); @@ -138,7 +139,7 @@ String PropertySetCSSStyleDeclaration::item(unsigned i) const { if (i >= m_propertySet->propertyCount()) return ""; - return getPropertyName(static_cast<CSSPropertyID>(m_propertySet->propertyAt(i).id())); + return getPropertyName(m_propertySet->propertyAt(i).id()); } String PropertySetCSSStyleDeclaration::cssText() const @@ -155,7 +156,7 @@ void PropertySetCSSStyleDeclaration::setCssText(const String& text, ExceptionCod // FIXME: Detect syntax errors and set ec. m_propertySet->parseDeclaration(text, contextStyleSheet()); - setNeedsStyleRecalc(); + didMutate(); #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif @@ -163,15 +164,15 @@ void PropertySetCSSStyleDeclaration::setCssText(const String& text, ExceptionCod PassRefPtr<CSSValue> PropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return 0; - return m_propertySet->getPropertyCSSValue(propertyID); + return cloneAndCacheForCSSOM(m_propertySet->getPropertyCSSValue(propertyID).get()); } String PropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); return m_propertySet->getPropertyValue(propertyID); @@ -179,7 +180,7 @@ String PropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyNa String PropertySetCSSStyleDeclaration::getPropertyPriority(const String& propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); return m_propertySet->propertyIsImportant(propertyID) ? "important" : ""; @@ -187,18 +188,18 @@ String PropertySetCSSStyleDeclaration::getPropertyPriority(const String& propert String PropertySetCSSStyleDeclaration::getPropertyShorthand(const String& propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); - int shorthandID = m_propertySet->getPropertyShorthand(propertyID); + CSSPropertyID shorthandID = m_propertySet->getPropertyShorthand(propertyID); if (!shorthandID) return String(); - return getPropertyName(static_cast<CSSPropertyID>(shorthandID)); + return getPropertyName(shorthandID); } bool PropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyName) { - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return false; return m_propertySet->isPropertyImplicit(propertyID); @@ -209,7 +210,7 @@ void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, con #if ENABLE(MUTATION_OBSERVERS) StyleAttributeMutationScope mutationScope(this); #endif - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return; bool important = priority.find("important", 0, false) != notFound; @@ -218,7 +219,7 @@ void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, con if (changed) { // CSS DOM requires raising SYNTAX_ERR of parsing failed, but this is too dangerous for compatibility, // see <http://bugs.webkit.org/show_bug.cgi?id=7296>. - setNeedsStyleRecalc(); + didMutate(); #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif @@ -230,14 +231,14 @@ String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName #if ENABLE(MUTATION_OBSERVERS) StyleAttributeMutationScope mutationScope(this); #endif - int propertyID = cssPropertyID(propertyName); + CSSPropertyID propertyID = cssPropertyID(propertyName); if (!propertyID) return String(); ec = 0; String result; bool changes = m_propertySet->removeProperty(propertyID, &result); if (changes) { - setNeedsStyleRecalc(); + didMutate(); #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif @@ -246,8 +247,8 @@ String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName } PassRefPtr<CSSValue> PropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID) -{ - return m_propertySet->getPropertyCSSValue(propertyID); +{ + return m_propertySet->getPropertyCSSValue(propertyID); } String PropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID) @@ -263,16 +264,39 @@ void PropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyI ec = 0; bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet()); if (changed) { - setNeedsStyleRecalc(); + didMutate(); #if ENABLE(MUTATION_OBSERVERS) mutationScope.enqueueMutationRecord(); #endif } } -CSSStyleSheet* PropertySetCSSStyleDeclaration::parentStyleSheet() const +void PropertySetCSSStyleDeclaration::didMutate() +{ + m_cssomCSSValueClones.clear(); + setNeedsStyleRecalc(); +} + +CSSValue* PropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* internalValue) +{ + if (!internalValue) + return 0; + + // The map is here to maintain the object identity of the CSSValues over multiple invocations. + // FIXME: It is likely that the identity is not important for web compatibility and this code should be removed. + if (!m_cssomCSSValueClones) + m_cssomCSSValueClones = adoptPtr(new HashMap<CSSValue*, RefPtr<CSSValue> >); + + RefPtr<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtr<CSSValue>()).iterator->second; + if (!clonedValue) + clonedValue = internalValue->cloneForCSSOM(); + return clonedValue.get(); +} + +StyleSheetInternal* PropertySetCSSStyleDeclaration::contextStyleSheet() const { - return contextStyleSheet(); + CSSStyleSheet* cssStyleSheet = parentStyleSheet(); + return cssStyleSheet ? cssStyleSheet->internal() : 0; } PassRefPtr<StylePropertySet> PropertySetCSSStyleDeclaration::copy() const @@ -289,16 +313,41 @@ bool PropertySetCSSStyleDeclaration::cssPropertyMatches(const CSSProperty* prope { return m_propertySet->propertyMatches(property); } + +StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(StylePropertySet* propertySet, CSSRule* parentRule) + : PropertySetCSSStyleDeclaration(propertySet) + , m_refCount(1) + , m_parentRule(parentRule) +{ + m_propertySet->ref(); +} + +StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration() +{ + m_propertySet->deref(); +} -void RuleCSSStyleDeclaration::setNeedsStyleRecalc() +void StyleRuleCSSStyleDeclaration::ref() +{ + ++m_refCount; +} + +void StyleRuleCSSStyleDeclaration::deref() +{ + ASSERT(m_refCount); + if (!--m_refCount) + delete this; +} + +void StyleRuleCSSStyleDeclaration::setNeedsStyleRecalc() { - if (CSSStyleSheet* styleSheet = contextStyleSheet()) { - if (Document* document = styleSheet->findDocument()) - document->styleSelectorChanged(DeferRecalcStyle); + if (CSSStyleSheet* styleSheet = parentStyleSheet()) { + if (Document* document = styleSheet->ownerDocument()) + document->styleResolverChanged(DeferRecalcStyle); } } - -CSSStyleSheet* RuleCSSStyleDeclaration::contextStyleSheet() const + +CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const { return m_parentRule ? m_parentRule->parentStyleSheet() : 0; } @@ -313,7 +362,7 @@ void InlineCSSStyleDeclaration::setNeedsStyleRecalc() return; } -CSSStyleSheet* InlineCSSStyleDeclaration::contextStyleSheet() const +CSSStyleSheet* InlineCSSStyleDeclaration::parentStyleSheet() const { return m_parentElement ? m_parentElement->document()->elementSheet() : 0; } diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h index 0edb98cf4..2b8f41295 100644 --- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h +++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h @@ -32,9 +32,9 @@ namespace WebCore { class CSSRule; class CSSProperty; -class CSSStyleSheet; class CSSValue; class StylePropertySet; +class StyleSheetInternal; class StyledElement; class PropertySetCSSStyleDeclaration : public CSSStyleDeclaration { @@ -42,14 +42,13 @@ public: PropertySetCSSStyleDeclaration(StylePropertySet* propertySet) : m_propertySet(propertySet) { } virtual StyledElement* parentElement() const { return 0; } - virtual void clearParentRule() { ASSERT_NOT_REACHED(); } virtual void clearParentElement() { ASSERT_NOT_REACHED(); } - virtual CSSStyleSheet* contextStyleSheet() const { return 0; } + StyleSheetInternal* contextStyleSheet() const; -private: virtual void ref() OVERRIDE; virtual void deref() OVERRIDE; - + +private: virtual CSSRule* parentRule() const OVERRIDE { return 0; }; virtual unsigned length() const OVERRIDE; virtual String item(unsigned index) const OVERRIDE; @@ -67,30 +66,41 @@ private: virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&) OVERRIDE; virtual bool cssPropertyMatches(const CSSProperty*) const OVERRIDE; - virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE; virtual PassRefPtr<StylePropertySet> copy() const OVERRIDE; virtual PassRefPtr<StylePropertySet> makeMutable() OVERRIDE; - virtual void setNeedsStyleRecalc() { } + virtual void setNeedsStyleRecalc() { } + + void didMutate(); + CSSValue* cloneAndCacheForCSSOM(CSSValue*); protected: StylePropertySet* m_propertySet; + OwnPtr<HashMap<CSSValue*, RefPtr<CSSValue> > > m_cssomCSSValueClones; }; -class RuleCSSStyleDeclaration : public PropertySetCSSStyleDeclaration +class StyleRuleCSSStyleDeclaration : public PropertySetCSSStyleDeclaration { public: - RuleCSSStyleDeclaration(StylePropertySet* propertySet, CSSRule* parentRule) - : PropertySetCSSStyleDeclaration(propertySet) - , m_parentRule(parentRule) + static PassRefPtr<StyleRuleCSSStyleDeclaration> create(StylePropertySet* propertySet, CSSRule* parentRule) { + return adoptRef(new StyleRuleCSSStyleDeclaration(propertySet, parentRule)); } + + void clearParentRule() { m_parentRule = 0; } -private: - virtual CSSRule* parentRule() const { return m_parentRule; }; - virtual void clearParentRule() { m_parentRule = 0; } - virtual void setNeedsStyleRecalc(); - virtual CSSStyleSheet* contextStyleSheet() const; + virtual void ref() OVERRIDE; + virtual void deref() OVERRIDE; + +private: + StyleRuleCSSStyleDeclaration(StylePropertySet*, CSSRule*); + virtual ~StyleRuleCSSStyleDeclaration(); + + virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE; + + virtual CSSRule* parentRule() const OVERRIDE { return m_parentRule; } + virtual void setNeedsStyleRecalc() OVERRIDE; + unsigned m_refCount; CSSRule* m_parentRule; }; @@ -104,10 +114,10 @@ public: } private: - virtual StyledElement* parentElement() const { return m_parentElement; } - virtual void clearParentElement() { m_parentElement = 0; } - virtual void setNeedsStyleRecalc(); - virtual CSSStyleSheet* contextStyleSheet() const; + virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE; + virtual StyledElement* parentElement() const OVERRIDE { return m_parentElement; } + virtual void clearParentElement() OVERRIDE { m_parentElement = 0; } + virtual void setNeedsStyleRecalc() OVERRIDE; StyledElement* m_parentElement; }; diff --git a/Source/WebCore/css/RGBColor.cpp b/Source/WebCore/css/RGBColor.cpp index 11ebfe4fa..eeb87c5ad 100644 --- a/Source/WebCore/css/RGBColor.cpp +++ b/Source/WebCore/css/RGBColor.cpp @@ -38,25 +38,33 @@ PassRefPtr<RGBColor> RGBColor::create(unsigned rgbColor) PassRefPtr<CSSPrimitiveValue> RGBColor::red() { unsigned value = (m_rgbColor >> 16) & 0xFF; - return CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + result->setCSSOMSafe(); + return result.release(); } PassRefPtr<CSSPrimitiveValue> RGBColor::green() { unsigned value = (m_rgbColor >> 8) & 0xFF; - return CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + result->setCSSOMSafe(); + return result.release(); } PassRefPtr<CSSPrimitiveValue> RGBColor::blue() { unsigned value = m_rgbColor & 0xFF; - return CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + result->setCSSOMSafe(); + return result.release(); } PassRefPtr<CSSPrimitiveValue> RGBColor::alpha() { float value = static_cast<float>((m_rgbColor >> 24) & 0xFF) / 0xFF; - return WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER); + RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER); + result->setCSSOMSafe(); + return result.release(); } } // namespace WebCore diff --git a/Source/WebCore/css/Rect.h b/Source/WebCore/css/Rect.h index b70c6c45f..355d6fb7b 100644 --- a/Source/WebCore/css/Rect.h +++ b/Source/WebCore/css/Rect.h @@ -40,6 +40,14 @@ public: protected: RectBase() { } + RectBase(const RectBase& cloneFrom) + : m_top(cloneFrom.m_top ? cloneFrom.m_top->cloneForCSSOM() : 0) + , m_right(cloneFrom.m_right ? cloneFrom.m_right->cloneForCSSOM() : 0) + , m_bottom(cloneFrom.m_bottom ? cloneFrom.m_bottom->cloneForCSSOM() : 0) + , m_left(cloneFrom.m_left ? cloneFrom.m_left->cloneForCSSOM() : 0) + { + } + ~RectBase() { } private: @@ -52,17 +60,23 @@ private: class Rect : public RectBase, public RefCounted<Rect> { public: static PassRefPtr<Rect> create() { return adoptRef(new Rect); } + + PassRefPtr<Rect> cloneForCSSOM() const { return adoptRef(new Rect(*this)); } private: Rect() { } + Rect(const Rect& cloneFrom) : RectBase(cloneFrom), RefCounted<Rect>() { } }; class Quad : public RectBase, public RefCounted<Quad> { public: static PassRefPtr<Quad> create() { return adoptRef(new Quad); } + + PassRefPtr<Quad> cloneForCSSOM() const { return adoptRef(new Quad(*this)); } private: Quad() { } + Quad(const Quad& cloneFrom) : RectBase(cloneFrom), RefCounted<Quad>() { } }; } // namespace WebCore diff --git a/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp b/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp index 7ef3b07d3..1cd8fa0aa 100644 --- a/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp @@ -68,7 +68,7 @@ PassRefPtr<SVGPaint> CSSComputedStyleDeclaration::adjustSVGPaintForCurrentColor( return paint.release(); } -PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const +PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const { Node* node = m_node.get(); if (!node) @@ -86,7 +86,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int pro if (!svgStyle) return 0; - switch (static_cast<CSSPropertyID>(propertyID)) { + switch (propertyID) { case CSSPropertyClipRule: return CSSPrimitiveValue::create(svgStyle->clipRule()); case CSSPropertyFloodOpacity: @@ -174,6 +174,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int pro case BS_LENGTH: return SVGLength::toCSSPrimitiveValue(svgStyle->baselineShiftValue()); } + ASSERT_NOT_REACHED(); + return 0; } case CSSPropertyGlyphOrientationHorizontal: return glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationHorizontal()); diff --git a/Source/WebCore/css/SVGCSSParser.cpp b/Source/WebCore/css/SVGCSSParser.cpp index 8a67fabf1..d06bb203b 100644 --- a/Source/WebCore/css/SVGCSSParser.cpp +++ b/Source/WebCore/css/SVGCSSParser.cpp @@ -37,7 +37,7 @@ using namespace std; namespace WebCore { -bool CSSParser::parseSVGValue(int propId, bool important) +bool CSSParser::parseSVGValue(CSSPropertyID propId, bool important) { CSSParserValue* value = m_valueList->current(); if (!value) @@ -66,7 +66,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) id >= CSSValueSuper) valid_primitive = true; else - valid_primitive = validUnit(value, FLength|FPercent, false); + valid_primitive = validUnit(value, FLength | FPercent, SVGAttributeMode); break; case CSSPropertyDominantBaseline: @@ -105,7 +105,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) break; case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit - valid_primitive = validUnit(value, FNumber|FNonNeg, false); + valid_primitive = validUnit(value, FNumber | FNonNeg, SVGAttributeMode); break; case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit @@ -122,7 +122,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) case CSSPropertyFillOpacity: case CSSPropertyStopOpacity: case CSSPropertyFloodOpacity: - valid_primitive = (!id && validUnit(value, FNumber|FPercent, false)); + valid_primitive = (!id && validUnit(value, FNumber | FPercent, SVGAttributeMode)); break; case CSSPropertyShapeRendering: @@ -201,17 +201,6 @@ bool CSSParser::parseSVGValue(int propId, bool important) } break; - case CSSPropertyColor: // <color> | inherit - if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || - (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) - parsedValue = SVGColor::createFromString(value->string); - else - parsedValue = parseSVGColor(); - - if (parsedValue) - m_valueList->next(); - break; - case CSSPropertyStopColor: // TODO : icccolor case CSSPropertyFloodColor: case CSSPropertyLightingColor: @@ -241,7 +230,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) case CSSPropertyStrokeWidth: // <length> | inherit case CSSPropertyStrokeDashoffset: - valid_primitive = validUnit(value, FLength | FPercent, false); + valid_primitive = validUnit(value, FLength | FPercent, SVGAttributeMode); break; case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit if (id == CSSValueNone) @@ -255,7 +244,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) if (id == CSSValueAuto || id == CSSValueNormal) valid_primitive = true; else - valid_primitive = validUnit(value, FLength, false); + valid_primitive = validUnit(value, FLength, SVGAttributeMode); break; case CSSPropertyClipPath: // <uri> | none | inherit @@ -335,7 +324,7 @@ PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray() CSSParserValue* value = m_valueList->current(); bool valid_primitive = true; while (value) { - valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false); + valid_primitive = validUnit(value, FLength | FPercent | FNonNeg, SVGAttributeMode); if (!valid_primitive) break; if (value->id != 0) diff --git a/Source/WebCore/css/SVGCSSStyleSelector.cpp b/Source/WebCore/css/SVGCSSStyleSelector.cpp index 318d72b73..5b3547f4d 100644 --- a/Source/WebCore/css/SVGCSSStyleSelector.cpp +++ b/Source/WebCore/css/SVGCSSStyleSelector.cpp @@ -29,7 +29,7 @@ #include "config.h" #if ENABLE(SVG) -#include "CSSStyleSelector.h" +#include "StyleResolver.h" #include "CSSPrimitiveValueMappings.h" #include "CSSPropertyNames.h" @@ -102,7 +102,7 @@ static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor) return color; } -void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) +void StyleResolver::applySVGProperty(CSSPropertyID id, CSSValue* value) { ASSERT(value); CSSPrimitiveValue* primitiveValue = 0; @@ -357,8 +357,6 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); - else - return; svgstyle->setMarkerStartResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document())); break; @@ -373,8 +371,6 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); - else - return; svgstyle->setMarkerMidResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document())); break; @@ -389,8 +385,6 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); - else - return; svgstyle->setMarkerEndResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document())); break; @@ -428,8 +422,6 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); - else - return; svgstyle->setFilterResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document())); break; @@ -444,8 +436,6 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); - else - return; svgstyle->setMaskerResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document())); break; @@ -460,8 +450,6 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) int type = primitiveValue->primitiveType(); if (type == CSSPrimitiveValue::CSS_URI) s = primitiveValue->getStringValue(); - else - return; svgstyle->setClipperResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document())); break; @@ -571,8 +559,8 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) if (!firstValue->isShadowValue()) return; ShadowValue* item = static_cast<ShadowValue*>(firstValue); - int x = item->x->computeLength<int>(style(), m_rootElementStyle); - int y = item->y->computeLength<int>(style(), m_rootElementStyle); + IntPoint location(item->x->computeLength<int>(style(), m_rootElementStyle), + item->y->computeLength<int>(style(), m_rootElementStyle)); int blur = item->blur ? item->blur->computeLength<int>(style(), m_rootElementStyle) : 0; Color color; if (item->color) @@ -582,7 +570,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) ASSERT(!item->spread); ASSERT(!item->style); - OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(x, y, blur, 0, Normal, false, color.isValid() ? color : Color::transparent)); + OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent)); svgstyle->setShadow(shadowData.release()); return; } @@ -596,7 +584,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) } default: // If you crash here, it's because you added a css property and are not handling it - // in either this switch statement or the one in CSSStyleSelector::applyProperty + // in either this switch statement or the one in StyleResolver::applyProperty ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id); return; } diff --git a/Source/WebCore/css/SelectorChecker.cpp b/Source/WebCore/css/SelectorChecker.cpp index 316f44650..55af512ea 100644 --- a/Source/WebCore/css/SelectorChecker.cpp +++ b/Source/WebCore/css/SelectorChecker.cpp @@ -69,7 +69,7 @@ SelectorChecker::SelectorChecker(Document* document, bool strictParsing) : m_document(document) , m_strictParsing(strictParsing) , m_documentIsHTML(document->isHTMLDocument()) - , m_isCollectingRulesOnly(false) + , m_mode(ResolvingStyle) , m_pseudoStyle(NOPSEUDO) , m_hasUnknownPseudoElements(false) { @@ -492,7 +492,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec return checkSelector(nextContext, dynamicPseudo); case CSSSelector::DirectAdjacent: - if (!m_isCollectingRulesOnly && context.element->parentElement()) { + if (m_mode == ResolvingStyle && context.element->parentElement()) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : context.element->parentNode()->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByDirectAdjacentRules(); @@ -506,7 +506,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec return checkSelector(nextContext, dynamicPseudo); case CSSSelector::IndirectAdjacent: - if (!m_isCollectingRulesOnly && context.element->parentElement()) { + if (m_mode == ResolvingStyle && context.element->parentElement()) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : context.element->parentNode()->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByForwardPositionalRules(); @@ -526,7 +526,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec // a selector is invalid if something follows a pseudo-element // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else) // to follow the pseudo elements. - if ((context.elementStyle || m_isCollectingRulesOnly) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION + if ((context.elementStyle || m_mode == CollectingRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION && !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && nextContext.selector->m_match == CSSSelector::PseudoClass)) return SelectorFailsCompletely; nextContext.isSubSelector = true; @@ -773,7 +773,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } } } - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { if (context.elementStyle) context.elementStyle->setEmptyState(result); else if (element->renderStyle() && (element->document()->usesSiblingRules() || element->renderStyle()->unique())) @@ -787,7 +787,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P bool result = false; if (!element->previousElementSibling()) result = true; - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : element->parentNode()->renderStyle(); if (parentStyle) @@ -809,7 +809,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P break; } } - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : element->parentNode()->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByForwardPositionalRules(); @@ -821,7 +821,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P // last-child matches the last child that is an element if (Element* parentElement = element->parentElement()) { bool result = parentElement->isFinishedParsingChildren() && !element->nextElementSibling(); - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) @@ -835,7 +835,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoLastOfType: // last-of-type matches the last element of its type if (Element* parentElement = element->parentElement()) { - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByBackwardPositionalRules(); @@ -855,7 +855,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P bool firstChild = !element->previousElementSibling(); bool onlyChild = firstChild && parentElement->isFinishedParsingChildren() && !element->nextElementSibling(); - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) { @@ -873,7 +873,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoOnlyOfType: // FIXME: This selector is very slow. if (Element* parentElement = element->parentElement()) { - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) { parentStyle->setChildrenAffectedByForwardPositionalRules(); @@ -909,7 +909,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P count++; } - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (childStyle) @@ -932,7 +932,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P if (sibling->hasTagName(type)) ++count; } - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByForwardPositionalRules(); @@ -946,7 +946,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P if (!selector->parseNth()) break; if (Element* parentElement = element->parentElement()) { - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByBackwardPositionalRules(); @@ -964,7 +964,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P if (!selector->parseNth()) break; if (Element* parentElement = element->parentElement()) { - if (!m_isCollectingRulesOnly) { + if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) parentStyle->setChildrenAffectedByBackwardPositionalRules(); @@ -1052,7 +1052,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoDefault: return element && element->isDefaultButtonForForm(); case CSSSelector::PseudoDisabled: - if (element && element->isFormControlElement()) + if (element && (element->isFormControlElement() || element->hasTagName(optionTag))) return !element->isEnabledFormControl(); break; case CSSSelector::PseudoReadOnly: @@ -1079,7 +1079,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P return (element->willValidate() && !element->isValidFormControlElement()) || element->hasUnacceptableValue(); case CSSSelector::PseudoChecked: { - if (!element || !element->isFormControlElement()) + if (!element) break; // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that // you can't be both checked and indeterminate. We will behave like WinIE behind the scenes and just @@ -1093,7 +1093,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } case CSSSelector::PseudoIndeterminate: { - if (!element || !element->isFormControlElement()) + if (!element) break; #if ENABLE(PROGRESS_TAG) if (element->hasTagName(progressTag)) { @@ -1169,7 +1169,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P return false; } if (selector->m_match == CSSSelector::PseudoElement) { - if (!context.elementStyle && !m_isCollectingRulesOnly) + if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules) return false; if (selector->isUnknownPseudoElement()) { diff --git a/Source/WebCore/css/SelectorChecker.h b/Source/WebCore/css/SelectorChecker.h index 22b127f02..3219dea96 100644 --- a/Source/WebCore/css/SelectorChecker.h +++ b/Source/WebCore/css/SelectorChecker.h @@ -30,10 +30,11 @@ #include "Attribute.h" #include "CSSSelector.h" -#include "Element.h" #include "InspectorInstrumentation.h" #include "LinkHash.h" #include "RenderStyleConstants.h" +#include "SpaceSplitString.h" +#include "StyledElement.h" #include <wtf/BloomFilter.h> #include <wtf/HashSet.h> #include <wtf/Vector.h> @@ -51,6 +52,7 @@ public: enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsAllSiblings, SelectorFailsCompletely }; enum VisitedMatchType { VisitedMatchDisabled, VisitedMatchEnabled }; + enum Mode { ResolvingStyle = 0, CollectingRules, QueryingRules }; struct SelectorCheckingContext { // Initial selector constructor @@ -95,8 +97,8 @@ public: Document* document() const { return m_document; } bool strictParsing() const { return m_strictParsing; } - bool isCollectingRulesOnly() const { return m_isCollectingRulesOnly; } - void setCollectingRulesOnly(bool b) { m_isCollectingRulesOnly = b; } + Mode mode() const { return m_mode; } + void setMode(Mode mode) { m_mode = mode; } PseudoId pseudoStyle() const { return m_pseudoStyle; } void setPseudoStyle(PseudoId pseudoId) { m_pseudoStyle = pseudoId; } @@ -116,6 +118,7 @@ public: // Find the ids or classes selectors are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope. static bool determineSelectorScopes(const CSSSelectorList&, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes); + static bool elementMatchesSelectorScopes(const StyledElement*, const HashSet<AtomicStringImpl*>& idScopes, const HashSet<AtomicStringImpl*>& classScopes); private: bool checkOneSelector(const SelectorCheckingContext&, PseudoId&) const; @@ -133,7 +136,7 @@ private: Document* m_document; bool m_strictParsing; bool m_documentIsHTML; - bool m_isCollectingRulesOnly; + Mode m_mode; PseudoId m_pseudoStyle; mutable bool m_hasUnknownPseudoElements; mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState; @@ -226,6 +229,20 @@ inline bool SelectorChecker::fastCheckRightmostAttributeSelector(const Element* return true; } +inline bool SelectorChecker::elementMatchesSelectorScopes(const StyledElement* element, const HashSet<AtomicStringImpl*>& idScopes, const HashSet<AtomicStringImpl*>& classScopes) +{ + if (!idScopes.isEmpty() && element->hasID() && idScopes.contains(element->idForStyleResolution().impl())) + return true; + if (classScopes.isEmpty() || !element->hasClass()) + return false; + const SpaceSplitString& classNames = element->classNames(); + for (unsigned i = 0; i < classNames.size(); ++i) { + if (classScopes.contains(classNames[i].impl())) + return true; + } + return false; +} + } #endif diff --git a/Source/WebCore/css/CSSStyleApplyProperty.cpp b/Source/WebCore/css/StyleBuilder.cpp index cfd6931d1..6a5e1632a 100644 --- a/Source/WebCore/css/CSSStyleApplyProperty.cpp +++ b/Source/WebCore/css/StyleBuilder.cpp @@ -23,14 +23,12 @@ */ #include "config.h" -#include "CSSStyleApplyProperty.h" +#include "StyleBuilder.h" #include "CSSAspectRatioValue.h" #include "CSSCalculationValue.h" #include "CSSCursorImageValue.h" -#include "CSSFlexValue.h" #include "CSSPrimitiveValueMappings.h" -#include "CSSStyleSelector.h" #include "CSSValueList.h" #include "CursorList.h" #include "Document.h" @@ -39,7 +37,9 @@ #include "Rect.h" #include "RenderObject.h" #include "RenderStyle.h" +#include "RenderView.h" #include "Settings.h" +#include "StyleResolver.h" #include <wtf/StdLibExtras.h> #include <wtf/UnusedParam.h> @@ -53,69 +53,69 @@ class ApplyPropertyExpanding { public: template <CSSPropertyID id> - static inline void applyInheritValue(CSSStyleSelector* selector) + static inline void applyInheritValue(StyleResolver* styleResolver) { if (id == CSSPropertyInvalid) return; - const CSSStyleApplyProperty& table = CSSStyleApplyProperty::sharedCSSStyleApplyProperty(); + const StyleBuilder& table = StyleBuilder::sharedStyleBuilder(); const PropertyHandler& handler = table.propertyHandler(id); if (handler.isValid()) - handler.applyInheritValue(selector); + handler.applyInheritValue(styleResolver); } - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - applyInheritValue<one>(selector); - applyInheritValue<two>(selector); - applyInheritValue<three>(selector); - applyInheritValue<four>(selector); - applyInheritValue<five>(selector); + applyInheritValue<one>(styleResolver); + applyInheritValue<two>(styleResolver); + applyInheritValue<three>(styleResolver); + applyInheritValue<four>(styleResolver); + applyInheritValue<five>(styleResolver); } template <CSSPropertyID id> - static inline void applyInitialValue(CSSStyleSelector* selector) + static inline void applyInitialValue(StyleResolver* styleResolver) { if (id == CSSPropertyInvalid) return; - const CSSStyleApplyProperty& table = CSSStyleApplyProperty::sharedCSSStyleApplyProperty(); + const StyleBuilder& table = StyleBuilder::sharedStyleBuilder(); const PropertyHandler& handler = table.propertyHandler(id); if (handler.isValid()) - handler.applyInitialValue(selector); + handler.applyInitialValue(styleResolver); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - applyInitialValue<one>(selector); - applyInitialValue<two>(selector); - applyInitialValue<three>(selector); - applyInitialValue<four>(selector); - applyInitialValue<five>(selector); + applyInitialValue<one>(styleResolver); + applyInitialValue<two>(styleResolver); + applyInitialValue<three>(styleResolver); + applyInitialValue<four>(styleResolver); + applyInitialValue<five>(styleResolver); } template <CSSPropertyID id> - static inline void applyValue(CSSStyleSelector* selector, CSSValue* value) + static inline void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (id == CSSPropertyInvalid) return; - const CSSStyleApplyProperty& table = CSSStyleApplyProperty::sharedCSSStyleApplyProperty(); + const StyleBuilder& table = StyleBuilder::sharedStyleBuilder(); const PropertyHandler& handler = table.propertyHandler(id); if (handler.isValid()) - handler.applyValue(selector, value); + handler.applyValue(styleResolver, value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!expandValue) return; - applyValue<one>(selector, value); - applyValue<two>(selector, value); - applyValue<three>(selector, value); - applyValue<four>(selector, value); - applyValue<five>(selector, value); + applyValue<one>(styleResolver, value); + applyValue<two>(styleResolver, value); + applyValue<three>(styleResolver, value); + applyValue<four>(styleResolver, value); + applyValue<five>(styleResolver, value); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } }; @@ -126,9 +126,9 @@ public: static void setValue(RenderStyle* style, SetterType value) { (style->*setterFunction)(value); } static GetterType value(RenderStyle* style) { return (style->*getterFunction)(); } static InitialType initial() { return (*initialFunction)(); } - static void applyInheritValue(CSSStyleSelector* selector) { setValue(selector->style(), value(selector->parentStyle())); } - static void applyInitialValue(CSSStyleSelector* selector) { setValue(selector->style(), initial()); } - static void applyValue(CSSStyleSelector*, CSSValue*) { } + static void applyInheritValue(StyleResolver* styleResolver) { setValue(styleResolver->style(), value(styleResolver->parentStyle())); } + static void applyInitialValue(StyleResolver* styleResolver) { setValue(styleResolver->style(), initial()); } + static void applyValue(StyleResolver*, CSSValue*) { } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } }; @@ -136,10 +136,10 @@ template <typename GetterType, GetterType (RenderStyle::*getterFunction)() const class ApplyPropertyDefault { public: static void setValue(RenderStyle* style, SetterType value) { (style->*setterFunction)(value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (value->isPrimitiveValue()) - setValue(selector->style(), *static_cast<CSSPrimitiveValue*>(value)); + setValue(styleResolver->style(), *static_cast<CSSPrimitiveValue*>(value)); } static PropertyHandler createHandler() { @@ -152,16 +152,16 @@ template <typename NumberType, NumberType (RenderStyle::*getterFunction)() const class ApplyPropertyNumber { public: static void setValue(RenderStyle* style, NumberType value) { (style->*setterFunction)(value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->getIdent() == idMapsToMinusOne) - setValue(selector->style(), -1); + setValue(styleResolver->style(), -1); else - setValue(selector->style(), primitiveValue->getValue<NumberType>(CSSPrimitiveValue::CSS_NUMBER)); + setValue(styleResolver->style(), primitiveValue->getValue<NumberType>(CSSPrimitiveValue::CSS_NUMBER)); } static PropertyHandler createHandler() { @@ -173,7 +173,7 @@ public: template <StyleImage* (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(PassRefPtr<StyleImage>), StyleImage* (*initialFunction)(), CSSPropertyID property> class ApplyPropertyStyleImage { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) { (selector->style()->*setterFunction)(selector->styleImage(property, value)); } + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { (styleResolver->style()->*setterFunction)(styleResolver->styleImage(property, value)); } static PropertyHandler createHandler() { PropertyHandler handler = ApplyPropertyDefaultBase<StyleImage*, getterFunction, PassRefPtr<StyleImage>, setterFunction, StyleImage*, initialFunction>::createHandler(); @@ -190,28 +190,28 @@ public: static bool hasAuto(RenderStyle* style) { return (style->*hasAutoFunction)(); } static void setAuto(RenderStyle* style) { (style->*setAutoFunction)(); } - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - if (hasAuto(selector->parentStyle())) - setAuto(selector->style()); + if (hasAuto(styleResolver->parentStyle())) + setAuto(styleResolver->style()); else - setValue(selector->style(), value(selector->parentStyle())); + setValue(styleResolver->style(), value(styleResolver->parentStyle())); } - static void applyInitialValue(CSSStyleSelector* selector) { setAuto(selector->style()); } + static void applyInitialValue(StyleResolver* styleResolver) { setAuto(styleResolver->style()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->getIdent() == autoIdentity) - setAuto(selector->style()); + setAuto(styleResolver->style()); else if (valueType == Number) - setValue(selector->style(), *primitiveValue); + setValue(styleResolver->style(), *primitiveValue); else if (valueType == ComputeLength) - setValue(selector->style(), primitiveValue->computeLength<T>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom())); + setValue(styleResolver->style(), primitiveValue->computeLength<T>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } @@ -219,27 +219,27 @@ public: class ApplyPropertyClip { private: - static Length convertToLength(CSSStyleSelector* selector, CSSPrimitiveValue* value) + static Length convertToLength(StyleResolver* styleResolver, CSSPrimitiveValue* value) { - return value->convertToLength<FixedConversion | PercentConversion | FractionConversion | AutoConversion>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()); + return value->convertToLength<FixedIntegerConversion | PercentConversion | FractionConversion | AutoConversion>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); } public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - RenderStyle* parentStyle = selector->parentStyle(); + RenderStyle* parentStyle = styleResolver->parentStyle(); if (!parentStyle->hasClip()) - return applyInitialValue(selector); - selector->style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft()); - selector->style()->setHasClip(true); + return applyInitialValue(styleResolver); + styleResolver->style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft()); + styleResolver->style()->setHasClip(true); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - selector->style()->setClip(Length(), Length(), Length(), Length()); - selector->style()->setHasClip(false); + styleResolver->style()->setClip(Length(), Length(), Length(), Length()); + styleResolver->style()->setHasClip(false); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; @@ -247,15 +247,15 @@ public: CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (Rect* rect = primitiveValue->getRectValue()) { - Length top = convertToLength(selector, rect->top()); - Length right = convertToLength(selector, rect->right()); - Length bottom = convertToLength(selector, rect->bottom()); - Length left = convertToLength(selector, rect->left()); - selector->style()->setClip(top, right, bottom, left); - selector->style()->setHasClip(true); + Length top = convertToLength(styleResolver, rect->top()); + Length right = convertToLength(styleResolver, rect->right()); + Length bottom = convertToLength(styleResolver, rect->bottom()); + Length left = convertToLength(styleResolver, rect->left()); + styleResolver->style()->setClip(top, right, bottom, left); + styleResolver->style()->setHasClip(true); } else if (primitiveValue->getIdent() == CSSValueAuto) { - selector->style()->setClip(Length(), Length(), Length(), Length()); - selector->style()->setHasClip(true); + styleResolver->style()->setClip(Length(), Length(), Length(), Length()); + styleResolver->style()->setHasClip(false); } } @@ -266,47 +266,47 @@ enum ColorInherit {NoInheritFromParent = 0, InheritFromParent}; Color defaultInitialColor(); Color defaultInitialColor() { return Color(); } template <ColorInherit inheritColorFromParent, - const Color& (RenderStyle::*getterFunction)() const, + Color (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(const Color&), void (RenderStyle::*visitedLinkSetterFunction)(const Color&), - const Color& (RenderStyle::*defaultFunction)() const, + Color (RenderStyle::*defaultFunction)() const, Color (*initialFunction)() = &defaultInitialColor> class ApplyPropertyColor { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { // Visited link style can never explicitly inherit from parent visited link style so no separate getters are needed. - const Color& color = (selector->parentStyle()->*getterFunction)(); - applyColorValue(selector, color.isValid() ? color : (selector->parentStyle()->*defaultFunction)()); + Color color = (styleResolver->parentStyle()->*getterFunction)(); + applyColorValue(styleResolver, color.isValid() ? color : (styleResolver->parentStyle()->*defaultFunction)()); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - applyColorValue(selector, initialFunction()); + applyColorValue(styleResolver, initialFunction()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (inheritColorFromParent && primitiveValue->getIdent() == CSSValueCurrentcolor) - applyInheritValue(selector); + applyInheritValue(styleResolver); else { - if (selector->applyPropertyToRegularStyle()) - (selector->style()->*setterFunction)(selector->colorFromPrimitiveValue(primitiveValue)); - if (selector->applyPropertyToVisitedLinkStyle()) - (selector->style()->*visitedLinkSetterFunction)(selector->colorFromPrimitiveValue(primitiveValue, /* forVisitedLink */ true)); + if (styleResolver->applyPropertyToRegularStyle()) + (styleResolver->style()->*setterFunction)(styleResolver->colorFromPrimitiveValue(primitiveValue)); + if (styleResolver->applyPropertyToVisitedLinkStyle()) + (styleResolver->style()->*visitedLinkSetterFunction)(styleResolver->colorFromPrimitiveValue(primitiveValue, /* forVisitedLink */ true)); } } - static void applyColorValue(CSSStyleSelector* selector, const Color& color) + static void applyColorValue(StyleResolver* styleResolver, const Color& color) { - if (selector->applyPropertyToRegularStyle()) - (selector->style()->*setterFunction)(color); - if (selector->applyPropertyToVisitedLinkStyle()) - (selector->style()->*visitedLinkSetterFunction)(color); + if (styleResolver->applyPropertyToRegularStyle()) + (styleResolver->style()->*setterFunction)(color); + if (styleResolver->applyPropertyToVisitedLinkStyle()) + (styleResolver->style()->*visitedLinkSetterFunction)(color); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } @@ -315,11 +315,11 @@ public: template <TextDirection (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(TextDirection), TextDirection (*initialFunction)()> class ApplyPropertyDirection { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - ApplyPropertyDefault<TextDirection, getterFunction, TextDirection, setterFunction, TextDirection, initialFunction>::applyValue(selector, value); - Element* element = selector->element(); - if (element && selector->element() == element->document()->documentElement()) + ApplyPropertyDefault<TextDirection, getterFunction, TextDirection, setterFunction, TextDirection, initialFunction>::applyValue(styleResolver, value); + Element* element = styleResolver->element(); + if (element && styleResolver->element() == element->document()->documentElement()) element->document()->setDirectionSetOnDocumentElement(true); } @@ -335,7 +335,6 @@ enum LengthIntrinsic { IntrinsicDisabled = 0, IntrinsicEnabled }; enum LengthMinIntrinsic { MinIntrinsicDisabled = 0, MinIntrinsicEnabled }; enum LengthNone { NoneDisabled = 0, NoneEnabled }; enum LengthUndefined { UndefinedDisabled = 0, UndefinedEnabled }; -enum LengthFlexDirection { FlexDirectionDisabled = 0, FlexWidth, FlexHeight }; template <Length (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(Length), Length (*initialFunction)(), @@ -343,55 +342,38 @@ template <Length (RenderStyle::*getterFunction)() const, LengthIntrinsic intrinsicEnabled = IntrinsicDisabled, LengthMinIntrinsic minIntrinsicEnabled = MinIntrinsicDisabled, LengthNone noneEnabled = NoneDisabled, - LengthUndefined noneUndefined = UndefinedDisabled, - LengthFlexDirection flexDirection = FlexDirectionDisabled> + LengthUndefined noneUndefined = UndefinedDisabled> class ApplyPropertyLength { public: static void setValue(RenderStyle* style, Length value) { (style->*setterFunction)(value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - float positiveFlex = 0; - float negativeFlex = 0; - if (!value->isPrimitiveValue()) { - if (!flexDirection || !value->isFlexValue()) - return; - - CSSFlexValue* flexValue = static_cast<CSSFlexValue*>(value); - value = flexValue->preferredSize(); - - positiveFlex = flexValue->positiveFlex(); - negativeFlex = flexValue->negativeFlex(); - } - - if (flexDirection == FlexWidth) { - selector->style()->setFlexboxWidthPositiveFlex(positiveFlex); - selector->style()->setFlexboxWidthNegativeFlex(negativeFlex); - } else if (flexDirection == FlexHeight) { - selector->style()->setFlexboxHeightPositiveFlex(positiveFlex); - selector->style()->setFlexboxHeightNegativeFlex(negativeFlex); - } + if (!value->isPrimitiveValue()) + return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (noneEnabled && primitiveValue->getIdent() == CSSValueNone) if (noneUndefined) - setValue(selector->style(), Length(Undefined)); + setValue(styleResolver->style(), Length(Undefined)); else - setValue(selector->style(), Length()); + setValue(styleResolver->style(), Length()); else if (intrinsicEnabled && primitiveValue->getIdent() == CSSValueIntrinsic) - setValue(selector->style(), Length(Intrinsic)); + setValue(styleResolver->style(), Length(Intrinsic)); else if (minIntrinsicEnabled && primitiveValue->getIdent() == CSSValueMinIntrinsic) - setValue(selector->style(), Length(MinIntrinsic)); + setValue(styleResolver->style(), Length(MinIntrinsic)); else if (autoEnabled && primitiveValue->getIdent() == CSSValueAuto) - setValue(selector->style(), Length()); + setValue(styleResolver->style(), Length()); else { if (primitiveValue->isLength()) { - Length length = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()); + Length length = primitiveValue->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); length.setQuirk(primitiveValue->isQuirkValue()); - setValue(selector->style(), length); + setValue(styleResolver->style(), length); } else if (primitiveValue->isPercentage()) - setValue(selector->style(), Length(primitiveValue->getDoubleValue(), Percent)); + setValue(styleResolver->style(), Length(primitiveValue->getDoubleValue(), Percent)); else if (primitiveValue->isCalculatedPercentageWithLength()) - setValue(selector->style(), Length(primitiveValue->cssCalcValue()->toCalcValue(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))); + setValue(styleResolver->style(), Length(primitiveValue->cssCalcValue()->toCalcValue(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()))); + else if (primitiveValue->isViewportPercentageLength()) + setValue(styleResolver->style(), primitiveValue->viewportPercentageLength()); } } @@ -407,16 +389,16 @@ template <StringIdentBehavior identBehavior, const AtomicString& (RenderStyle::* class ApplyPropertyString { public: static void setValue(RenderStyle* style, const AtomicString& value) { (style->*setterFunction)(value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if ((identBehavior == MapNoneToNull && primitiveValue->getIdent() == CSSValueNone) || (identBehavior == MapAutoToNull && primitiveValue->getIdent() == CSSValueAuto)) - setValue(selector->style(), nullAtom); + setValue(styleResolver->style(), nullAtom); else - setValue(selector->style(), primitiveValue->getStringValue()); + setValue(styleResolver->style(), primitiveValue->getStringValue()); } static PropertyHandler createHandler() { @@ -429,7 +411,7 @@ template <LengthSize (RenderStyle::*getterFunction)() const, void (RenderStyle:: class ApplyPropertyBorderRadius { public: static void setValue(RenderStyle* style, LengthSize value) { (style->*setterFunction)(value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; @@ -443,20 +425,24 @@ public: Length radiusHeight; if (pair->first()->isPercentage()) radiusWidth = Length(pair->first()->getDoubleValue(), Percent); + else if (pair->first()->isViewportPercentageLength()) + radiusWidth = pair->first()->viewportPercentageLength(); else if (pair->first()->isCalculatedPercentageWithLength()) { // FIXME calc(): http://webkit.org/b/16662 // handle this case return; } else - radiusWidth = Length(max(intMinForLength, min(intMaxForLength, pair->first()->computeLength<int>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))), Fixed); + radiusWidth = pair->first()->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); if (pair->second()->isPercentage()) radiusHeight = Length(pair->second()->getDoubleValue(), Percent); + else if (pair->second()->isViewportPercentageLength()) + radiusHeight = pair->second()->viewportPercentageLength(); else if (pair->second()->isCalculatedPercentageWithLength()) { // FIXME calc(): http://webkit.org/b/16662 // handle this case return; } else - radiusHeight = Length(max(intMinForLength, min(intMaxForLength, pair->second()->computeLength<int>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))), Fixed); + radiusHeight = pair->second()->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); int width = radiusWidth.value(); int height = radiusHeight.value(); if (width < 0 || height < 0) @@ -467,7 +453,7 @@ public: radiusWidth = radiusHeight; // Null out the other value. LengthSize size(radiusWidth, radiusHeight); - setValue(selector->style(), size); + setValue(styleResolver->style(), size); } static PropertyHandler createHandler() { @@ -498,14 +484,14 @@ template <typename T, void (FillLayer::*setFunction)(typename FillLayerAccessorTypes<T>::Setter), void (FillLayer::*clearFunction)(), typename FillLayerAccessorTypes<T>::Getter (*initialFunction)(EFillLayerType), - void (CSSStyleSelector::*mapFillFunction)(CSSPropertyID, FillLayer*, CSSValue*)> + void (StyleResolver::*mapFillFunction)(CSSPropertyID, FillLayer*, CSSValue*)> class ApplyPropertyFillLayer { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - FillLayer* currChild = (selector->style()->*accessLayersFunction)(); + FillLayer* currChild = (styleResolver->style()->*accessLayersFunction)(); FillLayer* prevChild = 0; - const FillLayer* currParent = (selector->parentStyle()->*layersFunction)(); + const FillLayer* currParent = (styleResolver->parentStyle()->*layersFunction)(); while (currParent && (currParent->*testFunction)()) { if (!currChild) { /* Need to make a new layer.*/ @@ -525,19 +511,23 @@ public: } } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - FillLayer* currChild = (selector->style()->*accessLayersFunction)(); + FillLayer* currChild = (styleResolver->style()->*accessLayersFunction)(); (currChild->*setFunction)((*initialFunction)(fillLayerType)); for (currChild = currChild->next(); currChild; currChild = currChild->next()) (currChild->*clearFunction)(); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - FillLayer* currChild = (selector->style()->*accessLayersFunction)(); + FillLayer* currChild = (styleResolver->style()->*accessLayersFunction)(); FillLayer* prevChild = 0; - if (value->isValueList()) { + if (value->isValueList() +#if ENABLE(CSS_IMAGE_SET) + && !value->isImageSetValue() +#endif + ) { /* Walk each value and put it into a layer, creating new layers as needed. */ CSSValueList* valueList = static_cast<CSSValueList*>(value); for (unsigned int i = 0; i < valueList->length(); i++) { @@ -546,12 +536,12 @@ public: currChild = new FillLayer(fillLayerType); prevChild->setNext(currChild); } - (selector->*mapFillFunction)(propertyId, currChild, valueList->itemWithoutBoundsCheck(i)); + (styleResolver->*mapFillFunction)(propertyId, currChild, valueList->itemWithoutBoundsCheck(i)); prevChild = currChild; currChild = currChild->next(); } } else { - (selector->*mapFillFunction)(propertyId, currChild, value); + (styleResolver->*mapFillFunction)(propertyId, currChild, value); currChild = currChild->next(); } while (currChild) { @@ -577,7 +567,7 @@ template <typename T, class ApplyPropertyComputeLength { public: static void setValue(RenderStyle* style, T value) { (style->*setterFunction)(value); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { // note: CSSPropertyLetter/WordSpacing right now sets to zero if it's not a primitive value for some reason... if (!value->isPrimitiveValue()) @@ -596,14 +586,14 @@ public: } else if (thicknessEnabled && ident == CSSValueThick) { length = 5; } else if (ident == CSSValueInvalid) { - float zoom = (svgZoomEnabled && selector->useSVGZoomRules()) ? 1.0f : selector->style()->effectiveZoom(); - length = primitiveValue->computeLength<T>(selector->style(), selector->rootElementStyle(), zoom); + float zoom = (svgZoomEnabled && styleResolver->useSVGZoomRules()) ? 1.0f : styleResolver->style()->effectiveZoom(); + length = primitiveValue->computeLength<T>(styleResolver->style(), styleResolver->rootElementStyle(), zoom); } else { ASSERT_NOT_REACHED(); length = 0; } - setValue(selector->style(), length); + setValue(styleResolver->style(), length); } static PropertyHandler createHandler() { @@ -615,28 +605,28 @@ public: template <typename T, T (FontDescription::*getterFunction)() const, void (FontDescription::*setterFunction)(T), T initialValue> class ApplyPropertyFont { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - FontDescription fontDescription = selector->fontDescription(); - (fontDescription.*setterFunction)((selector->parentFontDescription().*getterFunction)()); - selector->setFontDescription(fontDescription); + FontDescription fontDescription = styleResolver->fontDescription(); + (fontDescription.*setterFunction)((styleResolver->parentFontDescription().*getterFunction)()); + styleResolver->setFontDescription(fontDescription); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - FontDescription fontDescription = selector->fontDescription(); + FontDescription fontDescription = styleResolver->fontDescription(); (fontDescription.*setterFunction)(initialValue); - selector->setFontDescription(fontDescription); + styleResolver->setFontDescription(fontDescription); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - FontDescription fontDescription = selector->fontDescription(); + FontDescription fontDescription = styleResolver->fontDescription(); (fontDescription.*setterFunction)(*primitiveValue); - selector->setFontDescription(fontDescription); + styleResolver->setFontDescription(fontDescription); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } @@ -661,50 +651,50 @@ private: return size / 1.2f; } public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - float size = selector->parentStyle()->fontDescription().specifiedSize(); + float size = styleResolver->parentStyle()->fontDescription().specifiedSize(); if (size < 0) return; - FontDescription fontDescription = selector->style()->fontDescription(); - fontDescription.setKeywordSize(selector->parentStyle()->fontDescription().keywordSize()); - selector->setFontSize(fontDescription, size); - selector->setFontDescription(fontDescription); + FontDescription fontDescription = styleResolver->style()->fontDescription(); + fontDescription.setKeywordSize(styleResolver->parentStyle()->fontDescription().keywordSize()); + styleResolver->setFontSize(fontDescription, size); + styleResolver->setFontDescription(fontDescription); return; } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - FontDescription fontDescription = selector->style()->fontDescription(); - float size = selector->fontSizeForKeyword(selector->document(), CSSValueMedium, fontDescription.useFixedDefaultSize()); + FontDescription fontDescription = styleResolver->style()->fontDescription(); + float size = styleResolver->fontSizeForKeyword(styleResolver->document(), CSSValueMedium, fontDescription.useFixedDefaultSize()); if (size < 0) return; fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); - selector->setFontSize(fontDescription, size); - selector->setFontDescription(fontDescription); + styleResolver->setFontSize(fontDescription, size); + styleResolver->setFontDescription(fontDescription); return; } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - FontDescription fontDescription = selector->style()->fontDescription(); + FontDescription fontDescription = styleResolver->style()->fontDescription(); fontDescription.setKeywordSize(0); float parentSize = 0; bool parentIsAbsoluteSize = false; float size = 0; - if (selector->hasParentNode()) { - parentSize = selector->parentStyle()->fontDescription().specifiedSize(); - parentIsAbsoluteSize = selector->parentStyle()->fontDescription().isAbsoluteSize(); + if (styleResolver->hasParentNode()) { + parentSize = styleResolver->parentStyle()->fontDescription().specifiedSize(); + parentIsAbsoluteSize = styleResolver->parentStyle()->fontDescription().isAbsoluteSize(); } if (int ident = primitiveValue->getIdent()) { @@ -718,7 +708,7 @@ public: case CSSValueXLarge: case CSSValueXxLarge: case CSSValueWebkitXxxLarge: - size = selector->fontSizeForKeyword(selector->document(), ident, fontDescription.useFixedDefaultSize()); + size = styleResolver->fontSizeForKeyword(styleResolver->document(), ident, fontDescription.useFixedDefaultSize()); fontDescription.setKeywordSize(ident - CSSValueXxSmall + 1); break; case CSSValueLarger: @@ -736,9 +726,13 @@ public: fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength())); if (primitiveValue->isLength()) - size = primitiveValue->computeLength<float>(selector->parentStyle(), selector->rootElementStyle(), 1.0, true); + size = primitiveValue->computeLength<float>(styleResolver->parentStyle(), styleResolver->rootElementStyle(), 1.0, true); else if (primitiveValue->isPercentage()) size = (primitiveValue->getFloatValue() * parentSize) / 100.0f; + else if (primitiveValue->isCalculatedPercentageWithLength()) + size = primitiveValue->cssCalcValue()->toCalcValue(styleResolver->parentStyle(), styleResolver->rootElementStyle())->evaluate(parentSize); + else if (primitiveValue->isViewportPercentageLength()) + size = valueForLength(primitiveValue->viewportPercentageLength(), 0, styleResolver->document()->renderView()); else return; } @@ -746,8 +740,8 @@ public: if (size < 0) return; - selector->setFontSize(fontDescription, size); - selector->setFontDescription(fontDescription); + styleResolver->setFontSize(fontDescription, size); + styleResolver->setFontDescription(fontDescription); return; } @@ -756,12 +750,12 @@ public: class ApplyPropertyFontWeight { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - FontDescription fontDescription = selector->fontDescription(); + FontDescription fontDescription = styleResolver->fontDescription(); switch (primitiveValue->getIdent()) { case CSSValueInvalid: ASSERT_NOT_REACHED(); @@ -775,7 +769,7 @@ public: default: fontDescription.setWeight(*primitiveValue); } - selector->setFontDescription(fontDescription); + styleResolver->setFontDescription(fontDescription); } static PropertyHandler createHandler() { @@ -786,30 +780,30 @@ public: class ApplyPropertyFontVariantLigatures { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - const FontDescription& parentFontDescription = selector->parentFontDescription(); - FontDescription fontDescription = selector->fontDescription(); + const FontDescription& parentFontDescription = styleResolver->parentFontDescription(); + FontDescription fontDescription = styleResolver->fontDescription(); fontDescription.setCommonLigaturesState(parentFontDescription.commonLigaturesState()); fontDescription.setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState()); fontDescription.setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState()); - selector->setFontDescription(fontDescription); + styleResolver->setFontDescription(fontDescription); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - FontDescription fontDescription = selector->fontDescription(); + FontDescription fontDescription = styleResolver->fontDescription(); fontDescription.setCommonLigaturesState(FontDescription::NormalLigaturesState); fontDescription.setDiscretionaryLigaturesState(FontDescription::NormalLigaturesState); fontDescription.setHistoricalLigaturesState(FontDescription::NormalLigaturesState); - selector->setFontDescription(fontDescription); + styleResolver->setFontDescription(fontDescription); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState; FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState; @@ -855,11 +849,11 @@ public: } #endif - FontDescription fontDescription = selector->fontDescription(); + FontDescription fontDescription = styleResolver->fontDescription(); fontDescription.setCommonLigaturesState(commonLigaturesState); fontDescription.setDiscretionaryLigaturesState(discretionaryLigaturesState); fontDescription.setHistoricalLigaturesState(historicalLigaturesState); - selector->setFontDescription(fontDescription); + styleResolver->setFontDescription(fontDescription); } static PropertyHandler createHandler() @@ -875,13 +869,13 @@ template <BorderImageType borderImageType, void (RenderStyle::*setterFunction)(const NinePieceImage&)> class ApplyPropertyBorderImage { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { NinePieceImage image; if (borderImageType == Mask) image.setMaskDefaults(); - selector->mapNinePieceImage(property, value, image); - (selector->style()->*setterFunction)(image); + styleResolver->mapNinePieceImage(property, value, image); + (styleResolver->style()->*setterFunction)(image); } static PropertyHandler createHandler() @@ -898,29 +892,29 @@ private: static inline const NinePieceImage& getValue(RenderStyle* style) { return type == Image ? style->borderImage() : style->maskBoxImage(); } static inline void setValue(RenderStyle* style, const NinePieceImage& value) { return type == Image ? style->setBorderImage(value) : style->setMaskBoxImage(value); } public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - NinePieceImage image(getValue(selector->style())); + NinePieceImage image(getValue(styleResolver->style())); switch (modifier) { case Outset: - image.copyOutsetFrom(getValue(selector->parentStyle())); + image.copyOutsetFrom(getValue(styleResolver->parentStyle())); break; case Repeat: - image.copyRepeatFrom(getValue(selector->parentStyle())); + image.copyRepeatFrom(getValue(styleResolver->parentStyle())); break; case Slice: - image.copyImageSlicesFrom(getValue(selector->parentStyle())); + image.copyImageSlicesFrom(getValue(styleResolver->parentStyle())); break; case Width: - image.copyBorderSlicesFrom(getValue(selector->parentStyle())); + image.copyBorderSlicesFrom(getValue(styleResolver->parentStyle())); break; } - setValue(selector->style(), image); + setValue(styleResolver->style(), image); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - NinePieceImage image(getValue(selector->style())); + NinePieceImage image(getValue(styleResolver->style())); switch (modifier) { case Outset: image.setOutset(LengthBox(0)); @@ -939,27 +933,27 @@ public: image.setBorderSlices(type == Image ? LengthBox(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative)) : LengthBox()); break; } - setValue(selector->style(), image); + setValue(styleResolver->style(), image); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - NinePieceImage image(getValue(selector->style())); + NinePieceImage image(getValue(styleResolver->style())); switch (modifier) { case Outset: - image.setOutset(selector->mapNinePieceImageQuad(value)); + image.setOutset(styleResolver->mapNinePieceImageQuad(value)); break; case Repeat: - selector->mapNinePieceImageRepeat(value, image); + styleResolver->mapNinePieceImageRepeat(value, image); break; case Slice: - selector->mapNinePieceImageSlice(value, image); + styleResolver->mapNinePieceImageSlice(value, image); break; case Width: - image.setBorderSlices(selector->mapNinePieceImageQuad(value)); + image.setBorderSlices(styleResolver->mapNinePieceImageQuad(value)); break; } - setValue(selector->style(), image); + setValue(styleResolver->style(), image); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } @@ -968,7 +962,7 @@ public: template <CSSPropertyID id, StyleImage* (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(PassRefPtr<StyleImage>), StyleImage* (*initialFunction)()> class ApplyPropertyBorderImageSource { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) { (selector->style()->*setterFunction)(selector->styleImage(id, value)); } + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { (styleResolver->style()->*setterFunction)(styleResolver->styleImage(id, value)); } static PropertyHandler createHandler() { PropertyHandler handler = ApplyPropertyDefaultBase<StyleImage*, getterFunction, PassRefPtr<StyleImage>, setterFunction, StyleImage*, initialFunction>::createHandler(); @@ -980,16 +974,16 @@ enum CounterBehavior {Increment = 0, Reset}; template <CounterBehavior counterBehavior> class ApplyPropertyCounter { public: - static void emptyFunction(CSSStyleSelector*) { } - static void applyInheritValue(CSSStyleSelector* selector) + static void emptyFunction(StyleResolver*) { } + static void applyInheritValue(StyleResolver* styleResolver) { - CounterDirectiveMap& map = selector->style()->accessCounterDirectives(); - CounterDirectiveMap& parentMap = selector->parentStyle()->accessCounterDirectives(); + CounterDirectiveMap& map = styleResolver->style()->accessCounterDirectives(); + CounterDirectiveMap& parentMap = styleResolver->parentStyle()->accessCounterDirectives(); typedef CounterDirectiveMap::iterator Iterator; Iterator end = parentMap.end(); for (Iterator it = parentMap.begin(); it != end; ++it) { - CounterDirectives& directives = map.add(it->first, CounterDirectives()).first->second; + CounterDirectives& directives = map.add(it->first, CounterDirectives()).iterator->second; if (counterBehavior == Reset) { directives.m_reset = it->second.m_reset; directives.m_resetValue = it->second.m_resetValue; @@ -1008,14 +1002,14 @@ public: } } } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isValueList()) return; CSSValueList* list = static_cast<CSSValueList*>(value); - CounterDirectiveMap& map = selector->style()->accessCounterDirectives(); + CounterDirectiveMap& map = styleResolver->style()->accessCounterDirectives(); typedef CounterDirectiveMap::iterator Iterator; Iterator end = map.end(); @@ -1037,7 +1031,7 @@ public: AtomicString identifier = static_cast<CSSPrimitiveValue*>(pair->first())->getStringValue(); int value = static_cast<CSSPrimitiveValue*>(pair->second())->getIntValue(); - CounterDirectives& directives = map.add(identifier.impl(), CounterDirectives()).first->second; + CounterDirectives& directives = map.add(identifier.impl(), CounterDirectives()).iterator->second; if (counterBehavior == Reset) { directives.m_reset = true; directives.m_resetValue = value; @@ -1059,44 +1053,42 @@ public: class ApplyPropertyCursor { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - selector->style()->setCursor(selector->parentStyle()->cursor()); - selector->style()->setCursorList(selector->parentStyle()->cursors()); + styleResolver->style()->setCursor(styleResolver->parentStyle()->cursor()); + styleResolver->style()->setCursorList(styleResolver->parentStyle()->cursors()); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - selector->style()->clearCursorList(); - selector->style()->setCursor(RenderStyle::initialCursor()); + styleResolver->style()->clearCursorList(); + styleResolver->style()->setCursor(RenderStyle::initialCursor()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - selector->style()->clearCursorList(); + styleResolver->style()->clearCursorList(); if (value->isValueList()) { CSSValueList* list = static_cast<CSSValueList*>(value); int len = list->length(); - selector->style()->setCursor(CURSOR_AUTO); + styleResolver->style()->setCursor(CURSOR_AUTO); for (int i = 0; i < len; i++) { CSSValue* item = list->itemWithoutBoundsCheck(i); - if (!item->isPrimitiveValue()) - continue; - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(item); - if (primitiveValue->isURI()) { - if (primitiveValue->isCursorImageValue()) { - CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(primitiveValue); - if (image->updateIfSVGCursorIsUsed(selector->element())) // Elements with SVG cursors are not allowed to share style. - selector->style()->setUnique(); - selector->style()->addCursor(selector->cachedOrPendingFromValue(CSSPropertyCursor, image), image->hotSpot()); - } - } else if (primitiveValue->isIdent()) - selector->style()->setCursor(*primitiveValue); + if (item->isCursorImageValue()) { + CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(item); + if (image->updateIfSVGCursorIsUsed(styleResolver->element())) // Elements with SVG cursors are not allowed to share style. + styleResolver->style()->setUnique(); + styleResolver->style()->addCursor(styleResolver->cachedOrPendingFromValue(CSSPropertyCursor, image), image->hotSpot()); + } else if (item->isPrimitiveValue()) { + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(item); + if (primitiveValue->isIdent()) + styleResolver->style()->setCursor(*primitiveValue); + } } } else if (value->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->isIdent() && selector->style()->cursor() != ECursor(*primitiveValue)) - selector->style()->setCursor(*primitiveValue); + if (primitiveValue->isIdent() && styleResolver->style()->cursor() != ECursor(*primitiveValue)) + styleResolver->style()->setCursor(*primitiveValue); } } @@ -1105,7 +1097,7 @@ public: class ApplyPropertyTextAlign { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; @@ -1113,13 +1105,13 @@ public: CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->getIdent() != CSSValueWebkitMatchParent) - selector->style()->setTextAlign(*primitiveValue); - else if (selector->parentStyle()->textAlign() == TASTART) - selector->style()->setTextAlign(selector->parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); - else if (selector->parentStyle()->textAlign() == TAEND) - selector->style()->setTextAlign(selector->parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); + styleResolver->style()->setTextAlign(*primitiveValue); + else if (styleResolver->parentStyle()->textAlign() == TASTART) + styleResolver->style()->setTextAlign(styleResolver->parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); + else if (styleResolver->parentStyle()->textAlign() == TAEND) + styleResolver->style()->setTextAlign(styleResolver->parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); else - selector->style()->setTextAlign(selector->parentStyle()->textAlign()); + styleResolver->style()->setTextAlign(styleResolver->parentStyle()->textAlign()); } static PropertyHandler createHandler() { @@ -1130,7 +1122,7 @@ public: class ApplyPropertyTextDecoration { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { ETextDecoration t = RenderStyle::initialTextDecoration(); for (CSSValueListIterator i(value); i.hasMore(); i.advance()) { @@ -1138,7 +1130,7 @@ public: ASSERT(item->isPrimitiveValue()); t |= *static_cast<CSSPrimitiveValue*>(item); } - selector->style()->setTextDecoration(t); + styleResolver->style()->setTextDecoration(t); } static PropertyHandler createHandler() { @@ -1149,7 +1141,7 @@ public: class ApplyPropertyUnicodeBidi { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (value->isValueList()) { EUnicodeBidi rendererUnicodeBidi = RenderStyle::initialUnicodeBidi(); @@ -1163,12 +1155,12 @@ public: else rendererUnicodeBidi = currentValue; } - selector->style()->setUnicodeBidi(rendererUnicodeBidi); + styleResolver->style()->setUnicodeBidi(rendererUnicodeBidi); } if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - selector->style()->setUnicodeBidi(*primitiveValue); + styleResolver->style()->setUnicodeBidi(*primitiveValue); } static PropertyHandler createHandler() { @@ -1179,7 +1171,7 @@ public: class ApplyPropertyLineHeight { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; @@ -1190,21 +1182,23 @@ public: if (primitiveValue->getIdent() == CSSValueNormal) lineHeight = Length(-100.0, Percent); else if (primitiveValue->isLength()) { - double multiplier = selector->style()->effectiveZoom(); - if (selector->style()->textSizeAdjust()) { - if (Frame* frame = selector->document()->frame()) + double multiplier = styleResolver->style()->effectiveZoom(); + if (styleResolver->style()->textSizeAdjust()) { + if (Frame* frame = styleResolver->document()->frame()) multiplier *= frame->textZoomFactor(); } - lineHeight = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), multiplier); + lineHeight = primitiveValue->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle(), multiplier); } else if (primitiveValue->isPercentage()) { // FIXME: percentage should not be restricted to an integer here. - lineHeight = Length((selector->style()->fontSize() * primitiveValue->getIntValue()) / 100, Fixed); + lineHeight = Length((styleResolver->style()->fontSize() * primitiveValue->getIntValue()) / 100, 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); - } else + } else if (primitiveValue->isViewportPercentageLength()) + lineHeight = primitiveValue->viewportPercentageLength(); + else return; - selector->style()->setLineHeight(lineHeight); + styleResolver->style()->setLineHeight(lineHeight); } static PropertyHandler createHandler() { @@ -1291,11 +1285,11 @@ private: return true; } public: - static void applyInheritValue(CSSStyleSelector*) { } - static void applyInitialValue(CSSStyleSelector*) { } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyInheritValue(StyleResolver*) { } + static void applyInitialValue(StyleResolver*) { } + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - selector->style()->resetPageSizeType(); + styleResolver->style()->resetPageSizeType(); Length width; Length height; PageSizeType pageSizeType = PAGE_SIZE_AUTO; @@ -1311,8 +1305,8 @@ public: // <length>{2} if (!second->isLength()) return; - width = first->computeLength<Length>(selector->style(), selector->rootElementStyle()); - height = second->computeLength<Length>(selector->style(), selector->rootElementStyle()); + width = first->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle()); + height = second->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle()); } else { // <page-size> <orientation> // The value order is guaranteed. See CSSParser::parseSizeParameter. @@ -1330,7 +1324,7 @@ public: if (primitiveValue->isLength()) { // <length> pageSizeType = PAGE_SIZE_RESOLVED; - width = height = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle()); + width = height = primitiveValue->computeLength<Length>(styleResolver->style(), styleResolver->rootElementStyle()); } else { switch (primitiveValue->getIdent()) { case 0: @@ -1356,29 +1350,29 @@ public: default: return; } - selector->style()->setPageSizeType(pageSizeType); - selector->style()->setPageSize(LengthSize(width, height)); + styleResolver->style()->setPageSizeType(pageSizeType); + styleResolver->style()->setPageSize(LengthSize(width, height)); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } }; class ApplyPropertyTextEmphasisStyle { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - selector->style()->setTextEmphasisFill(selector->parentStyle()->textEmphasisFill()); - selector->style()->setTextEmphasisMark(selector->parentStyle()->textEmphasisMark()); - selector->style()->setTextEmphasisCustomMark(selector->parentStyle()->textEmphasisCustomMark()); + styleResolver->style()->setTextEmphasisFill(styleResolver->parentStyle()->textEmphasisFill()); + styleResolver->style()->setTextEmphasisMark(styleResolver->parentStyle()->textEmphasisMark()); + styleResolver->style()->setTextEmphasisCustomMark(styleResolver->parentStyle()->textEmphasisCustomMark()); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - selector->style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill()); - selector->style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark()); - selector->style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark()); + styleResolver->style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill()); + styleResolver->style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark()); + styleResolver->style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (value->isValueList()) { CSSValueList* list = static_cast<CSSValueList*>(value); @@ -1392,11 +1386,11 @@ public: CSSPrimitiveValue* value = static_cast<CSSPrimitiveValue*>(item); if (value->getIdent() == CSSValueFilled || value->getIdent() == CSSValueOpen) - selector->style()->setTextEmphasisFill(*value); + styleResolver->style()->setTextEmphasisFill(*value); else - selector->style()->setTextEmphasisMark(*value); + styleResolver->style()->setTextEmphasisMark(*value); } - selector->style()->setTextEmphasisCustomMark(nullAtom); + styleResolver->style()->setTextEmphasisCustomMark(nullAtom); return; } @@ -1405,20 +1399,20 @@ public: CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->isString()) { - selector->style()->setTextEmphasisFill(TextEmphasisFillFilled); - selector->style()->setTextEmphasisMark(TextEmphasisMarkCustom); - selector->style()->setTextEmphasisCustomMark(primitiveValue->getStringValue()); + styleResolver->style()->setTextEmphasisFill(TextEmphasisFillFilled); + styleResolver->style()->setTextEmphasisMark(TextEmphasisMarkCustom); + styleResolver->style()->setTextEmphasisCustomMark(primitiveValue->getStringValue()); return; } - selector->style()->setTextEmphasisCustomMark(nullAtom); + styleResolver->style()->setTextEmphasisCustomMark(nullAtom); if (primitiveValue->getIdent() == CSSValueFilled || primitiveValue->getIdent() == CSSValueOpen) { - selector->style()->setTextEmphasisFill(*primitiveValue); - selector->style()->setTextEmphasisMark(TextEmphasisMarkAuto); + styleResolver->style()->setTextEmphasisFill(*primitiveValue); + styleResolver->style()->setTextEmphasisMark(TextEmphasisMarkAuto); } else { - selector->style()->setTextEmphasisFill(TextEmphasisFillFilled); - selector->style()->setTextEmphasisMark(*primitiveValue); + styleResolver->style()->setTextEmphasisFill(TextEmphasisFillFilled); + styleResolver->style()->setTextEmphasisMark(*primitiveValue); } } @@ -1431,7 +1425,7 @@ template <typename T, bool (Animation::*testFunction)() const, void (Animation::*clearFunction)(), T (*initialFunction)(), - void (CSSStyleSelector::*mapFunction)(Animation*, CSSValue*), + void (StyleResolver::*mapFunction)(Animation*, CSSValue*), AnimationList* (RenderStyle::*animationGetterFunction)(), const AnimationList* (RenderStyle::*immutableAnimationGetterFunction)() const> class ApplyPropertyAnimation { @@ -1441,19 +1435,20 @@ public: static bool test(const Animation* animation) { return (animation->*testFunction)(); } static void clear(Animation* animation) { (animation->*clearFunction)(); } static T initial() { return (*initialFunction)(); } - static void map(CSSStyleSelector* selector, Animation* animation, CSSValue* value) { (selector->*mapFunction)(animation, value); } + static void map(StyleResolver* styleResolver, Animation* animation, CSSValue* value) { (styleResolver->*mapFunction)(animation, value); } static AnimationList* accessAnimations(RenderStyle* style) { return (style->*animationGetterFunction)(); } static const AnimationList* animations(RenderStyle* style) { return (style->*immutableAnimationGetterFunction)(); } - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - AnimationList* list = accessAnimations(selector->style()); - const AnimationList* parentList = animations(selector->parentStyle()); + AnimationList* list = accessAnimations(styleResolver->style()); + const AnimationList* parentList = animations(styleResolver->parentStyle()); size_t i = 0, parentSize = parentList ? parentList->size() : 0; for ( ; i < parentSize && test(parentList->animation(i)); ++i) { if (list->size() <= i) list->append(Animation::create()); setValue(list->animation(i), value(parentList->animation(i))); + list->animation(i)->setAnimationMode(parentList->animation(i)->animationMode()); } /* Reset any remaining animations to not have the property set. */ @@ -1461,9 +1456,9 @@ public: clear(list->animation(i)); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - AnimationList* list = accessAnimations(selector->style()); + AnimationList* list = accessAnimations(styleResolver->style()); if (list->isEmpty()) list->append(Animation::create()); setValue(list->animation(0), initial()); @@ -1471,22 +1466,22 @@ public: clear(list->animation(i)); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - AnimationList* list = accessAnimations(selector->style()); + AnimationList* list = accessAnimations(styleResolver->style()); size_t childIndex = 0; if (value->isValueList()) { /* Walk each value and put it into an animation, creating new animations as needed. */ for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { if (childIndex <= list->size()) list->append(Animation::create()); - map(selector, list->animation(childIndex), i.value()); + map(styleResolver, list->animation(childIndex), i.value()); ++childIndex; } } else { if (list->isEmpty()) list->append(Animation::create()); - map(selector, list->animation(childIndex), value); + map(styleResolver, list->animation(childIndex), value); childIndex = 1; } for ( ; childIndex < list->size(); ++childIndex) { @@ -1500,22 +1495,22 @@ public: class ApplyPropertyOutlineStyle { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - ApplyPropertyDefaultBase<OutlineIsAuto, &RenderStyle::outlineStyleIsAuto, OutlineIsAuto, &RenderStyle::setOutlineStyleIsAuto, OutlineIsAuto, &RenderStyle::initialOutlineStyleIsAuto>::applyInheritValue(selector); - ApplyPropertyDefaultBase<EBorderStyle, &RenderStyle::outlineStyle, EBorderStyle, &RenderStyle::setOutlineStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::applyInheritValue(selector); + ApplyPropertyDefaultBase<OutlineIsAuto, &RenderStyle::outlineStyleIsAuto, OutlineIsAuto, &RenderStyle::setOutlineStyleIsAuto, OutlineIsAuto, &RenderStyle::initialOutlineStyleIsAuto>::applyInheritValue(styleResolver); + ApplyPropertyDefaultBase<EBorderStyle, &RenderStyle::outlineStyle, EBorderStyle, &RenderStyle::setOutlineStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::applyInheritValue(styleResolver); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - ApplyPropertyDefaultBase<OutlineIsAuto, &RenderStyle::outlineStyleIsAuto, OutlineIsAuto, &RenderStyle::setOutlineStyleIsAuto, OutlineIsAuto, &RenderStyle::initialOutlineStyleIsAuto>::applyInitialValue(selector); - ApplyPropertyDefaultBase<EBorderStyle, &RenderStyle::outlineStyle, EBorderStyle, &RenderStyle::setOutlineStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::applyInitialValue(selector); + ApplyPropertyDefaultBase<OutlineIsAuto, &RenderStyle::outlineStyleIsAuto, OutlineIsAuto, &RenderStyle::setOutlineStyleIsAuto, OutlineIsAuto, &RenderStyle::initialOutlineStyleIsAuto>::applyInitialValue(styleResolver); + ApplyPropertyDefaultBase<EBorderStyle, &RenderStyle::outlineStyle, EBorderStyle, &RenderStyle::setOutlineStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::applyInitialValue(styleResolver); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { - ApplyPropertyDefault<OutlineIsAuto, &RenderStyle::outlineStyleIsAuto, OutlineIsAuto, &RenderStyle::setOutlineStyleIsAuto, OutlineIsAuto, &RenderStyle::initialOutlineStyleIsAuto>::applyValue(selector, value); - ApplyPropertyDefault<EBorderStyle, &RenderStyle::outlineStyle, EBorderStyle, &RenderStyle::setOutlineStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::applyValue(selector, value); + ApplyPropertyDefault<OutlineIsAuto, &RenderStyle::outlineStyleIsAuto, OutlineIsAuto, &RenderStyle::setOutlineStyleIsAuto, OutlineIsAuto, &RenderStyle::initialOutlineStyleIsAuto>::applyValue(styleResolver, value); + ApplyPropertyDefault<EBorderStyle, &RenderStyle::outlineStyle, EBorderStyle, &RenderStyle::setOutlineStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::applyValue(styleResolver, value); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } @@ -1523,7 +1518,7 @@ public: class ApplyPropertyResize { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; @@ -1535,13 +1530,13 @@ public: case 0: return; case CSSValueAuto: - if (Settings* settings = selector->document()->settings()) + if (Settings* settings = styleResolver->document()->settings()) r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE; break; default: r = *primitiveValue; } - selector->style()->setResize(r); + styleResolver->style()->setResize(r); } static PropertyHandler createHandler() @@ -1553,7 +1548,7 @@ public: class ApplyPropertyVerticalAlign { public: - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; @@ -1561,15 +1556,9 @@ public: CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->getIdent()) - return selector->style()->setVerticalAlign(*primitiveValue); + return styleResolver->style()->setVerticalAlign(*primitiveValue); - Length length; - if (primitiveValue->isLength()) - length = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()); - else if (primitiveValue->isPercentage()) - length = Length(primitiveValue->getDoubleValue(), Percent); - - selector->style()->setVerticalAlignLength(length); + styleResolver->style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion | ViewportPercentageConversion>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom())); } static PropertyHandler createHandler() @@ -1581,32 +1570,32 @@ public: class ApplyPropertyAspectRatio { public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - if (!selector->parentStyle()->hasAspectRatio()) + if (!styleResolver->parentStyle()->hasAspectRatio()) return; - selector->style()->setHasAspectRatio(true); - selector->style()->setAspectRatioDenominator(selector->parentStyle()->aspectRatioDenominator()); - selector->style()->setAspectRatioNumerator(selector->parentStyle()->aspectRatioNumerator()); + styleResolver->style()->setHasAspectRatio(true); + styleResolver->style()->setAspectRatioDenominator(styleResolver->parentStyle()->aspectRatioDenominator()); + styleResolver->style()->setAspectRatioNumerator(styleResolver->parentStyle()->aspectRatioNumerator()); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - selector->style()->setHasAspectRatio(RenderStyle::initialHasAspectRatio()); - selector->style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator()); - selector->style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator()); + styleResolver->style()->setHasAspectRatio(RenderStyle::initialHasAspectRatio()); + styleResolver->style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator()); + styleResolver->style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isAspectRatioValue()) { - selector->style()->setHasAspectRatio(false); + styleResolver->style()->setHasAspectRatio(false); return; } CSSAspectRatioValue* aspectRatioValue = static_cast<CSSAspectRatioValue*>(value); - selector->style()->setHasAspectRatio(true); - selector->style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue()); - selector->style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue()); + styleResolver->style()->setHasAspectRatio(true); + styleResolver->style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue()); + styleResolver->style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue()); } static PropertyHandler createHandler() @@ -1617,48 +1606,48 @@ public: class ApplyPropertyZoom { private: - static void resetEffectiveZoom(CSSStyleSelector* selector) + static void resetEffectiveZoom(StyleResolver* styleResolver) { // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect. - selector->setEffectiveZoom(selector->parentStyle() ? selector->parentStyle()->effectiveZoom() : RenderStyle::initialZoom()); + styleResolver->setEffectiveZoom(styleResolver->parentStyle() ? styleResolver->parentStyle()->effectiveZoom() : RenderStyle::initialZoom()); } public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - resetEffectiveZoom(selector); - selector->setZoom(selector->parentStyle()->zoom()); + resetEffectiveZoom(styleResolver); + styleResolver->setZoom(styleResolver->parentStyle()->zoom()); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - resetEffectiveZoom(selector); - selector->setZoom(RenderStyle::initialZoom()); + resetEffectiveZoom(styleResolver); + styleResolver->setZoom(RenderStyle::initialZoom()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { ASSERT(value->isPrimitiveValue()); CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->getIdent() == CSSValueNormal) { - resetEffectiveZoom(selector); - selector->setZoom(RenderStyle::initialZoom()); + resetEffectiveZoom(styleResolver); + styleResolver->setZoom(RenderStyle::initialZoom()); } else if (primitiveValue->getIdent() == CSSValueReset) { - selector->setEffectiveZoom(RenderStyle::initialZoom()); - selector->setZoom(RenderStyle::initialZoom()); + styleResolver->setEffectiveZoom(RenderStyle::initialZoom()); + styleResolver->setZoom(RenderStyle::initialZoom()); } else if (primitiveValue->getIdent() == CSSValueDocument) { - float docZoom = selector->document()->renderer()->style()->zoom(); - selector->setEffectiveZoom(docZoom); - selector->setZoom(docZoom); + float docZoom = styleResolver->rootElementStyle() ? styleResolver->rootElementStyle()->zoom() : RenderStyle::initialZoom(); + styleResolver->setEffectiveZoom(docZoom); + styleResolver->setZoom(docZoom); } else if (primitiveValue->isPercentage()) { - resetEffectiveZoom(selector); + resetEffectiveZoom(styleResolver); if (float percent = primitiveValue->getFloatValue()) - selector->setZoom(percent / 100.0f); + styleResolver->setZoom(percent / 100.0f); } else if (primitiveValue->isNumber()) { - resetEffectiveZoom(selector); + resetEffectiveZoom(styleResolver); if (float number = primitiveValue->getFloatValue()) - selector->setZoom(number); + styleResolver->setZoom(number); } } @@ -1670,74 +1659,135 @@ public: class ApplyPropertyDisplay { private: - static inline bool isValidDisplayValue(CSSStyleSelector* selector, EDisplay displayPropertyValue) + static inline bool isValidDisplayValue(StyleResolver* styleResolver, EDisplay displayPropertyValue) { #if ENABLE(SVG) - if (selector->element() && selector->element()->isSVGElement() && selector->style()->styleType() == NOPSEUDO) + if (styleResolver->element() && styleResolver->element()->isSVGElement() && styleResolver->style()->styleType() == NOPSEUDO) return (displayPropertyValue == INLINE || displayPropertyValue == BLOCK || displayPropertyValue == NONE); #else - UNUSED_PARAM(selector); + UNUSED_PARAM(styleResolver); UNUSED_PARAM(displayPropertyValue); #endif return true; } public: - static void applyInheritValue(CSSStyleSelector* selector) + static void applyInheritValue(StyleResolver* styleResolver) { - EDisplay display = selector->parentStyle()->display(); - if (!isValidDisplayValue(selector, display)) + EDisplay display = styleResolver->parentStyle()->display(); + if (!isValidDisplayValue(styleResolver, display)) return; - selector->style()->setDisplay(display); + styleResolver->style()->setDisplay(display); } - static void applyInitialValue(CSSStyleSelector* selector) + static void applyInitialValue(StyleResolver* styleResolver) { - selector->style()->setDisplay(RenderStyle::initialDisplay()); + styleResolver->style()->setDisplay(RenderStyle::initialDisplay()); } - static void applyValue(CSSStyleSelector* selector, CSSValue* value) + static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (!value->isPrimitiveValue()) return; EDisplay display = *static_cast<CSSPrimitiveValue*>(value); - if (!isValidDisplayValue(selector, display)) + if (!isValidDisplayValue(styleResolver, display)) + return; + + styleResolver->style()->setDisplay(display); + } + + static PropertyHandler createHandler() + { + return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); + } +}; + +class ApplyPropertyFlex { +public: + static void applyInheritValue(StyleResolver* styleResolver) + { + ApplyPropertyDefaultBase<float, &RenderStyle::positiveFlex, float, &RenderStyle::setPositiveFlex, float, &RenderStyle::initialNegativeFlex>::applyInheritValue(styleResolver); + ApplyPropertyDefaultBase<float, &RenderStyle::negativeFlex, float, &RenderStyle::setNegativeFlex, float, &RenderStyle::initialPositiveFlex>::applyInheritValue(styleResolver); + ApplyPropertyDefaultBase<Length, &RenderStyle::flexPreferredSize, Length, &RenderStyle::setFlexPreferredSize, Length, &RenderStyle::initialFlexPreferredSize>::applyInheritValue(styleResolver); + } + + static void applyInitialValue(StyleResolver* styleResolver) + { + styleResolver->style()->setPositiveFlex(RenderStyle::initialPositiveFlex()); + styleResolver->style()->setNegativeFlex(RenderStyle::initialNegativeFlex()); + styleResolver->style()->setFlexPreferredSize(RenderStyle::initialFlexPreferredSize()); + } + + static void applyValue(StyleResolver* styleResolver, CSSValue* value) + { + if (value->isPrimitiveValue()) { + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + if (primitiveValue->getIdent() == CSSValueNone) + applyInitialValue(styleResolver); + return; + } + + if (!value->isValueList()) + return; + CSSValueList* valueList = static_cast<CSSValueList*>(value); + if (valueList->length() != 3) + return; + + float flexValue = 0; + if (!getFlexValue(valueList->itemWithoutBoundsCheck(0), flexValue)) return; + styleResolver->style()->setPositiveFlex(flexValue); - selector->style()->setDisplay(display); + if (!getFlexValue(valueList->itemWithoutBoundsCheck(1), flexValue)) + return; + styleResolver->style()->setNegativeFlex(flexValue); + + ApplyPropertyLength<&RenderStyle::flexPreferredSize, &RenderStyle::setFlexPreferredSize, &RenderStyle::initialFlexPreferredSize, AutoEnabled>::applyValue(styleResolver, valueList->itemWithoutBoundsCheck(2)); } static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); } +private: + static bool getFlexValue(CSSValue* value, float& flexValue) + { + if (!value->isPrimitiveValue()) + return false; + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); + if (!primitiveValue->isNumber()) + return false; + flexValue = primitiveValue->getFloatValue(); + return true; + } + }; -const CSSStyleApplyProperty& CSSStyleApplyProperty::sharedCSSStyleApplyProperty() +const StyleBuilder& StyleBuilder::sharedStyleBuilder() { - DEFINE_STATIC_LOCAL(CSSStyleApplyProperty, cssStyleApplyPropertyInstance, ()); - return cssStyleApplyPropertyInstance; + DEFINE_STATIC_LOCAL(StyleBuilder, styleBuilderInstance, ()); + return styleBuilderInstance; } -CSSStyleApplyProperty::CSSStyleApplyProperty() +StyleBuilder::StyleBuilder() { for (int i = 0; i < numCSSProperties; ++i) m_propertyMap[i] = PropertyHandler(); // Please keep CSS property list in alphabetical order. - setPropertyHandler(CSSPropertyBackgroundAttachment, ApplyPropertyFillLayer<EFillAttachment, CSSPropertyBackgroundAttachment, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isAttachmentSet, &FillLayer::attachment, &FillLayer::setAttachment, &FillLayer::clearAttachment, &FillLayer::initialFillAttachment, &CSSStyleSelector::mapFillAttachment>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundClip, ApplyPropertyFillLayer<EFillBox, CSSPropertyBackgroundClip, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isClipSet, &FillLayer::clip, &FillLayer::setClip, &FillLayer::clearClip, &FillLayer::initialFillClip, &CSSStyleSelector::mapFillClip>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundAttachment, ApplyPropertyFillLayer<EFillAttachment, CSSPropertyBackgroundAttachment, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isAttachmentSet, &FillLayer::attachment, &FillLayer::setAttachment, &FillLayer::clearAttachment, &FillLayer::initialFillAttachment, &StyleResolver::mapFillAttachment>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundClip, ApplyPropertyFillLayer<EFillBox, CSSPropertyBackgroundClip, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isClipSet, &FillLayer::clip, &FillLayer::setClip, &FillLayer::clearClip, &FillLayer::initialFillClip, &StyleResolver::mapFillClip>::createHandler()); setPropertyHandler(CSSPropertyBackgroundColor, ApplyPropertyColor<NoInheritFromParent, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor, &RenderStyle::invalidColor>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundImage, ApplyPropertyFillLayer<StyleImage*, CSSPropertyBackgroundImage, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isImageSet, &FillLayer::image, &FillLayer::setImage, &FillLayer::clearImage, &FillLayer::initialFillImage, &CSSStyleSelector::mapFillImage>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundOrigin, ApplyPropertyFillLayer<EFillBox, CSSPropertyBackgroundOrigin, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isOriginSet, &FillLayer::origin, &FillLayer::setOrigin, &FillLayer::clearOrigin, &FillLayer::initialFillOrigin, &CSSStyleSelector::mapFillOrigin>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundImage, ApplyPropertyFillLayer<StyleImage*, CSSPropertyBackgroundImage, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isImageSet, &FillLayer::image, &FillLayer::setImage, &FillLayer::clearImage, &FillLayer::initialFillImage, &StyleResolver::mapFillImage>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundOrigin, ApplyPropertyFillLayer<EFillBox, CSSPropertyBackgroundOrigin, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isOriginSet, &FillLayer::origin, &FillLayer::setOrigin, &FillLayer::clearOrigin, &FillLayer::initialFillOrigin, &StyleResolver::mapFillOrigin>::createHandler()); setPropertyHandler(CSSPropertyBackgroundPosition, ApplyPropertyExpanding<SuppressValue, CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundPositionX, ApplyPropertyFillLayer<Length, CSSPropertyBackgroundPositionX, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isXPositionSet, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::clearXPosition, &FillLayer::initialFillXPosition, &CSSStyleSelector::mapFillXPosition>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundPositionY, ApplyPropertyFillLayer<Length, CSSPropertyBackgroundPositionY, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isYPositionSet, &FillLayer::yPosition, &FillLayer::setYPosition, &FillLayer::clearYPosition, &FillLayer::initialFillYPosition, &CSSStyleSelector::mapFillYPosition>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundPositionX, ApplyPropertyFillLayer<Length, CSSPropertyBackgroundPositionX, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isXPositionSet, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::clearXPosition, &FillLayer::initialFillXPosition, &StyleResolver::mapFillXPosition>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundPositionY, ApplyPropertyFillLayer<Length, CSSPropertyBackgroundPositionY, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isYPositionSet, &FillLayer::yPosition, &FillLayer::setYPosition, &FillLayer::clearYPosition, &FillLayer::initialFillYPosition, &StyleResolver::mapFillYPosition>::createHandler()); setPropertyHandler(CSSPropertyBackgroundRepeat, ApplyPropertyExpanding<SuppressValue, CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundRepeatX, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyBackgroundRepeatX, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isRepeatXSet, &FillLayer::repeatX, &FillLayer::setRepeatX, &FillLayer::clearRepeatX, &FillLayer::initialFillRepeatX, &CSSStyleSelector::mapFillRepeatX>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundRepeatY, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyBackgroundRepeatY, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isRepeatYSet, &FillLayer::repeatY, &FillLayer::setRepeatY, &FillLayer::clearRepeatY, &FillLayer::initialFillRepeatY, &CSSStyleSelector::mapFillRepeatY>::createHandler()); - setPropertyHandler(CSSPropertyBackgroundSize, ApplyPropertyFillLayer<FillSize, CSSPropertyBackgroundSize, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isSizeSet, &FillLayer::size, &FillLayer::setSize, &FillLayer::clearSize, &FillLayer::initialFillSize, &CSSStyleSelector::mapFillSize>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundRepeatX, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyBackgroundRepeatX, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isRepeatXSet, &FillLayer::repeatX, &FillLayer::setRepeatX, &FillLayer::clearRepeatX, &FillLayer::initialFillRepeatX, &StyleResolver::mapFillRepeatX>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundRepeatY, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyBackgroundRepeatY, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isRepeatYSet, &FillLayer::repeatY, &FillLayer::setRepeatY, &FillLayer::clearRepeatY, &FillLayer::initialFillRepeatY, &StyleResolver::mapFillRepeatY>::createHandler()); + setPropertyHandler(CSSPropertyBackgroundSize, ApplyPropertyFillLayer<FillSize, CSSPropertyBackgroundSize, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isSizeSet, &FillLayer::size, &FillLayer::setSize, &FillLayer::clearSize, &FillLayer::initialFillSize, &StyleResolver::mapFillSize>::createHandler()); setPropertyHandler(CSSPropertyBorder, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderStyle, CSSPropertyBorderWidth, CSSPropertyBorderColor>::createHandler()); setPropertyHandler(CSSPropertyBorderBottom, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderBottomColor, CSSPropertyBorderBottomStyle, CSSPropertyBorderBottomWidth>::createHandler()); setPropertyHandler(CSSPropertyBorderBottomColor, ApplyPropertyColor<NoInheritFromParent, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor, &RenderStyle::setVisitedLinkBorderBottomColor, &RenderStyle::color>::createHandler()); @@ -1788,7 +1838,7 @@ CSSStyleApplyProperty::CSSStyleApplyProperty() setPropertyHandler(CSSPropertyFontStyle, ApplyPropertyFont<FontItalic, &FontDescription::italic, &FontDescription::setItalic, FontItalicOff>::createHandler()); setPropertyHandler(CSSPropertyFontVariant, ApplyPropertyFont<FontSmallCaps, &FontDescription::smallCaps, &FontDescription::setSmallCaps, FontSmallCapsOff>::createHandler()); setPropertyHandler(CSSPropertyFontWeight, ApplyPropertyFontWeight::createHandler()); - setPropertyHandler(CSSPropertyHeight, ApplyPropertyLength<&RenderStyle::height, &RenderStyle::setHeight, &RenderStyle::initialSize, AutoEnabled, IntrinsicEnabled, MinIntrinsicEnabled, NoneDisabled, UndefinedDisabled, FlexHeight>::createHandler()); + setPropertyHandler(CSSPropertyHeight, ApplyPropertyLength<&RenderStyle::height, &RenderStyle::setHeight, &RenderStyle::initialSize, AutoEnabled, IntrinsicEnabled, MinIntrinsicEnabled, NoneDisabled, UndefinedDisabled>::createHandler()); setPropertyHandler(CSSPropertyImageRendering, ApplyPropertyDefault<EImageRendering, &RenderStyle::imageRendering, EImageRendering, &RenderStyle::setImageRendering, EImageRendering, &RenderStyle::initialImageRendering>::createHandler()); setPropertyHandler(CSSPropertyLeft, ApplyPropertyLength<&RenderStyle::left, &RenderStyle::setLeft, &RenderStyle::initialOffset, AutoEnabled>::createHandler()); setPropertyHandler(CSSPropertyLetterSpacing, ApplyPropertyComputeLength<int, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing, &RenderStyle::initialLetterWordSpacing, NormalEnabled, ThicknessDisabled, SVGZoomEnabled>::createHandler()); @@ -1832,25 +1882,26 @@ CSSStyleApplyProperty::CSSStyleApplyProperty() setPropertyHandler(CSSPropertyTextAlign, ApplyPropertyTextAlign::createHandler()); setPropertyHandler(CSSPropertyTextDecoration, ApplyPropertyTextDecoration::createHandler()); setPropertyHandler(CSSPropertyTextIndent, ApplyPropertyLength<&RenderStyle::textIndent, &RenderStyle::setTextIndent, &RenderStyle::initialTextIndent>::createHandler()); + setPropertyHandler(CSSPropertyTextOverflow, ApplyPropertyDefault<TextOverflow, &RenderStyle::textOverflow, TextOverflow, &RenderStyle::setTextOverflow, TextOverflow, &RenderStyle::initialTextOverflow>::createHandler()); setPropertyHandler(CSSPropertyTextRendering, ApplyPropertyFont<TextRenderingMode, &FontDescription::textRenderingMode, &FontDescription::setTextRenderingMode, AutoTextRendering>::createHandler()); setPropertyHandler(CSSPropertyTextTransform, ApplyPropertyDefault<ETextTransform, &RenderStyle::textTransform, ETextTransform, &RenderStyle::setTextTransform, ETextTransform, &RenderStyle::initialTextTransform>::createHandler()); setPropertyHandler(CSSPropertyTop, ApplyPropertyLength<&RenderStyle::top, &RenderStyle::setTop, &RenderStyle::initialOffset, AutoEnabled>::createHandler()); setPropertyHandler(CSSPropertyUnicodeBidi, ApplyPropertyUnicodeBidi::createHandler()); setPropertyHandler(CSSPropertyVerticalAlign, ApplyPropertyVerticalAlign::createHandler()); setPropertyHandler(CSSPropertyVisibility, ApplyPropertyDefault<EVisibility, &RenderStyle::visibility, EVisibility, &RenderStyle::setVisibility, EVisibility, &RenderStyle::initialVisibility>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationDelay, ApplyPropertyAnimation<double, &Animation::delay, &Animation::setDelay, &Animation::isDelaySet, &Animation::clearDelay, &Animation::initialAnimationDelay, &CSSStyleSelector::mapAnimationDelay, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationDirection, ApplyPropertyAnimation<Animation::AnimationDirection, &Animation::direction, &Animation::setDirection, &Animation::isDirectionSet, &Animation::clearDirection, &Animation::initialAnimationDirection, &CSSStyleSelector::mapAnimationDirection, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationDuration, ApplyPropertyAnimation<double, &Animation::duration, &Animation::setDuration, &Animation::isDurationSet, &Animation::clearDuration, &Animation::initialAnimationDuration, &CSSStyleSelector::mapAnimationDuration, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationFillMode, ApplyPropertyAnimation<unsigned, &Animation::fillMode, &Animation::setFillMode, &Animation::isFillModeSet, &Animation::clearFillMode, &Animation::initialAnimationFillMode, &CSSStyleSelector::mapAnimationFillMode, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationIterationCount, ApplyPropertyAnimation<int, &Animation::iterationCount, &Animation::setIterationCount, &Animation::isIterationCountSet, &Animation::clearIterationCount, &Animation::initialAnimationIterationCount, &CSSStyleSelector::mapAnimationIterationCount, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationName, ApplyPropertyAnimation<const String&, &Animation::name, &Animation::setName, &Animation::isNameSet, &Animation::clearName, &Animation::initialAnimationName, &CSSStyleSelector::mapAnimationName, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationPlayState, ApplyPropertyAnimation<EAnimPlayState, &Animation::playState, &Animation::setPlayState, &Animation::isPlayStateSet, &Animation::clearPlayState, &Animation::initialAnimationPlayState, &CSSStyleSelector::mapAnimationPlayState, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); - setPropertyHandler(CSSPropertyWebkitAnimationTimingFunction, ApplyPropertyAnimation<const PassRefPtr<TimingFunction>, &Animation::timingFunction, &Animation::setTimingFunction, &Animation::isTimingFunctionSet, &Animation::clearTimingFunction, &Animation::initialAnimationTimingFunction, &CSSStyleSelector::mapAnimationTimingFunction, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationDelay, ApplyPropertyAnimation<double, &Animation::delay, &Animation::setDelay, &Animation::isDelaySet, &Animation::clearDelay, &Animation::initialAnimationDelay, &StyleResolver::mapAnimationDelay, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationDirection, ApplyPropertyAnimation<Animation::AnimationDirection, &Animation::direction, &Animation::setDirection, &Animation::isDirectionSet, &Animation::clearDirection, &Animation::initialAnimationDirection, &StyleResolver::mapAnimationDirection, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationDuration, ApplyPropertyAnimation<double, &Animation::duration, &Animation::setDuration, &Animation::isDurationSet, &Animation::clearDuration, &Animation::initialAnimationDuration, &StyleResolver::mapAnimationDuration, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationFillMode, ApplyPropertyAnimation<unsigned, &Animation::fillMode, &Animation::setFillMode, &Animation::isFillModeSet, &Animation::clearFillMode, &Animation::initialAnimationFillMode, &StyleResolver::mapAnimationFillMode, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationIterationCount, ApplyPropertyAnimation<double, &Animation::iterationCount, &Animation::setIterationCount, &Animation::isIterationCountSet, &Animation::clearIterationCount, &Animation::initialAnimationIterationCount, &StyleResolver::mapAnimationIterationCount, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationName, ApplyPropertyAnimation<const String&, &Animation::name, &Animation::setName, &Animation::isNameSet, &Animation::clearName, &Animation::initialAnimationName, &StyleResolver::mapAnimationName, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationPlayState, ApplyPropertyAnimation<EAnimPlayState, &Animation::playState, &Animation::setPlayState, &Animation::isPlayStateSet, &Animation::clearPlayState, &Animation::initialAnimationPlayState, &StyleResolver::mapAnimationPlayState, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); + setPropertyHandler(CSSPropertyWebkitAnimationTimingFunction, ApplyPropertyAnimation<const PassRefPtr<TimingFunction>, &Animation::timingFunction, &Animation::setTimingFunction, &Animation::isTimingFunctionSet, &Animation::clearTimingFunction, &Animation::initialAnimationTimingFunction, &StyleResolver::mapAnimationTimingFunction, &RenderStyle::accessAnimations, &RenderStyle::animations>::createHandler()); setPropertyHandler(CSSPropertyWebkitAppearance, ApplyPropertyDefault<ControlPart, &RenderStyle::appearance, ControlPart, &RenderStyle::setAppearance, ControlPart, &RenderStyle::initialAppearance>::createHandler()); setPropertyHandler(CSSPropertyWebkitAspectRatio, ApplyPropertyAspectRatio::createHandler()); setPropertyHandler(CSSPropertyWebkitBackfaceVisibility, ApplyPropertyDefault<EBackfaceVisibility, &RenderStyle::backfaceVisibility, EBackfaceVisibility, &RenderStyle::setBackfaceVisibility, EBackfaceVisibility, &RenderStyle::initialBackfaceVisibility>::createHandler()); setPropertyHandler(CSSPropertyWebkitBackgroundClip, CSSPropertyBackgroundClip); - setPropertyHandler(CSSPropertyWebkitBackgroundComposite, ApplyPropertyFillLayer<CompositeOperator, CSSPropertyWebkitBackgroundComposite, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isCompositeSet, &FillLayer::composite, &FillLayer::setComposite, &FillLayer::clearComposite, &FillLayer::initialFillComposite, &CSSStyleSelector::mapFillComposite>::createHandler()); + setPropertyHandler(CSSPropertyWebkitBackgroundComposite, ApplyPropertyFillLayer<CompositeOperator, CSSPropertyWebkitBackgroundComposite, BackgroundFillLayer, &RenderStyle::accessBackgroundLayers, &RenderStyle::backgroundLayers, &FillLayer::isCompositeSet, &FillLayer::composite, &FillLayer::setComposite, &FillLayer::clearComposite, &FillLayer::initialFillComposite, &StyleResolver::mapFillComposite>::createHandler()); setPropertyHandler(CSSPropertyWebkitBackgroundOrigin, CSSPropertyBackgroundOrigin); setPropertyHandler(CSSPropertyWebkitBackgroundSize, CSSPropertyBackgroundSize); setPropertyHandler(CSSPropertyWebkitBorderFit, ApplyPropertyDefault<EBorderFit, &RenderStyle::borderFit, EBorderFit, &RenderStyle::setBorderFit, EBorderFit, &RenderStyle::initialBorderFit>::createHandler()); @@ -1879,10 +1930,12 @@ CSSStyleApplyProperty::CSSStyleApplyProperty() setPropertyHandler(CSSPropertyWebkitColumnSpan, ApplyPropertyDefault<ColumnSpan, &RenderStyle::columnSpan, ColumnSpan, &RenderStyle::setColumnSpan, ColumnSpan, &RenderStyle::initialColumnSpan>::createHandler()); setPropertyHandler(CSSPropertyWebkitColumnRuleStyle, ApplyPropertyDefault<EBorderStyle, &RenderStyle::columnRuleStyle, EBorderStyle, &RenderStyle::setColumnRuleStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::createHandler()); setPropertyHandler(CSSPropertyWebkitColumnWidth, ApplyPropertyAuto<float, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth, &RenderStyle::hasAutoColumnWidth, &RenderStyle::setHasAutoColumnWidth, ComputeLength>::createHandler()); + setPropertyHandler(CSSPropertyWebkitFlex, ApplyPropertyFlex::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexAlign, ApplyPropertyDefault<EFlexAlign, &RenderStyle::flexAlign, EFlexAlign, &RenderStyle::setFlexAlign, EFlexAlign, &RenderStyle::initialFlexAlign>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexDirection, ApplyPropertyDefault<EFlexDirection, &RenderStyle::flexDirection, EFlexDirection, &RenderStyle::setFlexDirection, EFlexDirection, &RenderStyle::initialFlexDirection>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexFlow, ApplyPropertyExpanding<SuppressValue, CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexItemAlign, ApplyPropertyDefault<EFlexAlign, &RenderStyle::flexItemAlign, EFlexAlign, &RenderStyle::setFlexItemAlign, EFlexAlign, &RenderStyle::initialFlexItemAlign>::createHandler()); + setPropertyHandler(CSSPropertyWebkitFlexLinePack, ApplyPropertyDefault<EFlexLinePack, &RenderStyle::flexLinePack, EFlexLinePack, &RenderStyle::setFlexLinePack, EFlexLinePack, &RenderStyle::initialFlexLinePack>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexOrder, ApplyPropertyDefault<int, &RenderStyle::flexOrder, int, &RenderStyle::setFlexOrder, int, &RenderStyle::initialFlexOrder>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexPack, ApplyPropertyDefault<EFlexPack, &RenderStyle::flexPack, EFlexPack, &RenderStyle::setFlexPack, EFlexPack, &RenderStyle::initialFlexPack>::createHandler()); setPropertyHandler(CSSPropertyWebkitFlexWrap, ApplyPropertyDefault<EFlexWrap, &RenderStyle::flexWrap, EFlexWrap, &RenderStyle::setFlexWrap, EFlexWrap, &RenderStyle::initialFlexWrap>::createHandler()); @@ -1908,24 +1961,24 @@ CSSStyleApplyProperty::CSSStyleApplyProperty() setPropertyHandler(CSSPropertyWebkitMarginTopCollapse, CSSPropertyWebkitMarginBeforeCollapse); setPropertyHandler(CSSPropertyWebkitMarqueeDirection, ApplyPropertyDefault<EMarqueeDirection, &RenderStyle::marqueeDirection, EMarqueeDirection, &RenderStyle::setMarqueeDirection, EMarqueeDirection, &RenderStyle::initialMarqueeDirection>::createHandler()); setPropertyHandler(CSSPropertyWebkitMarqueeStyle, ApplyPropertyDefault<EMarqueeBehavior, &RenderStyle::marqueeBehavior, EMarqueeBehavior, &RenderStyle::setMarqueeBehavior, EMarqueeBehavior, &RenderStyle::initialMarqueeBehavior>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskAttachment, ApplyPropertyFillLayer<EFillAttachment, CSSPropertyWebkitMaskAttachment, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isAttachmentSet, &FillLayer::attachment, &FillLayer::setAttachment, &FillLayer::clearAttachment, &FillLayer::initialFillAttachment, &CSSStyleSelector::mapFillAttachment>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskAttachment, ApplyPropertyFillLayer<EFillAttachment, CSSPropertyWebkitMaskAttachment, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isAttachmentSet, &FillLayer::attachment, &FillLayer::setAttachment, &FillLayer::clearAttachment, &FillLayer::initialFillAttachment, &StyleResolver::mapFillAttachment>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImage, ApplyPropertyBorderImage<Mask, CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImageOutset, ApplyPropertyBorderImageModifier<Mask, Outset>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImageRepeat, ApplyPropertyBorderImageModifier<Mask, Repeat>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImageSlice, ApplyPropertyBorderImageModifier<Mask, Slice>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImageSource, ApplyPropertyBorderImageSource<CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource, &RenderStyle::initialMaskBoxImageSource>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImageWidth, ApplyPropertyBorderImageModifier<Mask, Width>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskClip, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskClip, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isClipSet, &FillLayer::clip, &FillLayer::setClip, &FillLayer::clearClip, &FillLayer::initialFillClip, &CSSStyleSelector::mapFillClip>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskComposite, ApplyPropertyFillLayer<CompositeOperator, CSSPropertyWebkitMaskComposite, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isCompositeSet, &FillLayer::composite, &FillLayer::setComposite, &FillLayer::clearComposite, &FillLayer::initialFillComposite, &CSSStyleSelector::mapFillComposite>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskImage, ApplyPropertyFillLayer<StyleImage*, CSSPropertyWebkitMaskImage, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isImageSet, &FillLayer::image, &FillLayer::setImage, &FillLayer::clearImage, &FillLayer::initialFillImage, &CSSStyleSelector::mapFillImage>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskOrigin, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskOrigin, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isOriginSet, &FillLayer::origin, &FillLayer::setOrigin, &FillLayer::clearOrigin, &FillLayer::initialFillOrigin, &CSSStyleSelector::mapFillOrigin>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskClip, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskClip, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isClipSet, &FillLayer::clip, &FillLayer::setClip, &FillLayer::clearClip, &FillLayer::initialFillClip, &StyleResolver::mapFillClip>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskComposite, ApplyPropertyFillLayer<CompositeOperator, CSSPropertyWebkitMaskComposite, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isCompositeSet, &FillLayer::composite, &FillLayer::setComposite, &FillLayer::clearComposite, &FillLayer::initialFillComposite, &StyleResolver::mapFillComposite>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskImage, ApplyPropertyFillLayer<StyleImage*, CSSPropertyWebkitMaskImage, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isImageSet, &FillLayer::image, &FillLayer::setImage, &FillLayer::clearImage, &FillLayer::initialFillImage, &StyleResolver::mapFillImage>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskOrigin, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskOrigin, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isOriginSet, &FillLayer::origin, &FillLayer::setOrigin, &FillLayer::clearOrigin, &FillLayer::initialFillOrigin, &StyleResolver::mapFillOrigin>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskPosition, ApplyPropertyExpanding<SuppressValue, CSSPropertyWebkitMaskPositionX, CSSPropertyWebkitMaskPositionY>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskPositionX, ApplyPropertyFillLayer<Length, CSSPropertyWebkitMaskPositionX, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isXPositionSet, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::clearXPosition, &FillLayer::initialFillXPosition, &CSSStyleSelector::mapFillXPosition>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskPositionY, ApplyPropertyFillLayer<Length, CSSPropertyWebkitMaskPositionY, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isYPositionSet, &FillLayer::yPosition, &FillLayer::setYPosition, &FillLayer::clearYPosition, &FillLayer::initialFillYPosition, &CSSStyleSelector::mapFillYPosition>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskPositionX, ApplyPropertyFillLayer<Length, CSSPropertyWebkitMaskPositionX, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isXPositionSet, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::clearXPosition, &FillLayer::initialFillXPosition, &StyleResolver::mapFillXPosition>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskPositionY, ApplyPropertyFillLayer<Length, CSSPropertyWebkitMaskPositionY, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isYPositionSet, &FillLayer::yPosition, &FillLayer::setYPosition, &FillLayer::clearYPosition, &FillLayer::initialFillYPosition, &StyleResolver::mapFillYPosition>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskRepeat, ApplyPropertyExpanding<SuppressValue, CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskRepeatX, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyWebkitMaskRepeatX, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isRepeatXSet, &FillLayer::repeatX, &FillLayer::setRepeatX, &FillLayer::clearRepeatX, &FillLayer::initialFillRepeatX, &CSSStyleSelector::mapFillRepeatX>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskRepeatY, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyWebkitMaskRepeatY, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isRepeatYSet, &FillLayer::repeatY, &FillLayer::setRepeatY, &FillLayer::clearRepeatY, &FillLayer::initialFillRepeatY, &CSSStyleSelector::mapFillRepeatY>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskSize, ApplyPropertyFillLayer<FillSize, CSSPropertyWebkitMaskSize, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isSizeSet, &FillLayer::size, &FillLayer::setSize, &FillLayer::clearSize, &FillLayer::initialFillSize, &CSSStyleSelector::mapFillSize>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskRepeatX, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyWebkitMaskRepeatX, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isRepeatXSet, &FillLayer::repeatX, &FillLayer::setRepeatX, &FillLayer::clearRepeatX, &FillLayer::initialFillRepeatX, &StyleResolver::mapFillRepeatX>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskRepeatY, ApplyPropertyFillLayer<EFillRepeat, CSSPropertyWebkitMaskRepeatY, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isRepeatYSet, &FillLayer::repeatY, &FillLayer::setRepeatY, &FillLayer::clearRepeatY, &FillLayer::initialFillRepeatY, &StyleResolver::mapFillRepeatY>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskSize, ApplyPropertyFillLayer<FillSize, CSSPropertyWebkitMaskSize, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isSizeSet, &FillLayer::size, &FillLayer::setSize, &FillLayer::clearSize, &FillLayer::initialFillSize, &StyleResolver::mapFillSize>::createHandler()); setPropertyHandler(CSSPropertyWebkitMatchNearestMailBlockquoteColor, ApplyPropertyDefault<EMatchNearestMailBlockquoteColor, &RenderStyle::matchNearestMailBlockquoteColor, EMatchNearestMailBlockquoteColor, &RenderStyle::setMatchNearestMailBlockquoteColor, EMatchNearestMailBlockquoteColor, &RenderStyle::initialMatchNearestMailBlockquoteColor>::createHandler()); setPropertyHandler(CSSPropertyWebkitNbspMode, ApplyPropertyDefault<ENBSPMode, &RenderStyle::nbspMode, ENBSPMode, &RenderStyle::setNBSPMode, ENBSPMode, &RenderStyle::initialNBSPMode>::createHandler()); setPropertyHandler(CSSPropertyWebkitPerspectiveOrigin, ApplyPropertyExpanding<SuppressValue, CSSPropertyWebkitPerspectiveOriginX, CSSPropertyWebkitPerspectiveOriginY>::createHandler()); @@ -1950,10 +2003,10 @@ CSSStyleApplyProperty::CSSStyleApplyProperty() setPropertyHandler(CSSPropertyWebkitTransformOriginY, ApplyPropertyLength<&RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY, &RenderStyle::initialTransformOriginY>::createHandler()); setPropertyHandler(CSSPropertyWebkitTransformOriginZ, ApplyPropertyComputeLength<float, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ, &RenderStyle::initialTransformOriginZ>::createHandler()); setPropertyHandler(CSSPropertyWebkitTransformStyle, ApplyPropertyDefault<ETransformStyle3D, &RenderStyle::transformStyle3D, ETransformStyle3D, &RenderStyle::setTransformStyle3D, ETransformStyle3D, &RenderStyle::initialTransformStyle3D>::createHandler()); - setPropertyHandler(CSSPropertyWebkitTransitionDelay, ApplyPropertyAnimation<double, &Animation::delay, &Animation::setDelay, &Animation::isDelaySet, &Animation::clearDelay, &Animation::initialAnimationDelay, &CSSStyleSelector::mapAnimationDelay, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); - setPropertyHandler(CSSPropertyWebkitTransitionDuration, ApplyPropertyAnimation<double, &Animation::duration, &Animation::setDuration, &Animation::isDurationSet, &Animation::clearDuration, &Animation::initialAnimationDuration, &CSSStyleSelector::mapAnimationDuration, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); - setPropertyHandler(CSSPropertyWebkitTransitionProperty, ApplyPropertyAnimation<int, &Animation::property, &Animation::setProperty, &Animation::isPropertySet, &Animation::clearProperty, &Animation::initialAnimationProperty, &CSSStyleSelector::mapAnimationProperty, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); - setPropertyHandler(CSSPropertyWebkitTransitionTimingFunction, ApplyPropertyAnimation<const PassRefPtr<TimingFunction>, &Animation::timingFunction, &Animation::setTimingFunction, &Animation::isTimingFunctionSet, &Animation::clearTimingFunction, &Animation::initialAnimationTimingFunction, &CSSStyleSelector::mapAnimationTimingFunction, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); + setPropertyHandler(CSSPropertyWebkitTransitionDelay, ApplyPropertyAnimation<double, &Animation::delay, &Animation::setDelay, &Animation::isDelaySet, &Animation::clearDelay, &Animation::initialAnimationDelay, &StyleResolver::mapAnimationDelay, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); + setPropertyHandler(CSSPropertyWebkitTransitionDuration, ApplyPropertyAnimation<double, &Animation::duration, &Animation::setDuration, &Animation::isDurationSet, &Animation::clearDuration, &Animation::initialAnimationDuration, &StyleResolver::mapAnimationDuration, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); + setPropertyHandler(CSSPropertyWebkitTransitionProperty, ApplyPropertyAnimation<CSSPropertyID, &Animation::property, &Animation::setProperty, &Animation::isPropertySet, &Animation::clearProperty, &Animation::initialAnimationProperty, &StyleResolver::mapAnimationProperty, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); + setPropertyHandler(CSSPropertyWebkitTransitionTimingFunction, ApplyPropertyAnimation<const PassRefPtr<TimingFunction>, &Animation::timingFunction, &Animation::setTimingFunction, &Animation::isTimingFunctionSet, &Animation::clearTimingFunction, &Animation::initialAnimationTimingFunction, &StyleResolver::mapAnimationTimingFunction, &RenderStyle::accessTransitions, &RenderStyle::transitions>::createHandler()); setPropertyHandler(CSSPropertyWebkitUserDrag, ApplyPropertyDefault<EUserDrag, &RenderStyle::userDrag, EUserDrag, &RenderStyle::setUserDrag, EUserDrag, &RenderStyle::initialUserDrag>::createHandler()); setPropertyHandler(CSSPropertyWebkitUserModify, ApplyPropertyDefault<EUserModify, &RenderStyle::userModify, EUserModify, &RenderStyle::setUserModify, EUserModify, &RenderStyle::initialUserModify>::createHandler()); setPropertyHandler(CSSPropertyWebkitUserSelect, ApplyPropertyDefault<EUserSelect, &RenderStyle::userSelect, EUserSelect, &RenderStyle::setUserSelect, EUserSelect, &RenderStyle::initialUserSelect>::createHandler()); @@ -1964,7 +2017,7 @@ CSSStyleApplyProperty::CSSStyleApplyProperty() setPropertyHandler(CSSPropertyWebkitWrapThrough, ApplyPropertyDefault<WrapThrough, &RenderStyle::wrapThrough, WrapThrough, &RenderStyle::setWrapThrough, WrapThrough, &RenderStyle::initialWrapThrough>::createHandler()); setPropertyHandler(CSSPropertyWhiteSpace, ApplyPropertyDefault<EWhiteSpace, &RenderStyle::whiteSpace, EWhiteSpace, &RenderStyle::setWhiteSpace, EWhiteSpace, &RenderStyle::initialWhiteSpace>::createHandler()); setPropertyHandler(CSSPropertyWidows, ApplyPropertyDefault<short, &RenderStyle::widows, short, &RenderStyle::setWidows, short, &RenderStyle::initialWidows>::createHandler()); - setPropertyHandler(CSSPropertyWidth, ApplyPropertyLength<&RenderStyle::width, &RenderStyle::setWidth, &RenderStyle::initialSize, AutoEnabled, IntrinsicEnabled, MinIntrinsicEnabled, NoneDisabled, UndefinedDisabled, FlexWidth>::createHandler()); + setPropertyHandler(CSSPropertyWidth, ApplyPropertyLength<&RenderStyle::width, &RenderStyle::setWidth, &RenderStyle::initialSize, AutoEnabled, IntrinsicEnabled, MinIntrinsicEnabled, NoneDisabled, UndefinedDisabled>::createHandler()); setPropertyHandler(CSSPropertyWordBreak, ApplyPropertyDefault<EWordBreak, &RenderStyle::wordBreak, EWordBreak, &RenderStyle::setWordBreak, EWordBreak, &RenderStyle::initialWordBreak>::createHandler()); setPropertyHandler(CSSPropertyWordSpacing, ApplyPropertyComputeLength<int, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing, &RenderStyle::initialLetterWordSpacing, NormalEnabled, ThicknessDisabled, SVGZoomEnabled>::createHandler()); setPropertyHandler(CSSPropertyWordWrap, ApplyPropertyDefault<EWordWrap, &RenderStyle::wordWrap, EWordWrap, &RenderStyle::setWordWrap, EWordWrap, &RenderStyle::initialWordWrap>::createHandler()); diff --git a/Source/WebCore/css/CSSStyleApplyProperty.h b/Source/WebCore/css/StyleBuilder.h index 2e83d0fc1..a7221cb4e 100644 --- a/Source/WebCore/css/CSSStyleApplyProperty.h +++ b/Source/WebCore/css/StyleBuilder.h @@ -22,8 +22,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CSSStyleApplyProperty_h -#define CSSStyleApplyProperty_h +#ifndef StyleBuilder_h +#define StyleBuilder_h #include "CSSPropertyNames.h" #include <wtf/PassRefPtr.h> @@ -31,20 +31,20 @@ namespace WebCore { -class CSSStyleSelector; class CSSValue; -class CSSStyleApplyProperty; +class StyleBuilder; +class StyleResolver; class PropertyHandler { public: - typedef void (*InheritFunction)(CSSStyleSelector*); - typedef void (*InitialFunction)(CSSStyleSelector*); - typedef void (*ApplyFunction)(CSSStyleSelector*, CSSValue*); + typedef void (*InheritFunction)(StyleResolver*); + typedef void (*InitialFunction)(StyleResolver*); + typedef void (*ApplyFunction)(StyleResolver*, CSSValue*); PropertyHandler() : m_inherit(0), m_initial(0), m_apply(0) { } PropertyHandler(InheritFunction inherit, InitialFunction initial, ApplyFunction apply) : m_inherit(inherit), m_initial(initial), m_apply(apply) { } - void applyInheritValue(CSSStyleSelector* selector) const { ASSERT(m_inherit); (*m_inherit)(selector); } - void applyInitialValue(CSSStyleSelector* selector) const { ASSERT(m_initial); (*m_initial)(selector); } - void applyValue(CSSStyleSelector* selector, CSSValue* value) const { ASSERT(m_apply); (*m_apply)(selector, value); } + void applyInheritValue(StyleResolver* styleResolver) const { ASSERT(m_inherit); (*m_inherit)(styleResolver); } + void applyInitialValue(StyleResolver* styleResolver) const { ASSERT(m_initial); (*m_initial)(styleResolver); } + void applyValue(StyleResolver* styleResolver, CSSValue* value) const { ASSERT(m_apply); (*m_apply)(styleResolver, value); } bool isValid() const { return m_inherit && m_initial && m_apply; } InheritFunction inheritFunction() const { return m_inherit; } InitialFunction initialFunction() { return m_initial; } @@ -55,10 +55,10 @@ private: ApplyFunction m_apply; }; -class CSSStyleApplyProperty { - WTF_MAKE_NONCOPYABLE(CSSStyleApplyProperty); +class StyleBuilder { + WTF_MAKE_NONCOPYABLE(StyleBuilder); public: - static const CSSStyleApplyProperty& sharedCSSStyleApplyProperty(); + static const StyleBuilder& sharedStyleBuilder(); const PropertyHandler& propertyHandler(CSSPropertyID property) const { @@ -66,7 +66,7 @@ public: return m_propertyMap[index(property)]; } private: - CSSStyleApplyProperty(); + StyleBuilder(); static int index(CSSPropertyID property) { return property - firstCSSProperty; @@ -78,7 +78,7 @@ private: return i >= 0 && i < numCSSProperties; } - void setPropertyHandler(CSSPropertyID property, PropertyHandler handler) + void setPropertyHandler(CSSPropertyID property, const PropertyHandler& handler) { ASSERT(valid(property)); ASSERT(!propertyHandler(property).isValid()); @@ -98,4 +98,4 @@ private: } -#endif // CSSStyleApplyProperty_h +#endif // StyleBuilder_h diff --git a/Source/WebCore/css/StyleMedia.cpp b/Source/WebCore/css/StyleMedia.cpp index 5db8a6f98..c78c00a22 100644 --- a/Source/WebCore/css/StyleMedia.cpp +++ b/Source/WebCore/css/StyleMedia.cpp @@ -26,12 +26,12 @@ #include "config.h" #include "StyleMedia.h" -#include "CSSStyleSelector.h" #include "Document.h" #include "Frame.h" #include "FrameView.h" #include "MediaList.h" #include "MediaQueryEvaluator.h" +#include "StyleResolver.h" namespace WebCore { @@ -60,16 +60,14 @@ bool StyleMedia::matchMedium(const String& query) const if (!documentElement) return false; - CSSStyleSelector* styleSelector = document->styleSelector(); - if (!styleSelector) + StyleResolver* styleResolver = document->styleResolver(); + if (!styleResolver) return false; - RefPtr<RenderStyle> rootStyle = styleSelector->styleForElement(documentElement, 0 /*defaultParent*/, false /*allowSharing*/, true /*resolveForRootDefault*/); - RefPtr<MediaList> media = MediaList::create(); + RefPtr<RenderStyle> rootStyle = styleResolver->styleForElement(documentElement, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules); - ExceptionCode ec = 0; - media->setMediaText(query, ec); - if (ec) + RefPtr<MediaQuerySet> media = MediaQuerySet::create(); + if (!media->parse(query)) return false; MediaQueryEvaluator screenEval(type(), m_frame, rootStyle.get()); diff --git a/Source/WebCore/css/StylePropertySet.cpp b/Source/WebCore/css/StylePropertySet.cpp index 65452ec3b..a5c8806ba 100644 --- a/Source/WebCore/css/StylePropertySet.cpp +++ b/Source/WebCore/css/StylePropertySet.cpp @@ -23,13 +23,13 @@ #include "StylePropertySet.h" #include "CSSParser.h" -#include "CSSPropertyLonghand.h" -#include "CSSPropertyNames.h" #include "CSSValueKeywords.h" #include "CSSValueList.h" #include "CSSValuePool.h" #include "Document.h" #include "PropertySetCSSStyleDeclaration.h" +#include "StylePropertyShorthand.h" +#include <wtf/BitVector.h> #include <wtf/text/StringBuilder.h> using namespace std; @@ -43,23 +43,23 @@ static PropertySetCSSOMWrapperMap& propertySetCSSOMWrapperMap() return propertySetCSSOMWrapperMapInstance; } -StylePropertySet::StylePropertySet() - : m_strictParsing(false) - , m_hasCSSOMWrapper(false) +StylePropertySet::StylePropertySet(CSSParserMode cssParserMode) + : m_cssParserMode(cssParserMode) + , m_ownsCSSOMWrapper(false) { } StylePropertySet::StylePropertySet(const Vector<CSSProperty>& properties) : m_properties(properties) - , m_strictParsing(true) - , m_hasCSSOMWrapper(false) + , m_cssParserMode(CSSStrictMode) + , m_ownsCSSOMWrapper(false) { m_properties.shrinkToFit(); } -StylePropertySet::StylePropertySet(const CSSProperty* properties, int numProperties, bool useStrictParsing) - : m_strictParsing(useStrictParsing) - , m_hasCSSOMWrapper(false) +StylePropertySet::StylePropertySet(const CSSProperty* properties, int numProperties, CSSParserMode cssParserMode) + : m_cssParserMode(cssParserMode) + , m_ownsCSSOMWrapper(false) { // FIXME: This logic belongs in CSSParser. @@ -81,10 +81,18 @@ StylePropertySet::StylePropertySet(const CSSProperty* properties, int numPropert } } +StylePropertySet::StylePropertySet(const StylePropertySet& o) + : RefCounted<StylePropertySet>() + , m_properties(o.m_properties) + , m_cssParserMode(o.m_cssParserMode) + , m_ownsCSSOMWrapper(false) +{ +} + StylePropertySet::~StylePropertySet() { - ASSERT(!m_hasCSSOMWrapper || propertySetCSSOMWrapperMap().contains(this)); - if (m_hasCSSOMWrapper) + ASSERT(!m_ownsCSSOMWrapper || propertySetCSSOMWrapperMap().contains(this)); + if (m_ownsCSSOMWrapper) propertySetCSSOMWrapperMap().remove(this); } @@ -93,7 +101,7 @@ void StylePropertySet::copyPropertiesFrom(const StylePropertySet& other) m_properties = other.m_properties; } -String StylePropertySet::getPropertyValue(int propertyID) const +String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const { RefPtr<CSSValue> value = getPropertyCSSValue(propertyID); if (value) @@ -101,177 +109,83 @@ String StylePropertySet::getPropertyValue(int propertyID) const // Shorthand and 4-values properties switch (propertyID) { - case CSSPropertyBorderSpacing: { - const int properties[2] = { CSSPropertyWebkitBorderHorizontalSpacing, CSSPropertyWebkitBorderVerticalSpacing }; - return borderSpacingValue(properties); - } - case CSSPropertyBackgroundPosition: { - // FIXME: Is this correct? The code in cssparser.cpp is confusing - const int properties[2] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyBackgroundRepeat: { - const int properties[2] = { CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyBackground: { - const int properties[9] = { CSSPropertyBackgroundColor, - CSSPropertyBackgroundImage, - CSSPropertyBackgroundRepeatX, - CSSPropertyBackgroundRepeatY, - CSSPropertyBackgroundAttachment, - CSSPropertyBackgroundPositionX, - CSSPropertyBackgroundPositionY, - CSSPropertyBackgroundClip, - CSSPropertyBackgroundOrigin }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyBorder: { - const int properties[3][4] = {{ CSSPropertyBorderTopWidth, - CSSPropertyBorderRightWidth, - CSSPropertyBorderBottomWidth, - CSSPropertyBorderLeftWidth }, - { CSSPropertyBorderTopStyle, - CSSPropertyBorderRightStyle, - CSSPropertyBorderBottomStyle, - CSSPropertyBorderLeftStyle }, - { CSSPropertyBorderTopColor, - CSSPropertyBorderRightColor, - CSSPropertyBorderBottomColor, - CSSPropertyBorderLeftColor }}; - String res; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { - String value = getCommonValue(properties[i]); - if (!value.isNull()) { - if (!res.isNull()) - res += " "; - res += value; - } - } - return res; - } - case CSSPropertyBorderTop: { - const int properties[3] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle, - CSSPropertyBorderTopColor}; - return getShorthandValue(properties); - } - case CSSPropertyBorderRight: { - const int properties[3] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle, - CSSPropertyBorderRightColor}; - return getShorthandValue(properties); - } - case CSSPropertyBorderBottom: { - const int properties[3] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle, - CSSPropertyBorderBottomColor}; - return getShorthandValue(properties); - } - case CSSPropertyBorderLeft: { - const int properties[3] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle, - CSSPropertyBorderLeftColor}; - return getShorthandValue(properties); - } - case CSSPropertyOutline: { - const int properties[3] = { CSSPropertyOutlineWidth, CSSPropertyOutlineStyle, - CSSPropertyOutlineColor }; - return getShorthandValue(properties); - } - case CSSPropertyBorderColor: { - const int properties[4] = { CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, - CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor }; - return get4Values(properties); - } - case CSSPropertyBorderWidth: { - const int properties[4] = { CSSPropertyBorderTopWidth, CSSPropertyBorderRightWidth, - CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth }; - return get4Values(properties); - } - case CSSPropertyBorderStyle: { - const int properties[4] = { CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, - CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle }; - return get4Values(properties); - } - case CSSPropertyWebkitFlexFlow: { - const int properties[] = { CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap }; - return getShorthandValue(properties); - } - case CSSPropertyFont: - return fontValue(); - case CSSPropertyMargin: { - const int properties[4] = { CSSPropertyMarginTop, CSSPropertyMarginRight, - CSSPropertyMarginBottom, CSSPropertyMarginLeft }; - return get4Values(properties); - } - case CSSPropertyOverflow: { - const int properties[2] = { CSSPropertyOverflowX, CSSPropertyOverflowY }; - return getCommonValue(properties); - } - case CSSPropertyPadding: { - const int properties[4] = { CSSPropertyPaddingTop, CSSPropertyPaddingRight, - CSSPropertyPaddingBottom, CSSPropertyPaddingLeft }; - return get4Values(properties); - } - case CSSPropertyListStyle: { - const int properties[3] = { CSSPropertyListStyleType, CSSPropertyListStylePosition, - CSSPropertyListStyleImage }; - return getShorthandValue(properties); - } - case CSSPropertyWebkitMaskPosition: { - // FIXME: Is this correct? The code in cssparser.cpp is confusing - const int properties[2] = { CSSPropertyWebkitMaskPositionX, CSSPropertyWebkitMaskPositionY }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyWebkitMaskRepeat: { - const int properties[2] = { CSSPropertyWebkitMaskRepeatX, CSSPropertyWebkitMaskRepeatY }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyWebkitMask: { - const int properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat, - CSSPropertyWebkitMaskAttachment, CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskClip, - CSSPropertyWebkitMaskOrigin }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyWebkitTransformOrigin: { - const int properties[3] = { CSSPropertyWebkitTransformOriginX, - CSSPropertyWebkitTransformOriginY, - CSSPropertyWebkitTransformOriginZ }; - return getShorthandValue(properties); - } - case CSSPropertyWebkitTransition: { - const int properties[4] = { CSSPropertyWebkitTransitionProperty, CSSPropertyWebkitTransitionDuration, - CSSPropertyWebkitTransitionTimingFunction, CSSPropertyWebkitTransitionDelay }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyWebkitAnimation: { - const int properties[7] = { CSSPropertyWebkitAnimationName, CSSPropertyWebkitAnimationDuration, - CSSPropertyWebkitAnimationTimingFunction, CSSPropertyWebkitAnimationDelay, - CSSPropertyWebkitAnimationIterationCount, CSSPropertyWebkitAnimationDirection, - CSSPropertyWebkitAnimationFillMode }; - return getLayeredShorthandValue(properties); - } - case CSSPropertyWebkitWrap: { - const int properties[3] = { CSSPropertyWebkitWrapFlow, CSSPropertyWebkitWrapMargin, - CSSPropertyWebkitWrapPadding }; - return getShorthandValue(properties); - } + case CSSPropertyBorderSpacing: + return borderSpacingValue(borderSpacingShorthand()); + case CSSPropertyBackgroundPosition: + return getLayeredShorthandValue(backgroundPositionShorthand()); + case CSSPropertyBackgroundRepeat: + return getLayeredShorthandValue(backgroundRepeatShorthand()); + case CSSPropertyBackground: + return getLayeredShorthandValue(backgroundShorthand()); + case CSSPropertyBorder: + return borderPropertyValue(OmitUncommonValues); + case CSSPropertyBorderTop: + return getShorthandValue(borderTopShorthand()); + case CSSPropertyBorderRight: + return getShorthandValue(borderRightShorthand()); + case CSSPropertyBorderBottom: + return getShorthandValue(borderBottomShorthand()); + case CSSPropertyBorderLeft: + return getShorthandValue(borderLeftShorthand()); + case CSSPropertyOutline: + return getShorthandValue(outlineShorthand()); + case CSSPropertyBorderColor: + return get4Values(borderColorShorthand()); + case CSSPropertyBorderWidth: + return get4Values(borderWidthShorthand()); + case CSSPropertyBorderStyle: + return get4Values(borderStyleShorthand()); + case CSSPropertyWebkitFlexFlow: + return getShorthandValue(webkitFlexFlowShorthand()); + case CSSPropertyFont: + return fontValue(); + case CSSPropertyMargin: + return get4Values(marginShorthand()); + case CSSPropertyOverflow: + return getCommonValue(overflowShorthand()); + case CSSPropertyPadding: + return get4Values(paddingShorthand()); + case CSSPropertyListStyle: + return getShorthandValue(listStyleShorthand()); + case CSSPropertyWebkitMaskPosition: + return getLayeredShorthandValue(webkitMaskPositionShorthand()); + case CSSPropertyWebkitMaskRepeat: + return getLayeredShorthandValue(webkitMaskRepeatShorthand()); + case CSSPropertyWebkitMask: + return getLayeredShorthandValue(webkitMaskShorthand()); + case CSSPropertyWebkitTransformOrigin: + return getShorthandValue(webkitTransformOriginShorthand()); + case CSSPropertyWebkitTransition: + return getLayeredShorthandValue(webkitTransitionShorthand()); + case CSSPropertyWebkitAnimation: + return getLayeredShorthandValue(webkitAnimationShorthand()); + case CSSPropertyWebkitWrap: + return getShorthandValue(webkitWrapShorthand()); #if ENABLE(SVG) - case CSSPropertyMarker: { - RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyMarkerStart); - if (value) - return value->cssText(); - } + case CSSPropertyMarker: { + RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyMarkerStart); + if (value) + return value->cssText(); + return String(); + } #endif + case CSSPropertyBorderRadius: + return get4Values(borderRadiusShorthand()); + default: + return String(); } - return String(); } -String StylePropertySet::borderSpacingValue(const int properties[2]) const +String StylePropertySet::borderSpacingValue(const StylePropertyShorthand& shorthand) const { - RefPtr<CSSValue> horizontalValue = getPropertyCSSValue(properties[0]); - RefPtr<CSSValue> verticalValue = getPropertyCSSValue(properties[1]); + RefPtr<CSSValue> horizontalValue = getPropertyCSSValue(shorthand.properties()[0]); + RefPtr<CSSValue> verticalValue = getPropertyCSSValue(shorthand.properties()[1]); - if (!horizontalValue) + // While standard border-spacing property does not allow specifying border-spacing-vertical without + // specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.html#separated-borders>, + // -webkit-border-spacing-vertical can be set without -webkit-border-spacing-horizontal. + if (!horizontalValue || !verticalValue) return String(); - ASSERT(verticalValue); // By <http://www.w3.org/TR/CSS21/tables.html#separated-borders>. String horizontalValueCSSText = horizontalValue->cssText(); String verticalValueCSSText = verticalValue->cssText(); @@ -280,7 +194,7 @@ String StylePropertySet::borderSpacingValue(const int properties[2]) const return horizontalValueCSSText + ' ' + verticalValueCSSText; } -bool StylePropertySet::appendFontLonghandValueIfExplicit(int propertyId, StringBuilder& result) const +bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyId, StringBuilder& result) const { const CSSProperty* property = findPropertyWithId(propertyId); if (!property) @@ -336,43 +250,48 @@ String StylePropertySet::fontValue() const return result.toString(); } -String StylePropertySet::get4Values(const int* properties) const +String StylePropertySet::get4Values(const StylePropertyShorthand& shorthand) const { // Assume the properties are in the usual order top, right, bottom, left. - RefPtr<CSSValue> topValue = getPropertyCSSValue(properties[0]); - RefPtr<CSSValue> rightValue = getPropertyCSSValue(properties[1]); - RefPtr<CSSValue> bottomValue = getPropertyCSSValue(properties[2]); - RefPtr<CSSValue> leftValue = getPropertyCSSValue(properties[3]); + const CSSProperty* top = findPropertyWithId(shorthand.properties()[0]); + const CSSProperty* right = findPropertyWithId(shorthand.properties()[1]); + const CSSProperty* bottom = findPropertyWithId(shorthand.properties()[2]); + const CSSProperty* left = findPropertyWithId(shorthand.properties()[3]); // All 4 properties must be specified. - if (!topValue || !rightValue || !bottomValue || !leftValue) + if (!top || !top->value() || !right || !right->value() || !bottom || !bottom->value() || !left || !left->value()) + return String(); + if (top->value()->isInitialValue() || right->value()->isInitialValue() || bottom->value()->isInitialValue() || left->value()->isInitialValue()) + return String(); + if (top->isImportant() != right->isImportant() || right->isImportant() != bottom->isImportant() || bottom->isImportant() != left->isImportant()) return String(); - bool showLeft = rightValue->cssText() != leftValue->cssText(); - bool showBottom = (topValue->cssText() != bottomValue->cssText()) || showLeft; - bool showRight = (topValue->cssText() != rightValue->cssText()) || showBottom; + bool showLeft = right->value()->cssText() != left->value()->cssText(); + bool showBottom = (top->value()->cssText() != bottom->value()->cssText()) || showLeft; + bool showRight = (top->value()->cssText() != right->value()->cssText()) || showBottom; - String res = topValue->cssText(); + String res = top->value()->cssText(); if (showRight) - res += " " + rightValue->cssText(); + res += " " + right->value()->cssText(); if (showBottom) - res += " " + bottomValue->cssText(); + res += " " + bottom->value()->cssText(); if (showLeft) - res += " " + leftValue->cssText(); + res += " " + left->value()->cssText(); return res; } -String StylePropertySet::getLayeredShorthandValue(const int* properties, size_t size) const +String StylePropertySet::getLayeredShorthandValue(const StylePropertyShorthand& shorthand) const { String res; + const unsigned size = shorthand.length(); // Begin by collecting the properties into an array. Vector< RefPtr<CSSValue> > values(size); size_t numLayers = 0; - for (size_t i = 0; i < size; ++i) { - values[i] = getPropertyCSSValue(properties[i]); + for (unsigned i = 0; i < size; ++i) { + values[i] = getPropertyCSSValue(shorthand.properties()[i]); if (values[i]) { if (values[i]->isValueList()) { CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get()); @@ -389,7 +308,7 @@ String StylePropertySet::getLayeredShorthandValue(const int* properties, size_t bool useRepeatXShorthand = false; bool useRepeatYShorthand = false; bool useSingleWordShorthand = false; - for (size_t j = 0; j < size; j++) { + for (unsigned j = 0; j < size; j++) { RefPtr<CSSValue> value; if (values[j]) { if (values[j]->isValueList()) @@ -398,7 +317,7 @@ String StylePropertySet::getLayeredShorthandValue(const int* properties, size_t value = values[j]; // Color only belongs in the last layer. - if (properties[j] == CSSPropertyBackgroundColor) { + if (shorthand.properties()[j] == CSSPropertyBackgroundColor) { if (i != numLayers - 1) value = 0; } else if (i != 0) // Other singletons only belong in the first layer. @@ -409,10 +328,10 @@ String StylePropertySet::getLayeredShorthandValue(const int* properties, size_t // We need to report background-repeat as it was written in the CSS. If the property is implicit, // then it was written with only one value. Here we figure out which value that was so we can // report back correctly. - if (properties[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(properties[j])) { + if (shorthand.properties()[j] == CSSPropertyBackgroundRepeatX && isPropertyImplicit(shorthand.properties()[j])) { // BUG 49055: make sure the value was not reset in the layer check just above. - if (j < size - 1 && properties[j + 1] == CSSPropertyBackgroundRepeatY && value) { + if (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyBackgroundRepeatY && value) { RefPtr<CSSValue> yValue; RefPtr<CSSValue> nextValue = values[j + 1]; if (nextValue->isValueList()) @@ -460,33 +379,35 @@ String StylePropertySet::getLayeredShorthandValue(const int* properties, size_t res += layerRes; } } - return res; } -String StylePropertySet::getShorthandValue(const int* properties, size_t size) const +String StylePropertySet::getShorthandValue(const StylePropertyShorthand& shorthand) const { String res; - for (size_t i = 0; i < size; ++i) { - if (!isPropertyImplicit(properties[i])) { - RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]); - // FIXME: provide default value if !value - if (value) { - if (!res.isNull()) - res += " "; - res += value->cssText(); - } + for (unsigned i = 0; i < shorthand.length(); ++i) { + if (!isPropertyImplicit(shorthand.properties()[i])) { + RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); + if (!value) + return String(); + if (value->isInitialValue()) + continue; + if (!res.isNull()) + res += " "; + res += value->cssText(); } } return res; } // only returns a non-null value if all properties have the same, non-null value -String StylePropertySet::getCommonValue(const int* properties, size_t size) const +String StylePropertySet::getCommonValue(const StylePropertyShorthand& shorthand) const { String res; - for (size_t i = 0; i < size; ++i) { - RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]); + bool lastPropertyWasImportant = false; + for (unsigned i = 0; i < shorthand.length(); ++i) { + RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]); + // FIXME: CSSInitialValue::cssText should generate the right value. if (!value) return String(); String text = value->cssText(); @@ -496,25 +417,51 @@ String StylePropertySet::getCommonValue(const int* properties, size_t size) cons res = text; else if (res != text) return String(); + + bool currentPropertyIsImportant = propertyIsImportant(shorthand.properties()[i]); + if (i && lastPropertyWasImportant != currentPropertyIsImportant) + return String(); + lastPropertyWasImportant = currentPropertyIsImportant; } return res; } -PassRefPtr<CSSValue> StylePropertySet::getPropertyCSSValue(int propertyID) const +String StylePropertySet::borderPropertyValue(CommonValueMode valueMode) const +{ + const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand() }; + StringBuilder result; + for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) { + String value = getCommonValue(properties[i]); + if (value.isNull()) { + if (valueMode == ReturnNullOnUncommonValues) + return String(); + ASSERT(valueMode == OmitUncommonValues); + continue; + } + if (value == "initial") + continue; + if (!result.isEmpty()) + result.append(' '); + result.append(value); + } + return result.isEmpty() ? String() : result.toString(); +} + +PassRefPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID) const { const CSSProperty* property = findPropertyWithId(propertyID); return property ? property->value() : 0; } -bool StylePropertySet::removeShorthandProperty(int propertyID) +bool StylePropertySet::removeShorthandProperty(CSSPropertyID propertyID) { - CSSPropertyLonghand longhand = longhandForProperty(propertyID); - if (!longhand.length()) + StylePropertyShorthand shorthand = shorthandForProperty(propertyID); + if (!shorthand.length()) return false; - return removePropertiesInSet(longhand.properties(), longhand.length()); + return removePropertiesInSet(shorthand.properties(), shorthand.length()); } -bool StylePropertySet::removeProperty(int propertyID, String* returnText) +bool StylePropertySet::removeProperty(CSSPropertyID propertyID, String* returnText) { if (removeShorthandProperty(propertyID)) { // FIXME: Return an equivalent shorthand when possible. @@ -540,36 +487,36 @@ bool StylePropertySet::removeProperty(int propertyID, String* returnText) return true; } -bool StylePropertySet::propertyIsImportant(int propertyID) const +bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const { const CSSProperty* property = findPropertyWithId(propertyID); if (property) return property->isImportant(); - CSSPropertyLonghand longhands = longhandForProperty(propertyID); - if (!longhands.length()) + StylePropertyShorthand shorthand = shorthandForProperty(propertyID); + if (!shorthand.length()) return false; - for (unsigned i = 0; i < longhands.length(); ++i) { - if (!propertyIsImportant(longhands.properties()[i])) + for (unsigned i = 0; i < shorthand.length(); ++i) { + if (!propertyIsImportant(shorthand.properties()[i])) return false; } return true; } -int StylePropertySet::getPropertyShorthand(int propertyID) const +CSSPropertyID StylePropertySet::getPropertyShorthand(CSSPropertyID propertyID) const { const CSSProperty* property = findPropertyWithId(propertyID); - return property ? property->shorthandID() : 0; + return property ? property->shorthandID() : CSSPropertyInvalid; } -bool StylePropertySet::isPropertyImplicit(int propertyID) const +bool StylePropertySet::isPropertyImplicit(CSSPropertyID propertyID) const { const CSSProperty* property = findPropertyWithId(propertyID); return property ? property->isImplicit() : false; } -bool StylePropertySet::setProperty(int propertyID, const String& value, bool important, CSSStyleSheet* contextStyleSheet) +bool StylePropertySet::setProperty(CSSPropertyID propertyID, const String& value, bool important, StyleSheetInternal* contextStyleSheet) { // Setting the value to an empty string just removes the property in both IE and Gecko. // Setting it to null seems to produce less consistent results, but we treat it just the same. @@ -580,22 +527,22 @@ bool StylePropertySet::setProperty(int propertyID, const String& value, bool imp // When replacing an existing property value, this moves the property to the end of the list. // Firefox preserves the position, and MSIE moves the property to the beginning. - return CSSParser::parseValue(this, propertyID, value, important, useStrictParsing(), contextStyleSheet); + return CSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet); } -void StylePropertySet::setProperty(int propertyID, PassRefPtr<CSSValue> prpValue, bool important) +void StylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> prpValue, bool important) { - CSSPropertyLonghand longhand = longhandForProperty(propertyID); - if (!longhand.length()) { + StylePropertyShorthand shorthand = shorthandForProperty(propertyID); + if (!shorthand.length()) { setProperty(CSSProperty(propertyID, prpValue, important)); return; } - removePropertiesInSet(longhand.properties(), longhand.length()); + removePropertiesInSet(shorthand.properties(), shorthand.length()); RefPtr<CSSValue> value = prpValue; - for (unsigned i = 0; i < longhand.length(); ++i) - m_properties.append(CSSProperty(longhand.properties()[i], value, important)); + for (unsigned i = 0; i < shorthand.length(); ++i) + m_properties.append(CSSProperty(shorthand.properties()[i], value, important)); } void StylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slot) @@ -610,22 +557,22 @@ void StylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slo m_properties.append(property); } -bool StylePropertySet::setProperty(int propertyID, int identifier, bool important, CSSStyleSheet* contextStyleSheet) +bool StylePropertySet::setProperty(CSSPropertyID propertyID, int identifier, bool important) { - RefPtr<CSSPrimitiveValue> value; - if (Document* document = contextStyleSheet ? contextStyleSheet->findDocument() : 0) - value = document->cssValuePool()->createIdentifierValue(identifier); - else - value = CSSPrimitiveValue::createIdentifier(identifier); - - setProperty(CSSProperty(propertyID, value.release(), important)); + setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important)); return true; } -void StylePropertySet::parseDeclaration(const String& styleDeclaration, CSSStyleSheet* contextStyleSheet) +void StylePropertySet::parseDeclaration(const String& styleDeclaration, StyleSheetInternal* contextStyleSheet) { m_properties.clear(); - CSSParser parser(useStrictParsing()); + + CSSParserContext context(cssParserMode()); + if (contextStyleSheet) { + context = contextStyleSheet->parserContext(); + context.mode = cssParserMode(); + } + CSSParser parser(context); parser.parseDeclaration(this, styleDeclaration, 0, contextStyleSheet); } @@ -639,34 +586,181 @@ void StylePropertySet::addParsedProperties(const CSSProperty* properties, int nu void StylePropertySet::addParsedProperty(const CSSProperty& property) { // Only add properties that have no !important counterpart present - if (!propertyIsImportant(property.id()) || property.isImportant()) { - removeProperty(property.id()); - m_properties.append(property); - } + if (!propertyIsImportant(property.id()) || property.isImportant()) + setProperty(property); } String StylePropertySet::asText() const { - String result = ""; + StringBuilder result; const CSSProperty* positionXProp = 0; const CSSProperty* positionYProp = 0; const CSSProperty* repeatXProp = 0; const CSSProperty* repeatYProp = 0; + // FIXME: Stack-allocate the buffer for these BitVectors. + BitVector shorthandPropertyUsed; + BitVector shorthandPropertyAppeared; + unsigned size = m_properties.size(); for (unsigned n = 0; n < size; ++n) { const CSSProperty& prop = m_properties[n]; - if (prop.id() == CSSPropertyBackgroundPositionX) + CSSPropertyID propertyID = prop.id(); + CSSPropertyID shorthandPropertyID = CSSPropertyInvalid; + CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid; + String value; + + switch (propertyID) { + case CSSPropertyBackgroundPositionX: positionXProp = ∝ - else if (prop.id() == CSSPropertyBackgroundPositionY) + continue; + case CSSPropertyBackgroundPositionY: positionYProp = ∝ - else if (prop.id() == CSSPropertyBackgroundRepeatX) + continue; + case CSSPropertyBackgroundRepeatX: repeatXProp = ∝ - else if (prop.id() == CSSPropertyBackgroundRepeatY) + continue; + case CSSPropertyBackgroundRepeatY: repeatYProp = ∝ - else - result += prop.cssText(); + continue; + case CSSPropertyBorderTopWidth: + case CSSPropertyBorderRightWidth: + case CSSPropertyBorderBottomWidth: + case CSSPropertyBorderLeftWidth: + if (!borderFallbackShorthandProperty) + borderFallbackShorthandProperty = CSSPropertyBorderWidth; + case CSSPropertyBorderTopStyle: + case CSSPropertyBorderRightStyle: + case CSSPropertyBorderBottomStyle: + case CSSPropertyBorderLeftStyle: + if (!borderFallbackShorthandProperty) + borderFallbackShorthandProperty = CSSPropertyBorderStyle; + case CSSPropertyBorderTopColor: + case CSSPropertyBorderRightColor: + case CSSPropertyBorderBottomColor: + case CSSPropertyBorderLeftColor: + if (!borderFallbackShorthandProperty) + borderFallbackShorthandProperty = CSSPropertyBorderColor; + + // FIXME: Deal with cases where only some of border-(top|right|bottom|left) are specified. + if (!shorthandPropertyAppeared.get(CSSPropertyBorder - firstCSSProperty)) { + value = borderPropertyValue(ReturnNullOnUncommonValues); + if (value.isNull()) + shorthandPropertyAppeared.ensureSizeAndSet(CSSPropertyBorder - firstCSSProperty, numCSSProperties); + else + shorthandPropertyID = CSSPropertyBorder; + } else if (shorthandPropertyUsed.get(CSSPropertyBorder - firstCSSProperty)) + shorthandPropertyID = CSSPropertyBorder; + if (!shorthandPropertyID) + shorthandPropertyID = borderFallbackShorthandProperty; + break; + case CSSPropertyWebkitBorderHorizontalSpacing: + case CSSPropertyWebkitBorderVerticalSpacing: + shorthandPropertyID = CSSPropertyBorderSpacing; + break; + case CSSPropertyFontFamily: + case CSSPropertyLineHeight: + case CSSPropertyFontSize: + case CSSPropertyFontStyle: + case CSSPropertyFontVariant: + case CSSPropertyFontWeight: + // Don't use CSSPropertyFont because old UAs can't recognize them but are important for editing. + break; + case CSSPropertyListStyleType: + case CSSPropertyListStylePosition: + case CSSPropertyListStyleImage: + shorthandPropertyID = CSSPropertyListStyle; + break; + case CSSPropertyMarginTop: + case CSSPropertyMarginRight: + case CSSPropertyMarginBottom: + case CSSPropertyMarginLeft: + shorthandPropertyID = CSSPropertyMargin; + break; + case CSSPropertyOutlineWidth: + case CSSPropertyOutlineStyle: + case CSSPropertyOutlineColor: + shorthandPropertyID = CSSPropertyOutline; + break; + case CSSPropertyOverflowX: + case CSSPropertyOverflowY: + shorthandPropertyID = CSSPropertyOverflow; + break; + case CSSPropertyPaddingTop: + case CSSPropertyPaddingRight: + case CSSPropertyPaddingBottom: + case CSSPropertyPaddingLeft: + shorthandPropertyID = CSSPropertyPadding; + break; + case CSSPropertyWebkitAnimationName: + case CSSPropertyWebkitAnimationDuration: + case CSSPropertyWebkitAnimationTimingFunction: + case CSSPropertyWebkitAnimationDelay: + case CSSPropertyWebkitAnimationIterationCount: + case CSSPropertyWebkitAnimationDirection: + case CSSPropertyWebkitAnimationFillMode: + shorthandPropertyID = CSSPropertyWebkitAnimation; + break; + case CSSPropertyWebkitFlexDirection: + case CSSPropertyWebkitFlexWrap: + shorthandPropertyID = CSSPropertyWebkitFlexFlow; + break; + case CSSPropertyWebkitMaskPositionX: + case CSSPropertyWebkitMaskPositionY: + case CSSPropertyWebkitMaskRepeatX: + case CSSPropertyWebkitMaskRepeatY: + case CSSPropertyWebkitMaskImage: + case CSSPropertyWebkitMaskRepeat: + case CSSPropertyWebkitMaskAttachment: + case CSSPropertyWebkitMaskPosition: + case CSSPropertyWebkitMaskClip: + case CSSPropertyWebkitMaskOrigin: + shorthandPropertyID = CSSPropertyWebkitMask; + break; + case CSSPropertyWebkitTransformOriginX: + case CSSPropertyWebkitTransformOriginY: + case CSSPropertyWebkitTransformOriginZ: + shorthandPropertyID = CSSPropertyWebkitTransformOrigin; + break; + case CSSPropertyWebkitTransitionProperty: + case CSSPropertyWebkitTransitionDuration: + case CSSPropertyWebkitTransitionTimingFunction: + case CSSPropertyWebkitTransitionDelay: + shorthandPropertyID = CSSPropertyWebkitTransition; + break; + case CSSPropertyWebkitWrapFlow: + case CSSPropertyWebkitWrapMargin: + case CSSPropertyWebkitWrapPadding: + shorthandPropertyID = CSSPropertyWebkitWrap; + break; + default: + break; + } + + unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty; + if (shorthandPropertyID) { + if (shorthandPropertyUsed.get(shortPropertyIndex)) + continue; + if (!shorthandPropertyAppeared.get(shortPropertyIndex) && value.isNull()) + value = getPropertyValue(shorthandPropertyID); + shorthandPropertyAppeared.ensureSizeAndSet(shortPropertyIndex, numCSSProperties); + } + + if (!value.isNull()) { + propertyID = shorthandPropertyID; + shorthandPropertyUsed.ensureSizeAndSet(shortPropertyIndex, numCSSProperties); + } else + value = prop.value()->cssText(); + + if (value == "initial" && !CSSProperty::isInheritedProperty(propertyID)) + continue; + + result.append(getPropertyName(propertyID)); + result.append(": "); + result.append(value); + result.append(prop.isImportant() ? " !important" : ""); + result.append("; "); } // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output. @@ -674,37 +768,45 @@ String StylePropertySet::asText() const // would not work in Firefox (<rdar://problem/5143183>) // It would be a better solution if background-position was CSS_PAIR. if (positionXProp && positionYProp && positionXProp->isImportant() == positionYProp->isImportant()) { - String positionValue; - const int properties[2] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY }; + result.append("background-position: "); if (positionXProp->value()->isValueList() || positionYProp->value()->isValueList()) - positionValue = getLayeredShorthandValue(properties); - else - positionValue = positionXProp->value()->cssText() + " " + positionYProp->value()->cssText(); - result += "background-position: " + positionValue + (positionXProp->isImportant() ? " !important" : "") + "; "; + result.append(getLayeredShorthandValue(backgroundPositionShorthand())); + else { + result.append(positionXProp->value()->cssText()); + result.append(" "); + result.append(positionYProp->value()->cssText()); + } + if (positionXProp->isImportant()) + result.append(" !important"); + result.append("; "); } else { if (positionXProp) - result += positionXProp->cssText(); + result.append(positionXProp->cssText()); if (positionYProp) - result += positionYProp->cssText(); + result.append(positionYProp->cssText()); } // FIXME: We need to do the same for background-repeat. if (repeatXProp && repeatYProp && repeatXProp->isImportant() == repeatYProp->isImportant()) { - String repeatValue; - const int repeatProperties[2] = { CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY }; + result.append("background-repeat: "); if (repeatXProp->value()->isValueList() || repeatYProp->value()->isValueList()) - repeatValue = getLayeredShorthandValue(repeatProperties); - else - repeatValue = repeatXProp->value()->cssText() + " " + repeatYProp->value()->cssText(); - result += "background-repeat: " + repeatValue + (repeatXProp->isImportant() ? " !important" : "") + "; "; + result.append(getLayeredShorthandValue(backgroundRepeatShorthand())); + else { + result.append(repeatXProp->value()->cssText()); + result.append(" "); + result.append(repeatYProp->value()->cssText()); + } + if (repeatXProp->isImportant()) + result.append(" !important"); + result.append("; "); } else { if (repeatXProp) - result += repeatXProp->cssText(); + result.append(repeatXProp->cssText()); if (repeatYProp) - result += repeatYProp->cssText(); + result.append(repeatYProp->cssText()); } - return result; + return result.toString(); } void StylePropertySet::merge(const StylePropertySet* other, bool argOverridesOnConflict) @@ -722,7 +824,7 @@ void StylePropertySet::merge(const StylePropertySet* other, bool argOverridesOnC } } -void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, CSSStyleSheet* contextStyleSheet) +void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, StyleSheetInternal* contextStyleSheet) { size_t size = m_properties.size(); for (size_t i = 0; i < size; ++i) @@ -731,7 +833,7 @@ void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, CSSStyle // This is the list of properties we want to copy in the copyBlockProperties() function. // It is the list of CSS properties that apply specially to block-level elements. -static const int blockProperties[] = { +static const CSSPropertyID blockProperties[] = { CSSPropertyOrphans, CSSPropertyOverflow, // This can be also be applied to replaced elements CSSPropertyWebkitAspectRatio, @@ -767,13 +869,13 @@ void StylePropertySet::removeBlockProperties() removePropertiesInSet(blockProperties, numBlockProperties); } -bool StylePropertySet::removePropertiesInSet(const int* set, unsigned length) +bool StylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned length) { if (m_properties.isEmpty()) return false; // FIXME: This is always used with static sets and in that case constructing the hash repeatedly is pretty pointless. - HashSet<int> toRemove; + HashSet<CSSPropertyID> toRemove; for (unsigned i = 0; i < length; ++i) toRemove.add(set[i]); @@ -796,19 +898,19 @@ bool StylePropertySet::removePropertiesInSet(const int* set, unsigned length) return changed; } -const CSSProperty* StylePropertySet::findPropertyWithId(int propertyID) const +const CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID) const { for (int n = m_properties.size() - 1 ; n >= 0; --n) { - if (propertyID == m_properties[n].m_id) + if (propertyID == m_properties[n].id()) return &m_properties[n]; } return 0; } -CSSProperty* StylePropertySet::findPropertyWithId(int propertyID) +CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID) { for (int n = m_properties.size() - 1 ; n >= 0; --n) { - if (propertyID == m_properties[n].m_id) + if (propertyID == m_properties[n].id()) return &m_properties[n]; } return 0; @@ -822,7 +924,7 @@ bool StylePropertySet::propertyMatches(const CSSProperty* property) const void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style) { - Vector<int> propertiesToRemove; + Vector<CSSPropertyID> propertiesToRemove; size_t size = m_properties.size(); for (size_t i = 0; i < size; ++i) { const CSSProperty& property = m_properties[i]; @@ -836,7 +938,7 @@ void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style) void StylePropertySet::removeEquivalentProperties(const CSSStyleDeclaration* style) { - Vector<int> propertiesToRemove; + Vector<CSSPropertyID> propertiesToRemove; size_t size = m_properties.size(); for (size_t i = 0; i < size; ++i) { const CSSProperty& property = m_properties[i]; @@ -850,10 +952,10 @@ void StylePropertySet::removeEquivalentProperties(const CSSStyleDeclaration* sty PassRefPtr<StylePropertySet> StylePropertySet::copy() const { - return adoptRef(new StylePropertySet(m_properties)); + return adoptRef(new StylePropertySet(*this)); } -PassRefPtr<StylePropertySet> StylePropertySet::copyPropertiesInSet(const int* set, unsigned length) const +PassRefPtr<StylePropertySet> StylePropertySet::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const { Vector<CSSProperty> list; list.reserveInitialCapacity(length); @@ -867,57 +969,44 @@ PassRefPtr<StylePropertySet> StylePropertySet::copyPropertiesInSet(const int* se CSSStyleDeclaration* StylePropertySet::ensureCSSStyleDeclaration() const { - if (m_hasCSSOMWrapper) { + if (m_ownsCSSOMWrapper) { ASSERT(!static_cast<CSSStyleDeclaration*>(propertySetCSSOMWrapperMap().get(this))->parentRule()); ASSERT(!propertySetCSSOMWrapperMap().get(this)->parentElement()); return propertySetCSSOMWrapperMap().get(this); } - m_hasCSSOMWrapper = true; + m_ownsCSSOMWrapper = true; PropertySetCSSStyleDeclaration* cssomWrapper = new PropertySetCSSStyleDeclaration(const_cast<StylePropertySet*>(this)); propertySetCSSOMWrapperMap().add(this, adoptPtr(cssomWrapper)); return cssomWrapper; } -CSSStyleDeclaration* StylePropertySet::ensureRuleCSSStyleDeclaration(const CSSRule* parentRule) const -{ - if (m_hasCSSOMWrapper) { - ASSERT(static_cast<CSSStyleDeclaration*>(propertySetCSSOMWrapperMap().get(this))->parentRule() == parentRule); - return propertySetCSSOMWrapperMap().get(this); - } - m_hasCSSOMWrapper = true; - PropertySetCSSStyleDeclaration* cssomWrapper = new RuleCSSStyleDeclaration(const_cast<StylePropertySet*>(this), const_cast<CSSRule*>(parentRule)); - propertySetCSSOMWrapperMap().add(this, adoptPtr(cssomWrapper)); - return cssomWrapper; -} - CSSStyleDeclaration* StylePropertySet::ensureInlineCSSStyleDeclaration(const StyledElement* parentElement) const { - if (m_hasCSSOMWrapper) { + if (m_ownsCSSOMWrapper) { ASSERT(propertySetCSSOMWrapperMap().get(this)->parentElement() == parentElement); return propertySetCSSOMWrapperMap().get(this); } - m_hasCSSOMWrapper = true; + m_ownsCSSOMWrapper = true; PropertySetCSSStyleDeclaration* cssomWrapper = new InlineCSSStyleDeclaration(const_cast<StylePropertySet*>(this), const_cast<StyledElement*>(parentElement)); propertySetCSSOMWrapperMap().add(this, adoptPtr(cssomWrapper)); return cssomWrapper; } -void StylePropertySet::clearParentRule(CSSRule* rule) -{ - if (!m_hasCSSOMWrapper) - return; - ASSERT_UNUSED(rule, static_cast<CSSStyleDeclaration*>(propertySetCSSOMWrapperMap().get(this))->parentRule() == rule); - propertySetCSSOMWrapperMap().get(this)->clearParentRule(); -} - void StylePropertySet::clearParentElement(StyledElement* element) { - if (!m_hasCSSOMWrapper) + if (!m_ownsCSSOMWrapper) return; ASSERT_UNUSED(element, propertySetCSSOMWrapperMap().get(this)->parentElement() == element); propertySetCSSOMWrapperMap().get(this)->clearParentElement(); } +unsigned StylePropertySet::averageSizeInBytes() +{ + // Please update this if the storage scheme changes so that this longer reflects the actual size. + return sizeof(StylePropertySet); +} + +// See the function above if you need to update this. class SameSizeAsStylePropertySet : public RefCounted<SameSizeAsStylePropertySet> { Vector<CSSProperty, 4> properties; unsigned bitfield; diff --git a/Source/WebCore/css/StylePropertySet.h b/Source/WebCore/css/StylePropertySet.h index 90452ff67..1ff576a8b 100644 --- a/Source/WebCore/css/StylePropertySet.h +++ b/Source/WebCore/css/StylePropertySet.h @@ -21,8 +21,10 @@ #ifndef StylePropertySet_h #define StylePropertySet_h +#include "CSSParserMode.h" #include "CSSPrimitiveValue.h" #include "CSSProperty.h" +#include "CSSPropertyNames.h" #include <wtf/ListHashSet.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> @@ -34,18 +36,20 @@ class CSSStyleDeclaration; class KURL; class PropertySetCSSStyleDeclaration; class StyledElement; +class StylePropertyShorthand; +class StyleSheetInternal; class StylePropertySet : public RefCounted<StylePropertySet> { public: ~StylePropertySet(); - static PassRefPtr<StylePropertySet> create() + static PassRefPtr<StylePropertySet> create(CSSParserMode cssParserMode = CSSQuirksMode) { - return adoptRef(new StylePropertySet); + return adoptRef(new StylePropertySet(cssParserMode)); } - static PassRefPtr<StylePropertySet> create(const CSSProperty* properties, int numProperties, bool useStrictParsing) + static PassRefPtr<StylePropertySet> create(const CSSProperty* properties, int numProperties, CSSParserMode cssParserMode) { - return adoptRef(new StylePropertySet(properties, numProperties, useStrictParsing)); + return adoptRef(new StylePropertySet(properties, numProperties, cssParserMode)); } static PassRefPtr<StylePropertySet> create(const Vector<CSSProperty>& properties) { @@ -58,37 +62,37 @@ public: void shrinkToFit() { m_properties.shrinkToFit(); } - PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const; - String getPropertyValue(int propertyID) const; - bool propertyIsImportant(int propertyID) const; - int getPropertyShorthand(int propertyID) const; - bool isPropertyImplicit(int propertyID) const; + PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const; + String getPropertyValue(CSSPropertyID) const; + bool propertyIsImportant(CSSPropertyID) const; + CSSPropertyID getPropertyShorthand(CSSPropertyID) const; + bool isPropertyImplicit(CSSPropertyID) const; // These expand shorthand properties into multiple properties. - bool setProperty(int propertyID, const String& value, bool important = false, CSSStyleSheet* contextStyleSheet = 0); - void setProperty(int propertyID, PassRefPtr<CSSValue>, bool important = false); + bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetInternal* contextStyleSheet = 0); + void setProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important = false); // These do not. FIXME: This is too messy, we can do better. - bool setProperty(int propertyID, int value, bool important = false, CSSStyleSheet* contextStyleSheet = 0); + bool setProperty(CSSPropertyID, int identifier, bool important = false); void setProperty(const CSSProperty&, CSSProperty* slot = 0); - bool removeProperty(int propertyID, String* returnText = 0); + bool removeProperty(CSSPropertyID, String* returnText = 0); - void parseDeclaration(const String& styleDeclaration, CSSStyleSheet* contextStyleSheet); + void parseDeclaration(const String& styleDeclaration, StyleSheetInternal* contextStyleSheet); void addParsedProperties(const CSSProperty*, int numProperties); void addParsedProperty(const CSSProperty&); PassRefPtr<StylePropertySet> copyBlockProperties() const; void removeBlockProperties(); - bool removePropertiesInSet(const int* set, unsigned length); + bool removePropertiesInSet(const CSSPropertyID* set, unsigned length); void merge(const StylePropertySet*, bool argOverridesOnConflict = true); - void setStrictParsing(bool b) { m_strictParsing = b; } - bool useStrictParsing() const { return m_strictParsing; } + void setCSSParserMode(CSSParserMode cssParserMode) { m_cssParserMode = cssParserMode; } + CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); } - void addSubresourceStyleURLs(ListHashSet<KURL>&, CSSStyleSheet* contextStyleSheet); + void addSubresourceStyleURLs(ListHashSet<KURL>&, StyleSheetInternal* contextStyleSheet); PassRefPtr<StylePropertySet> copy() const; // Used by StyledElement::copyNonAttributeProperties(). @@ -97,48 +101,48 @@ public: void removeEquivalentProperties(const StylePropertySet*); void removeEquivalentProperties(const CSSStyleDeclaration*); - PassRefPtr<StylePropertySet> copyPropertiesInSet(const int* set, unsigned length) const; + PassRefPtr<StylePropertySet> copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const; String asText() const; - void clearParentRule(CSSRule*); void clearParentElement(StyledElement*); CSSStyleDeclaration* ensureCSSStyleDeclaration() const; - CSSStyleDeclaration* ensureRuleCSSStyleDeclaration(const CSSRule* parentRule) const; CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(const StyledElement* parentElement) const; - bool hasCSSOMWrapper() const { return m_hasCSSOMWrapper; } + // FIXME: Expand the concept of mutable/immutable StylePropertySet. + bool isMutable() const { return m_ownsCSSOMWrapper; } + + static unsigned averageSizeInBytes(); private: - StylePropertySet(); + StylePropertySet(CSSParserMode); StylePropertySet(const Vector<CSSProperty>&); - StylePropertySet(const CSSProperty*, int numProperties, bool useStrictParsing); + StylePropertySet(const StylePropertySet&); + StylePropertySet(const CSSProperty*, int numProperties, CSSParserMode); void setNeedsStyleRecalc(); - String getShorthandValue(const int* properties, size_t) const; - String getCommonValue(const int* properties, size_t) const; - String getLayeredShorthandValue(const int* properties, size_t) const; - String get4Values(const int* properties) const; - String borderSpacingValue(const int properties[2]) const; + String getShorthandValue(const StylePropertyShorthand&) const; + String getCommonValue(const StylePropertyShorthand&) const; + enum CommonValueMode { OmitUncommonValues, ReturnNullOnUncommonValues }; + String borderPropertyValue(CommonValueMode) const; + String getLayeredShorthandValue(const StylePropertyShorthand&) const; + String get4Values(const StylePropertyShorthand&) const; + String borderSpacingValue(const StylePropertyShorthand&) const; String fontValue() const; - bool appendFontLonghandValueIfExplicit(int propertyID, StringBuilder& result) const; - - template<size_t size> String getShorthandValue(const int (&properties)[size]) const { return getShorthandValue(properties, size); } - template<size_t size> String getCommonValue(const int (&properties)[size]) const { return getCommonValue(properties, size); } - template<size_t size> String getLayeredShorthandValue(const int (&properties)[size]) const { return getLayeredShorthandValue(properties, size); } + bool appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result) const; - bool removeShorthandProperty(int propertyID); + bool removeShorthandProperty(CSSPropertyID); bool propertyMatches(const CSSProperty*) const; - const CSSProperty* findPropertyWithId(int propertyID) const; - CSSProperty* findPropertyWithId(int propertyID); + const CSSProperty* findPropertyWithId(CSSPropertyID) const; + CSSProperty* findPropertyWithId(CSSPropertyID); Vector<CSSProperty, 4> m_properties; - bool m_strictParsing : 1; - mutable bool m_hasCSSOMWrapper : 1; + unsigned m_cssParserMode : 2; + mutable unsigned m_ownsCSSOMWrapper : 1; friend class PropertySetCSSStyleDeclaration; }; diff --git a/Source/WebCore/css/StylePropertyShorthand.cpp b/Source/WebCore/css/StylePropertyShorthand.cpp new file mode 100644 index 000000000..1aae48d95 --- /dev/null +++ b/Source/WebCore/css/StylePropertyShorthand.cpp @@ -0,0 +1,507 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "StylePropertyShorthand.h" + +#include <wtf/StdLibExtras.h> + +namespace WebCore { + +// FIXME: Add CSSPropertyBackgroundSize to the shorthand. +const StylePropertyShorthand& backgroundShorthand() +{ + static const CSSPropertyID backgroundProperties[] = { + CSSPropertyBackgroundColor, + CSSPropertyBackgroundImage, + CSSPropertyBackgroundRepeatX, + CSSPropertyBackgroundRepeatY, + CSSPropertyBackgroundAttachment, + CSSPropertyBackgroundPositionX, + CSSPropertyBackgroundPositionY, + CSSPropertyBackgroundClip, + CSSPropertyBackgroundOrigin + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, backgroundShorthand, (backgroundProperties, WTF_ARRAY_LENGTH(backgroundProperties))); + return backgroundShorthand; +} + +const StylePropertyShorthand& backgroundPositionShorthand() +{ + static const CSSPropertyID backgroundPositionProperties[] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, backgroundPositionLonghands, (backgroundPositionProperties, WTF_ARRAY_LENGTH(backgroundPositionProperties))); + return backgroundPositionLonghands; +} + +const StylePropertyShorthand& backgroundRepeatShorthand() +{ + static const CSSPropertyID backgroundRepeatProperties[] = { CSSPropertyBackgroundRepeatX, CSSPropertyBackgroundRepeatY }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, backgroundRepeatLonghands, (backgroundRepeatProperties, WTF_ARRAY_LENGTH(backgroundRepeatProperties))); + return backgroundRepeatLonghands; +} + +const StylePropertyShorthand& borderShorthand() +{ + // Do not change the order of the following four shorthands, and keep them together. + static const CSSPropertyID borderProperties[4][3] = { + { CSSPropertyBorderTopColor, CSSPropertyBorderTopStyle, CSSPropertyBorderTopWidth }, + { CSSPropertyBorderRightColor, CSSPropertyBorderRightStyle, CSSPropertyBorderRightWidth }, + { CSSPropertyBorderBottomColor, CSSPropertyBorderBottomStyle, CSSPropertyBorderBottomWidth }, + { CSSPropertyBorderLeftColor, CSSPropertyBorderLeftStyle, CSSPropertyBorderLeftWidth } + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderLonghands, (borderProperties[0], sizeof(borderProperties) / sizeof(borderProperties[0][0]))); + return borderLonghands; +} + +const StylePropertyShorthand& borderAbridgedShorthand() +{ + static const CSSPropertyID borderAbridgedProperties[] = { CSSPropertyBorderWidth, CSSPropertyBorderStyle, CSSPropertyBorderColor }; + static const StylePropertyShorthand* propertiesForInitialization[] = { + &borderWidthShorthand(), + &borderStyleShorthand(), + &borderColorShorthand(), + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderAbridgedLonghands, + (borderAbridgedProperties, propertiesForInitialization, WTF_ARRAY_LENGTH(borderAbridgedProperties))); + return borderAbridgedLonghands; +} + +const StylePropertyShorthand& borderBottomShorthand() +{ + static const CSSPropertyID borderBottomProperties[] = { CSSPropertyBorderBottomWidth, CSSPropertyBorderBottomStyle, CSSPropertyBorderBottomColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderBottomLonghands, (borderBottomProperties, WTF_ARRAY_LENGTH(borderBottomProperties))); + return borderBottomLonghands; +} + +const StylePropertyShorthand& borderColorShorthand() +{ + static const CSSPropertyID borderColorProperties[] = { + CSSPropertyBorderTopColor, + CSSPropertyBorderRightColor, + CSSPropertyBorderBottomColor, + CSSPropertyBorderLeftColor + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderColorLonghands, (borderColorProperties, WTF_ARRAY_LENGTH(borderColorProperties))); + return borderColorLonghands; +} + +const StylePropertyShorthand& borderImageShorthand() +{ + static const CSSPropertyID borderImageProperties[] = { + CSSPropertyBorderImageSource, + CSSPropertyBorderImageSlice, + CSSPropertyBorderImageWidth, + CSSPropertyBorderImageOutset, + CSSPropertyBorderImageRepeat + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderImageLonghands, (borderImageProperties, WTF_ARRAY_LENGTH(borderImageProperties))); + return borderImageLonghands; +} + +const StylePropertyShorthand& borderLeftShorthand() +{ + static const CSSPropertyID borderLeftProperties[] = { CSSPropertyBorderLeftWidth, CSSPropertyBorderLeftStyle, CSSPropertyBorderLeftColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderLeftLonghands, (borderLeftProperties, WTF_ARRAY_LENGTH(borderLeftProperties))); + return borderLeftLonghands; +} + +const StylePropertyShorthand& borderRadiusShorthand() +{ + static const CSSPropertyID borderRadiusProperties[] = { + CSSPropertyBorderTopRightRadius, + CSSPropertyBorderTopLeftRadius, + CSSPropertyBorderBottomLeftRadius, + CSSPropertyBorderBottomRightRadius + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderRadiusLonghands, (borderRadiusProperties, WTF_ARRAY_LENGTH(borderRadiusProperties))); + return borderRadiusLonghands; +} + +const StylePropertyShorthand& borderRightShorthand() +{ + static const CSSPropertyID borderRightProperties[] = { CSSPropertyBorderRightWidth, CSSPropertyBorderRightStyle, CSSPropertyBorderRightColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderRightLonghands, (borderRightProperties, WTF_ARRAY_LENGTH(borderRightProperties))); + return borderRightLonghands; +} + +const StylePropertyShorthand& borderSpacingShorthand() +{ + static const CSSPropertyID borderSpacingProperties[] = { CSSPropertyWebkitBorderHorizontalSpacing, CSSPropertyWebkitBorderVerticalSpacing }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderSpacingLonghands, (borderSpacingProperties, WTF_ARRAY_LENGTH(borderSpacingProperties))); + return borderSpacingLonghands; +} + +const StylePropertyShorthand& borderStyleShorthand() +{ + static const CSSPropertyID borderStyleProperties[] = { + CSSPropertyBorderTopStyle, + CSSPropertyBorderRightStyle, + CSSPropertyBorderBottomStyle, + CSSPropertyBorderLeftStyle + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderStyleLonghands, (borderStyleProperties, WTF_ARRAY_LENGTH(borderStyleProperties))); + return borderStyleLonghands; +} + +const StylePropertyShorthand& borderTopShorthand() +{ + static const CSSPropertyID borderTopProperties[] = { CSSPropertyBorderTopWidth, CSSPropertyBorderTopStyle, CSSPropertyBorderTopColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderTopLonghands, (borderTopProperties, WTF_ARRAY_LENGTH(borderTopProperties))); + return borderTopLonghands; +} + +const StylePropertyShorthand& borderWidthShorthand() +{ + static const CSSPropertyID borderWidthProperties[] = { + CSSPropertyBorderTopWidth, + CSSPropertyBorderRightWidth, + CSSPropertyBorderBottomWidth, + CSSPropertyBorderLeftWidth + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderWidthLonghands, (borderWidthProperties, WTF_ARRAY_LENGTH(borderWidthProperties))); + return borderWidthLonghands; +} + +const StylePropertyShorthand& listStyleShorthand() +{ + static const CSSPropertyID listStyleProperties[] = { + CSSPropertyListStyleType, + CSSPropertyListStylePosition, + CSSPropertyListStyleImage + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, listStyleLonghands, (listStyleProperties, WTF_ARRAY_LENGTH(listStyleProperties))); + return listStyleLonghands; +} + +const StylePropertyShorthand& fontShorthand() +{ + static const CSSPropertyID fontProperties[] = { + CSSPropertyFontFamily, + CSSPropertyFontSize, + CSSPropertyFontStyle, + CSSPropertyFontVariant, + CSSPropertyFontWeight, + CSSPropertyLineHeight + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, fontLonghands, (fontProperties, WTF_ARRAY_LENGTH(fontProperties))); + return fontLonghands; +} + +const StylePropertyShorthand& marginShorthand() +{ + static const CSSPropertyID marginProperties[] = { + CSSPropertyMarginTop, + CSSPropertyMarginRight, + CSSPropertyMarginBottom, + CSSPropertyMarginLeft + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, marginLonghands, (marginProperties, WTF_ARRAY_LENGTH(marginProperties))); + return marginLonghands; +} + +const StylePropertyShorthand& outlineShorthand() +{ + static const CSSPropertyID outlineProperties[] = { + CSSPropertyOutlineColor, + CSSPropertyOutlineStyle, + CSSPropertyOutlineWidth + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, outlineLonghands, (outlineProperties, WTF_ARRAY_LENGTH(outlineProperties))); + return outlineLonghands; +} + +const StylePropertyShorthand& overflowShorthand() +{ + static const CSSPropertyID overflowProperties[] = { CSSPropertyOverflowX, CSSPropertyOverflowY }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, overflowLonghands, (overflowProperties, WTF_ARRAY_LENGTH(overflowProperties))); + return overflowLonghands; +} + +const StylePropertyShorthand& paddingShorthand() +{ + static const CSSPropertyID paddingProperties[] = { + CSSPropertyPaddingTop, + CSSPropertyPaddingRight, + CSSPropertyPaddingBottom, + CSSPropertyPaddingLeft + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, paddingLonghands, (paddingProperties, WTF_ARRAY_LENGTH(paddingProperties))); + return paddingLonghands; +} + +const StylePropertyShorthand& webkitAnimationShorthand() +{ + static const CSSPropertyID animationProperties[] = { + CSSPropertyWebkitAnimationName, + CSSPropertyWebkitAnimationDuration, + CSSPropertyWebkitAnimationTimingFunction, + CSSPropertyWebkitAnimationDelay, + CSSPropertyWebkitAnimationIterationCount, + CSSPropertyWebkitAnimationDirection, + CSSPropertyWebkitAnimationFillMode + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitAnimationLonghands, (animationProperties, WTF_ARRAY_LENGTH(animationProperties))); + return webkitAnimationLonghands; +} + +const StylePropertyShorthand& webkitBorderAfterShorthand() +{ + static const CSSPropertyID borderAfterProperties[] = { CSSPropertyWebkitBorderAfterWidth, CSSPropertyWebkitBorderAfterStyle, CSSPropertyWebkitBorderAfterColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitBorderAfterLonghands, (borderAfterProperties, WTF_ARRAY_LENGTH(borderAfterProperties))); + return webkitBorderAfterLonghands; +} + +const StylePropertyShorthand& webkitBorderBeforeShorthand() +{ + static const CSSPropertyID borderBeforeProperties[] = { CSSPropertyWebkitBorderBeforeWidth, CSSPropertyWebkitBorderBeforeStyle, CSSPropertyWebkitBorderBeforeColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitBorderBeforeLonghands, (borderBeforeProperties, WTF_ARRAY_LENGTH(borderBeforeProperties))); + return webkitBorderBeforeLonghands; +} + +const StylePropertyShorthand& webkitBorderEndShorthand() +{ + static const CSSPropertyID borderEndProperties[] = { CSSPropertyWebkitBorderEndWidth, CSSPropertyWebkitBorderEndStyle, CSSPropertyWebkitBorderEndColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitBorderEndLonghands, (borderEndProperties, WTF_ARRAY_LENGTH(borderEndProperties))); + return webkitBorderEndLonghands; +} + +const StylePropertyShorthand& webkitBorderStartShorthand() +{ + static const CSSPropertyID borderStartProperties[] = { CSSPropertyWebkitBorderStartWidth, CSSPropertyWebkitBorderStartStyle, CSSPropertyWebkitBorderStartColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitBorderStartLonghands, (borderStartProperties, WTF_ARRAY_LENGTH(borderStartProperties))); + return webkitBorderStartLonghands; +} + +const StylePropertyShorthand& webkitColumnsShorthand() +{ + static const CSSPropertyID columnsProperties[] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitColumnsLonghands, (columnsProperties, WTF_ARRAY_LENGTH(columnsProperties))); + return webkitColumnsLonghands; +} + +const StylePropertyShorthand& webkitColumnRuleShorthand() +{ + static const CSSPropertyID columnRuleProperties[] = { + CSSPropertyWebkitColumnRuleWidth, + CSSPropertyWebkitColumnRuleStyle, + CSSPropertyWebkitColumnRuleColor, + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitColumnRuleLonghands, (columnRuleProperties, WTF_ARRAY_LENGTH(columnRuleProperties))); + return webkitColumnRuleLonghands; +} + +const StylePropertyShorthand& webkitFlexFlowShorthand() +{ + static const CSSPropertyID flexFlowProperties[] = { CSSPropertyWebkitFlexDirection, CSSPropertyWebkitFlexWrap }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitFlexFlowLonghands, (flexFlowProperties, WTF_ARRAY_LENGTH(flexFlowProperties))); + return webkitFlexFlowLonghands; +} + +const StylePropertyShorthand& webkitMarginCollapseShorthand() +{ + static const CSSPropertyID marginCollapseProperties[] = { CSSPropertyWebkitMarginBeforeCollapse, CSSPropertyWebkitMarginAfterCollapse }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitMarginCollapseLonghands, (marginCollapseProperties, WTF_ARRAY_LENGTH(marginCollapseProperties))); + return webkitMarginCollapseLonghands; +} + +const StylePropertyShorthand& webkitMarqueeShorthand() +{ + static const CSSPropertyID marqueeProperties[] = { + CSSPropertyWebkitMarqueeDirection, + CSSPropertyWebkitMarqueeIncrement, + CSSPropertyWebkitMarqueeRepetition, + CSSPropertyWebkitMarqueeStyle, + CSSPropertyWebkitMarqueeSpeed + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitMarqueeLonghands, (marqueeProperties, WTF_ARRAY_LENGTH(marqueeProperties))); + return webkitMarqueeLonghands; +} + +const StylePropertyShorthand& webkitMaskShorthand() +{ + static const CSSPropertyID maskProperties[] = { + CSSPropertyWebkitMaskImage, + CSSPropertyWebkitMaskRepeatX, + CSSPropertyWebkitMaskRepeatY, + CSSPropertyWebkitMaskAttachment, + CSSPropertyWebkitMaskPositionX, + CSSPropertyWebkitMaskPositionY, + CSSPropertyWebkitMaskClip, + CSSPropertyWebkitMaskOrigin + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitMaskLonghands, (maskProperties, WTF_ARRAY_LENGTH(maskProperties))); + return webkitMaskLonghands; +} + +const StylePropertyShorthand& webkitMaskPositionShorthand() +{ + static const CSSPropertyID maskPositionProperties[] = { CSSPropertyWebkitMaskPositionX, CSSPropertyWebkitMaskPositionY }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitMaskPositionLonghands, (maskPositionProperties, WTF_ARRAY_LENGTH(maskPositionProperties))); + return webkitMaskPositionLonghands; +} + +const StylePropertyShorthand& webkitMaskRepeatShorthand() +{ + static const CSSPropertyID maskRepeatProperties[] = { CSSPropertyWebkitMaskRepeatX, CSSPropertyWebkitMaskRepeatY }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitMaskRepeatLonghands, (maskRepeatProperties, WTF_ARRAY_LENGTH(maskRepeatProperties))); + return webkitMaskRepeatLonghands; +} + +const StylePropertyShorthand& webkitTextEmphasisShorthand() +{ + static const CSSPropertyID textEmphasisProperties[] = { + CSSPropertyWebkitTextEmphasisStyle, + CSSPropertyWebkitTextEmphasisColor + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitTextEmphasisLonghands, (textEmphasisProperties, WTF_ARRAY_LENGTH(textEmphasisProperties))); + return webkitTextEmphasisLonghands; +} + +const StylePropertyShorthand& webkitTextStrokeShorthand() +{ + static const CSSPropertyID textStrokeProperties[] = { CSSPropertyWebkitTextStrokeWidth, CSSPropertyWebkitTextStrokeColor }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitTextStrokeLonghands, (textStrokeProperties, WTF_ARRAY_LENGTH(textStrokeProperties))); + return webkitTextStrokeLonghands; +} + +const StylePropertyShorthand& webkitTransitionShorthand() +{ + static const CSSPropertyID transitionProperties[] = { + CSSPropertyWebkitTransitionProperty, + CSSPropertyWebkitTransitionDuration, + CSSPropertyWebkitTransitionTimingFunction, + CSSPropertyWebkitTransitionDelay + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitTransitionLonghands, (transitionProperties, WTF_ARRAY_LENGTH(transitionProperties))); + return webkitTransitionLonghands; +} + +const StylePropertyShorthand& webkitTransformOriginShorthand() +{ + static const CSSPropertyID transformOriginProperties[] = { + CSSPropertyWebkitTransformOriginX, + CSSPropertyWebkitTransformOriginY, + CSSPropertyWebkitTransformOriginZ + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitTransformOriginLonghands, (transformOriginProperties, WTF_ARRAY_LENGTH(transformOriginProperties))); + return webkitTransformOriginLonghands; +} + +const StylePropertyShorthand& webkitWrapShorthand() +{ + static const CSSPropertyID webkitWrapProperties[] = { + CSSPropertyWebkitWrapFlow, + CSSPropertyWebkitWrapMargin, + CSSPropertyWebkitWrapPadding + }; + DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitWrapLonghands, (webkitWrapProperties, WTF_ARRAY_LENGTH(webkitWrapProperties))); + return webkitWrapLonghands; +} + +// Returns an empty list if the property is not a shorthand +const StylePropertyShorthand& shorthandForProperty(CSSPropertyID propertyID) +{ + switch (propertyID) { + case CSSPropertyBackground: + return backgroundShorthand(); + case CSSPropertyBackgroundPosition: + return backgroundPositionShorthand(); + case CSSPropertyBackgroundRepeat: + return backgroundRepeatShorthand(); + case CSSPropertyBorder: + return borderShorthand(); + case CSSPropertyBorderBottom: + return borderBottomShorthand(); + case CSSPropertyBorderColor: + return borderColorShorthand(); + case CSSPropertyBorderImage: + return borderImageShorthand(); + case CSSPropertyBorderLeft: + return borderLeftShorthand(); + case CSSPropertyBorderRadius: + return borderRadiusShorthand(); + case CSSPropertyBorderRight: + return borderRightShorthand(); + case CSSPropertyBorderSpacing: + return borderSpacingShorthand(); + case CSSPropertyBorderStyle: + return borderStyleShorthand(); + case CSSPropertyBorderTop: + return borderTopShorthand(); + case CSSPropertyBorderWidth: + return borderWidthShorthand(); + case CSSPropertyListStyle: + return listStyleShorthand(); + case CSSPropertyFont: + return fontShorthand(); + case CSSPropertyMargin: + return marginShorthand(); + case CSSPropertyOutline: + return outlineShorthand(); + case CSSPropertyOverflow: + return overflowShorthand(); + case CSSPropertyPadding: + return paddingShorthand(); + case CSSPropertyWebkitAnimation: + return webkitAnimationShorthand(); + case CSSPropertyWebkitBorderAfter: + return webkitBorderAfterShorthand(); + case CSSPropertyWebkitBorderBefore: + return webkitBorderBeforeShorthand(); + case CSSPropertyWebkitBorderEnd: + return webkitBorderEndShorthand(); + case CSSPropertyWebkitBorderStart: + return webkitBorderStartShorthand(); + case CSSPropertyWebkitBorderRadius: + return borderRadiusShorthand(); + case CSSPropertyWebkitColumns: + return webkitColumnsShorthand(); + case CSSPropertyWebkitColumnRule: + return webkitColumnRuleShorthand(); + case CSSPropertyWebkitFlexFlow: + return webkitFlexFlowShorthand(); + case CSSPropertyWebkitMarginCollapse: + return webkitMarginCollapseShorthand(); + case CSSPropertyWebkitMarquee: + return webkitMarqueeShorthand(); + case CSSPropertyWebkitMask: + return webkitMaskShorthand(); + case CSSPropertyWebkitMaskPosition: + return webkitMaskPositionShorthand(); + case CSSPropertyWebkitMaskRepeat: + return webkitMaskRepeatShorthand(); + case CSSPropertyWebkitTextEmphasis: + return webkitTextEmphasisShorthand(); + case CSSPropertyWebkitTextStroke: + return webkitTextStrokeShorthand(); + case CSSPropertyWebkitTransition: + return webkitTransitionShorthand(); + case CSSPropertyWebkitTransformOrigin: + return webkitTransformOriginShorthand(); + case CSSPropertyWebkitWrap: + return webkitWrapShorthand(); + default: { + DEFINE_STATIC_LOCAL(StylePropertyShorthand, emptyShorthand, ()); + return emptyShorthand; + } + } +} + +} // namespace WebCore diff --git a/Source/WebCore/css/StylePropertyShorthand.h b/Source/WebCore/css/StylePropertyShorthand.h new file mode 100644 index 000000000..175e3e1e5 --- /dev/null +++ b/Source/WebCore/css/StylePropertyShorthand.h @@ -0,0 +1,106 @@ +/* + * (C) 1999-2003 Lars Knoll (knoll@kde.org) + * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef StylePropertyShorthand_h +#define StylePropertyShorthand_h + +#include "CSSPropertyNames.h" + +namespace WebCore { + +class StylePropertyShorthand { +public: + StylePropertyShorthand() + : m_properties(0) + , m_propertiesForInitialization(0) + , m_length(0) + { + } + + StylePropertyShorthand(const CSSPropertyID* properties, unsigned numProperties) + : m_properties(properties) + , m_propertiesForInitialization(0) + , m_length(numProperties) + { + } + + StylePropertyShorthand(const CSSPropertyID* properties, const StylePropertyShorthand** propertiesForInitialization, unsigned numProperties) + : m_properties(properties) + , m_propertiesForInitialization(propertiesForInitialization) + , m_length(numProperties) + { + } + + const CSSPropertyID* properties() const { return m_properties; } + const StylePropertyShorthand** propertiesForInitialization() const { return m_propertiesForInitialization; } + unsigned length() const { return m_length; } + +private: + const CSSPropertyID* m_properties; + const StylePropertyShorthand** m_propertiesForInitialization; + unsigned m_length; +}; + +const StylePropertyShorthand& backgroundShorthand(); +const StylePropertyShorthand& backgroundPositionShorthand(); +const StylePropertyShorthand& backgroundRepeatShorthand(); +const StylePropertyShorthand& borderShorthand(); +const StylePropertyShorthand& borderAbridgedShorthand(); +const StylePropertyShorthand& borderBottomShorthand(); +const StylePropertyShorthand& borderColorShorthand(); +const StylePropertyShorthand& borderImageShorthand(); +const StylePropertyShorthand& borderLeftShorthand(); +const StylePropertyShorthand& borderRadiusShorthand(); +const StylePropertyShorthand& borderRightShorthand(); +const StylePropertyShorthand& borderSpacingShorthand(); +const StylePropertyShorthand& borderStyleShorthand(); +const StylePropertyShorthand& borderTopShorthand(); +const StylePropertyShorthand& borderWidthShorthand(); +const StylePropertyShorthand& listStyleShorthand(); +const StylePropertyShorthand& fontShorthand(); +const StylePropertyShorthand& marginShorthand(); +const StylePropertyShorthand& outlineShorthand(); +const StylePropertyShorthand& overflowShorthand(); +const StylePropertyShorthand& paddingShorthand(); +const StylePropertyShorthand& webkitAnimationShorthand(); +const StylePropertyShorthand& webkitBorderAfterShorthand(); +const StylePropertyShorthand& webkitBorderBeforeShorthand(); +const StylePropertyShorthand& webkitBorderEndShorthand(); +const StylePropertyShorthand& webkitBorderStartShorthand(); +const StylePropertyShorthand& webkitColumnsShorthand(); +const StylePropertyShorthand& webkitColumnRuleShorthand(); +const StylePropertyShorthand& webkitFlexFlowShorthand(); +const StylePropertyShorthand& webkitMarginCollapseShorthand(); +const StylePropertyShorthand& webkitMarqueeShorthand(); +const StylePropertyShorthand& webkitMaskShorthand(); +const StylePropertyShorthand& webkitMaskPositionShorthand(); +const StylePropertyShorthand& webkitMaskRepeatShorthand(); +const StylePropertyShorthand& webkitTextEmphasisShorthand(); +const StylePropertyShorthand& webkitTextStrokeShorthand(); +const StylePropertyShorthand& webkitTransitionShorthand(); +const StylePropertyShorthand& webkitTransformOriginShorthand(); +const StylePropertyShorthand& webkitWrapShorthand(); + +// Returns an empty list if the property is not a shorthand +const StylePropertyShorthand& shorthandForProperty(CSSPropertyID); + +} // namespace WebCore + +#endif // StylePropertyShorthand_h diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/StyleResolver.cpp index e9823d586..2d9933481 100644 --- a/Source/WebCore/css/CSSStyleSelector.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -26,14 +26,9 @@ */ #include "config.h" -#include "CSSStyleSelector.h" +#include "StyleResolver.h" #include "Attribute.h" -#include "CachedImage.h" -#include "CalculationValue.h" -#include "ContentData.h" -#include "Counter.h" -#include "CounterContent.h" #include "CSSBorderImage.h" #include "CSSCalculationValue.h" #include "CSSCursorImageValue.h" @@ -50,11 +45,15 @@ #include "CSSRuleList.h" #include "CSSSelector.h" #include "CSSSelectorList.h" -#include "CSSStyleApplyProperty.h" #include "CSSStyleRule.h" #include "CSSStyleSheet.h" #include "CSSTimingFunctionValue.h" #include "CSSValueList.h" +#include "CachedImage.h" +#include "CalculationValue.h" +#include "ContentData.h" +#include "Counter.h" +#include "CounterContent.h" #include "CursorList.h" #include "FontFeatureValue.h" #include "FontValue.h" @@ -65,6 +64,7 @@ #include "HTMLElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" +#include "HTMLOptionElement.h" #include "HTMLProgressElement.h" #include "HTMLStyleElement.h" #include "HTMLTextAreaElement.h" @@ -90,6 +90,8 @@ #include "RenderTheme.h" #include "RotateTransformOperation.h" #include "RuntimeEnabledFeatures.h" +#include "SVGDocumentExtensions.h" +#include "SVGFontFaceElement.h" #include "ScaleTransformOperation.h" #include "SecurityOrigin.h" #include "Settings.h" @@ -97,10 +99,11 @@ #include "ShadowRoot.h" #include "ShadowValue.h" #include "SkewTransformOperation.h" +#include "StyleBuilder.h" #include "StyleCachedImage.h" +#include "StyleGeneratedImage.h" #include "StylePendingImage.h" #include "StyleRule.h" -#include "StyleGeneratedImage.h" #include "StyleSheetList.h" #include "Text.h" #include "TransformationMatrix.h" @@ -140,6 +143,15 @@ #include "WebKitCSSShaderValue.h" #endif +#if ENABLE(CSS_IMAGE_SET) +#include "CSSImageSetValue.h" +#include "StyleCachedImageSet.h" +#endif + +#if PLATFORM(QT) || PLATFORM(BLACKBERRY) +#define FIXED_POSITION_CREATES_STACKING_CONTEXT 1 +#endif + using namespace std; namespace WebCore { @@ -173,7 +185,7 @@ if (primitiveValue) \ class RuleData { public: - RuleData(StyleRule*, CSSSelector*, unsigned position, bool canUseFastCheckSelector, bool inRegionRule); + RuleData(StyleRule*, CSSSelector*, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule); unsigned position() const { return m_position; } StyleRule* rule() const { return m_rule; } @@ -185,6 +197,7 @@ public: bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; } unsigned specificity() const { return m_specificity; } unsigned linkMatchType() const { return m_linkMatchType; } + bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; } bool isInRegionRule() const { return m_isInRegionRule; } // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance. @@ -197,12 +210,13 @@ private: unsigned m_specificity; // This number was picked fairly arbitrarily. We can probably lower it if we need to. // Some simple testing showed <100,000 RuleData's on large sites. - unsigned m_position : 25; + unsigned m_position : 24; unsigned m_hasFastCheckableSelector : 1; unsigned m_hasMultipartSelector : 1; unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1; unsigned m_containsUncommonAttributeSelector : 1; unsigned m_linkMatchType : 2; // SelectorChecker::LinkMatchMask + unsigned m_hasDocumentSecurityOrigin : 1; unsigned m_isInRegionRule : 1; // Use plain array instead of a Vector to minimize memory overhead. unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount]; @@ -221,21 +235,21 @@ COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_s class RuleSet { WTF_MAKE_NONCOPYABLE(RuleSet); public: - RuleSet(); + static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); } typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap; - void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0, const ContainerNode* = 0); + void addRulesFromSheet(StyleSheetInternal*, const MediaQueryEvaluator&, StyleResolver* = 0, const ContainerNode* = 0); - void addStyleRule(StyleRule*, bool canUseFastCheckSelector = true, bool isInRegionRule = false); - void addRule(StyleRule*, CSSSelector*, bool canUseFastCheckSelector = true, bool isInRegionRule = false); - void addPageRule(CSSPageRule*); + void addStyleRule(StyleRule*, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule = false); + void addRule(StyleRule*, CSSSelector*, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule = false); + void addPageRule(StyleRulePage*); void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&); - void addRegionRule(WebKitCSSRegionRule*); + void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin); void shrinkToFit(); void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; } - const CSSStyleSelector::Features& features() const { return m_features; } + const StyleResolver::Features& features() const { return m_features; } const Vector<RuleData>* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); } const Vector<RuleData>* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); } @@ -244,9 +258,11 @@ public: const Vector<RuleData>* linkPseudoClassRules() const { return &m_linkPseudoClassRules; } const Vector<RuleData>* focusPseudoClassRules() const { return &m_focusPseudoClassRules; } const Vector<RuleData>* universalRules() const { return &m_universalRules; } - const Vector<CSSPageRule*>& pageRules() const { return m_pageRules; } + const Vector<StyleRulePage*>& pageRules() const { return m_pageRules; } public: + RuleSet(); + AtomRuleMap m_idRules; AtomRuleMap m_classRules; AtomRuleMap m_tagRules; @@ -254,13 +270,13 @@ public: Vector<RuleData> m_linkPseudoClassRules; Vector<RuleData> m_focusPseudoClassRules; Vector<RuleData> m_universalRules; - Vector<CSSPageRule*> m_pageRules; + Vector<StyleRulePage*> m_pageRules; unsigned m_ruleCount; bool m_autoShrinkToFitEnabled; - CSSStyleSelector::Features m_features; + StyleResolver::Features m_features; struct RuleSetSelectorPair { - RuleSetSelectorPair(CSSSelector* selector, RuleSet* ruleSet) : selector(selector), ruleSet(adoptPtr(ruleSet)) { } + RuleSetSelectorPair(CSSSelector* selector, PassOwnPtr<RuleSet> ruleSet) : selector(selector), ruleSet(ruleSet) { } RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { } CSSSelector* selector; OwnPtr<RuleSet> ruleSet; @@ -273,12 +289,21 @@ static RuleSet* defaultStyle; static RuleSet* defaultQuirksStyle; static RuleSet* defaultPrintStyle; static RuleSet* defaultViewSourceStyle; -static CSSStyleSheet* simpleDefaultStyleSheet; +static StyleSheetInternal* simpleDefaultStyleSheet; +static StyleSheetInternal* defaultStyleSheet; +static StyleSheetInternal* quirksStyleSheet; +static StyleSheetInternal* svgStyleSheet; +static StyleSheetInternal* mathMLStyleSheet; +static StyleSheetInternal* mediaControlsStyleSheet; +static StyleSheetInternal* fullscreenStyleSheet; -RenderStyle* CSSStyleSelector::s_styleNotYetAvailable; +RenderStyle* StyleResolver::s_styleNotYetAvailable; static void loadFullDefaultStyle(); static void loadSimpleDefaultStyle(); +template <class ListType> +static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >&, ListType*); + // 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}"; @@ -315,13 +340,11 @@ static StylePropertySet* rightToLeftDeclaration() return rightToLeftDecl.get(); } -CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet, - CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets, const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets, - bool strictParsing, bool matchAuthorAndUserStyles) +StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) : m_hasUAAppearance(false) , m_backgroundData(BackgroundFillLayer) , m_matchedPropertiesCacheAdditionsSinceLastSweep(0) - , m_checker(document, strictParsing) + , m_checker(document, !document->inQuirksMode()) , m_parentStyle(0) , m_rootElementStyle(0) , m_element(0) @@ -336,7 +359,7 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee , m_fontSelector(CSSFontSelector::create(document)) , m_applyPropertyToRegularStyle(true) , m_applyPropertyToVisitedLinkStyle(false) - , m_applyProperty(CSSStyleApplyProperty::sharedCSSStyleApplyProperty()) + , m_styleBuilder(StyleBuilder::sharedStyleBuilder()) #if ENABLE(CSS_SHADERS) , m_hasPendingShaders(false) #endif @@ -349,9 +372,8 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee if (!defaultStyle) { if (!root || elementCanUseSimpleDefaultStyle(root)) loadSimpleDefaultStyle(); - else { + else loadFullDefaultStyle(); - } } // construct document root element default style. this is needed @@ -367,65 +389,65 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee m_medium = adoptPtr(new MediaQueryEvaluator("all")); if (root) - m_rootDefaultStyle = styleForElement(root, 0, false, true); // don't ref, because the RenderStyle is allocated from global heap + m_rootDefaultStyle = styleForElement(root, 0, DisallowStyleSharing, MatchOnlyUserAgentRules); if (m_rootDefaultStyle && view) m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get())); - m_authorStyle = adoptPtr(new RuleSet); + m_authorStyle = RuleSet::create(); // Adding rules from multiple sheets, shrink at the end. // Adding global rules from multiple sheets, shrink at the end. // Note that there usually is only 1 sheet for scoped rules, so auto-shrink-to-fit is fine. m_authorStyle->disableAutoShrinkToFit(); // FIXME: This sucks! The user sheet is reparsed every time! - OwnPtr<RuleSet> tempUserStyle = adoptPtr(new RuleSet); - if (pageUserSheet) - tempUserStyle->addRulesFromSheet(pageUserSheet, *m_medium, this); - if (pageGroupUserSheets) { - unsigned length = pageGroupUserSheets->size(); - for (unsigned i = 0; i < length; i++) { - if (pageGroupUserSheets->at(i)->isUserStyleSheet()) - tempUserStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this); - else - m_authorStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this); - } - } - if (documentUserSheets) { - unsigned length = documentUserSheets->size(); - for (unsigned i = 0; i < length; i++) { - if (documentUserSheets->at(i)->isUserStyleSheet()) - tempUserStyle->addRulesFromSheet(documentUserSheets->at(i).get(), *m_medium, this); - else - m_authorStyle->addRulesFromSheet(documentUserSheets->at(i).get(), *m_medium, this); - } - } - + OwnPtr<RuleSet> tempUserStyle = RuleSet::create(); + if (CSSStyleSheet* pageUserSheet = document->pageUserSheet()) + tempUserStyle->addRulesFromSheet(pageUserSheet->internal(), *m_medium, this); + addAuthorRulesAndCollectUserRulesFromSheets(document->pageGroupUserSheets(), *tempUserStyle); + addAuthorRulesAndCollectUserRulesFromSheets(document->documentUserSheets(), *tempUserStyle); if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRules.size() > 0) m_userStyle = tempUserStyle.release(); - // Add rules from elements like SVG's <font-face> - if (mappedElementSheet) { - // FIXME: see if style scopes can/should be added here. - m_authorStyle->addRulesFromSheet(mappedElementSheet, *m_medium, this); +#if ENABLE(SVG_FONTS) + if (document->svgExtensions()) { + const HashSet<SVGFontFaceElement*>& svgFontFaceElements = document->svgExtensions()->svgFontFaceElements(); + HashSet<SVGFontFaceElement*>::const_iterator end = svgFontFaceElements.end(); + for (HashSet<SVGFontFaceElement*>::const_iterator it = svgFontFaceElements.begin(); it != end; ++it) + fontSelector()->addFontFaceRule((*it)->fontFaceRule()); } +#endif - // add stylesheets from document - appendAuthorStylesheets(0, styleSheets->vector()); + appendAuthorStylesheets(0, document->styleSheets()->vector()); } - -static PassOwnPtr<RuleSet> makeRuleSet(const Vector<CSSStyleSelector::RuleSelectorPair>& rules) + +void StyleResolver::addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >* userSheets, RuleSet& userStyle) +{ + if (!userSheets) + return; + + unsigned length = userSheets->size(); + for (unsigned i = 0; i < length; i++) { + StyleSheetInternal* sheet = userSheets->at(i)->internal(); + if (sheet->isUserStyleSheet()) + userStyle.addRulesFromSheet(sheet, *m_medium, this); + else + m_authorStyle->addRulesFromSheet(sheet, *m_medium, this); + } +} + +static PassOwnPtr<RuleSet> makeRuleSet(const Vector<StyleResolver::RuleFeature>& rules) { size_t size = rules.size(); if (!size) return nullptr; - OwnPtr<RuleSet> ruleSet = adoptPtr(new RuleSet); + OwnPtr<RuleSet> ruleSet = RuleSet::create(); for (size_t i = 0; i < size; ++i) - ruleSet->addRule(rules[i].rule, rules[i].selector); + ruleSet->addRule(rules[i].rule, rules[i].selector, rules[i].hasDocumentSecurityOrigin, false); return ruleSet.release(); } -void CSSStyleSelector::collectFeatures() +void StyleResolver::collectFeatures() { m_features.clear(); // Collect all ids and rules using sibling selectors (:first-child and similar) @@ -445,14 +467,14 @@ void CSSStyleSelector::collectFeatures() } #if ENABLE(STYLE_SCOPED) -const ContainerNode* CSSStyleSelector::determineScope(const CSSStyleSheet* sheet) +const ContainerNode* StyleResolver::determineScope(const StyleSheetInternal* sheet) { ASSERT(sheet); if (!RuntimeEnabledFeatures::styleScopedEnabled()) return 0; - Node* ownerNode = sheet->findStyleSheetOwnerNode(); + Node* ownerNode = sheet->singleOwnerNode(); if (!ownerNode || !ownerNode->isHTMLElement() || !ownerNode->hasTagName(HTMLNames::styleTag)) return 0; @@ -467,7 +489,7 @@ const ContainerNode* CSSStyleSelector::determineScope(const CSSStyleSheet* sheet return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; } -inline RuleSet* CSSStyleSelector::ruleSetForScope(const ContainerNode* scope) const +inline RuleSet* StyleResolver::ruleSetForScope(const ContainerNode* scope) const { if (!scope->hasScopedHTMLStyleChild()) return 0; @@ -476,26 +498,33 @@ inline RuleSet* CSSStyleSelector::ruleSetForScope(const ContainerNode* scope) co } #endif -void CSSStyleSelector::appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >& stylesheets) +void StyleResolver::appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >& stylesheets) { // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated. unsigned size = stylesheets.size(); for (unsigned i = firstNew; i < size; ++i) { - if (!stylesheets[i]->isCSSStyleSheet() || stylesheets[i]->disabled()) + if (!stylesheets[i]->isCSSStyleSheet()) continue; CSSStyleSheet* cssSheet = static_cast<CSSStyleSheet*>(stylesheets[i].get()); + if (cssSheet->disabled()) + continue; + if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), this)) + continue; + StyleSheetInternal* sheet = cssSheet->internal(); #if ENABLE(STYLE_SCOPED) - const ContainerNode* scope = determineScope(cssSheet); + const ContainerNode* scope = determineScope(sheet); if (scope) { - pair<ScopedRuleSetMap::iterator, bool> addResult = m_scopedAuthorStyles.add(scope, nullptr); - if (addResult.second) - addResult.first->second = adoptPtr(new RuleSet()); - addResult.first->second->addRulesFromSheet(cssSheet, *m_medium, this, scope); + ScopedRuleSetMap::AddResult addResult = m_scopedAuthorStyles.add(scope, nullptr); + if (addResult.isNewEntry) + addResult.iterator->second = RuleSet::create(); + addResult.iterator->second->addRulesFromSheet(sheet, *m_medium, this, scope); continue; } #endif - m_authorStyle->addRulesFromSheet(cssSheet, *m_medium, this); + m_authorStyle->addRulesFromSheet(sheet, *m_medium, this); + if (!m_styleRuleToCSSOMWrapperMap.isEmpty()) + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, cssSheet); } m_authorStyle->shrinkToFit(); collectFeatures(); @@ -505,7 +534,7 @@ void CSSStyleSelector::appendAuthorStylesheets(unsigned firstNew, const Vector<R } #if ENABLE(STYLE_SCOPED) -void CSSStyleSelector::setupScopeStack(const ContainerNode* parent) +void StyleResolver::setupScopeStack(const ContainerNode* parent) { // The scoping element stack shouldn't be used if <style scoped> isn't used anywhere. ASSERT(!m_scopedAuthorStyles.isEmpty()); @@ -520,7 +549,7 @@ void CSSStyleSelector::setupScopeStack(const ContainerNode* parent) m_scopeStackParent = parent; } -void CSSStyleSelector::pushScope(const ContainerNode* scope, const ContainerNode* scopeParent) +void StyleResolver::pushScope(const ContainerNode* scope, const ContainerNode* scopeParent) { // Shortcut: Don't bother with the scoping element stack if <style scoped> isn't used anywhere. if (m_scopedAuthorStyles.isEmpty()) { @@ -541,7 +570,7 @@ void CSSStyleSelector::pushScope(const ContainerNode* scope, const ContainerNode m_scopeStackParent = scope; } -void CSSStyleSelector::popScope(const ContainerNode* scope) +void StyleResolver::popScope(const ContainerNode* scope) { // Only bother to update the scoping element stack if it is consistent. if (scopeStackIsConsistent(scope)) { @@ -551,7 +580,7 @@ void CSSStyleSelector::popScope(const ContainerNode* scope) } #endif -void CSSStyleSelector::pushParentElement(Element* parent) +void StyleResolver::pushParentElement(Element* parent) { const ContainerNode* parentsParent = parent->parentOrHostElement(); @@ -568,7 +597,7 @@ void CSSStyleSelector::pushParentElement(Element* parent) pushScope(parent, parent->parentOrHostNode()); } -void CSSStyleSelector::popParentElement(Element* parent) +void StyleResolver::popParentElement(Element* parent) { // Note that we may get invoked for some random elements in some wacky cases during style resolve. // Pause maintaining the stack in this case. @@ -577,31 +606,31 @@ void CSSStyleSelector::popParentElement(Element* parent) popScope(parent); } -void CSSStyleSelector::pushParentShadowRoot(const ShadowRoot* shadowRoot) +void StyleResolver::pushParentShadowRoot(const ShadowRoot* shadowRoot) { ASSERT(shadowRoot->host()); pushScope(shadowRoot, shadowRoot->host()); } -void CSSStyleSelector::popParentShadowRoot(const ShadowRoot* shadowRoot) +void StyleResolver::popParentShadowRoot(const ShadowRoot* shadowRoot) { ASSERT(shadowRoot->host()); popScope(shadowRoot); } // This is a simplified style setting function for keyframe styles -void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule) +void StyleResolver::addKeyframeStyle(PassRefPtr<StyleRuleKeyframes> rule) { AtomicString s(rule->name()); m_keyframesRuleMap.set(s.impl(), rule); } -CSSStyleSelector::~CSSStyleSelector() +StyleResolver::~StyleResolver() { m_fontSelector->clearDocument(); } -void CSSStyleSelector::sweepMatchedPropertiesCache() +void StyleResolver::sweepMatchedPropertiesCache() { // Look for cache entries containing a style declaration with a single ref and remove them. // This may happen when an element attribute mutation causes it to swap out its Attribute::decl() @@ -622,18 +651,18 @@ void CSSStyleSelector::sweepMatchedPropertiesCache() m_matchedPropertiesCache.remove(toRemove[i]); } -CSSStyleSelector::Features::Features() +StyleResolver::Features::Features() : usesFirstLineRules(false) , usesBeforeAfterRules(false) , usesLinkRules(false) { } -CSSStyleSelector::Features::~Features() +StyleResolver::Features::~Features() { } -void CSSStyleSelector::Features::add(const CSSStyleSelector::Features& other) +void StyleResolver::Features::add(const StyleResolver::Features& other) { HashSet<AtomicStringImpl*>::iterator end = other.idsInRules.end(); for (HashSet<AtomicStringImpl*>::iterator it = other.idsInRules.begin(); it != end; ++it) @@ -648,7 +677,7 @@ void CSSStyleSelector::Features::add(const CSSStyleSelector::Features& other) usesLinkRules = usesLinkRules || other.usesLinkRules; } -void CSSStyleSelector::Features::clear() +void StyleResolver::Features::clear() { idsInRules.clear(); attrsInRules.clear(); @@ -659,14 +688,14 @@ void CSSStyleSelector::Features::clear() usesLinkRules = false; } -static CSSStyleSheet* parseUASheet(const String& str) +static StyleSheetInternal* parseUASheet(const String& str) { - CSSStyleSheet* sheet = CSSStyleSheet::create().leakRef(); // leak the sheet on purpose + StyleSheetInternal* sheet = StyleSheetInternal::create().leakRef(); // leak the sheet on purpose sheet->parseString(str); return sheet; } -static CSSStyleSheet* parseUASheet(const char* characters, unsigned size) +static StyleSheetInternal* parseUASheet(const char* characters, unsigned size) { return parseUASheet(String(characters, size)); } @@ -678,26 +707,26 @@ static void loadFullDefaultStyle() ASSERT(defaultPrintStyle == defaultStyle); delete defaultStyle; simpleDefaultStyleSheet->deref(); - defaultStyle = new RuleSet; - defaultPrintStyle = new RuleSet; + defaultStyle = RuleSet::create().leakPtr(); + defaultPrintStyle = RuleSet::create().leakPtr(); simpleDefaultStyleSheet = 0; } else { ASSERT(!defaultStyle); - defaultStyle = new RuleSet; - defaultPrintStyle = new RuleSet; - defaultQuirksStyle = new RuleSet; + defaultStyle = RuleSet::create().leakPtr(); + defaultPrintStyle = RuleSet::create().leakPtr(); + defaultQuirksStyle = RuleSet::create().leakPtr(); } // Strict-mode rules. String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet(); - CSSStyleSheet* defaultSheet = parseUASheet(defaultRules); - defaultStyle->addRulesFromSheet(defaultSheet, screenEval()); - defaultPrintStyle->addRulesFromSheet(defaultSheet, printEval()); + defaultStyleSheet = parseUASheet(defaultRules); + defaultStyle->addRulesFromSheet(defaultStyleSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(defaultStyleSheet, printEval()); // Quirks-mode rules. String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraQuirksStyleSheet(); - CSSStyleSheet* quirksSheet = parseUASheet(quirksRules); - defaultQuirksStyle->addRulesFromSheet(quirksSheet, screenEval()); + quirksStyleSheet = parseUASheet(quirksRules); + defaultQuirksStyle->addRulesFromSheet(quirksStyleSheet, screenEval()); } static void loadSimpleDefaultStyle() @@ -705,10 +734,10 @@ static void loadSimpleDefaultStyle() ASSERT(!defaultStyle); ASSERT(!simpleDefaultStyleSheet); - defaultStyle = new RuleSet; + defaultStyle = RuleSet::create().leakPtr(); // There are no media-specific rules in the simple default style. defaultPrintStyle = defaultStyle; - defaultQuirksStyle = new RuleSet; + defaultQuirksStyle = RuleSet::create().leakPtr(); simpleDefaultStyleSheet = parseUASheet(simpleUserAgentStyleSheet, strlen(simpleUserAgentStyleSheet)); defaultStyle->addRulesFromSheet(simpleDefaultStyleSheet, screenEval()); @@ -719,7 +748,7 @@ static void loadSimpleDefaultStyle() static void loadViewSourceStyle() { ASSERT(!defaultViewSourceStyle); - defaultViewSourceStyle = new RuleSet; + defaultViewSourceStyle = RuleSet::create().leakPtr(); defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval()); } @@ -729,54 +758,46 @@ static void ensureDefaultStyleSheetsForElement(Element* element) loadFullDefaultStyle(); #if ENABLE(SVG) - static bool loadedSVGUserAgentSheet; - if (element->isSVGElement() && !loadedSVGUserAgentSheet) { + if (element->isSVGElement() && !svgStyleSheet) { // SVG rules. - loadedSVGUserAgentSheet = true; - CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)); - defaultStyle->addRulesFromSheet(svgSheet, screenEval()); - defaultPrintStyle->addRulesFromSheet(svgSheet, printEval()); + svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet)); + defaultStyle->addRulesFromSheet(svgStyleSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(svgStyleSheet, printEval()); } #endif - static bool loadedMathMLUserAgentSheet; #if ENABLE(MATHML) - if (element->isMathMLElement() && !loadedMathMLUserAgentSheet) { + if (element->isMathMLElement() && !mathMLStyleSheet) { // MathML rules. - loadedMathMLUserAgentSheet = true; - CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet)); - defaultStyle->addRulesFromSheet(mathMLSheet, screenEval()); - defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval()); + mathMLStyleSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet)); + defaultStyle->addRulesFromSheet(mathMLStyleSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(mathMLStyleSheet, printEval()); } #endif #if ENABLE(VIDEO) - static bool loadedMediaStyleSheet; - if (!loadedMediaStyleSheet && (element->hasTagName(videoTag) || element->hasTagName(audioTag))) { - loadedMediaStyleSheet = true; + if (!mediaControlsStyleSheet && (element->hasTagName(videoTag) || element->hasTagName(audioTag))) { String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(element->document()->page())->extraMediaControlsStyleSheet(); - CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules); - defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval()); - defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, printEval()); + mediaControlsStyleSheet = parseUASheet(mediaRules); + defaultStyle->addRulesFromSheet(mediaControlsStyleSheet, screenEval()); + defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet, printEval()); } #endif #if ENABLE(FULLSCREEN_API) - static bool loadedFullScreenStyleSheet; - if (!loadedFullScreenStyleSheet && element->document()->webkitIsFullScreen()) { - loadedFullScreenStyleSheet = true; + if (!fullscreenStyleSheet && element->document()->webkitIsFullScreen()) { String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraFullScreenStyleSheet(); - CSSStyleSheet* fullscreenSheet = parseUASheet(fullscreenRules); - defaultStyle->addRulesFromSheet(fullscreenSheet, screenEval()); - defaultQuirksStyle->addRulesFromSheet(fullscreenSheet, screenEval()); + fullscreenStyleSheet = parseUASheet(fullscreenRules); + defaultStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval()); + defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval()); } #endif ASSERT(defaultStyle->features().idsInRules.isEmpty()); - ASSERT_UNUSED(loadedMathMLUserAgentSheet, loadedMathMLUserAgentSheet || defaultStyle->features().siblingRules.isEmpty()); + ASSERT(mathMLStyleSheet || defaultStyle->features().siblingRules.isEmpty()); } -void CSSStyleSelector::addMatchedProperties(MatchResult& matchResult, StylePropertySet* properties, StyleRule* rule, unsigned linkMatchType, bool inRegionRule) +void StyleResolver::addMatchedProperties(MatchResult& matchResult, StylePropertySet* properties, StyleRule* rule, unsigned linkMatchType, bool inRegionRule) { matchResult.matchedProperties.grow(matchResult.matchedProperties.size() + 1); MatchedProperties& newProperties = matchResult.matchedProperties.last(); @@ -786,7 +807,7 @@ void CSSStyleSelector::addMatchedProperties(MatchResult& matchResult, StylePrope matchResult.matchedRules.append(rule); } -inline void CSSStyleSelector::addElementStyleProperties(MatchResult& result, StylePropertySet* propertySet, bool isCacheable) +inline void StyleResolver::addElementStyleProperties(MatchResult& result, StylePropertySet* propertySet, bool isCacheable) { if (!propertySet) return; @@ -798,7 +819,7 @@ inline void CSSStyleSelector::addElementStyleProperties(MatchResult& result, Sty result.isCacheable = false; } -void CSSStyleSelector::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) +void StyleResolver::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) { ASSERT(rules); ASSERT(m_element); @@ -827,7 +848,7 @@ void CSSStyleSelector::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, collectMatchingRulesForList(rules->universalRules(), firstRuleIndex, lastRuleIndex, options); } -void CSSStyleSelector::collectMatchingRulesForRegion(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) +void StyleResolver::collectMatchingRulesForRegion(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) { if (!m_regionForStyling) return; @@ -843,18 +864,18 @@ void CSSStyleSelector::collectMatchingRulesForRegion(RuleSet* rules, int& firstR } } -void CSSStyleSelector::sortAndTransferMatchedRules(MatchResult& result) +void StyleResolver::sortAndTransferMatchedRules(MatchResult& result) { if (m_matchedRules.isEmpty()) return; sortMatchedRules(); - if (m_checker.isCollectingRulesOnly()) { + if (m_checker.mode() == SelectorChecker::CollectingRules) { if (!m_ruleList) - m_ruleList = CSSRuleList::create(); + m_ruleList = StaticCSSRuleList::create(); for (unsigned i = 0; i < m_matchedRules.size(); ++i) - m_ruleList->append(m_matchedRules[i]->rule()->ensureCSSStyleRule()); + m_ruleList->rules().append(m_matchedRules[i]->rule()->createCSSOMWrapper()); return; } @@ -871,7 +892,7 @@ void CSSStyleSelector::sortAndTransferMatchedRules(MatchResult& result) } } -void CSSStyleSelector::matchScopedAuthorRules(MatchResult& result, bool includeEmptyRules) +void StyleResolver::matchScopedAuthorRules(MatchResult& result, bool includeEmptyRules) { #if ENABLE(STYLE_SCOPED) if (m_scopedAuthorStyles.isEmpty()) @@ -902,7 +923,7 @@ void CSSStyleSelector::matchScopedAuthorRules(MatchResult& result, bool includeE #endif } -void CSSStyleSelector::matchAuthorRules(MatchResult& result, bool includeEmptyRules) +void StyleResolver::matchAuthorRules(MatchResult& result, bool includeEmptyRules) { m_matchedRules.clear(); result.ranges.lastAuthorRule = result.matchedProperties.size() - 1; @@ -920,7 +941,7 @@ void CSSStyleSelector::matchAuthorRules(MatchResult& result, bool includeEmptyRu sortAndTransferMatchedRules(result); } -void CSSStyleSelector::matchUserRules(MatchResult& result, bool includeEmptyRules) +void StyleResolver::matchUserRules(MatchResult& result, bool includeEmptyRules) { if (!m_userStyle) return; @@ -934,7 +955,7 @@ void CSSStyleSelector::matchUserRules(MatchResult& result, bool includeEmptyRule sortAndTransferMatchedRules(result); } -void CSSStyleSelector::matchUARules(MatchResult& result, RuleSet* rules) +void StyleResolver::matchUARules(MatchResult& result, RuleSet* rules) { m_matchedRules.clear(); @@ -973,7 +994,7 @@ inline bool MatchingUARulesScope::isMatchingUARules() bool MatchingUARulesScope::m_matchingUARules = false; -void CSSStyleSelector::collectMatchingRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) +void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) { if (!rules) return; @@ -1016,15 +1037,15 @@ void CSSStyleSelector::collectMatchingRulesForList(const Vector<RuleData>* rules InspectorInstrumentation::didMatchRule(cookie, false); continue; } - // FIXME: Exposing getMatchedCSSRules as a web facing API is forcing us to have a way to get the base URL per-rule. - if (m_sameOriginOnly && !m_checker.document()->securityOrigin()->canRequest(rule->ensureCSSStyleRule()->baseURL())) { + // FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed. + if (m_sameOriginOnly && !ruleData.hasDocumentSecurityOrigin()) { InspectorInstrumentation::didMatchRule(cookie, false); continue; } // If we're matching normal rules, set a pseudo bit if // we really just matched a pseudo-element. if (m_dynamicPseudo != NOPSEUDO && m_checker.pseudoStyle() == NOPSEUDO) { - if (m_checker.isCollectingRulesOnly()) { + if (m_checker.mode() == SelectorChecker::CollectingRules) { InspectorInstrumentation::didMatchRule(cookie, false); continue; } @@ -1053,12 +1074,12 @@ static inline bool compareRules(const RuleData* r1, const RuleData* r2) return (specificity1 == specificity2) ? r1->position() < r2->position() : specificity1 < specificity2; } -void CSSStyleSelector::sortMatchedRules() +void StyleResolver::sortMatchedRules() { std::sort(m_matchedRules.begin(), m_matchedRules.end(), compareRules); } -void CSSStyleSelector::matchAllRules(MatchResult& result) +void StyleResolver::matchAllRules(MatchResult& result, bool includeSMILProperties) { matchUARules(result); @@ -1091,19 +1112,19 @@ void CSSStyleSelector::matchAllRules(MatchResult& result) if (m_matchAuthorAndUserStyles && m_styledElement && m_styledElement->inlineStyle()) { // Inline style is immutable as long as there is no CSSOM wrapper. // FIXME: Media control shadow trees seem to have problems with caching. - bool isInlineStyleCacheable = !m_styledElement->inlineStyle()->hasCSSOMWrapper() && !m_styledElement->isInShadowTree(); + bool isInlineStyleCacheable = !m_styledElement->inlineStyle()->isMutable() && !m_styledElement->isInShadowTree(); // FIXME: Constify. addElementStyleProperties(result, const_cast<StylePropertySet*>(m_styledElement->inlineStyle()), isInlineStyleCacheable); } #if ENABLE(SVG) // Now check SMIL animation override style. - if (m_matchAuthorAndUserStyles && m_styledElement && m_styledElement->isSVGElement()) + if (includeSMILProperties && m_matchAuthorAndUserStyles && m_styledElement && m_styledElement->isSVGElement()) addElementStyleProperties(result, static_cast<SVGElement*>(m_styledElement)->animatedSMILStyleProperties(), false /* isCacheable */); #endif } -inline void CSSStyleSelector::initElement(Element* e) +inline void StyleResolver::initElement(Element* e) { if (m_element != e) { m_element = e; @@ -1116,7 +1137,7 @@ inline void CSSStyleSelector::initElement(Element* e) } } -inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID) +inline void StyleResolver::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID) { m_checker.setPseudoStyle(pseudoID); @@ -1143,7 +1164,7 @@ inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* paren static const unsigned cStyleSearchThreshold = 10; static const unsigned cStyleSearchLevelThreshold = 10; -Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned& visitedNodeCount) const +Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCount) const { if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold) return 0; @@ -1190,7 +1211,7 @@ Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned& visitedNodeC return 0; } -bool CSSStyleSelector::matchesRuleSet(RuleSet* ruleSet) +bool StyleResolver::matchesRuleSet(RuleSet* ruleSet) { if (!ruleSet) return false; @@ -1205,22 +1226,8 @@ bool CSSStyleSelector::matchesRuleSet(RuleSet* ruleSet) return true; } -bool CSSStyleSelector::canShareStyleWithControl(StyledElement* element) const +bool StyleResolver::canShareStyleWithControl(StyledElement* element) const { -#if ENABLE(PROGRESS_TAG) - if (element->hasTagName(progressTag)) { - if (!m_element->hasTagName(progressTag)) - return false; - - HTMLProgressElement* thisProgressElement = static_cast<HTMLProgressElement*>(element); - HTMLProgressElement* otherProgressElement = static_cast<HTMLProgressElement*>(m_element); - if (thisProgressElement->isDeterminate() != otherProgressElement->isDeterminate()) - return false; - - return true; - } -#endif - HTMLInputElement* thisInputElement = element->toInputElement(); HTMLInputElement* otherInputElement = m_element->toInputElement(); @@ -1287,7 +1294,12 @@ static inline bool attributeStylesEqual(StylePropertySet* a, StylePropertySet* b return true; } -bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const +inline bool elementHasDirectionAuto(Element* element) +{ + return element->isHTMLElement() && toHTMLElement(element)->hasDirectionAuto(); +} + +bool StyleResolver::canShareStyleWithElement(StyledElement* element) const { RenderStyle* style = element->renderStyle(); @@ -1346,6 +1358,21 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const return false; #endif +#if ENABLE(PROGRESS_TAG) + if (element->hasTagName(progressTag)) { + if (!m_element->hasTagName(progressTag)) + return false; + + HTMLProgressElement* thisProgressElement = static_cast<HTMLProgressElement*>(element); + HTMLProgressElement* otherProgressElement = static_cast<HTMLProgressElement*>(m_element); + if (thisProgressElement->isDeterminate() != otherProgressElement->isDeterminate()) + return false; + } +#endif + + if (element->hasTagName(optionTag)) + return false; + bool isControl = element->isFormControlElement(); if (isControl != m_element->isFormControlElement()) @@ -1369,7 +1396,7 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const return false; #endif - if (equalIgnoringCase(element->fastGetAttribute(dirAttr), "auto") || equalIgnoringCase(m_element->fastGetAttribute(dirAttr), "auto")) + if (elementHasDirectionAuto(element) || elementHasDirectionAuto(m_element)) return false; if (element->hasClass() && m_element->getAttribute(classAttr) != element->getAttribute(classAttr)) @@ -1387,7 +1414,7 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const return true; } -inline StyledElement* CSSStyleSelector::findSiblingForStyleSharing(Node* node, unsigned& count) const +inline StyledElement* StyleResolver::findSiblingForStyleSharing(Node* node, unsigned& count) const { for (; node; node = node->previousSibling()) { if (!node->isStyledElement()) @@ -1408,7 +1435,7 @@ static inline bool parentStylePreventsSharing(const RenderStyle* parentStyle) || parentStyle->childrenAffectedByDirectAdjacentRules(); } -RenderStyle* CSSStyleSelector::locateSharedStyle() +RenderStyle* StyleResolver::locateSharedStyle() { if (!m_styledElement || !m_parentStyle) return 0; @@ -1457,7 +1484,7 @@ RenderStyle* CSSStyleSelector::locateSharedStyle() return shareElement->renderStyle(); } -void CSSStyleSelector::matchUARules(MatchResult& result) +void StyleResolver::matchUARules(MatchResult& result) { MatchingUARulesScope scope; @@ -1480,7 +1507,7 @@ void CSSStyleSelector::matchUARules(MatchResult& result) } } -PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document, CSSFontSelector* fontSelector) +PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document* document, CSSFontSelector* fontSelector) { Frame* frame = document->frame(); @@ -1531,10 +1558,10 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document, C fontDescription.firstFamily().appendFamily(0); } fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1); - int size = CSSStyleSelector::fontSizeForKeyword(document, CSSValueMedium, false); + int size = StyleResolver::fontSizeForKeyword(document, CSSValueMedium, false); fontDescription.setSpecifiedSize(size); bool useSVGZoomRules = document->isSVGDocument(); - fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules)); + fontDescription.setComputedSize(StyleResolver::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules)); } documentStyle->setFontDescription(fontDescription); @@ -1551,14 +1578,12 @@ static inline bool isAtShadowBoundary(Element* element) return parentNode && parentNode->isShadowRoot(); } -// If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where -// relative units are interpreted according to document root element style, styled only with UA stylesheet - -PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, RenderRegion* regionForStyling) +PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent, + StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, RenderRegion* regionForStyling) { // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer // will vanish if a style recalc happens during loading. - if (allowSharing && !element->document()->haveStylesheetsLoaded() && !element->renderer()) { + if (sharingBehavior == AllowStyleSharing && !element->document()->haveStylesheetsLoaded() && !element->renderer()) { if (!s_styleNotYetAvailable) { s_styleNotYetAvailable = RenderStyle::create().leakRef(); s_styleNotYetAvailable->setDisplay(NONE); @@ -1571,7 +1596,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, Rend initElement(element); initForStyleResolve(element, defaultParent); m_regionForStyling = regionForStyling; - if (allowSharing) { + if (sharingBehavior == AllowStyleSharing) { RenderStyle* sharedStyle = locateSharedStyle(); if (sharedStyle) return sharedStyle; @@ -1599,10 +1624,10 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, Rend ensureDefaultStyleSheetsForElement(element); MatchResult matchResult; - if (resolveForRootDefault) + if (matchingBehavior == MatchOnlyUserAgentRules) matchUARules(matchResult); else - matchAllRules(matchResult); + matchAllRules(matchResult, matchingBehavior != MatchAllRulesExcludingSMIL); applyMatchedProperties(matchResult); @@ -1615,11 +1640,11 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, Rend return m_style.release(); } -PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeValue& keyframe) +PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(const RenderStyle* elementStyle, const StyleKeyframe* keyframe, KeyframeValue& keyframeValue) { MatchResult result; - if (keyframeRule->declaration()) - addMatchedProperties(result, keyframeRule->declaration()); + if (keyframe->properties()) + addMatchedProperties(result, keyframe->properties()); ASSERT(!m_style); @@ -1631,7 +1656,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* el // We don't need to bother with !important. Since there is only ever one // decl, there's nothing to override. So just add the first properties. bool inheritedOnly = false; - if (keyframeRule->style()) + if (keyframe->properties()) applyMatchedProperties<true>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly); // If our font got dirtied, go ahead and update it now. @@ -1642,7 +1667,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* el applyProperty(CSSPropertyLineHeight, m_lineHeightValue); // Now do rest of the properties. - if (keyframeRule->style()) + if (keyframe->properties()) applyMatchedProperties<false>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly); // If our font got dirtied by one of the non-essential font props, @@ -1658,21 +1683,21 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* el #endif // Add all the animating properties to the keyframe. - if (StylePropertySet* styleDeclaration = keyframeRule->declaration()) { + if (StylePropertySet* styleDeclaration = keyframe->properties()) { unsigned propertyCount = styleDeclaration->propertyCount(); for (unsigned i = 0; i < propertyCount; ++i) { - int property = styleDeclaration->propertyAt(i).id(); + CSSPropertyID property = styleDeclaration->propertyAt(i).id(); // Timing-function within keyframes is special, because it is not animated; it just // describes the timing function between this keyframe and the next. if (property != CSSPropertyWebkitAnimationTimingFunction) - keyframe.addProperty(property); + keyframeValue.addProperty(property); } } return m_style.release(); } -void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list) +void StyleResolver::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list) { list.clear(); @@ -1686,49 +1711,56 @@ void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* if (it == m_keyframesRuleMap.end()) return; - const WebKitCSSKeyframesRule* rule = it->second.get(); + const StyleRuleKeyframes* keyframesRule = it->second.get(); // Construct and populate the style for each keyframe - for (unsigned i = 0; i < rule->length(); ++i) { + const Vector<RefPtr<StyleKeyframe> >& keyframes = keyframesRule->keyframes(); + for (unsigned i = 0; i < keyframes.size(); ++i) { // Apply the declaration to the style. This is a simplified version of the logic in styleForElement initElement(e); initForStyleResolve(e); - const WebKitCSSKeyframeRule* keyframeRule = rule->item(i); + const StyleKeyframe* keyframe = keyframes[i].get(); - KeyframeValue keyframe(0, 0); - keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule, keyframe)); + KeyframeValue keyframeValue(0, 0); + keyframeValue.setStyle(styleForKeyframe(elementStyle, keyframe, keyframeValue)); // Add this keyframe style to all the indicated key times Vector<float> keys; - keyframeRule->getKeys(keys); + keyframe->getKeys(keys); for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) { - keyframe.setKey(keys[keyIndex]); - list.insert(keyframe); + keyframeValue.setKey(keys[keyIndex]); + list.insert(keyframeValue); } } // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe) int initialListSize = list.size(); - if (initialListSize > 0 && list[0].key() != 0) { - RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create(); - keyframeRule->setKeyText("0%"); - KeyframeValue keyframe(0, 0); - keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe)); - list.insert(keyframe); + if (initialListSize > 0 && list[0].key()) { + static StyleKeyframe* zeroPercentKeyframe; + if (!zeroPercentKeyframe) { + zeroPercentKeyframe = StyleKeyframe::create().leakRef(); + zeroPercentKeyframe->setKeyText("0%"); + } + KeyframeValue keyframeValue(0, 0); + keyframeValue.setStyle(styleForKeyframe(elementStyle, zeroPercentKeyframe, keyframeValue)); + list.insert(keyframeValue); } // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe) if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) { - RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create(); - keyframeRule->setKeyText("100%"); - KeyframeValue keyframe(1, 0); - keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe)); - list.insert(keyframe); + static StyleKeyframe* hundredPercentKeyframe; + if (!hundredPercentKeyframe) { + hundredPercentKeyframe = StyleKeyframe::create().leakRef(); + hundredPercentKeyframe->setKeyText("100%"); + } + KeyframeValue keyframeValue(1, 0); + keyframeValue.setStyle(styleForKeyframe(elementStyle, hundredPercentKeyframe, keyframeValue)); + list.insert(keyframeValue); } } -PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle) +PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle) { if (!e) return 0; @@ -1775,7 +1807,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, return m_style.release(); } -PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex) +PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex) { initForStyleResolve(m_checker.document()->documentElement()); // m_rootElementStyle will be set to the document style. @@ -1887,7 +1919,7 @@ static EDisplay equivalentBlockDisplay(EDisplay display, bool isFloating, bool s return BLOCK; } -void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e) +void StyleResolver::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e) { // Cache our original display. style->setOriginalDisplay(style->display()); @@ -1895,21 +1927,20 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent if (style->display() != NONE) { // If we have a <td> that specifies a float property, in quirks mode we just drop the float // property. - // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force + // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force // these tags to retain their display types. if (!m_checker.strictParsing() && e) { if (e->hasTagName(tdTag)) { style->setDisplay(TABLE_CELL); style->setFloating(NoFloat); - } - else if (e->hasTagName(tableTag)) + } else if (e->hasTagName(tableTag)) style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE); } if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) { if (style->whiteSpace() == KHTML_NOWRAP) { // Figure out if we are really nowrapping or if we should just - // use normal instead. If the width of the cell is fixed, then + // use normal instead. If the width of the cell is fixed, then // we don't actually use NOWRAP. if (style->width().isFixed()) style->setWhiteSpace(NORMAL); @@ -1922,13 +1953,19 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT)) style->setTextAlign(TAAUTO); - // Frames and framesets never honor position:relative or position:absolute. This is necessary to - // fix a crash where a site tries to position these objects. They also never honor display. + // Frames and framesets never honor position:relative or position:absolute. This is necessary to + // fix a crash where a site tries to position these objects. They also never honor display. if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) { style->setPosition(StaticPosition); style->setDisplay(BLOCK); } + // Ruby text does not support float or position. This might change with evolution of the specification. + if (e && e->hasTagName(rtTag)) { + style->setPosition(StaticPosition); + style->setFloating(NoFloat); + } + // Table headers with a text-align of auto will change the text-align to center. if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO) style->setTextAlign(CENTER); @@ -1945,12 +1982,12 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent if (style->display() == INLINE && style->styleType() == NOPSEUDO && parentStyle && style->writingMode() != parentStyle->writingMode()) style->setDisplay(INLINE_BLOCK); - // After performing the display mutation, check table rows. We do not honor position:relative on - // table rows or cells. This has been established in CSS2.1 (and caused a crash in containingBlock() + // After performing the display mutation, check table rows. We do not honor position:relative on + // table rows or cells. This has been established in CSS2.1 (and caused a crash in containingBlock() // on some sites). if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP - || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW) && - style->position() == RelativePosition) + || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW) + && style->position() == RelativePosition) style->setPosition(StaticPosition); // writing-mode does not apply to table row groups, table column groups, table rows, and table columns. @@ -1971,11 +2008,14 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent if (style->position() == StaticPosition) style->setHasAutoZIndex(); - // Auto z-index becomes 0 for the root element and transparent objects. This prevents + // Auto z-index becomes 0 for the root element and transparent objects. This prevents // cases where objects that should be blended as a single unit end up with a non-transparent - // object wedged in between them. Auto z-index also becomes 0 for objects that specify transforms/masks/reflections. + // object wedged in between them. Auto z-index also becomes 0 for objects that specify transforms/masks/reflections. if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f || style->hasTransformRelatedProperty() || style->hasMask() || style->boxReflect() || style->hasFilter() +#ifdef FIXED_POSITION_CREATES_STACKING_CONTEXT + || style->position() == FixedPosition +#endif #if ENABLE(OVERFLOW_SCROLLING) // Touch overflow scrolling creates a stacking context. || style->useTouchOverflowScrolling() @@ -2009,8 +2049,8 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto. // FIXME: Eventually table sections will support auto and scroll. - if (style->display() == TABLE || style->display() == INLINE_TABLE || - style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) { + if (style->display() == TABLE || style->display() == INLINE_TABLE + || style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) { if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN) style->setOverflowX(OVISIBLE); if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN) @@ -2034,7 +2074,7 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent // 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) { - // Don't apply intrinsic margins to image buttons. The designer knows how big the images are, + // Don't apply intrinsic margins to image buttons. The designer knows how big the images are, // so we have to treat all image buttons as though they were explicitly sized. if (!e->hasTagName(inputTag) || !static_cast<HTMLInputElement*>(e)->isImageButton()) addIntrinsicMargins(style); @@ -2048,6 +2088,12 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent if (style->hasPseudoStyle(FIRST_LETTER)) style->setUnique(); + // FIXME: when dropping the -webkit prefix on transform-style, we should also have opacity < 1 cause flattening. + if (style->preserves3D() && (style->overflowX() != OVISIBLE + || style->overflowY() != OVISIBLE + || style->hasFilter())) + style->setTransformStyle3D(TransformStyle3DFlat); + #if ENABLE(SVG) if (e && e->isSVGElement()) { // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty @@ -2064,11 +2110,16 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parent // Only the root <svg> element in an SVG document fragment tree honors css position if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement())) style->setPosition(RenderStyle::initialPosition()); + + // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should + // not be scaled again. + if (e->hasTagName(SVGNames::foreignObjectTag)) + style->setEffectiveZoom(RenderStyle::initialZoom()); } #endif } -bool CSSStyleSelector::checkRegionStyle(Element* regionElement) +bool StyleResolver::checkRegionStyle(Element* regionElement) { // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment, // so all region rules are global by default. Verify whether that can stand or needs changing. @@ -2092,7 +2143,7 @@ bool CSSStyleSelector::checkRegionStyle(Element* regionElement) return false; } -void CSSStyleSelector::updateFont() +void StyleResolver::updateFont() { if (!m_fontDirty) return; @@ -2104,7 +2155,7 @@ void CSSStyleSelector::updateFont() m_fontDirty = false; } -void CSSStyleSelector::cacheBorderAndBackground() +void StyleResolver::cacheBorderAndBackground() { m_hasUAAppearance = m_style->hasAppearance(); if (m_hasUAAppearance) { @@ -2114,17 +2165,17 @@ void CSSStyleSelector::cacheBorderAndBackground() } } -PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, unsigned rulesToInclude) +PassRefPtr<CSSRuleList> StyleResolver::styleRulesForElement(Element* e, unsigned rulesToInclude) { return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude); } -PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude) +PassRefPtr<CSSRuleList> StyleResolver::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude) { if (!e || !e->document()->haveStylesheetsLoaded()) return 0; - m_checker.setCollectingRulesOnly(true); + m_checker.setMode(SelectorChecker::CollectingRules); initElement(e); initForStyleResolve(e, 0, pseudoId); @@ -2148,12 +2199,12 @@ PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, m_sameOriginOnly = false; } - m_checker.setCollectingRulesOnly(false); + m_checker.setMode(SelectorChecker::ResolvingStyle); return m_ruleList.release(); } -inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData, const ContainerNode* scope) +inline bool StyleResolver::checkSelector(const RuleData& ruleData, const ContainerNode* scope) { m_dynamicPseudo = NOPSEUDO; m_checker.clearHasUnknownPseudoElements(); @@ -2187,7 +2238,7 @@ inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData, const Cont return true; } -bool CSSStyleSelector::checkRegionSelector(CSSSelector* regionSelector, Element* regionElement) +bool StyleResolver::checkRegionSelector(CSSSelector* regionSelector, Element* regionElement) { if (!regionSelector || !regionElement) return false; @@ -2202,27 +2253,27 @@ bool CSSStyleSelector::checkRegionSelector(CSSSelector* regionSelector, Element* return false; } -bool CSSStyleSelector::determineStylesheetSelectorScopes(CSSStyleSheet* stylesheet, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes) +bool StyleResolver::determineStylesheetSelectorScopes(StyleSheetInternal* stylesheet, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes) { ASSERT(!stylesheet->isLoading()); - - size_t size = stylesheet->length(); - for (size_t i = 0; i < size; i++) { - CSSRule* rule = stylesheet->item(i); + + const Vector<RefPtr<StyleRuleImport> >& importRules = stylesheet->importRules(); + for (unsigned i = 0; i < importRules.size(); ++i) { + if (!importRules[i]->styleSheet()) + continue; + if (!determineStylesheetSelectorScopes(importRules[i]->styleSheet(), idScopes, classScopes)) + return false; + } + + const Vector<RefPtr<StyleRuleBase> >& rules = stylesheet->childRules(); + for (unsigned i = 0; i < rules.size(); i++) { + StyleRuleBase* rule = rules[i].get(); if (rule->isStyleRule()) { - StyleRule* styleRule = static_cast<CSSStyleRule*>(rule)->styleRule(); + StyleRule* styleRule = static_cast<StyleRule*>(rule); if (!SelectorChecker::determineSelectorScopes(styleRule->selectorList(), idScopes, classScopes)) return false; continue; } - if (rule->isImportRule()) { - CSSImportRule* importRule = static_cast<CSSImportRule*>(rule); - if (importRule->styleSheet()) { - if (!determineStylesheetSelectorScopes(importRule->styleSheet(), idScopes, classScopes)) - return false; - } - continue; - } // FIXME: Media rules and maybe some others could be allowed. return false; } @@ -2265,18 +2316,19 @@ static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attri static inline bool containsUncommonAttributeSelector(const CSSSelector* selector) { - while (selector) { + for (; selector; selector = selector->tagHistory()) { // Allow certain common attributes (used in the default style) in the selectors that match the current element. if (selector->isAttributeSelector() && !isCommonAttributeSelectorAttribute(selector->attribute())) return true; if (selectorListContainsUncommonAttributeSelector(selector)) return true; - if (selector->relation() != CSSSelector::SubSelector) + if (selector->relation() != CSSSelector::SubSelector) { + selector = selector->tagHistory(); break; - selector = selector->tagHistory(); - }; + } + } - for (selector = selector->tagHistory(); selector; selector = selector->tagHistory()) { + for (; selector; selector = selector->tagHistory()) { if (selector->isAttributeSelector()) return true; if (selectorListContainsUncommonAttributeSelector(selector)) @@ -2285,7 +2337,7 @@ static inline bool containsUncommonAttributeSelector(const CSSSelector* selector return false; } -RuleData::RuleData(StyleRule* rule, CSSSelector* selector, unsigned position, bool canUseFastCheckSelector, bool inRegionRule) +RuleData::RuleData(StyleRule* rule, CSSSelector* selector, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule) : m_rule(rule) , m_selector(selector) , m_specificity(selector->specificity()) @@ -2295,6 +2347,7 @@ RuleData::RuleData(StyleRule* rule, CSSSelector* selector, unsigned position, bo , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector)) , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(selector)) , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector)) + , m_hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) , m_isInRegionRule(inRegionRule) { SelectorChecker::collectIdentifierHashes(m_selector, m_descendantSelectorIdentifierHashes, maximumIdentifierCount); @@ -2306,7 +2359,7 @@ RuleSet::RuleSet() { } -static inline void collectFeaturesFromSelector(CSSStyleSelector::Features& features, const CSSSelector* selector) +static inline void collectFeaturesFromSelector(StyleResolver::Features& features, const CSSSelector* selector) { if (selector->m_match == CSSSelector::Id) features.idsInRules.add(selector->value().impl()); @@ -2329,7 +2382,7 @@ static inline void collectFeaturesFromSelector(CSSStyleSelector::Features& featu } } -static void collectFeaturesFromRuleData(CSSStyleSelector::Features& features, const RuleData& ruleData) +static void collectFeaturesFromRuleData(StyleResolver::Features& features, const RuleData& ruleData) { bool foundSiblingSelector = false; for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) { @@ -2345,24 +2398,24 @@ static void collectFeaturesFromRuleData(CSSStyleSelector::Features& features, co foundSiblingSelector = true; } if (foundSiblingSelector) - features.siblingRules.append(CSSStyleSelector::RuleSelectorPair(ruleData.rule(), ruleData.selector())); + features.siblingRules.append(StyleResolver::RuleFeature(ruleData.rule(), ruleData.selector(), ruleData.hasDocumentSecurityOrigin())); if (ruleData.containsUncommonAttributeSelector()) - features.uncommonAttributeRules.append(CSSStyleSelector::RuleSelectorPair(ruleData.rule(), ruleData.selector())); + features.uncommonAttributeRules.append(StyleResolver::RuleFeature(ruleData.rule(), ruleData.selector(), ruleData.hasDocumentSecurityOrigin())); } void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleData& ruleData) { if (!key) return; - OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).first->second; + OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).iterator->second; if (!rules) rules = adoptPtr(new Vector<RuleData>); rules->append(ruleData); } -void RuleSet::addRule(StyleRule* rule, CSSSelector* selector, bool canUseFastCheckSelector, bool inRegionRule) +void RuleSet::addRule(StyleRule* rule, CSSSelector* selector, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule) { - RuleData ruleData(rule, selector, m_ruleCount++, canUseFastCheckSelector, inRegionRule); + RuleData ruleData(rule, selector, m_ruleCount++, hasDocumentSecurityOrigin, canUseFastCheckSelector, inRegionRule); collectFeaturesFromRuleData(m_features, ruleData); if (selector->m_match == CSSSelector::Id) { @@ -2400,110 +2453,110 @@ void RuleSet::addRule(StyleRule* rule, CSSSelector* selector, bool canUseFastChe m_universalRules.append(ruleData); } -void RuleSet::addPageRule(CSSPageRule* rule) +void RuleSet::addPageRule(StyleRulePage* rule) { m_pageRules.append(rule); } -void RuleSet::addRegionRule(WebKitCSSRegionRule* rule) +void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin) { - RuleSet* regionRuleSet = new RuleSet; + OwnPtr<RuleSet> regionRuleSet = RuleSet::create(); // The region rule set should take into account the position inside the parent rule set. // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from // the stylesheet that contains the region block. regionRuleSet->m_ruleCount = m_ruleCount; // Collect the region rules into a rule set - CSSRuleList* regionStylingRules = rule->cssRules(); - unsigned rulesSize = regionStylingRules->length(); - for (unsigned i = 0; i < rulesSize; ++i) { - CSSRule* regionStylingRule = regionStylingRules->item(i); + const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules(); + for (unsigned i = 0; i < childRules.size(); ++i) { + StyleRuleBase* regionStylingRule = childRules[i].get(); if (regionStylingRule->isStyleRule()) - regionRuleSet->addStyleRule(static_cast<CSSStyleRule*>(regionStylingRule)->styleRule(), true, true); + regionRuleSet->addStyleRule(static_cast<StyleRule*>(regionStylingRule), hasDocumentSecurityOrigin, true, true); } + // Update the "global" rule count so that proper order is maintained + m_ruleCount = regionRuleSet->m_ruleCount; - m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(rule->selectorList().first(), regionRuleSet)); + m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), regionRuleSet.release())); } -void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector, const ContainerNode* scope) +void RuleSet::addRulesFromSheet(StyleSheetInternal* sheet, const MediaQueryEvaluator& medium, StyleResolver* styleSelector, const ContainerNode* scope) { ASSERT(sheet); + + 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(), styleSelector))) + addRulesFromSheet(importRule->styleSheet(), medium, styleSelector, scope); + } + bool hasDocumentSecurityOrigin = styleSelector && styleSelector->document()->securityOrigin()->canRequest(sheet->baseURL()); - // No media implies "all", but if a media list exists it must - // contain our current medium - if (sheet->media() && !medium.eval(sheet->media(), styleSelector)) - return; // the style sheet doesn't apply - - int len = sheet->length(); + const Vector<RefPtr<StyleRuleBase> >& rules = sheet->childRules(); + for (unsigned i = 0; i < rules.size(); ++i) { + StyleRuleBase* rule = rules[i].get(); - for (int i = 0; i < len; i++) { - CSSRule* rule = sheet->item(i); + ASSERT(!rule->isImportRule()); if (rule->isStyleRule()) - addStyleRule(static_cast<CSSStyleRule*>(rule)->styleRule(), !scope); + addStyleRule(static_cast<StyleRule*>(rule), hasDocumentSecurityOrigin, !scope); else if (rule->isPageRule()) - addPageRule(static_cast<CSSPageRule*>(rule)); - else if (rule->isImportRule()) { - CSSImportRule* import = static_cast<CSSImportRule*>(rule); - if (import->styleSheet() && (!import->media() || medium.eval(import->media(), styleSelector))) - addRulesFromSheet(import->styleSheet(), medium, styleSelector, scope); - } + addPageRule(static_cast<StyleRulePage*>(rule)); else if (rule->isMediaRule()) { - CSSMediaRule* r = static_cast<CSSMediaRule*>(rule); - CSSRuleList* rules = r->cssRules(); + StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); - if ((!r->media() || medium.eval(r->media(), styleSelector)) && rules) { + if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), styleSelector))) { // Traverse child elements of the @media rule. - for (unsigned j = 0; j < rules->length(); j++) { - CSSRule *childItem = rules->item(j); - if (childItem->isStyleRule()) - addStyleRule(static_cast<CSSStyleRule*>(childItem)->styleRule(), !scope); - else if (childItem->isPageRule()) - addPageRule(static_cast<CSSPageRule*>(childItem)); - else if (childItem->isFontFaceRule() && styleSelector) { + const Vector<RefPtr<StyleRuleBase> >& childRules = mediaRule->childRules(); + for (unsigned j = 0; j < childRules.size(); ++j) { + StyleRuleBase* childRule = childRules[j].get(); + if (childRule->isStyleRule()) + addStyleRule(static_cast<StyleRule*>(childRule), hasDocumentSecurityOrigin, !scope); + else if (childRule->isPageRule()) + addPageRule(static_cast<StyleRulePage*>(childRule)); + else if (childRule->isFontFaceRule() && styleSelector) { // Add this font face to our set. // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. if (scope) continue; - const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem); + const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(childRule); styleSelector->fontSelector()->addFontFaceRule(fontFaceRule); styleSelector->invalidateMatchedPropertiesCache(); - } else if (childItem->isKeyframesRule() && styleSelector) { + } else if (childRule->isKeyframesRule() && styleSelector) { // Add this keyframe rule to our set. // FIXME(BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. if (scope) continue; - styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem)); + styleSelector->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(childRule)); } - } // for rules - } // if rules + } // for rules + } // if rules } else if (rule->isFontFaceRule() && styleSelector) { // Add this font face to our set. // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. if (scope) continue; - const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(rule); + const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); styleSelector->fontSelector()->addFontFaceRule(fontFaceRule); styleSelector->invalidateMatchedPropertiesCache(); - } else if (rule->isKeyframesRule()) { + } else if (rule->isKeyframesRule() && styleSelector) { // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. if (scope) continue; - styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(rule)); + styleSelector->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); } else if (rule->isRegionRule() && styleSelector) { // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment. if (scope) continue; - addRegionRule(static_cast<WebKitCSSRegionRule*>(rule)); + addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); } } if (m_autoShrinkToFitEnabled) shrinkToFit(); } -void RuleSet::addStyleRule(StyleRule* rule, bool canUseFastCheckSelector, bool isInRegionRule) +void RuleSet::addStyleRule(StyleRule* rule, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule) { for (CSSSelector* s = rule->selectorList().first(); s; s = CSSSelectorList::next(s)) - addRule(rule, s, canUseFastCheckSelector, isInRegionRule); + addRule(rule, s, hasDocumentSecurityOrigin, canUseFastCheckSelector, isInRegionRule); } static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map) @@ -2528,44 +2581,18 @@ void RuleSet::shrinkToFit() // ------------------------------------------------------------------------------------- // this is mostly boring stuff on how to apply a certain rule to the renderstyle... -static Length convertToLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, bool toFloat, double multiplier = 1) +Length StyleResolver::convertToIntLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier) { - // This function is tolerant of a null style value. The only place style is used is in - // length measurements, like 'ems' and 'px'. And in those cases style is only used - // when the units are EMS or EXS. So we will just fail in those cases. - Length l; - if (!primitiveValue) { - l = Length(Undefined); - } else { - if (!style && primitiveValue->isFontRelativeLength()) { - l = Length(Undefined); - } else if (primitiveValue->isLength()) { - if (toFloat) - l = Length(primitiveValue->computeLength<double>(style, rootStyle, multiplier), Fixed); - else - l = primitiveValue->computeLength<Length>(style, rootStyle, multiplier); - } else if (primitiveValue->isPercentage()) - l = Length(primitiveValue->getDoubleValue(), Percent); - else if (primitiveValue->isNumber()) - l = Length(primitiveValue->getDoubleValue() * 100.0, Percent); - else - l = Length(Undefined); - } - return l; + return primitiveValue ? primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | FractionConversion | ViewportPercentageConversion>(style, rootStyle, multiplier) : Length(Undefined); } -Length CSSStyleSelector::convertToIntLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier) +Length StyleResolver::convertToFloatLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier) { - return convertToLength(primitiveValue, style, rootStyle, false, multiplier); -} - -Length CSSStyleSelector::convertToFloatLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier) -{ - return convertToLength(primitiveValue, style, rootStyle, true, multiplier); + return primitiveValue ? primitiveValue->convertToLength<FixedFloatConversion | PercentConversion | FractionConversion | ViewportPercentageConversion>(style, rootStyle, multiplier) : Length(Undefined); } template <bool applyFirst> -void CSSStyleSelector::applyProperties(const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, bool filterRegionProperties) +void StyleResolver::applyProperties(const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, bool filterRegionProperties) { ASSERT(!filterRegionProperties || m_regionForStyling); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willProcessRule(document(), rule); @@ -2582,9 +2609,9 @@ void CSSStyleSelector::applyProperties(const StylePropertySet* properties, Style ASSERT(!current.value()->isInheritedValue()); continue; } - int property = current.id(); + CSSPropertyID property = current.id(); - if (filterRegionProperties && !CSSStyleSelector::isValidRegionStyleProperty(property)) + if (filterRegionProperties && !StyleResolver::isValidRegionStyleProperty(property)) continue; if (applyFirst) { @@ -2609,7 +2636,7 @@ void CSSStyleSelector::applyProperties(const StylePropertySet* properties, Style } template <bool applyFirst> -void CSSStyleSelector::applyMatchedProperties(const MatchResult& matchResult, bool isImportant, int startIndex, int endIndex, bool inheritedOnly) +void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, bool isImportant, int startIndex, int endIndex, bool inheritedOnly) { if (startIndex == -1) return; @@ -2634,13 +2661,13 @@ void CSSStyleSelector::applyMatchedProperties(const MatchResult& matchResult, bo } } -unsigned CSSStyleSelector::computeMatchedPropertiesHash(const MatchedProperties* properties, unsigned size) +unsigned StyleResolver::computeMatchedPropertiesHash(const MatchedProperties* properties, unsigned size) { return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size); } -bool operator==(const CSSStyleSelector::MatchRanges& a, const CSSStyleSelector::MatchRanges& b) +bool operator==(const StyleResolver::MatchRanges& a, const StyleResolver::MatchRanges& b) { return a.firstUARule == b.firstUARule && a.lastUARule == b.lastUARule @@ -2650,22 +2677,22 @@ bool operator==(const CSSStyleSelector::MatchRanges& a, const CSSStyleSelector:: && a.lastUserRule == b.lastUserRule; } -bool operator!=(const CSSStyleSelector::MatchRanges& a, const CSSStyleSelector::MatchRanges& b) +bool operator!=(const StyleResolver::MatchRanges& a, const StyleResolver::MatchRanges& b) { return !(a == b); } -bool operator==(const CSSStyleSelector::MatchedProperties& a, const CSSStyleSelector::MatchedProperties& b) +bool operator==(const StyleResolver::MatchedProperties& a, const StyleResolver::MatchedProperties& b) { return a.properties == b.properties && a.linkMatchType == b.linkMatchType; } -bool operator!=(const CSSStyleSelector::MatchedProperties& a, const CSSStyleSelector::MatchedProperties& b) +bool operator!=(const StyleResolver::MatchedProperties& a, const StyleResolver::MatchedProperties& b) { return !(a == b); } -const CSSStyleSelector::MatchedPropertiesCacheItem* CSSStyleSelector::findFromMatchedPropertiesCache(unsigned hash, const MatchResult& matchResult) +const StyleResolver::MatchedPropertiesCacheItem* StyleResolver::findFromMatchedPropertiesCache(unsigned hash, const MatchResult& matchResult) { ASSERT(hash); @@ -2686,7 +2713,7 @@ const CSSStyleSelector::MatchedPropertiesCacheItem* CSSStyleSelector::findFromMa return &cacheItem; } -void CSSStyleSelector::addToMatchedPropertiesCache(const RenderStyle* style, const RenderStyle* parentStyle, unsigned hash, const MatchResult& matchResult) +void StyleResolver::addToMatchedPropertiesCache(const RenderStyle* style, const RenderStyle* parentStyle, unsigned hash, const MatchResult& matchResult) { static unsigned matchedDeclarationCacheAdditionsBetweenSweeps = 100; if (++m_matchedPropertiesCacheAdditionsSinceLastSweep >= matchedDeclarationCacheAdditionsBetweenSweeps) { @@ -2705,7 +2732,7 @@ void CSSStyleSelector::addToMatchedPropertiesCache(const RenderStyle* style, con m_matchedPropertiesCache.add(hash, cacheItem); } -void CSSStyleSelector::invalidateMatchedPropertiesCache() +void StyleResolver::invalidateMatchedPropertiesCache() { m_matchedPropertiesCache.clear(); } @@ -2727,7 +2754,7 @@ static bool isCacheableInMatchedPropertiesCache(const Element* element, const Re return true; } -void CSSStyleSelector::applyMatchedProperties(const MatchResult& matchResult) +void StyleResolver::applyMatchedProperties(const MatchResult& matchResult) { unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0; bool applyInheritedOnly = false; @@ -2801,17 +2828,17 @@ void CSSStyleSelector::applyMatchedProperties(const MatchResult& matchResult) addToMatchedPropertiesCache(m_style.get(), m_parentStyle, cacheHash, matchResult); } -static inline bool comparePageRules(const CSSPageRule* r1, const CSSPageRule* r2) +static inline bool comparePageRules(const StyleRulePage* r1, const StyleRulePage* r2) { return r1->selector()->specificity() < r2->selector()->specificity(); } -void CSSStyleSelector::matchPageRules(MatchResult& result, RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName) +void StyleResolver::matchPageRules(MatchResult& result, RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName) { if (!rules) return; - Vector<CSSPageRule*> matchedPageRules; + Vector<StyleRulePage*> matchedPageRules; matchPageRulesForList(matchedPageRules, rules->pageRules(), isLeftPage, isFirstPage, pageName); if (matchedPageRules.isEmpty()) return; @@ -2822,11 +2849,11 @@ void CSSStyleSelector::matchPageRules(MatchResult& result, RuleSet* rules, bool addMatchedProperties(result, matchedPageRules[i]->properties()); } -void CSSStyleSelector::matchPageRulesForList(Vector<CSSPageRule*>& matchedRules, const Vector<CSSPageRule*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName) +void StyleResolver::matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName) { unsigned size = rules.size(); for (unsigned i = 0; i < size; ++i) { - CSSPageRule* rule = rules[i]; + StyleRulePage* rule = rules[i]; const AtomicString& selectorLocalName = rule->selector()->tag().localName(); if (selectorLocalName != starAtom && selectorLocalName != pageName) continue; @@ -2846,7 +2873,7 @@ void CSSStyleSelector::matchPageRulesForList(Vector<CSSPageRule*>& matchedRules, } } -bool CSSStyleSelector::isLeftPage(int pageIndex) const +bool StyleResolver::isLeftPage(int pageIndex) const { bool isFirstPageLeft = false; if (!m_rootElementStyle->isLeftToRightDirection()) @@ -2855,19 +2882,77 @@ bool CSSStyleSelector::isLeftPage(int pageIndex) const return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2; } -bool CSSStyleSelector::isFirstPage(int pageIndex) const +bool StyleResolver::isFirstPage(int pageIndex) const { // FIXME: In case of forced left/right page, page at index 1 (not 0) can be the first page. return (!pageIndex); } -String CSSStyleSelector::pageName(int /* pageIndex */) const +String StyleResolver::pageName(int /* pageIndex */) const { // FIXME: Implement page index to page name mapping. return ""; } -void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue* value, RenderStyle* style) +template <class ListType> +static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >& wrapperMap, ListType* listType) +{ + if (!listType) + return; + unsigned size = listType->length(); + for (unsigned i = 0; i < size; ++i) { + CSSRule* cssRule = listType->item(i); + if (cssRule->isImportRule()) + collectCSSOMWrappers(wrapperMap, static_cast<CSSImportRule*>(cssRule)->styleSheet()); + else if (cssRule->isMediaRule()) + collectCSSOMWrappers(wrapperMap, static_cast<CSSMediaRule*>(cssRule)); + else if (cssRule->isRegionRule()) + collectCSSOMWrappers(wrapperMap, static_cast<WebKitCSSRegionRule*>(cssRule)); + else if (cssRule->isStyleRule()) { + CSSStyleRule* cssStyleRule = static_cast<CSSStyleRule*>(cssRule); + wrapperMap.add(cssStyleRule->styleRule(), cssStyleRule); + } + } +} + +static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >& wrapperMap, HashSet<RefPtr<CSSStyleSheet> >& sheetWrapperSet, StyleSheetInternal* styleSheet) +{ + if (!styleSheet) + return; + RefPtr<CSSStyleSheet> styleSheetWrapper = CSSStyleSheet::create(styleSheet); + sheetWrapperSet.add(styleSheetWrapper); + collectCSSOMWrappers(wrapperMap, styleSheetWrapper.get()); +} + +static void collectCSSOMWrappers(HashMap<StyleRule*, RefPtr<CSSStyleRule> >& wrapperMap, Document* document) +{ + const Vector<RefPtr<StyleSheet> >& styleSheets = document->styleSheets()->vector(); + for (unsigned i = 0; i < styleSheets.size(); ++i) { + StyleSheet* styleSheet = styleSheets[i].get(); + if (!styleSheet->isCSSStyleSheet()) + continue; + collectCSSOMWrappers(wrapperMap, static_cast<CSSStyleSheet*>(styleSheet)); + } + collectCSSOMWrappers(wrapperMap, document->pageUserSheet()); +} + +CSSStyleRule* StyleResolver::ensureFullCSSOMWrapperForInspector(StyleRule* rule) +{ + if (m_styleRuleToCSSOMWrapperMap.isEmpty()) { + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, simpleDefaultStyleSheet); + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, defaultStyleSheet); + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, quirksStyleSheet); + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, svgStyleSheet); + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, mathMLStyleSheet); + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, mediaControlsStyleSheet); + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, m_styleSheetCSSOMWrapperSet, fullscreenStyleSheet); + + collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, document()); + } + return m_styleRuleToCSSOMWrapperMap.get(rule).get(); +} + +void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, RenderStyle* style) { initElement(0); initForStyleResolve(0, style); @@ -2875,41 +2960,41 @@ void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue* value, RenderStyle applyPropertyToCurrentStyle(id, value); } -void CSSStyleSelector::applyPropertyToCurrentStyle(int id, CSSValue* value) +void StyleResolver::applyPropertyToCurrentStyle(CSSPropertyID id, CSSValue* value) { if (value) applyProperty(id, value); } -inline bool isValidVisitedLinkProperty(int id) -{ - switch(static_cast<CSSPropertyID>(id)) { - case CSSPropertyBackgroundColor: - case CSSPropertyBorderLeftColor: - case CSSPropertyBorderRightColor: - case CSSPropertyBorderTopColor: - case CSSPropertyBorderBottomColor: - case CSSPropertyColor: - case CSSPropertyOutlineColor: - case CSSPropertyWebkitColumnRuleColor: - case CSSPropertyWebkitTextEmphasisColor: - case CSSPropertyWebkitTextFillColor: - case CSSPropertyWebkitTextStrokeColor: - // Also allow shorthands so that inherit/initial still work. - case CSSPropertyBackground: - case CSSPropertyBorderLeft: - case CSSPropertyBorderRight: - case CSSPropertyBorderTop: - case CSSPropertyBorderBottom: - case CSSPropertyOutline: - case CSSPropertyWebkitColumnRule: +inline bool isValidVisitedLinkProperty(CSSPropertyID id) +{ + switch (id) { + case CSSPropertyBackgroundColor: + case CSSPropertyBorderLeftColor: + case CSSPropertyBorderRightColor: + case CSSPropertyBorderTopColor: + case CSSPropertyBorderBottomColor: + case CSSPropertyColor: + case CSSPropertyOutlineColor: + case CSSPropertyWebkitColumnRuleColor: + case CSSPropertyWebkitTextEmphasisColor: + case CSSPropertyWebkitTextFillColor: + case CSSPropertyWebkitTextStrokeColor: + // Also allow shorthands so that inherit/initial still work. + case CSSPropertyBackground: + case CSSPropertyBorderLeft: + case CSSPropertyBorderRight: + case CSSPropertyBorderTop: + case CSSPropertyBorderBottom: + case CSSPropertyOutline: + case CSSPropertyWebkitColumnRule: #if ENABLE(SVG) - case CSSPropertyFill: - case CSSPropertyStroke: + case CSSPropertyFill: + case CSSPropertyStroke: #endif - return true; - default: - break; + return true; + default: + break; } return false; @@ -2917,9 +3002,9 @@ inline bool isValidVisitedLinkProperty(int id) // http://dev.w3.org/csswg/css3-regions/#the-at-region-style-rule // FIXME: add incremental support for other region styling properties. -inline bool CSSStyleSelector::isValidRegionStyleProperty(int id) +inline bool StyleResolver::isValidRegionStyleProperty(CSSPropertyID id) { - switch (static_cast<CSSPropertyID>(id)) { + switch (id) { case CSSPropertyBackgroundColor: return true; default: @@ -2937,35 +3022,27 @@ inline bool CSSStyleSelector::isValidRegionStyleProperty(int id) // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale, // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size). -bool CSSStyleSelector::useSVGZoomRules() +bool StyleResolver::useSVGZoomRules() { return m_element && m_element->isSVGElement(); } #if ENABLE(CSS_GRID_LAYOUT) -static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, CSSStyleSelector* selector, Length& length) +static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, StyleResolver* selector, Length& length) { - if (primitiveValue->getIdent() == CSSValueAuto) { - length = Length(); - return true; - } - - if (primitiveValue->isLength()) { - length = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()); - length.setQuirk(primitiveValue->isQuirkValue()); - return true; - } + Length workingLength = primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | ViewportPercentageConversion | AutoConversion>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()); + if (workingLength.isUndefined()) + return false; - if (primitiveValue->isPercentage()) { - length = Length(primitiveValue->getDoubleValue(), Percent); - return true; - } + if (primitiveValue->isLength()) + workingLength.setQuirk(primitiveValue->isQuirkValue()); - return false; + length = workingLength; + return true; } -static bool createGridTrackList(CSSValue* value, Vector<Length>& lengths, CSSStyleSelector* selector) +static bool createGridTrackList(CSSValue* value, Vector<Length>& lengths, StyleResolver* selector) { // Handle 'none'. if (value->isPrimitiveValue()) { @@ -3012,7 +3089,7 @@ static bool createGridPosition(CSSValue* value, Length& position) } #endif -void CSSStyleSelector::applyProperty(int id, CSSValue *value) +void StyleResolver::applyProperty(CSSPropertyID id, CSSValue *value) { bool isInherit = m_parentNode && value->isInheritedValue(); bool isInitial = value->isInitialValue() || (!m_parentNode && value->isInheritedValue()); @@ -3024,13 +3101,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; } - CSSPropertyID property = static_cast<CSSPropertyID>(id); - - if (isInherit && m_parentStyle && !m_parentStyle->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(property)) + if (isInherit && m_parentStyle && !m_parentStyle->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id)) m_parentStyle->setHasExplicitlyInheritedProperties(); // check lookup table for implementations and use when available - const PropertyHandler& handler = m_applyProperty.propertyHandler(property); + const PropertyHandler& handler = m_styleBuilder.propertyHandler(id); if (handler.isValid()) { if (isInherit) handler.applyInheritValue(this); @@ -3046,94 +3121,100 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) float zoomFactor = m_style->effectiveZoom(); // What follows is a list that maps the CSS properties into their corresponding front-end - // RenderStyle values. Shorthands (e.g. border, background) occur in this list as well and + // RenderStyle values. Shorthands (e.g. border, background) occur in this list as well and // are only hit when mapping "inherit" or "initial" into front-end values. - switch (property) { -// lists + switch (id) { + // lists case CSSPropertyContent: // list of string, uri, counter, attr, i - { - // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This - // note is a reminder that eventually "inherit" needs to be supported. - - if (isInitial) { - m_style->clearContent(); - return; - } - - if (!value->isValueList()) - return; + { + // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This + // note is a reminder that eventually "inherit" needs to be supported. - bool didSet = false; - for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { - CSSValue* item = i.value(); - if (item->isImageGeneratorValue()) { - m_style->setContent(StyleGeneratedImage::create(static_cast<CSSImageGeneratorValue*>(item)), didSet); - didSet = true; + if (isInitial) { + m_style->clearContent(); + return; } - if (!item->isPrimitiveValue()) - continue; + if (!value->isValueList()) + return; - CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item); + bool didSet = false; + for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { + CSSValue* item = i.value(); + if (item->isImageGeneratorValue()) { + m_style->setContent(StyleGeneratedImage::create(static_cast<CSSImageGeneratorValue*>(item)), didSet); + didSet = true; +#if ENABLE(CSS_IMAGE_SET) + } else if (item->isImageSetValue()) { + m_style->setContent(setOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageSetValue*>(item)), didSet); + didSet = true; +#endif + } - if (contentValue->isString()) { - m_style->setContent(contentValue->getStringValue().impl(), didSet); - didSet = true; - } else if (contentValue->isAttr()) { - // FIXME: Can a namespace be specified for an attr(foo)? - if (m_style->styleType() == NOPSEUDO) - m_style->setUnique(); - else - m_parentStyle->setUnique(); - QualifiedName attr(nullAtom, contentValue->getStringValue().impl(), nullAtom); - const AtomicString& value = m_element->getAttribute(attr); - m_style->setContent(value.isNull() ? emptyAtom : value.impl(), didSet); - didSet = true; - // register the fact that the attribute value affects the style - m_features.attrsInRules.add(attr.localName().impl()); - } else if (contentValue->isURI()) { - if (!contentValue->isImageValue()) - break; - m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(contentValue)), didSet); - didSet = true; - } else if (contentValue->isCounter()) { - Counter* counterValue = contentValue->getCounterValue(); - EListStyleType listStyleType = NoneListStyle; - int listStyleIdent = counterValue->listStyleIdent(); - if (listStyleIdent != CSSValueNone) - listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc); - OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), listStyleType, counterValue->separator())); - m_style->setContent(counter.release(), didSet); - didSet = true; - } else { - switch (contentValue->getIdent()) { - case CSSValueOpenQuote: - m_style->setContent(OPEN_QUOTE, didSet); + if (item->isImageValue()) { + m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(item)), didSet); didSet = true; - break; - case CSSValueCloseQuote: - m_style->setContent(CLOSE_QUOTE, didSet); + continue; + } + + if (!item->isPrimitiveValue()) + continue; + + CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item); + + if (contentValue->isString()) { + m_style->setContent(contentValue->getStringValue().impl(), didSet); didSet = true; - break; - case CSSValueNoOpenQuote: - m_style->setContent(NO_OPEN_QUOTE, didSet); + } else if (contentValue->isAttr()) { + // FIXME: Can a namespace be specified for an attr(foo)? + if (m_style->styleType() == NOPSEUDO) + m_style->setUnique(); + else + m_parentStyle->setUnique(); + QualifiedName attr(nullAtom, contentValue->getStringValue().impl(), nullAtom); + const AtomicString& value = m_element->getAttribute(attr); + m_style->setContent(value.isNull() ? emptyAtom : value.impl(), didSet); didSet = true; - break; - case CSSValueNoCloseQuote: - m_style->setContent(NO_CLOSE_QUOTE, didSet); + // register the fact that the attribute value affects the style + m_features.attrsInRules.add(attr.localName().impl()); + } else if (contentValue->isCounter()) { + Counter* counterValue = contentValue->getCounterValue(); + EListStyleType listStyleType = NoneListStyle; + int listStyleIdent = counterValue->listStyleIdent(); + if (listStyleIdent != CSSValueNone) + listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc); + OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), listStyleType, counterValue->separator())); + m_style->setContent(counter.release(), didSet); didSet = true; - break; - default: - // normal and none do not have any effect. - {} + } else { + switch (contentValue->getIdent()) { + case CSSValueOpenQuote: + m_style->setContent(OPEN_QUOTE, didSet); + didSet = true; + break; + case CSSValueCloseQuote: + m_style->setContent(CLOSE_QUOTE, didSet); + didSet = true; + break; + case CSSValueNoOpenQuote: + m_style->setContent(NO_OPEN_QUOTE, didSet); + didSet = true; + break; + case CSSValueNoCloseQuote: + m_style->setContent(NO_CLOSE_QUOTE, didSet); + didSet = true; + break; + default: + // normal and none do not have any effect. + { } + } } } + if (!didSet) + m_style->clearContent(); + return; } - if (!didSet) - m_style->clearContent(); - return; - } case CSSPropertyQuotes: if (isInherit) { if (m_parentStyle) @@ -3174,7 +3255,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) fontDescription.setIsSpecifiedFont(parentFontDescription.isSpecifiedFont()); setFontDescription(fontDescription); return; - } else if (isInitial) { + } + + if (isInitial) { FontDescription initialDesc = FontDescription(); FontDescription fontDescription = m_style->fontDescription(); // We need to adjust the size to account for the generic family change from monospace @@ -3209,33 +3292,33 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) face = contentValue->getStringValue(); else if (settings) { switch (contentValue->getIdent()) { - case CSSValueWebkitBody: - face = settings->standardFontFamily(); - break; - case CSSValueSerif: - face = serifFamily; - fontDescription.setGenericFamily(FontDescription::SerifFamily); - break; - case CSSValueSansSerif: - face = sansSerifFamily; - fontDescription.setGenericFamily(FontDescription::SansSerifFamily); - break; - case CSSValueCursive: - face = cursiveFamily; - fontDescription.setGenericFamily(FontDescription::CursiveFamily); - break; - case CSSValueFantasy: - face = fantasyFamily; - fontDescription.setGenericFamily(FontDescription::FantasyFamily); - break; - case CSSValueMonospace: - face = monospaceFamily; - fontDescription.setGenericFamily(FontDescription::MonospaceFamily); - break; - case CSSValueWebkitPictograph: - face = pictographFamily; - fontDescription.setGenericFamily(FontDescription::PictographFamily); - break; + case CSSValueWebkitBody: + face = settings->standardFontFamily(); + break; + case CSSValueSerif: + face = serifFamily; + fontDescription.setGenericFamily(FontDescription::SerifFamily); + break; + case CSSValueSansSerif: + face = sansSerifFamily; + fontDescription.setGenericFamily(FontDescription::SansSerifFamily); + break; + case CSSValueCursive: + face = cursiveFamily; + fontDescription.setGenericFamily(FontDescription::CursiveFamily); + break; + case CSSValueFantasy: + face = fantasyFamily; + fontDescription.setGenericFamily(FontDescription::FantasyFamily); + break; + case CSSValueMonospace: + face = monospaceFamily; + fontDescription.setGenericFamily(FontDescription::MonospaceFamily); + break; + case CSSValueWebkitPictograph: + face = pictographFamily; + fontDescription.setGenericFamily(FontDescription::PictographFamily); + break; } } @@ -3270,8 +3353,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) if (isInitial) { m_style->clearBackgroundLayers(); m_style->setBackgroundColor(Color()); - } - else if (isInherit) { + } else if (isInherit) { m_style->inheritBackgroundLayers(*m_parentStyle->backgroundLayers()); m_style->setBackgroundColor(m_parentStyle->backgroundColor()); } @@ -3314,7 +3396,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) FontDescription fontDescription; RenderTheme::defaultTheme()->systemFont(primitiveValue->getIdent(), fontDescription); - // Double-check and see if the theme did anything. If not, don't bother updating the font. + // Double-check and see if the theme did anything. If not, don't bother updating the font. if (fontDescription.isAbsoluteSize()) { // Make sure the rendering mode and printer font settings are updated. Settings* settings = m_checker.document()->settings(); @@ -3329,9 +3411,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) setFontDescription(fontDescription); } } else if (value->isFontValue()) { - FontValue *font = static_cast<FontValue*>(value); - if (!font->style || !font->variant || !font->weight || - !font->size || !font->lineHeight || !font->family) + FontValue* font = static_cast<FontValue*>(value); + if (!font->style || !font->variant || !font->weight + || !font->size || !font->lineHeight || !font->family) return; applyProperty(CSSPropertyFontStyle, font->style.get()); applyProperty(CSSPropertyFontVariant, font->variant.get()); @@ -3377,7 +3459,10 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) Color color; if (item->color) color = colorFromPrimitiveValue(item->color.get()); - OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(x, y, blur, spread, shadowStyle, id == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent)); + else if (m_style) + color = m_style->color(); + + OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(IntPoint(x, y), blur, spread, shadowStyle, id == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent)); if (id == CSSPropertyTextShadow) m_style->setTextShadow(shadowData.release(), i.index()); // add to the list if this is not the first entry else @@ -3398,26 +3483,18 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) CSSReflectValue* reflectValue = static_cast<CSSReflectValue*>(value); RefPtr<StyleReflection> reflection = StyleReflection::create(); reflection->setDirection(reflectValue->direction()); - if (reflectValue->offset()) { - if (reflectValue->offset()->isPercentage()) - reflection->setOffset(Length(reflectValue->offset()->getDoubleValue(), Percent)); - else - reflection->setOffset(reflectValue->offset()->computeLength<Length>(style(), m_rootElementStyle, zoomFactor)); - } + if (reflectValue->offset()) + reflection->setOffset(reflectValue->offset()->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(style(), m_rootElementStyle, zoomFactor)); NinePieceImage mask; mask.setMaskDefaults(); - mapNinePieceImage(property, reflectValue->mask(), mask); + mapNinePieceImage(id, reflectValue->mask(), mask); reflection->setMask(mask); m_style->setBoxReflect(reflection.release()); return; } case CSSPropertyOpacity: - HANDLE_INHERIT_AND_INITIAL(opacity, Opacity) - if (!primitiveValue || !primitiveValue->isNumber()) - return; // Error case. - // Clamp opacity to the range 0-1 - m_style->setOpacity(clampTo<float>(primitiveValue->getDoubleValue(), 0, 1)); + HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(opacity, Opacity) return; case CSSPropertySrc: // Only used in @font-face rules. return; @@ -3428,8 +3505,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) m_style->setColumnRuleColor(m_parentStyle->columnRuleColor().isValid() ? m_parentStyle->columnRuleColor() : m_parentStyle->color()); m_style->setColumnRuleStyle(m_parentStyle->columnRuleStyle()); m_style->setColumnRuleWidth(m_parentStyle->columnRuleWidth()); - } - else if (isInitial) + } else if (isInitial) m_style->resetColumnRule(); return; case CSSPropertyWebkitMarquee: @@ -3457,15 +3533,15 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; if (int ident = primitiveValue->getIdent()) { switch (ident) { - case CSSValueSlow: - m_style->setMarqueeSpeed(500); // 500 msec. - break; - case CSSValueNormal: - m_style->setMarqueeSpeed(85); // 85msec. The WinIE default. - break; - case CSSValueFast: - m_style->setMarqueeSpeed(10); // 10msec. Super fast. - break; + case CSSValueSlow: + m_style->setMarqueeSpeed(500); // 500 msec. + break; + case CSSValueNormal: + m_style->setMarqueeSpeed(85); // 85msec. The WinIE default. + break; + case CSSValueFast: + m_style->setMarqueeSpeed(10); // 10msec. Super fast. + break; } } else if (primitiveValue->isTime()) m_style->setMarqueeSpeed(primitiveValue->computeTime<int, CSSPrimitiveValue::Milliseconds>()); @@ -3479,41 +3555,30 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; if (primitiveValue->getIdent()) { switch (primitiveValue->getIdent()) { - case CSSValueSmall: - m_style->setMarqueeIncrement(Length(1, Fixed)); // 1px. - break; - case CSSValueNormal: - m_style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default. - break; - case CSSValueLarge: - m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px. - break; + case CSSValueSmall: + m_style->setMarqueeIncrement(Length(1, Fixed)); // 1px. + break; + case CSSValueNormal: + m_style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default. + break; + case CSSValueLarge: + m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px. + break; } } else { - Length marqueeLength = convertToIntLength(primitiveValue, style(), m_rootElementStyle, 1); + Length marqueeLength = convertToIntLength(primitiveValue, style(), m_rootElementStyle); if (!marqueeLength.isUndefined()) m_style->setMarqueeIncrement(marqueeLength); } return; } - case CSSPropertyTextOverflow: { - // This property is supported by WinIE, and so we leave off the "-webkit-" in order to - // work with WinIE-specific pages that use the property. - HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textOverflow, TextOverflow) - return; - } - case CSSPropertyWebkitLineClamp: { - HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp) - if (!primitiveValue) - return; - if (primitiveValue->isNumber()) - m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_NUMBER), LineClampLineCount)); - else if (primitiveValue->isPercentage()) - m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE), LineClampPercentage)); + case CSSPropertyWebkitLineClamp: + HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(lineClamp, LineClamp) return; - } case CSSPropertyWebkitLocale: { HANDLE_INHERIT_AND_INITIAL(locale, Locale); + if (!primitiveValue) + return; if (primitiveValue->getIdent() == CSSValueAuto) m_style->setLocale(nullAtom); else @@ -3541,11 +3606,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; } - DashboardRegion *region = primitiveValue->getDashboardRegionValue(); + DashboardRegion* region = primitiveValue->getDashboardRegionValue(); if (!region) return; - DashboardRegion *first = region; + DashboardRegion* first = region; while (region) { Length top = convertToIntLength(region->top(), style(), m_rootElementStyle); Length right = convertToIntLength(region->right(), style(), m_rootElementStyle); @@ -3577,20 +3642,20 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth) float width = 0; switch (primitiveValue->getIdent()) { - case CSSValueThin: - case CSSValueMedium: - case CSSValueThick: { - double result = 1.0 / 48; - if (primitiveValue->getIdent() == CSSValueMedium) - result *= 3; - else if (primitiveValue->getIdent() == CSSValueThick) - result *= 5; - width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(style(), m_rootElementStyle, zoomFactor); - break; - } - default: - width = primitiveValue->computeLength<float>(style(), m_rootElementStyle, zoomFactor); - break; + case CSSValueThin: + case CSSValueMedium: + case CSSValueThick: { + double result = 1.0 / 48; + if (primitiveValue->getIdent() == CSSValueMedium) + result *= 3; + else if (primitiveValue->getIdent() == CSSValueThick) + result *= 5; + width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(style(), m_rootElementStyle, zoomFactor); + break; + } + default: + width = primitiveValue->computeLength<float>(style(), m_rootElementStyle, zoomFactor); + break; } m_style->setTextStrokeWidth(width); return; @@ -3604,7 +3669,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) } case CSSPropertyWebkitPerspective: { HANDLE_INHERIT_AND_INITIAL(perspective, Perspective) - if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) { + + if (!primitiveValue) + return; + + if (primitiveValue->getIdent() == CSSValueNone) { m_style->setPerspective(0); return; } @@ -3636,13 +3705,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; case CSSPropertyPointerEvents: { -#if ENABLE(DASHBOARD_SUPPORT) - // <rdar://problem/6561077> Work around the Stocks widget's misuse of the - // pointer-events property by not applying it in Dashboard. - Settings* settings = m_checker.document()->settings(); - if (settings && settings->usesDashboardBackwardCompatibilityMode()) - return; -#endif HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(pointerEvents, PointerEvents) return; } @@ -3705,7 +3767,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) case CSSPropertyWebkitMaxLogicalWidth: case CSSPropertyWebkitMaxLogicalHeight: { - int newId = CSSProperty::resolveDirectionAwareProperty(id, m_style->direction(), m_style->writingMode()); + CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, m_style->direction(), m_style->writingMode()); ASSERT(newId != id); return applyProperty(newId, value); } @@ -3759,7 +3821,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) return; } - case CSSPropertyWebkitWrapShapeInside: + case CSSPropertyWebkitShapeInside: HANDLE_INHERIT_AND_INITIAL(wrapShapeInside, WrapShapeInside); if (!primitiveValue) return; @@ -3769,7 +3831,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) m_style->setWrapShapeInside(primitiveValue->getShapeValue()); return; - case CSSPropertyWebkitWrapShapeOutside: + case CSSPropertyWebkitShapeOutside: HANDLE_INHERIT_AND_INITIAL(wrapShapeOutside, WrapShapeOutside); if (!primitiveValue) return; @@ -3846,7 +3908,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) } #endif - // These properties are implemented in the CSSStyleApplyProperty lookup table. + // These properties are implemented in the StyleBuilder lookup table. case CSSPropertyBackgroundAttachment: case CSSPropertyBackgroundClip: case CSSPropertyBackgroundColor: @@ -3953,6 +4015,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) case CSSPropertyTextAlign: case CSSPropertyTextDecoration: case CSSPropertyTextIndent: + case CSSPropertyTextOverflow: case CSSPropertyTextRendering: case CSSPropertyTextTransform: case CSSPropertyTop: @@ -4000,10 +4063,12 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) case CSSPropertyWebkitColumns: case CSSPropertyWebkitColumnSpan: case CSSPropertyWebkitColumnWidth: + case CSSPropertyWebkitFlex: case CSSPropertyWebkitFlexAlign: case CSSPropertyWebkitFlexDirection: case CSSPropertyWebkitFlexFlow: case CSSPropertyWebkitFlexItemAlign: + case CSSPropertyWebkitFlexLinePack: case CSSPropertyWebkitFlexOrder: case CSSPropertyWebkitFlexPack: case CSSPropertyWebkitFlexWrap: @@ -4097,7 +4162,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) } } -void CSSStyleSelector::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setAttachment(FillLayer::initialFillAttachment(layer->type())); @@ -4109,21 +4174,21 @@ void CSSStyleSelector::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSVal CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); switch (primitiveValue->getIdent()) { - case CSSValueFixed: - layer->setAttachment(FixedBackgroundAttachment); - break; - case CSSValueScroll: - layer->setAttachment(ScrollBackgroundAttachment); - break; - case CSSValueLocal: - layer->setAttachment(LocalBackgroundAttachment); - break; - default: - return; + case CSSValueFixed: + layer->setAttachment(FixedBackgroundAttachment); + break; + case CSSValueScroll: + layer->setAttachment(ScrollBackgroundAttachment); + break; + case CSSValueLocal: + layer->setAttachment(LocalBackgroundAttachment); + break; + default: + return; } } -void CSSStyleSelector::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setClip(FillLayer::initialFillClip(layer->type())); @@ -4137,7 +4202,7 @@ void CSSStyleSelector::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* va layer->setClip(*primitiveValue); } -void CSSStyleSelector::mapFillComposite(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillComposite(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setComposite(FillLayer::initialFillComposite(layer->type())); @@ -4151,7 +4216,7 @@ void CSSStyleSelector::mapFillComposite(CSSPropertyID, FillLayer* layer, CSSValu layer->setComposite(*primitiveValue); } -void CSSStyleSelector::mapFillOrigin(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillOrigin(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setOrigin(FillLayer::initialFillOrigin(layer->type())); @@ -4165,7 +4230,7 @@ void CSSStyleSelector::mapFillOrigin(CSSPropertyID, FillLayer* layer, CSSValue* layer->setOrigin(*primitiveValue); } -PassRefPtr<StyleImage> CSSStyleSelector::styleImage(CSSPropertyID property, CSSValue* value) +PassRefPtr<StyleImage> StyleResolver::styleImage(CSSPropertyID property, CSSValue* value) { if (value->isImageValue()) return cachedOrPendingFromValue(property, static_cast<CSSImageValue*>(value)); @@ -4173,10 +4238,15 @@ PassRefPtr<StyleImage> CSSStyleSelector::styleImage(CSSPropertyID property, CSSV if (value->isImageGeneratorValue()) return generatedOrPendingFromValue(property, static_cast<CSSImageGeneratorValue*>(value)); +#if ENABLE(CSS_IMAGE_SET) + if (value->isImageSetValue()) + return setOrPendingFromValue(property, static_cast<CSSImageSetValue*>(value)); +#endif + return 0; } -PassRefPtr<StyleImage> CSSStyleSelector::cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value) +PassRefPtr<StyleImage> StyleResolver::cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value) { RefPtr<StyleImage> image = value->cachedOrPendingImage(); if (image && image->isPendingImage()) @@ -4184,7 +4254,7 @@ PassRefPtr<StyleImage> CSSStyleSelector::cachedOrPendingFromValue(CSSPropertyID return image.release(); } -PassRefPtr<StyleImage> CSSStyleSelector::generatedOrPendingFromValue(CSSPropertyID property, CSSImageGeneratorValue* value) +PassRefPtr<StyleImage> StyleResolver::generatedOrPendingFromValue(CSSPropertyID property, CSSImageGeneratorValue* value) { if (value->isPending()) { m_pendingImageProperties.add(property); @@ -4193,7 +4263,17 @@ PassRefPtr<StyleImage> CSSStyleSelector::generatedOrPendingFromValue(CSSProperty return StyleGeneratedImage::create(value); } -void CSSStyleSelector::mapFillImage(CSSPropertyID property, FillLayer* layer, CSSValue* value) +#if ENABLE(CSS_IMAGE_SET) +PassRefPtr<StyleImage> StyleResolver::setOrPendingFromValue(CSSPropertyID property, CSSImageSetValue* value) +{ + RefPtr<StyleImage> image = value->cachedOrPendingImageSet(document()); + if (image && image->isPendingImage()) + m_pendingImageProperties.add(property); + return image.release(); +} +#endif + +void StyleResolver::mapFillImage(CSSPropertyID property, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setImage(FillLayer::initialFillImage(layer->type())); @@ -4203,7 +4283,7 @@ void CSSStyleSelector::mapFillImage(CSSPropertyID property, FillLayer* layer, CS layer->setImage(styleImage(property, value)); } -void CSSStyleSelector::mapFillRepeatX(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillRepeatX(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setRepeatX(FillLayer::initialFillRepeatX(layer->type())); @@ -4217,7 +4297,7 @@ void CSSStyleSelector::mapFillRepeatX(CSSPropertyID, FillLayer* layer, CSSValue* layer->setRepeatX(*primitiveValue); } -void CSSStyleSelector::mapFillRepeatY(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillRepeatY(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setRepeatY(FillLayer::initialFillRepeatY(layer->type())); @@ -4231,7 +4311,7 @@ void CSSStyleSelector::mapFillRepeatY(CSSPropertyID, FillLayer* layer, CSSValue* layer->setRepeatY(*primitiveValue); } -void CSSStyleSelector::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (!value->isPrimitiveValue()) { layer->setSizeType(SizeNone); @@ -4253,31 +4333,22 @@ void CSSStyleSelector::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* va return; } - Pair* pair = primitiveValue->getPairValue(); - - CSSPrimitiveValue* first = pair ? static_cast<CSSPrimitiveValue*>(pair->first()) : primitiveValue; - CSSPrimitiveValue* second = pair ? static_cast<CSSPrimitiveValue*>(pair->second()) : 0; - - Length firstLength, secondLength; - float zoomFactor = m_style->effectiveZoom(); - if (first->getIdent() == CSSValueAuto) - firstLength = Length(); - else if (first->isLength()) - firstLength = first->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); - else if (first->isPercentage()) - firstLength = Length(first->getDoubleValue(), Percent); - else - return; + Length firstLength; + Length secondLength; - if (!second || second->getIdent() == CSSValueAuto) + if (Pair* pair = primitiveValue->getPairValue()) { + CSSPrimitiveValue* first = static_cast<CSSPrimitiveValue*>(pair->first()); + CSSPrimitiveValue* second = static_cast<CSSPrimitiveValue*>(pair->second()); + firstLength = first->convertToLength<AnyConversion>(style(), m_rootElementStyle, zoomFactor); + secondLength = second->convertToLength<AnyConversion>(style(), m_rootElementStyle, zoomFactor); + } else { + firstLength = primitiveValue->convertToLength<AnyConversion>(style(), m_rootElementStyle, zoomFactor); secondLength = Length(); - else if (second->isLength()) - secondLength = second->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); - else if (second->isPercentage()) - secondLength = Length(second->getDoubleValue(), Percent); - else + } + + if (firstLength.isUndefined() || secondLength.isUndefined()) return; b.setWidth(firstLength); @@ -4285,7 +4356,7 @@ void CSSStyleSelector::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* va layer->setSizeLength(b); } -void CSSStyleSelector::mapFillXPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillXPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setXPosition(FillLayer::initialFillXPosition(layer->type())); @@ -4298,17 +4369,21 @@ void CSSStyleSelector::mapFillXPosition(CSSPropertyID, FillLayer* layer, CSSValu float zoomFactor = m_style->effectiveZoom(); CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - Length l; + Length length; if (primitiveValue->isLength()) - l = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); + length = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); else if (primitiveValue->isPercentage()) - l = Length(primitiveValue->getDoubleValue(), Percent); + length = Length(primitiveValue->getDoubleValue(), Percent); + else if (primitiveValue->isCalculatedPercentageWithLength()) + length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), m_rootElementStyle, zoomFactor)); + else if (primitiveValue->isViewportPercentageLength()) + length = primitiveValue->viewportPercentageLength(); else return; - layer->setXPosition(l); + layer->setXPosition(length); } -void CSSStyleSelector::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) +void StyleResolver::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); @@ -4321,17 +4396,21 @@ void CSSStyleSelector::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValu float zoomFactor = m_style->effectiveZoom(); CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - Length l; + Length length; if (primitiveValue->isLength()) - l = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); + length = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); else if (primitiveValue->isPercentage()) - l = Length(primitiveValue->getDoubleValue(), Percent); + length = Length(primitiveValue->getDoubleValue(), Percent); + else if (primitiveValue->isCalculatedPercentageWithLength()) + length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), m_rootElementStyle, zoomFactor)); + else if (primitiveValue->isViewportPercentageLength()) + length = primitiveValue->viewportPercentageLength(); else return; - layer->setYPosition(l); + layer->setYPosition(length); } -void CSSStyleSelector::mapAnimationDelay(Animation* animation, CSSValue* value) +void StyleResolver::mapAnimationDelay(Animation* animation, CSSValue* value) { if (value->isInitialValue()) { animation->setDelay(Animation::initialAnimationDelay()); @@ -4345,7 +4424,7 @@ void CSSStyleSelector::mapAnimationDelay(Animation* animation, CSSValue* value) animation->setDelay(primitiveValue->computeTime<float, CSSPrimitiveValue::Seconds>()); } -void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value) +void StyleResolver::mapAnimationDirection(Animation* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setDirection(Animation::initialAnimationDirection()); @@ -4372,7 +4451,7 @@ void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value) } } -void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* value) +void StyleResolver::mapAnimationDuration(Animation* animation, CSSValue* value) { if (value->isInitialValue()) { animation->setDuration(Animation::initialAnimationDuration()); @@ -4386,7 +4465,7 @@ void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* valu animation->setDuration(primitiveValue->computeTime<float, CSSPrimitiveValue::Seconds>()); } -void CSSStyleSelector::mapAnimationFillMode(Animation* layer, CSSValue* value) +void StyleResolver::mapAnimationFillMode(Animation* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setFillMode(Animation::initialAnimationFillMode()); @@ -4413,7 +4492,7 @@ void CSSStyleSelector::mapAnimationFillMode(Animation* layer, CSSValue* value) } } -void CSSStyleSelector::mapAnimationIterationCount(Animation* animation, CSSValue* value) +void StyleResolver::mapAnimationIterationCount(Animation* animation, CSSValue* value) { if (value->isInitialValue()) { animation->setIterationCount(Animation::initialAnimationIterationCount()); @@ -4427,10 +4506,10 @@ void CSSStyleSelector::mapAnimationIterationCount(Animation* animation, CSSValue if (primitiveValue->getIdent() == CSSValueInfinite) animation->setIterationCount(-1); else - animation->setIterationCount(int(primitiveValue->getFloatValue())); + animation->setIterationCount(primitiveValue->getFloatValue()); } -void CSSStyleSelector::mapAnimationName(Animation* layer, CSSValue* value) +void StyleResolver::mapAnimationName(Animation* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setName(Animation::initialAnimationName()); @@ -4447,7 +4526,7 @@ void CSSStyleSelector::mapAnimationName(Animation* layer, CSSValue* value) layer->setName(primitiveValue->getStringValue()); } -void CSSStyleSelector::mapAnimationPlayState(Animation* layer, CSSValue* value) +void StyleResolver::mapAnimationPlayState(Animation* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setPlayState(Animation::initialAnimationPlayState()); @@ -4462,10 +4541,11 @@ void CSSStyleSelector::mapAnimationPlayState(Animation* layer, CSSValue* value) layer->setPlayState(playState); } -void CSSStyleSelector::mapAnimationProperty(Animation* animation, CSSValue* value) +void StyleResolver::mapAnimationProperty(Animation* animation, CSSValue* value) { if (value->isInitialValue()) { - animation->setProperty(Animation::initialAnimationProperty()); + animation->setAnimationMode(Animation::AnimateAll); + animation->setProperty(CSSPropertyInvalid); return; } @@ -4473,15 +4553,19 @@ void CSSStyleSelector::mapAnimationProperty(Animation* animation, CSSValue* valu return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->getIdent() == CSSValueAll) - animation->setProperty(cAnimateAll); - else if (primitiveValue->getIdent() == CSSValueNone) - animation->setProperty(cAnimateNone); - else + if (primitiveValue->getIdent() == CSSValueAll) { + animation->setAnimationMode(Animation::AnimateAll); + animation->setProperty(CSSPropertyInvalid); + } else if (primitiveValue->getIdent() == CSSValueNone) { + animation->setAnimationMode(Animation::AnimateNone); + animation->setProperty(CSSPropertyInvalid); + } else { + animation->setAnimationMode(Animation::AnimateSingleProperty); animation->setProperty(static_cast<CSSPropertyID>(primitiveValue->getIdent())); + } } -void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue* value) +void StyleResolver::mapAnimationTimingFunction(Animation* animation, CSSValue* value) { if (value->isInitialValue()) { animation->setTimingFunction(Animation::initialAnimationTimingFunction()); @@ -4491,45 +4575,42 @@ void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue if (value->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); switch (primitiveValue->getIdent()) { - case CSSValueLinear: - animation->setTimingFunction(LinearTimingFunction::create()); - break; - case CSSValueEase: - animation->setTimingFunction(CubicBezierTimingFunction::create()); - break; - case CSSValueEaseIn: - animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0)); - break; - case CSSValueEaseOut: - animation->setTimingFunction(CubicBezierTimingFunction::create(0.0, 0.0, 0.58, 1.0)); - break; - case CSSValueEaseInOut: - animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 0.58, 1.0)); - break; - case CSSValueStepStart: - animation->setTimingFunction(StepsTimingFunction::create(1, true)); - break; - case CSSValueStepEnd: - animation->setTimingFunction(StepsTimingFunction::create(1, false)); - break; + case CSSValueLinear: + animation->setTimingFunction(LinearTimingFunction::create()); + break; + case CSSValueEase: + animation->setTimingFunction(CubicBezierTimingFunction::create()); + break; + case CSSValueEaseIn: + animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0)); + break; + case CSSValueEaseOut: + animation->setTimingFunction(CubicBezierTimingFunction::create(0.0, 0.0, 0.58, 1.0)); + break; + case CSSValueEaseInOut: + animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 0.58, 1.0)); + break; + case CSSValueStepStart: + animation->setTimingFunction(StepsTimingFunction::create(1, true)); + break; + case CSSValueStepEnd: + animation->setTimingFunction(StepsTimingFunction::create(1, false)); + break; } return; } - if (value->isTimingFunctionValue()) { - CSSTimingFunctionValue* timingFunction = static_cast<CSSTimingFunctionValue*>(value); - if (timingFunction->isCubicBezierTimingFunctionValue()) { - CSSCubicBezierTimingFunctionValue* cubicTimingFunction = static_cast<CSSCubicBezierTimingFunctionValue*>(value); - animation->setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2())); - } else if (timingFunction->isStepsTimingFunctionValue()) { - CSSStepsTimingFunctionValue* stepsTimingFunction = static_cast<CSSStepsTimingFunctionValue*>(value); - animation->setTimingFunction(StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart())); - } else - animation->setTimingFunction(LinearTimingFunction::create()); - } + if (value->isCubicBezierTimingFunctionValue()) { + CSSCubicBezierTimingFunctionValue* cubicTimingFunction = static_cast<CSSCubicBezierTimingFunctionValue*>(value); + animation->setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2())); + } else if (value->isStepsTimingFunctionValue()) { + CSSStepsTimingFunctionValue* stepsTimingFunction = static_cast<CSSStepsTimingFunctionValue*>(value); + animation->setTimingFunction(StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart())); + } else if (value->isLinearTimingFunctionValue()) + animation->setTimingFunction(LinearTimingFunction::create()); } -void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value, NinePieceImage& image) +void StyleResolver::mapNinePieceImage(CSSPropertyID property, CSSValue* value, NinePieceImage& image) { // If we're not a value list, then we are "none" and don't need to alter the empty image at all. if (!value || !value->isValueList()) @@ -4550,7 +4631,11 @@ void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value for (unsigned i = 0 ; i < borderImage->length() ; ++i) { CSSValue* current = borderImage->item(i); - if (current->isImageValue() || current->isImageGeneratorValue()) + if (current->isImageValue() || current->isImageGeneratorValue() +#if ENABLE(CSS_IMAGE_SET) + || current->isImageSetValue() +#endif + ) image.setImage(styleImage(imageProperty, current)); else if (current->isBorderImageSliceValue()) mapNinePieceImageSlice(current, image); @@ -4588,7 +4673,7 @@ void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value } } -void CSSStyleSelector::mapNinePieceImageSlice(CSSValue* value, NinePieceImage& image) +void StyleResolver::mapNinePieceImageSlice(CSSValue* value, NinePieceImage& image) { if (!value || !value->isBorderImageSliceValue()) return; @@ -4621,7 +4706,7 @@ void CSSStyleSelector::mapNinePieceImageSlice(CSSValue* value, NinePieceImage& i image.setFill(borderImageSlice->m_fill); } -LengthBox CSSStyleSelector::mapNinePieceImageQuad(CSSValue* value) +LengthBox StyleResolver::mapNinePieceImageQuad(CSSValue* value) { if (!value || !value->isPrimitiveValue()) return LengthBox(); @@ -4666,7 +4751,7 @@ LengthBox CSSStyleSelector::mapNinePieceImageQuad(CSSValue* value) return box; } -void CSSStyleSelector::mapNinePieceImageRepeat(CSSValue* value, NinePieceImage& image) +void StyleResolver::mapNinePieceImageRepeat(CSSValue* value, NinePieceImage& image) { if (!value || !value->isPrimitiveValue()) return; @@ -4714,7 +4799,7 @@ void CSSStyleSelector::mapNinePieceImageRepeat(CSSValue* value, NinePieceImage& image.setVerticalRule(verticalRule); } -void CSSStyleSelector::checkForTextSizeAdjust() +void StyleResolver::checkForTextSizeAdjust() { if (m_style->textSizeAdjust()) return; @@ -4724,7 +4809,7 @@ void CSSStyleSelector::checkForTextSizeAdjust() m_style->setFontDescription(newFontDescription); } -void CSSStyleSelector::checkForZoomChange(RenderStyle* style, RenderStyle* parentStyle) +void StyleResolver::checkForZoomChange(RenderStyle* style, RenderStyle* parentStyle) { if (style->effectiveZoom() == parentStyle->effectiveZoom()) return; @@ -4735,7 +4820,7 @@ void CSSStyleSelector::checkForZoomChange(RenderStyle* style, RenderStyle* paren style->setFontDescription(newFontDescription); } -void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle) +void StyleResolver::checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle) { const FontDescription& childFont = style->fontDescription(); @@ -4747,12 +4832,12 @@ void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderSty return; // For now, lump all families but monospace together. - if (childFont.genericFamily() != FontDescription::MonospaceFamily && - parentFont.genericFamily() != FontDescription::MonospaceFamily) + if (childFont.genericFamily() != FontDescription::MonospaceFamily + && parentFont.genericFamily() != FontDescription::MonospaceFamily) return; // We know the parent is monospace or the child is monospace, and that font - // size was unspecified. We want to scale our font size as appropriate. + // size was unspecified. We want to scale our font size as appropriate. // If the font uses a keyword size, then we refetch from the table rather than // multiplying by our scale factor. float size; @@ -4773,13 +4858,13 @@ void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderSty style->setFontDescription(newFontDescription); } -void CSSStyleSelector::setFontSize(FontDescription& fontDescription, float size) +void StyleResolver::setFontSize(FontDescription& fontDescription, float size) { fontDescription.setSpecifiedSize(size); fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.document(), m_style.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules())); } -float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, RenderStyle* style, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules) +float StyleResolver::getComputedSizeFromSpecifiedSize(Document* document, RenderStyle* style, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules) { float zoomFactor = 1.0f; if (!useSVGZoomRules) { @@ -4788,10 +4873,10 @@ float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, Ren zoomFactor *= frame->textZoomFactor(); } - return CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, zoomFactor, isAbsoluteSize, specifiedSize); + return StyleResolver::getComputedSizeFromSpecifiedSize(document, zoomFactor, isAbsoluteSize, specifiedSize); } -float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, float zoomFactor, bool isAbsoluteSize, float specifiedSize, ESmartMinimumForFontSize useSmartMinimumForFontSize) +float StyleResolver::getComputedSizeFromSpecifiedSize(Document* document, float zoomFactor, bool isAbsoluteSize, float specifiedSize, ESmartMinimumForFontSize useSmartMinimumForFontSize) { // Text with a 0px font size should not be visible and therefore needs to be // exempt from minimum font size rules. Acid3 relies on this for pixel-perfect @@ -4800,8 +4885,8 @@ float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, flo if (fabsf(specifiedSize) < std::numeric_limits<float>::epsilon()) return 0.0f; - // We support two types of minimum font size. The first is a hard override that applies to - // all fonts. This is "minSize." The second type of minimum font size is a "smart minimum" + // We support two types of minimum font size. The first is a hard override that applies to + // all fonts. This is "minSize." The second type of minimum font size is a "smart minimum" // that is applied only when the Web page can't know what size it really asked for, e.g., // when it uses logical sizes like "small" or expresses the font-size as a percentage of // the user's default font setting. @@ -4818,13 +4903,13 @@ float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, flo int minLogicalSize = settings->minimumLogicalFontSize(); float zoomedSize = specifiedSize * zoomFactor; - // Apply the hard minimum first. We only apply the hard minimum if after zooming we're still too small. + // Apply the hard minimum first. We only apply the hard minimum if after zooming we're still too small. if (zoomedSize < minSize) zoomedSize = minSize; - // Now apply the "smart minimum." This minimum is also only applied if we're still too small - // after zooming. The font size must either be relative to the user default or the original size - // must have been acceptable. In other words, we only apply the smart minimum whenever we're positive + // Now apply the "smart minimum." This minimum is also only applied if we're still too small + // after zooming. The font size must either be relative to the user default or the original size + // must have been acceptable. In other words, we only apply the smart minimum whenever we're positive // doing so won't disrupt the layout. if (useSmartMinimumForFontSize && zoomedSize < minLogicalSize && (specifiedSize >= minLogicalSize || !isAbsoluteSize)) zoomedSize = minLogicalSize; @@ -4838,7 +4923,7 @@ const int fontSizeTableMax = 16; const int fontSizeTableMin = 9; const int totalKeywords = 8; -// WinIE/Nav4 table for font sizes. Designed to match the legacy font mapping system of HTML. +// WinIE/Nav4 table for font sizes. Designed to match the legacy font mapping system of HTML. static const int quirksFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] = { { 9, 9, 9, 9, 11, 14, 18, 28 }, @@ -4848,7 +4933,7 @@ static const int quirksFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][to { 9, 9, 10, 13, 16, 20, 26, 40 }, // fixed font default (13) { 9, 9, 11, 14, 17, 21, 28, 42 }, { 9, 10, 12, 15, 17, 23, 30, 45 }, - { 9, 10, 13, 16, 18, 24, 32, 48 } // proportional font default (16) + { 9, 10, 13, 16, 18, 24, 32, 48 } // proportional font default (16) }; // HTML 1 2 3 4 5 6 7 // CSS xxs xs s m l xl xxl @@ -4865,7 +4950,7 @@ static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][to { 9, 10, 12, 13, 16, 20, 26, 39 }, // fixed font default (13) { 9, 10, 12, 14, 17, 21, 28, 42 }, { 9, 10, 13, 15, 18, 23, 30, 45 }, - { 9, 10, 13, 16, 18, 24, 32, 48 } // proportional font default (16) + { 9, 10, 13, 16, 18, 24, 32, 48 } // proportional font default (16) }; // HTML 1 2 3 4 5 6 7 // CSS xxs xs s m l xl xxl @@ -4876,7 +4961,7 @@ static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][to // factors for each keyword value. static const float fontSizeFactors[totalKeywords] = { 0.60f, 0.75f, 0.89f, 1.0f, 1.2f, 1.5f, 2.0f, 3.0f }; -float CSSStyleSelector::fontSizeForKeyword(Document* document, int keyword, bool shouldUseFixedDefaultSize) +float StyleResolver::fontSizeForKeyword(Document* document, int keyword, bool shouldUseFixedDefaultSize) { Settings* settings = document->settings(); if (!settings) @@ -4907,7 +4992,7 @@ static int findNearestLegacyFontSize(int pixelFontSize, const T* table, int mult return totalKeywords - 1; } -int CSSStyleSelector::legacyFontSize(Document* document, int pixelFontSize, bool shouldUseFixedDefaultSize) +int StyleResolver::legacyFontSize(Document* document, int pixelFontSize, bool shouldUseFixedDefaultSize) { Settings* settings = document->settings(); if (!settings) @@ -4960,7 +5045,7 @@ static Color colorForCSSValue(int cssValueId) return RenderTheme::defaultTheme()->systemColor(cssValueId); } -Color CSSStyleSelector::colorFromPrimitiveValue(CSSPrimitiveValue* value, bool forVisitedLink) const +Color StyleResolver::colorFromPrimitiveValue(CSSPrimitiveValue* value, bool forVisitedLink) const { if (value->isRGBColor()) return Color(value->getRGBA32Value()); @@ -4984,17 +5069,17 @@ Color CSSStyleSelector::colorFromPrimitiveValue(CSSPrimitiveValue* value, bool f } } -bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname) const +bool StyleResolver::hasSelectorForAttribute(const AtomicString &attrname) const { return m_features.attrsInRules.contains(attrname.impl()); } -void CSSStyleSelector::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result) +void StyleResolver::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result) { m_viewportDependentMediaQueryResults.append(adoptPtr(new MediaQueryResult(*expr, result))); } -bool CSSStyleSelector::affectedByViewportChange() const +bool StyleResolver::affectedByViewportChange() const { unsigned s = m_viewportDependentMediaQueryResults.size(); for (unsigned i = 0; i < s; i++) { @@ -5007,33 +5092,33 @@ bool CSSStyleSelector::affectedByViewportChange() const static TransformOperation::OperationType getTransformOperationType(WebKitCSSTransformValue::TransformOperationType type) { switch (type) { - case WebKitCSSTransformValue::ScaleTransformOperation: return TransformOperation::SCALE; - case WebKitCSSTransformValue::ScaleXTransformOperation: return TransformOperation::SCALE_X; - case WebKitCSSTransformValue::ScaleYTransformOperation: return TransformOperation::SCALE_Y; - case WebKitCSSTransformValue::ScaleZTransformOperation: return TransformOperation::SCALE_Z; - case WebKitCSSTransformValue::Scale3DTransformOperation: return TransformOperation::SCALE_3D; - case WebKitCSSTransformValue::TranslateTransformOperation: return TransformOperation::TRANSLATE; - case WebKitCSSTransformValue::TranslateXTransformOperation: return TransformOperation::TRANSLATE_X; - case WebKitCSSTransformValue::TranslateYTransformOperation: return TransformOperation::TRANSLATE_Y; - case WebKitCSSTransformValue::TranslateZTransformOperation: return TransformOperation::TRANSLATE_Z; - case WebKitCSSTransformValue::Translate3DTransformOperation: return TransformOperation::TRANSLATE_3D; - case WebKitCSSTransformValue::RotateTransformOperation: return TransformOperation::ROTATE; - case WebKitCSSTransformValue::RotateXTransformOperation: return TransformOperation::ROTATE_X; - case WebKitCSSTransformValue::RotateYTransformOperation: return TransformOperation::ROTATE_Y; - case WebKitCSSTransformValue::RotateZTransformOperation: return TransformOperation::ROTATE_Z; - case WebKitCSSTransformValue::Rotate3DTransformOperation: return TransformOperation::ROTATE_3D; - case WebKitCSSTransformValue::SkewTransformOperation: return TransformOperation::SKEW; - case WebKitCSSTransformValue::SkewXTransformOperation: return TransformOperation::SKEW_X; - case WebKitCSSTransformValue::SkewYTransformOperation: return TransformOperation::SKEW_Y; - case WebKitCSSTransformValue::MatrixTransformOperation: return TransformOperation::MATRIX; - case WebKitCSSTransformValue::Matrix3DTransformOperation: return TransformOperation::MATRIX_3D; - case WebKitCSSTransformValue::PerspectiveTransformOperation: return TransformOperation::PERSPECTIVE; - case WebKitCSSTransformValue::UnknownTransformOperation: return TransformOperation::NONE; + case WebKitCSSTransformValue::ScaleTransformOperation: return TransformOperation::SCALE; + case WebKitCSSTransformValue::ScaleXTransformOperation: return TransformOperation::SCALE_X; + case WebKitCSSTransformValue::ScaleYTransformOperation: return TransformOperation::SCALE_Y; + case WebKitCSSTransformValue::ScaleZTransformOperation: return TransformOperation::SCALE_Z; + case WebKitCSSTransformValue::Scale3DTransformOperation: return TransformOperation::SCALE_3D; + case WebKitCSSTransformValue::TranslateTransformOperation: return TransformOperation::TRANSLATE; + case WebKitCSSTransformValue::TranslateXTransformOperation: return TransformOperation::TRANSLATE_X; + case WebKitCSSTransformValue::TranslateYTransformOperation: return TransformOperation::TRANSLATE_Y; + case WebKitCSSTransformValue::TranslateZTransformOperation: return TransformOperation::TRANSLATE_Z; + case WebKitCSSTransformValue::Translate3DTransformOperation: return TransformOperation::TRANSLATE_3D; + case WebKitCSSTransformValue::RotateTransformOperation: return TransformOperation::ROTATE; + case WebKitCSSTransformValue::RotateXTransformOperation: return TransformOperation::ROTATE_X; + case WebKitCSSTransformValue::RotateYTransformOperation: return TransformOperation::ROTATE_Y; + case WebKitCSSTransformValue::RotateZTransformOperation: return TransformOperation::ROTATE_Z; + case WebKitCSSTransformValue::Rotate3DTransformOperation: return TransformOperation::ROTATE_3D; + case WebKitCSSTransformValue::SkewTransformOperation: return TransformOperation::SKEW; + case WebKitCSSTransformValue::SkewXTransformOperation: return TransformOperation::SKEW_X; + case WebKitCSSTransformValue::SkewYTransformOperation: return TransformOperation::SKEW_Y; + case WebKitCSSTransformValue::MatrixTransformOperation: return TransformOperation::MATRIX; + case WebKitCSSTransformValue::Matrix3DTransformOperation: return TransformOperation::MATRIX_3D; + case WebKitCSSTransformValue::PerspectiveTransformOperation: return TransformOperation::PERSPECTIVE; + case WebKitCSSTransformValue::UnknownTransformOperation: return TransformOperation::NONE; } return TransformOperation::NONE; } -bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle* style, RenderStyle* rootStyle, TransformOperations& outOperations) +bool StyleResolver::createTransformOperations(CSSValue* inValue, RenderStyle* style, RenderStyle* rootStyle, TransformOperations& outOperations) { if (!inValue || !inValue->isValueList()) { outOperations.clear(); @@ -5064,212 +5149,212 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle* CSSPrimitiveValue* firstValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(0)); switch (transformValue->operationType()) { - case WebKitCSSTransformValue::ScaleTransformOperation: - case WebKitCSSTransformValue::ScaleXTransformOperation: - case WebKitCSSTransformValue::ScaleYTransformOperation: { - double sx = 1.0; - double sy = 1.0; - if (transformValue->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation) - sy = firstValue->getDoubleValue(); - else { - sx = firstValue->getDoubleValue(); - if (transformValue->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) { - if (transformValue->length() > 1) { - CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); - sy = secondValue->getDoubleValue(); - } else - sy = sx; - } + case WebKitCSSTransformValue::ScaleTransformOperation: + case WebKitCSSTransformValue::ScaleXTransformOperation: + case WebKitCSSTransformValue::ScaleYTransformOperation: { + double sx = 1.0; + double sy = 1.0; + if (transformValue->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation) + sy = firstValue->getDoubleValue(); + else { + sx = firstValue->getDoubleValue(); + if (transformValue->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) { + if (transformValue->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); + sy = secondValue->getDoubleValue(); + } else + sy = sx; } - operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(transformValue->operationType()))); - break; } - case WebKitCSSTransformValue::ScaleZTransformOperation: - case WebKitCSSTransformValue::Scale3DTransformOperation: { - double sx = 1.0; - double sy = 1.0; - double sz = 1.0; - if (transformValue->operationType() == WebKitCSSTransformValue::ScaleZTransformOperation) - sz = firstValue->getDoubleValue(); - else if (transformValue->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation) - sy = firstValue->getDoubleValue(); - else { - sx = firstValue->getDoubleValue(); - if (transformValue->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) { - if (transformValue->length() > 2) { - CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2)); - sz = thirdValue->getDoubleValue(); - } - if (transformValue->length() > 1) { - CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); - sy = secondValue->getDoubleValue(); - } else - sy = sx; + operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::ScaleZTransformOperation: + case WebKitCSSTransformValue::Scale3DTransformOperation: { + double sx = 1.0; + double sy = 1.0; + double sz = 1.0; + if (transformValue->operationType() == WebKitCSSTransformValue::ScaleZTransformOperation) + sz = firstValue->getDoubleValue(); + else if (transformValue->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation) + sy = firstValue->getDoubleValue(); + else { + sx = firstValue->getDoubleValue(); + if (transformValue->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) { + if (transformValue->length() > 2) { + CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2)); + sz = thirdValue->getDoubleValue(); } + if (transformValue->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); + sy = secondValue->getDoubleValue(); + } else + sy = sx; } - operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(transformValue->operationType()))); - break; } - case WebKitCSSTransformValue::TranslateTransformOperation: - case WebKitCSSTransformValue::TranslateXTransformOperation: - case WebKitCSSTransformValue::TranslateYTransformOperation: { - Length tx = Length(0, Fixed); - Length ty = Length(0, Fixed); - if (transformValue->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation) - ty = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - else { - tx = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - if (transformValue->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) { - if (transformValue->length() > 1) { - CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); - ty = convertToFloatLength(secondValue, style, rootStyle, zoomFactor); - } + operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::TranslateTransformOperation: + case WebKitCSSTransformValue::TranslateXTransformOperation: + case WebKitCSSTransformValue::TranslateYTransformOperation: { + Length tx = Length(0, Fixed); + Length ty = Length(0, Fixed); + if (transformValue->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation) + ty = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); + else { + tx = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); + if (transformValue->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) { + if (transformValue->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); + ty = convertToFloatLength(secondValue, style, rootStyle, zoomFactor); } } + } - if (tx.isUndefined() || ty.isUndefined()) - return false; + if (tx.isUndefined() || ty.isUndefined()) + return false; - operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(transformValue->operationType()))); - break; - } - case WebKitCSSTransformValue::TranslateZTransformOperation: - case WebKitCSSTransformValue::Translate3DTransformOperation: { - Length tx = Length(0, Fixed); - Length ty = Length(0, Fixed); - Length tz = Length(0, Fixed); - if (transformValue->operationType() == WebKitCSSTransformValue::TranslateZTransformOperation) - tz = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - else if (transformValue->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation) - ty = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - else { - tx = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - if (transformValue->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) { - if (transformValue->length() > 2) { - CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2)); - tz = convertToFloatLength(thirdValue, style, rootStyle, zoomFactor); - } - if (transformValue->length() > 1) { - CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); - ty = convertToFloatLength(secondValue, style, rootStyle, zoomFactor); - } + operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::TranslateZTransformOperation: + case WebKitCSSTransformValue::Translate3DTransformOperation: { + Length tx = Length(0, Fixed); + Length ty = Length(0, Fixed); + Length tz = Length(0, Fixed); + if (transformValue->operationType() == WebKitCSSTransformValue::TranslateZTransformOperation) + tz = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); + else if (transformValue->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation) + ty = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); + else { + tx = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); + if (transformValue->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) { + if (transformValue->length() > 2) { + CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2)); + tz = convertToFloatLength(thirdValue, style, rootStyle, zoomFactor); + } + if (transformValue->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); + ty = convertToFloatLength(secondValue, style, rootStyle, zoomFactor); } } + } - if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined()) - return false; + if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined()) + return false; - operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType()))); - break; - } - case WebKitCSSTransformValue::RotateTransformOperation: { - double angle = firstValue->computeDegrees(); - operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType()))); - break; - } - case WebKitCSSTransformValue::RotateXTransformOperation: - case WebKitCSSTransformValue::RotateYTransformOperation: - case WebKitCSSTransformValue::RotateZTransformOperation: { - double x = 0; - double y = 0; - double z = 0; - double angle = firstValue->computeDegrees(); - - if (transformValue->operationType() == WebKitCSSTransformValue::RotateXTransformOperation) - x = 1; - else if (transformValue->operationType() == WebKitCSSTransformValue::RotateYTransformOperation) - y = 1; - else - z = 1; - operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); - break; - } - case WebKitCSSTransformValue::Rotate3DTransformOperation: { - if (transformValue->length() < 4) - break; - CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); - CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2)); - CSSPrimitiveValue* fourthValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(3)); - double x = firstValue->getDoubleValue(); - double y = secondValue->getDoubleValue(); - double z = thirdValue->getDoubleValue(); - double angle = fourthValue->computeDegrees(); - operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); + operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::RotateTransformOperation: { + double angle = firstValue->computeDegrees(); + operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::RotateXTransformOperation: + case WebKitCSSTransformValue::RotateYTransformOperation: + case WebKitCSSTransformValue::RotateZTransformOperation: { + double x = 0; + double y = 0; + double z = 0; + double angle = firstValue->computeDegrees(); + + if (transformValue->operationType() == WebKitCSSTransformValue::RotateXTransformOperation) + x = 1; + else if (transformValue->operationType() == WebKitCSSTransformValue::RotateYTransformOperation) + y = 1; + else + z = 1; + operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::Rotate3DTransformOperation: { + if (transformValue->length() < 4) break; - } - case WebKitCSSTransformValue::SkewTransformOperation: - case WebKitCSSTransformValue::SkewXTransformOperation: - case WebKitCSSTransformValue::SkewYTransformOperation: { - double angleX = 0; - double angleY = 0; - double angle = firstValue->computeDegrees(); - if (transformValue->operationType() == WebKitCSSTransformValue::SkewYTransformOperation) - angleY = angle; - else { - angleX = angle; - if (transformValue->operationType() == WebKitCSSTransformValue::SkewTransformOperation) { - if (transformValue->length() > 1) { - CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); - angleY = secondValue->computeDegrees(); - } + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); + CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2)); + CSSPrimitiveValue* fourthValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(3)); + double x = firstValue->getDoubleValue(); + double y = secondValue->getDoubleValue(); + double z = thirdValue->getDoubleValue(); + double angle = fourthValue->computeDegrees(); + operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::SkewTransformOperation: + case WebKitCSSTransformValue::SkewXTransformOperation: + case WebKitCSSTransformValue::SkewYTransformOperation: { + double angleX = 0; + double angleY = 0; + double angle = firstValue->computeDegrees(); + if (transformValue->operationType() == WebKitCSSTransformValue::SkewYTransformOperation) + angleY = angle; + else { + angleX = angle; + if (transformValue->operationType() == WebKitCSSTransformValue::SkewTransformOperation) { + if (transformValue->length() > 1) { + CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1)); + angleY = secondValue->computeDegrees(); } } - operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(transformValue->operationType()))); - break; } - case WebKitCSSTransformValue::MatrixTransformOperation: { - if (transformValue->length() < 6) - break; - double a = firstValue->getDoubleValue(); - double b = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(); - double c = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(); - double d = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(); - double e = zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(); - double f = zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(); - operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f)); + operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(transformValue->operationType()))); + break; + } + case WebKitCSSTransformValue::MatrixTransformOperation: { + if (transformValue->length() < 6) break; - } - case WebKitCSSTransformValue::Matrix3DTransformOperation: { - if (transformValue->length() < 16) - break; - TransformationMatrix matrix(static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(0))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(6))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(7))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(8))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(9))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(10))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(11))->getDoubleValue(), - zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(12))->getDoubleValue(), - zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(13))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(14))->getDoubleValue(), - static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(15))->getDoubleValue()); - operations.operations().append(Matrix3DTransformOperation::create(matrix)); + double a = firstValue->getDoubleValue(); + double b = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(); + double c = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(); + double d = static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(); + double e = zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(); + double f = zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(); + operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f)); + break; + } + case WebKitCSSTransformValue::Matrix3DTransformOperation: { + if (transformValue->length() < 16) break; + TransformationMatrix matrix(static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(0))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(1))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(2))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(3))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(4))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(5))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(6))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(7))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(8))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(9))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(10))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(11))->getDoubleValue(), + zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(12))->getDoubleValue(), + zoomFactor * static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(13))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(14))->getDoubleValue(), + static_cast<CSSPrimitiveValue*>(transformValue->itemWithoutBoundsCheck(15))->getDoubleValue()); + operations.operations().append(Matrix3DTransformOperation::create(matrix)); + break; + } + case WebKitCSSTransformValue::PerspectiveTransformOperation: { + Length p = Length(0, Fixed); + if (firstValue->isLength()) + p = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); + else { + // This is a quirk that should go away when 3d transforms are finalized. + double val = firstValue->getDoubleValue(); + p = val >= 0 ? Length(clampToPositiveInteger(val), Fixed) : Length(Undefined); } - case WebKitCSSTransformValue::PerspectiveTransformOperation: { - Length p = Length(0, Fixed); - if (firstValue->isLength()) - p = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - else { - // This is a quirk that should go away when 3d transforms are finalized. - double val = firstValue->getDoubleValue(); - p = val >= 0 ? Length(clampToPositiveInteger(val), Fixed) : Length(Undefined); - } - if (p.isUndefined()) - return false; + if (p.isUndefined()) + return false; - operations.operations().append(PerspectiveTransformOperation::create(p)); - break; - } - case WebKitCSSTransformValue::UnknownTransformOperation: - ASSERT_NOT_REACHED(); - break; + operations.operations().append(PerspectiveTransformOperation::create(p)); + break; + } + case WebKitCSSTransformValue::UnknownTransformOperation: + ASSERT_NOT_REACHED(); + break; } } @@ -5314,14 +5399,14 @@ static FilterOperation::OperationType filterOperationForType(WebKitCSSFilterValu } #if ENABLE(CSS_SHADERS) -StyleShader* CSSStyleSelector::styleShader(CSSValue* value) +StyleShader* StyleResolver::styleShader(CSSValue* value) { if (value->isWebKitCSSShaderValue()) return cachedOrPendingStyleShaderFromValue(static_cast<WebKitCSSShaderValue*>(value)); return 0; } -StyleShader* CSSStyleSelector::cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue* value) +StyleShader* StyleResolver::cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue* value) { StyleShader* shader = value->cachedOrPendingShader(); if (shader && shader->isPendingShader()) @@ -5329,7 +5414,7 @@ StyleShader* CSSStyleSelector::cachedOrPendingStyleShaderFromValue(WebKitCSSShad return shader; } -void CSSStyleSelector::loadPendingShaders() +void StyleResolver::loadPendingShaders() { if (!m_style->hasFilter() || !m_hasPendingShaders) return; @@ -5361,7 +5446,7 @@ static bool sortParametersByNameComparator(const RefPtr<CustomFilterParameter>& return codePointCompareLessThan(a->name(), b->name()); } -PassRefPtr<CustomFilterParameter> CSSStyleSelector::parseCustomFilterNumberParamter(const String& name, CSSValueList* values) +PassRefPtr<CustomFilterParameter> StyleResolver::parseCustomFilterNumberParamter(const String& name, CSSValueList* values) { RefPtr<CustomFilterNumberParameter> numberParameter = CustomFilterNumberParameter::create(name); for (unsigned i = 0; i < values->length(); ++i) { @@ -5376,7 +5461,7 @@ PassRefPtr<CustomFilterParameter> CSSStyleSelector::parseCustomFilterNumberParam return numberParameter.release(); } -bool CSSStyleSelector::parseCustomFilterParameterList(CSSValue* parametersValue, CustomFilterParameterList& parameterList) +bool StyleResolver::parseCustomFilterParameterList(CSSValue* parametersValue, CustomFilterParameterList& parameterList) { HashSet<String> knownParameterNames; CSSValueListIterator parameterIterator(parametersValue); @@ -5438,7 +5523,7 @@ bool CSSStyleSelector::parseCustomFilterParameterList(CSSValue* parametersValue, return true; } -PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation(WebKitCSSFilterValue* filterValue) +PassRefPtr<CustomFilterOperation> StyleResolver::createCustomFilterOperation(WebKitCSSFilterValue* filterValue) { ASSERT(filterValue->length()); @@ -5522,12 +5607,21 @@ PassRefPtr<CustomFilterOperation> CSSStyleSelector::createCustomFilterOperation( } #endif -bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* style, RenderStyle* rootStyle, FilterOperations& outOperations) +bool StyleResolver::createFilterOperations(CSSValue* inValue, RenderStyle* style, RenderStyle* rootStyle, FilterOperations& outOperations) { - if (!inValue || !inValue->isValueList()) { - outOperations.clear(); + ASSERT(outOperations.isEmpty()); + + if (!inValue) return false; + + if (inValue->isPrimitiveValue()) { + CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(inValue); + if (primitiveValue->getIdent() == CSSValueNone) + return true; } + + if (!inValue->isValueList()) + return false; float zoomFactor = style ? style->effectiveZoom() : 1; FilterOperations operations; @@ -5608,9 +5702,8 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st } case WebKitCSSFilterValue::BlurFilterOperation: { Length stdDeviation = Length(0, Fixed); - if (filterValue->length() >= 1) { + if (filterValue->length() >= 1) stdDeviation = convertToFloatLength(firstValue, style, rootStyle, zoomFactor); - } if (stdDeviation.isUndefined()) return false; @@ -5626,14 +5719,14 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st continue; ShadowValue* item = static_cast<ShadowValue*>(cssValue); - int x = item->x->computeLength<int>(style, rootStyle, zoomFactor); - int y = item->y->computeLength<int>(style, rootStyle, zoomFactor); + 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 color; if (item->color) color = colorFromPrimitiveValue(item->color.get()); - operations.operations().append(DropShadowFilterOperation::create(x, y, blur, color.isValid() ? color : Color::transparent, operationType)); + operations.operations().append(DropShadowFilterOperation::create(location, blur, color.isValid() ? color : Color::transparent, operationType)); break; } case WebKitCSSFilterValue::UnknownFilterOperation: @@ -5649,7 +5742,7 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st #endif -PassRefPtr<StyleImage> CSSStyleSelector::loadPendingImage(StylePendingImage* pendingImage) +PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendingImage) { CachedResourceLoader* cachedResourceLoader = m_element->document()->cachedResourceLoader(); @@ -5664,85 +5757,92 @@ PassRefPtr<StyleImage> CSSStyleSelector::loadPendingImage(StylePendingImage* pen return StyleGeneratedImage::create(imageGeneratorValue); } +#if ENABLE(CSS_IMAGE_SET) + if (pendingImage->cssImageSetValue()) { + CSSImageSetValue* imageSetValue = pendingImage->cssImageSetValue(); + return imageSetValue->cachedImageSet(cachedResourceLoader); + } +#endif + return 0; } -void CSSStyleSelector::loadPendingImages() +void StyleResolver::loadPendingImages() { if (m_pendingImageProperties.isEmpty()) return; - HashSet<int>::const_iterator end = m_pendingImageProperties.end(); - for (HashSet<int>::const_iterator it = m_pendingImageProperties.begin(); it != end; ++it) { - CSSPropertyID currentProperty = static_cast<CSSPropertyID>(*it); + HashSet<CSSPropertyID>::const_iterator end = m_pendingImageProperties.end(); + for (HashSet<CSSPropertyID>::const_iterator it = m_pendingImageProperties.begin(); it != end; ++it) { + CSSPropertyID currentProperty = *it; switch (currentProperty) { - case CSSPropertyBackgroundImage: { - for (FillLayer* backgroundLayer = m_style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) { - if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) - backgroundLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image()))); - } - break; + case CSSPropertyBackgroundImage: { + for (FillLayer* backgroundLayer = m_style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) { + if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) + backgroundLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image()))); } - case CSSPropertyContent: { - for (ContentData* contentData = const_cast<ContentData*>(m_style->contentData()); contentData; contentData = contentData->next()) { - if (contentData->isImage()) { - StyleImage* image = static_cast<ImageContentData*>(contentData)->image(); - if (image->isPendingImage()) { - RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(image)); - if (loadedImage) - static_cast<ImageContentData*>(contentData)->setImage(loadedImage.release()); - } + break; + } + case CSSPropertyContent: { + for (ContentData* contentData = const_cast<ContentData*>(m_style->contentData()); contentData; contentData = contentData->next()) { + if (contentData->isImage()) { + StyleImage* image = static_cast<ImageContentData*>(contentData)->image(); + if (image->isPendingImage()) { + RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(image)); + if (loadedImage) + static_cast<ImageContentData*>(contentData)->setImage(loadedImage.release()); } } - break; } - case CSSPropertyCursor: { - if (CursorList* cursorList = m_style->cursors()) { - for (size_t i = 0; i < cursorList->size(); ++i) { - CursorData& currentCursor = cursorList->at(i); - if (StyleImage* image = currentCursor.image()) { - if (image->isPendingImage()) - currentCursor.setImage(loadPendingImage(static_cast<StylePendingImage*>(image))); - } + break; + } + case CSSPropertyCursor: { + if (CursorList* cursorList = m_style->cursors()) { + for (size_t i = 0; i < cursorList->size(); ++i) { + CursorData& currentCursor = cursorList->at(i); + if (StyleImage* image = currentCursor.image()) { + if (image->isPendingImage()) + currentCursor.setImage(loadPendingImage(static_cast<StylePendingImage*>(image))); } } - break; - } - case CSSPropertyListStyleImage: { - if (m_style->listStyleImage() && m_style->listStyleImage()->isPendingImage()) - m_style->setListStyleImage(loadPendingImage(static_cast<StylePendingImage*>(m_style->listStyleImage()))); - break; } - case CSSPropertyBorderImageSource: { - if (m_style->borderImageSource() && m_style->borderImageSource()->isPendingImage()) - m_style->setBorderImageSource(loadPendingImage(static_cast<StylePendingImage*>(m_style->borderImageSource()))); - break; - } - case CSSPropertyWebkitBoxReflect: { - if (StyleReflection* reflection = m_style->boxReflect()) { - const NinePieceImage& maskImage = reflection->mask(); - if (maskImage.image() && maskImage.image()->isPendingImage()) { - RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(maskImage.image())); - reflection->setMask(NinePieceImage(loadedImage.release(), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule())); - } + break; + } + case CSSPropertyListStyleImage: { + if (m_style->listStyleImage() && m_style->listStyleImage()->isPendingImage()) + m_style->setListStyleImage(loadPendingImage(static_cast<StylePendingImage*>(m_style->listStyleImage()))); + break; + } + case CSSPropertyBorderImageSource: { + if (m_style->borderImageSource() && m_style->borderImageSource()->isPendingImage()) + m_style->setBorderImageSource(loadPendingImage(static_cast<StylePendingImage*>(m_style->borderImageSource()))); + break; + } + case CSSPropertyWebkitBoxReflect: { + if (StyleReflection* reflection = m_style->boxReflect()) { + const NinePieceImage& maskImage = reflection->mask(); + if (maskImage.image() && maskImage.image()->isPendingImage()) { + RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(maskImage.image())); + reflection->setMask(NinePieceImage(loadedImage.release(), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule())); } - break; - } - case CSSPropertyWebkitMaskBoxImageSource: { - if (m_style->maskBoxImageSource() && m_style->maskBoxImageSource()->isPendingImage()) - m_style->setMaskBoxImageSource(loadPendingImage(static_cast<StylePendingImage*>(m_style->maskBoxImageSource()))); - break; } - case CSSPropertyWebkitMaskImage: { - for (FillLayer* maskLayer = m_style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) { - if (maskLayer->image() && maskLayer->image()->isPendingImage()) - maskLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(maskLayer->image()))); - } - break; + break; + } + case CSSPropertyWebkitMaskBoxImageSource: { + if (m_style->maskBoxImageSource() && m_style->maskBoxImageSource()->isPendingImage()) + m_style->setMaskBoxImageSource(loadPendingImage(static_cast<StylePendingImage*>(m_style->maskBoxImageSource()))); + break; + } + case CSSPropertyWebkitMaskImage: { + for (FillLayer* maskLayer = m_style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) { + if (maskLayer->image() && maskLayer->image()->isPendingImage()) + maskLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(maskLayer->image()))); } - default: - ASSERT_NOT_REACHED(); + break; + } + default: + ASSERT_NOT_REACHED(); } } diff --git a/Source/WebCore/css/CSSStyleSelector.h b/Source/WebCore/css/StyleResolver.h index 099a9a73e..3916a7323 100644 --- a/Source/WebCore/css/CSSStyleSelector.h +++ b/Source/WebCore/css/StyleResolver.h @@ -19,10 +19,11 @@ * */ -#ifndef CSSStyleSelector_h -#define CSSStyleSelector_h +#ifndef StyleResolver_h +#define StyleResolver_h #include "CSSRule.h" +#include "CSSValueList.h" #include "LinkHash.h" #include "MediaQueryExp.h" #include "RenderStyle.h" @@ -41,13 +42,14 @@ class CSSFontSelector; class CSSPageRule; class CSSPrimitiveValue; class CSSProperty; +class CSSRuleList; class CSSFontFace; class CSSFontFaceRule; class CSSImageGeneratorValue; +class CSSImageSetValue; class CSSImageValue; -class CSSRuleList; class CSSSelector; -class CSSStyleApplyProperty; +class CSSStyleRule; class CSSStyleSheet; class CSSValue; class ContainerNode; @@ -66,18 +68,22 @@ class RenderRegion; class RuleData; class RuleSet; class Settings; +class StaticCSSRuleList; +class StyleBuilder; class StyleImage; +class StyleKeyframe; class StylePendingImage; class StylePropertySet; class StyleRule; +class StyleRuleKeyframes; +class StyleRulePage; +class StyleRuleRegion; class StyleShader; class StyleSheet; +class StyleSheetInternal; class StyleSheetList; class StyledElement; -class WebKitCSSKeyframeRule; -class WebKitCSSKeyframesRule; class WebKitCSSFilterValue; -class WebKitCSSRegionRule; class WebKitCSSShaderValue; #if ENABLE(CSS_SHADERS) @@ -97,14 +103,27 @@ public: bool m_result; }; +enum StyleSharingBehavior { + AllowStyleSharing, + DisallowStyleSharing, +}; + +// MatchOnlyUserAgentRules is used in media queries, where relative units +// are interpreted according to the document root element style, and styled only +// from the User Agent Stylesheet rules. + +enum RuleMatchingBehavior { + MatchAllRules, + MatchAllRulesExcludingSMIL, + MatchOnlyUserAgentRules, +}; + // This class selects a RenderStyle for a given element based on a collection of stylesheets. -class CSSStyleSelector { - WTF_MAKE_NONCOPYABLE(CSSStyleSelector); WTF_MAKE_FAST_ALLOCATED; +class StyleResolver { + WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED; public: - CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet, - CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets, const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets, - bool strictParsing, bool matchAuthorAndUserStyles); - ~CSSStyleSelector(); + StyleResolver(Document*, bool matchAuthorAndUserStyles); + ~StyleResolver(); // Using these during tree walk will allow style selector to optimize child and descendant selector lookups. void pushParentElement(Element*); @@ -112,7 +131,8 @@ public: void pushParentShadowRoot(const ShadowRoot*); void popParentShadowRoot(const ShadowRoot*); - PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, RenderRegion* regionForStyling = 0); + PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing, + RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0); void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&); @@ -127,9 +147,9 @@ public: RenderStyle* rootElementStyle() const { return m_rootElementStyle; } Element* element() const { return m_element; } Document* document() const { return m_checker.document(); } - FontDescription fontDescription() { return style()->fontDescription(); } - FontDescription parentFontDescription() {return parentStyle()->fontDescription(); } - void setFontDescription(FontDescription fontDescription) { m_fontDirty |= style()->setFontDescription(fontDescription); } + const FontDescription& fontDescription() { return style()->fontDescription(); } + const FontDescription& parentFontDescription() { return parentStyle()->fontDescription(); } + void setFontDescription(const FontDescription& fontDescription) { m_fontDirty |= style()->setFontDescription(fontDescription); } void setZoom(float f) { m_fontDirty |= style()->setZoom(f); } void setEffectiveZoom(float f) { m_fontDirty |= style()->setEffectiveZoom(f); } void setTextSizeAdjust(bool b) { m_fontDirty |= style()->setTextSizeAdjust(b); } @@ -138,7 +158,7 @@ public: void appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >&); // Find the ids or classes the selectors on a stylesheet are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope. - static bool determineStylesheetSelectorScopes(CSSStyleSheet*, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes); + static bool determineStylesheetSelectorScopes(StyleSheetInternal*, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes); private: void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO); @@ -150,7 +170,7 @@ private: StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const; bool canShareStyleWithElement(StyledElement*) const; - PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeValue&); + PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&); #if ENABLE(STYLE_SCOPED) void pushScope(const ContainerNode* scope, const ContainerNode* scopeParent); @@ -183,9 +203,9 @@ public: public: void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style. - void applyPropertyToStyle(int id, CSSValue*, RenderStyle*); + void applyPropertyToStyle(CSSPropertyID, CSSValue*, RenderStyle*); - void applyPropertyToCurrentStyle(int id, CSSValue*); + void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*); void updateFont(); @@ -212,7 +232,7 @@ public: void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); } void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); } - void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule>); + void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>); bool checkRegionStyle(Element* regionElement); @@ -224,6 +244,10 @@ public: static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations); void invalidateMatchedPropertiesCache(); + + // WARNING. This will construct CSSOM wrappers for all style rules and cache then in a map for significant memory cost. + // It is here to support inspector. Don't use for any regular engine functions. + CSSStyleRule* ensureFullCSSOMWrapperForInspector(StyleRule*); #if ENABLE(CSS_FILTERS) bool createFilterOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, FilterOperations& outOperations); @@ -237,20 +261,26 @@ public: #endif #endif // ENABLE(CSS_FILTERS) - struct RuleSelectorPair { - RuleSelectorPair(StyleRule* rule, CSSSelector* selector) : rule(rule), selector(selector) { } + struct RuleFeature { + RuleFeature(StyleRule* rule, CSSSelector* selector, bool hasDocumentSecurityOrigin) + : rule(rule) + , selector(selector) + , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) + { + } StyleRule* rule; CSSSelector* selector; + bool hasDocumentSecurityOrigin; }; struct Features { Features(); ~Features(); - void add(const CSSStyleSelector::Features&); + void add(const StyleResolver::Features&); void clear(); HashSet<AtomicStringImpl*> idsInRules; HashSet<AtomicStringImpl*> attrsInRules; - Vector<RuleSelectorPair> siblingRules; - Vector<RuleSelectorPair> uncommonAttributeRules; + Vector<RuleFeature> siblingRules; + Vector<RuleFeature> uncommonAttributeRules; bool usesFirstLineRules; bool usesBeforeAfterRules; bool usesLinkRules; @@ -307,7 +337,7 @@ private: static void addMatchedProperties(MatchResult&, StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, bool inRegionRule = false); void addElementStyleProperties(MatchResult&, StylePropertySet*, bool isCacheable = true); - void matchAllRules(MatchResult&); + void matchAllRules(MatchResult&, bool includeSMILProperties); void matchUARules(MatchResult&); void matchUARules(MatchResult&, RuleSet*); void matchAuthorRules(MatchResult&, bool includeEmptyRules); @@ -328,10 +358,10 @@ private: template <bool firstPass> void applyProperties(const StylePropertySet* properties, StyleRule*, bool isImportant, bool inheritedOnly, bool filterRegionProperties); - static bool isValidRegionStyleProperty(int id); + static bool isValidRegionStyleProperty(CSSPropertyID); void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName); - void matchPageRulesForList(Vector<CSSPageRule*>& matchedRules, const Vector<CSSPageRule*>&, bool isLeftPage, bool isFirstPage, const String& pageName); + void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName); bool isLeftPage(int pageIndex) const; bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); } bool isFirstPage(int pageIndex) const; @@ -349,7 +379,7 @@ private: FillLayer m_backgroundData; Color m_backgroundColor; - typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap; + typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap; KeyframesRuleMap m_keyframesRuleMap; public: @@ -358,6 +388,9 @@ public: PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*); PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*); PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue*); +#if ENABLE(CSS_IMAGE_SET) + PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*); +#endif bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; } bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; } @@ -368,6 +401,8 @@ public: private: static RenderStyle* s_styleNotYetAvailable; + void addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >*, RuleSet& userStyle); + void cacheBorderAndBackground(); void mapFillAttachment(CSSPropertyID, FillLayer*, CSSValue*); @@ -399,9 +434,10 @@ public: private: bool canShareStyleWithControl(StyledElement*) const; - void applyProperty(int id, CSSValue*); + void applyProperty(CSSPropertyID, CSSValue*); + #if ENABLE(SVG) - void applySVGProperty(int id, CSSValue*); + void applySVGProperty(CSSPropertyID, CSSValue*); #endif PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*); @@ -430,9 +466,9 @@ private: // merge sorting. Vector<const RuleData*, 32> m_matchedRules; - RefPtr<CSSRuleList> m_ruleList; + RefPtr<StaticCSSRuleList> m_ruleList; - HashSet<int> m_pendingImageProperties; // Hash of CSSPropertyIDs + HashSet<CSSPropertyID> m_pendingImageProperties; OwnPtr<MediaQueryEvaluator> m_medium; RefPtr<RenderStyle> m_rootDefaultStyle; @@ -459,14 +495,17 @@ private: bool m_applyPropertyToRegularStyle; bool m_applyPropertyToVisitedLinkStyle; - const CSSStyleApplyProperty& m_applyProperty; + const StyleBuilder& m_styleBuilder; + + HashMap<StyleRule*, RefPtr<CSSStyleRule> > m_styleRuleToCSSOMWrapperMap; + HashSet<RefPtr<CSSStyleSheet> > m_styleSheetCSSOMWrapperSet; #if ENABLE(CSS_SHADERS) bool m_hasPendingShaders; #endif #if ENABLE(STYLE_SCOPED) - static const ContainerNode* determineScope(const CSSStyleSheet*); + static const ContainerNode* determineScope(const StyleSheetInternal*); typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap; @@ -491,7 +530,7 @@ private: const ContainerNode* m_scopeStackParent; #endif - friend class CSSStyleApplyProperty; + friend class StyleBuilder; friend bool operator==(const MatchedProperties&, const MatchedProperties&); friend bool operator!=(const MatchedProperties&, const MatchedProperties&); friend bool operator==(const MatchRanges&, const MatchRanges&); @@ -500,4 +539,4 @@ private: } // namespace WebCore -#endif // CSSStyleSelector_h +#endif // StyleResolver_h diff --git a/Source/WebCore/css/StyleRule.cpp b/Source/WebCore/css/StyleRule.cpp index fc0f9d67d..83b2a6153 100644 --- a/Source/WebCore/css/StyleRule.cpp +++ b/Source/WebCore/css/StyleRule.cpp @@ -22,29 +22,240 @@ #include "config.h" #include "StyleRule.h" +#include "CSSCharsetRule.h" +#include "CSSFontFaceRule.h" +#include "CSSImportRule.h" +#include "CSSMediaRule.h" +#include "CSSPageRule.h" +#include "CSSStyleRule.h" +#include "WebKitCSSKeyframeRule.h" +#include "WebKitCSSKeyframesRule.h" +#include "WebKitCSSRegionRule.h" + namespace WebCore { -StyleRule::StyleRule(int line, CSSStyleRule* wrapper) - : m_sourceLine(line) - , m_cssomWrapper(wrapper) +PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const { + return createCSSOMWrapper(parentSheet, 0); } - + +PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const +{ + return createCSSOMWrapper(0, parentRule); +} + +void StyleRuleBase::destroy() +{ + switch (type()) { + case Style: + delete static_cast<StyleRule*>(this); + return; + case Page: + delete static_cast<StyleRulePage*>(this); + return; + case FontFace: + delete static_cast<StyleRuleFontFace*>(this); + return; + case Media: + delete static_cast<StyleRuleMedia*>(this); + return; + case Region: + delete static_cast<StyleRuleRegion*>(this); + return; + case Import: + delete static_cast<StyleRuleImport*>(this); + return; + case Keyframes: + delete static_cast<StyleRuleKeyframes*>(this); + return; + case Unknown: + case Charset: + case Keyframe: + ASSERT_NOT_REACHED(); + return; + } + ASSERT_NOT_REACHED(); +} + +PassRefPtr<StyleRuleBase> StyleRuleBase::copy() const +{ + switch (type()) { + case Style: + return static_cast<const StyleRule*>(this)->copy(); + case Page: + return static_cast<const StyleRulePage*>(this)->copy(); + case FontFace: + return static_cast<const StyleRuleFontFace*>(this)->copy(); + case Media: + return static_cast<const StyleRuleMedia*>(this)->copy(); + case Region: + return static_cast<const StyleRuleRegion*>(this)->copy(); + case Import: + // FIXME: Copy import rules. + ASSERT_NOT_REACHED(); + return 0; + case Keyframes: + return static_cast<const StyleRuleKeyframes*>(this)->copy(); + case Unknown: + case Charset: + case Keyframe: + ASSERT_NOT_REACHED(); + return 0; + } + ASSERT_NOT_REACHED(); + return 0; +} + +PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const +{ + RefPtr<CSSRule> rule; + StyleRuleBase* self = const_cast<StyleRuleBase*>(this); + switch (type()) { + case Style: + rule = CSSStyleRule::create(static_cast<StyleRule*>(self), parentSheet); + break; + case Page: + rule = CSSPageRule::create(static_cast<StyleRulePage*>(self), parentSheet); + break; + case FontFace: + rule = CSSFontFaceRule::create(static_cast<StyleRuleFontFace*>(self), parentSheet); + break; + case Media: + rule = CSSMediaRule::create(static_cast<StyleRuleMedia*>(self), parentSheet); + break; + case Region: + rule = WebKitCSSRegionRule::create(static_cast<StyleRuleRegion*>(self), parentSheet); + break; + case Import: + rule = CSSImportRule::create(static_cast<StyleRuleImport*>(self), parentSheet); + break; + case Keyframes: + rule = WebKitCSSKeyframesRule::create(static_cast<StyleRuleKeyframes*>(self), parentSheet); + break; + case Unknown: + case Charset: + case Keyframe: + ASSERT_NOT_REACHED(); + return 0; + } + if (parentRule) + rule->setParentRule(parentRule); + return rule.release(); +} + +unsigned StyleRule::averageSizeInBytes() +{ + return sizeof(StyleRule) + StylePropertySet::averageSizeInBytes(); +} + +StyleRule::StyleRule(int sourceLine) + : StyleRuleBase(Style, sourceLine) +{ +} + +StyleRule::StyleRule(const StyleRule& o) + : StyleRuleBase(o) + , m_properties(o.m_properties->copy()) + , m_selectorList(o.m_selectorList) +{ +} + StyleRule::~StyleRule() { } - -void StyleRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls, CSSStyleSheet* styleSheet) + +void StyleRule::setProperties(PassRefPtr<StylePropertySet> properties) +{ + m_properties = properties; +} + +StyleRulePage::StyleRulePage() + : StyleRuleBase(Page) { - if (!m_properties) - return; - m_properties->addSubresourceStyleURLs(urls, styleSheet); +} + +StyleRulePage::StyleRulePage(const StyleRulePage& o) + : StyleRuleBase(o) + , m_properties(o.m_properties->copy()) + , m_selectorList(o.m_selectorList) +{ +} + +StyleRulePage::~StyleRulePage() +{ +} + +void StyleRulePage::setProperties(PassRefPtr<StylePropertySet> properties) +{ + m_properties = properties; +} + +StyleRuleFontFace::StyleRuleFontFace() + : StyleRuleBase(FontFace, 0) +{ +} + +StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& o) + : StyleRuleBase(o) + , m_properties(o.m_properties->copy()) +{ +} + +StyleRuleFontFace::~StyleRuleFontFace() +{ +} + +void StyleRuleFontFace::setProperties(PassRefPtr<StylePropertySet> properties) +{ + m_properties = properties; +} + +StyleRuleBlock::StyleRuleBlock(Type type, Vector<RefPtr<StyleRuleBase> >& adoptRule) + : StyleRuleBase(type, 0) +{ + m_childRules.swap(adoptRule); +} + +StyleRuleBlock::StyleRuleBlock(const StyleRuleBlock& o) + : StyleRuleBase(o) + , m_childRules(o.m_childRules.size()) +{ + for (unsigned i = 0; i < m_childRules.size(); ++i) + m_childRules[i] = o.m_childRules[i]->copy(); +} + +void StyleRuleBlock::wrapperInsertRule(unsigned index, PassRefPtr<StyleRuleBase> rule) +{ + m_childRules.insert(index, rule); } -CSSStyleRule* StyleRule::ensureCSSStyleRule() const +void StyleRuleBlock::wrapperRemoveRule(unsigned index) +{ + m_childRules.remove(index); +} + +StyleRuleMedia::StyleRuleMedia(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules) + : StyleRuleBlock(Media, adoptRules) + , m_mediaQueries(media) +{ +} + +StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o) + : StyleRuleBlock(o) + , m_mediaQueries(o.m_mediaQueries->copy()) +{ +} + +StyleRuleRegion::StyleRuleRegion(Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<StyleRuleBase> >& adoptRules) + : StyleRuleBlock(Region, adoptRules) +{ + m_selectorList.adoptSelectorVector(*selectors); +} + +StyleRuleRegion::StyleRuleRegion(const StyleRuleRegion& o) + : StyleRuleBlock(o) + , m_selectorList(o.m_selectorList) { - ASSERT(m_cssomWrapper); - return m_cssomWrapper; } } // namespace WebCore diff --git a/Source/WebCore/css/StyleRule.h b/Source/WebCore/css/StyleRule.h index e230a94fd..f3989e0b2 100644 --- a/Source/WebCore/css/StyleRule.h +++ b/Source/WebCore/css/StyleRule.h @@ -23,39 +23,186 @@ #define StyleRule_h #include "CSSSelectorList.h" -#include "StylePropertySet.h" -#include <wtf/PassRefPtr.h> +#include "MediaList.h" #include <wtf/RefPtr.h> namespace WebCore { +class CSSRule; class CSSStyleRule; +class CSSStyleSheet; +class StylePropertySet; -class StyleRule { - WTF_MAKE_NONCOPYABLE(StyleRule); WTF_MAKE_FAST_ALLOCATED; +class StyleRuleBase : public WTF::RefCountedBase { public: - StyleRule(int sourceLine, CSSStyleRule*); - ~StyleRule(); - - const CSSSelectorList& selectorList() const { return m_selectorList; } - StylePropertySet* properties() const { return m_properties.get(); } + enum Type { + Unknown, // Not used. + Style, + Charset, // Not used. These are internally strings owned by the style sheet. + Import, + Media, + FontFace, + Page, + Keyframes, + Keyframe, // Not used. These are internally non-rule StyleKeyframe objects. + Region + }; + Type type() const { return static_cast<Type>(m_type); } - void addSubresourceStyleURLs(ListHashSet<KURL>& urls, CSSStyleSheet*); + bool isCharsetRule() const { return type() == Charset; } + bool isFontFaceRule() const { return type() == FontFace; } + bool isKeyframesRule() const { return type() == Keyframes; } + bool isMediaRule() const { return type() == Media; } + bool isPageRule() const { return type() == Page; } + bool isStyleRule() const { return type() == Style; } + bool isRegionRule() const { return type() == Region; } + bool isImportRule() const { return type() == Import; } + + PassRefPtr<StyleRuleBase> copy() const; int sourceLine() const { return m_sourceLine; } + + void deref() + { + if (derefBase()) + destroy(); + } + + // FIXME: There shouldn't be any need for the null parent version. + PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const; + PassRefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const; + +protected: + StyleRuleBase(Type type, signed sourceLine = 0) : m_type(type), m_sourceLine(sourceLine) { } + StyleRuleBase(const StyleRuleBase& o) : WTF::RefCountedBase(), m_type(o.m_type), m_sourceLine(o.m_sourceLine) { } + + ~StyleRuleBase() { } + +private: + void destroy(); - CSSStyleRule* ensureCSSStyleRule() const; + PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const; + + unsigned m_type : 4; + signed m_sourceLine : 28; +}; + +class StyleRule : public StyleRuleBase { +public: + static PassRefPtr<StyleRule> create(int sourceLine) { return adoptRef(new StyleRule(sourceLine)); } - void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); } - void adoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); } - void setProperties(PassRefPtr<StylePropertySet> properties) { m_properties = properties; } + ~StyleRule(); + + const CSSSelectorList& selectorList() const { return m_selectorList; } + StylePropertySet* properties() const { return m_properties.get(); } + void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); } + void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); } + void setProperties(PassRefPtr<StylePropertySet>); + + PassRefPtr<StyleRule> copy() const { return adoptRef(new StyleRule(*this)); } + + static unsigned averageSizeInBytes(); + private: + StyleRule(int sourceLine); + StyleRule(const StyleRule&); + RefPtr<StylePropertySet> m_properties; CSSSelectorList m_selectorList; - signed m_sourceLine; +}; + +class StyleRuleFontFace : public StyleRuleBase { +public: + static PassRefPtr<StyleRuleFontFace> create() { return adoptRef(new StyleRuleFontFace); } + + ~StyleRuleFontFace(); + + StylePropertySet* properties() const { return m_properties.get(); } + + void setProperties(PassRefPtr<StylePropertySet>); + + PassRefPtr<StyleRuleFontFace> copy() const { return adoptRef(new StyleRuleFontFace(*this)); } + +private: + StyleRuleFontFace(); + StyleRuleFontFace(const StyleRuleFontFace&); - CSSStyleRule* m_cssomWrapper; + RefPtr<StylePropertySet> m_properties; +}; + +class StyleRulePage : public StyleRuleBase { +public: + static PassRefPtr<StyleRulePage> create() { return adoptRef(new StyleRulePage); } + + ~StyleRulePage(); + + const CSSSelector* selector() const { return m_selectorList.first(); } + StylePropertySet* properties() const { return m_properties.get(); } + + void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); } + void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); } + void setProperties(PassRefPtr<StylePropertySet>); + + PassRefPtr<StyleRulePage> copy() const { return adoptRef(new StyleRulePage(*this)); } + +private: + StyleRulePage(); + StyleRulePage(const StyleRulePage&); + + RefPtr<StylePropertySet> m_properties; + CSSSelectorList m_selectorList; +}; + +class StyleRuleBlock : public StyleRuleBase { +public: + const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; } + + void wrapperInsertRule(unsigned, PassRefPtr<StyleRuleBase>); + void wrapperRemoveRule(unsigned); + +protected: + StyleRuleBlock(Type, Vector<RefPtr<StyleRuleBase> >& adoptRule); + StyleRuleBlock(const StyleRuleBlock&); + +private: + Vector<RefPtr<StyleRuleBase> > m_childRules; +}; + +class StyleRuleMedia : public StyleRuleBlock { +public: + static PassRefPtr<StyleRuleMedia> create(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules) + { + return adoptRef(new StyleRuleMedia(media, adoptRules)); + } + + MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); } + + PassRefPtr<StyleRuleMedia> copy() const { return adoptRef(new StyleRuleMedia(*this)); } + +private: + StyleRuleMedia(PassRefPtr<MediaQuerySet>, Vector<RefPtr<StyleRuleBase> >& adoptRules); + StyleRuleMedia(const StyleRuleMedia&); + + RefPtr<MediaQuerySet> m_mediaQueries; +}; + +class StyleRuleRegion : public StyleRuleBlock { +public: + static PassRefPtr<StyleRuleRegion> create(Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<StyleRuleBase> >& adoptRules) + { + return adoptRef(new StyleRuleRegion(selectors, adoptRules)); + } + + const CSSSelectorList& selectorList() const { return m_selectorList; } + + PassRefPtr<StyleRuleRegion> copy() const { return adoptRef(new StyleRuleRegion(*this)); } + +private: + StyleRuleRegion(Vector<OwnPtr<CSSParserSelector> >*, Vector<RefPtr<StyleRuleBase> >& adoptRules); + StyleRuleRegion(const StyleRuleRegion&); + + CSSSelectorList m_selectorList; }; } // namespace WebCore diff --git a/Source/WebCore/css/StyleSheet.cpp b/Source/WebCore/css/StyleSheet.cpp index 9813c3cf9..20ff5667a 100644 --- a/Source/WebCore/css/StyleSheet.cpp +++ b/Source/WebCore/css/StyleSheet.cpp @@ -20,72 +20,10 @@ #include "config.h" #include "StyleSheet.h" -#include "CSSImportRule.h" -#include "CSSStyleSheet.h" -#include "Document.h" -#include "MediaList.h" -#include "Node.h" - namespace WebCore { -StyleSheet::StyleSheet(Node* parentNode, const String& originalURL, const KURL& finalURL) - : m_disabled(false) - , m_ownerRule(0) - , m_ownerNode(parentNode) - , m_originalURL(originalURL) - , m_finalURL(finalURL) -{ -} - -StyleSheet::StyleSheet(CSSImportRule* parentRule, const String& originalURL, const KURL& finalURL) - : m_disabled(false) - , m_ownerRule(parentRule) - , m_ownerNode(0) - , m_originalURL(originalURL) - , m_finalURL(finalURL) -{ -} - StyleSheet::~StyleSheet() { - if (m_media) - m_media->setParentStyleSheet(0); -} - -StyleSheet* StyleSheet::parentStyleSheet() const -{ - ASSERT(isCSSStyleSheet()); - return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; -} - -void StyleSheet::setMedia(PassRefPtr<MediaList> media) -{ - ASSERT(isCSSStyleSheet()); - ASSERT(!media->parentStyleSheet() || media->parentStyleSheet() == this); - - if (m_media) - m_media->setParentStyleSheet(0); - - m_media = media; - m_media->setParentStyleSheet(static_cast<CSSStyleSheet*>(this)); -} - -KURL StyleSheet::baseURL() const -{ - if (!m_finalURL.isNull()) - return m_finalURL; - if (StyleSheet* parentSheet = parentStyleSheet()) - return parentSheet->baseURL(); - if (!m_ownerNode) - return KURL(); - return m_ownerNode->document()->baseURL(); -} - -void StyleSheet::setDisabled(bool disabled) -{ - m_disabled = disabled; - if (isCSSStyleSheet()) - static_cast<CSSStyleSheet*>(this)->styleSheetChanged(); } } diff --git a/Source/WebCore/css/StyleSheet.h b/Source/WebCore/css/StyleSheet.h index b28749a2c..7b413752d 100644 --- a/Source/WebCore/css/StyleSheet.h +++ b/Source/WebCore/css/StyleSheet.h @@ -1,6 +1,6 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2008, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,6 +21,7 @@ #ifndef StyleSheet_h #define StyleSheet_h +#include "CSSParserMode.h" #include "KURLHash.h" #include "PlatformString.h" #include <wtf/ListHashSet.h> @@ -31,57 +32,28 @@ namespace WebCore { class CSSImportRule; class MediaList; class Node; +class StyleRuleImport; +class StyleSheet; class StyleSheet : public RefCounted<StyleSheet> { public: virtual ~StyleSheet(); - bool disabled() const { return m_disabled; } - void setDisabled(bool); - - Node* ownerNode() const { return m_ownerNode; } - void clearOwnerNode() { m_ownerNode = 0; } - - CSSImportRule* ownerRule() const { return m_ownerRule; } - void clearOwnerRule() { m_ownerRule = 0; } - - StyleSheet* parentStyleSheet() const; - - // Note that href is the URL that started the redirect chain that led to - // this style sheet. This property probably isn't useful for much except - // the JavaScript binding (which needs to use this value for security). - const String& href() const { return m_originalURL; } - - void setFinalURL(const KURL& finalURL) { m_finalURL = finalURL; } - const KURL& finalURL() const { return m_finalURL; } - - const String& title() const { return m_strTitle; } - void setTitle(const String& s) { m_strTitle = s; } - MediaList* media() const { return m_media.get(); } - void setMedia(PassRefPtr<MediaList>); - + virtual bool disabled() const = 0; + virtual void setDisabled(bool) = 0; + virtual Node* ownerNode() const = 0; + virtual StyleSheet* parentStyleSheet() const { return 0; } + virtual String href() const = 0; + virtual String title() const = 0; + virtual MediaList* media() const { return 0; } virtual String type() const = 0; - virtual bool isLoading() = 0; - - virtual bool parseString(const String&, bool strict = true) = 0; + virtual CSSImportRule* ownerRule() const { return 0; } + virtual void clearOwnerNode() = 0; + virtual KURL baseURL() const = 0; + virtual bool isLoading() const = 0; virtual bool isCSSStyleSheet() const { return false; } virtual bool isXSLStyleSheet() const { return false; } - - KURL baseURL() const; - -protected: - StyleSheet(Node* ownerNode, const String& href, const KURL& finalURL); - StyleSheet(CSSImportRule* parentRule, const String& href, const KURL& finalURL); - -private: - bool m_disabled; - CSSImportRule* m_ownerRule; - Node* m_ownerNode; - String m_originalURL; - KURL m_finalURL; - String m_strTitle; - RefPtr<MediaList> m_media; }; } // namespace diff --git a/Source/WebCore/css/WebKitCSSFilterValue.cpp b/Source/WebCore/css/WebKitCSSFilterValue.cpp index 2cbbf9c45..2916dc2d1 100644 --- a/Source/WebCore/css/WebKitCSSFilterValue.cpp +++ b/Source/WebCore/css/WebKitCSSFilterValue.cpp @@ -99,6 +99,17 @@ String WebKitCSSFilterValue::customCssText() const return result + CSSValueList::customCssText() + ")"; } +WebKitCSSFilterValue::WebKitCSSFilterValue(const WebKitCSSFilterValue& cloneFrom) + : CSSValueList(cloneFrom) + , m_type(cloneFrom.m_type) +{ +} + +PassRefPtr<WebKitCSSFilterValue> WebKitCSSFilterValue::cloneForCSSOM() const +{ + return adoptRef(new WebKitCSSFilterValue(*this)); +} + } #endif // ENABLE(CSS_FILTERS) diff --git a/Source/WebCore/css/WebKitCSSFilterValue.h b/Source/WebCore/css/WebKitCSSFilterValue.h index 640ea36cb..a34d5745c 100644 --- a/Source/WebCore/css/WebKitCSSFilterValue.h +++ b/Source/WebCore/css/WebKitCSSFilterValue.h @@ -66,8 +66,11 @@ public: FilterOperationType operationType() const { return m_type; } + PassRefPtr<WebKitCSSFilterValue> cloneForCSSOM() const; + private: WebKitCSSFilterValue(FilterOperationType); + WebKitCSSFilterValue(const WebKitCSSFilterValue& cloneFrom); FilterOperationType m_type; }; diff --git a/Source/WebCore/css/WebKitCSSKeyframeRule.cpp b/Source/WebCore/css/WebKitCSSKeyframeRule.cpp index 59f650ff0..7692086d0 100644 --- a/Source/WebCore/css/WebKitCSSKeyframeRule.cpp +++ b/Source/WebCore/css/WebKitCSSKeyframeRule.cpp @@ -26,39 +26,19 @@ #include "config.h" #include "WebKitCSSKeyframeRule.h" +#include "PropertySetCSSStyleDeclaration.h" #include "StylePropertySet.h" +#include "WebKitCSSKeyframesRule.h" namespace WebCore { - -WebKitCSSKeyframeRule::WebKitCSSKeyframeRule(CSSStyleSheet* parent) - : CSSRule(parent, CSSRule::WEBKIT_KEYFRAME_RULE) -{ -} - -WebKitCSSKeyframeRule::~WebKitCSSKeyframeRule() -{ - if (m_style) - m_style->clearParentRule(this); -} - -String WebKitCSSKeyframeRule::cssText() const -{ - String result = m_key; - - result += " { "; - result += m_style->asText(); - result += "}"; - - return result; -} - -void WebKitCSSKeyframeRule::setDeclaration(PassRefPtr<StylePropertySet> style) + +void StyleKeyframe::setProperties(PassRefPtr<StylePropertySet> properties) { - m_style = style; + m_properties = properties; } /* static */ -void WebKitCSSKeyframeRule::parseKeyString(const String& s, Vector<float>& keys) +void StyleKeyframe::parseKeyString(const String& s, Vector<float>& keys) { keys.clear(); Vector<String> strings; @@ -67,18 +47,17 @@ void WebKitCSSKeyframeRule::parseKeyString(const String& s, Vector<float>& keys) for (size_t i = 0; i < strings.size(); ++i) { float key = -1; String cur = strings[i].stripWhiteSpace(); - + // For now the syntax MUST be 'xxx%' or 'from' or 'to', where xxx is a legal floating point number if (cur == "from") key = 0; else if (cur == "to") key = 1; - else if (cur.endsWith("%")) { + else if (cur.endsWith('%')) { float k = cur.substring(0, cur.length() - 1).toFloat(); if (k >= 0 && k <= 100) key = k/100; } - if (key < 0) { keys.clear(); return; @@ -88,4 +67,35 @@ void WebKitCSSKeyframeRule::parseKeyString(const String& s, Vector<float>& keys) } } +String StyleKeyframe::cssText() const +{ + String result = keyText(); + + result += " { "; + result += m_properties->asText(); + result += "}"; + + return result; +} + +WebKitCSSKeyframeRule::WebKitCSSKeyframeRule(StyleKeyframe* keyframe, WebKitCSSKeyframesRule* parent) + : CSSRule(0, CSSRule::WEBKIT_KEYFRAME_RULE) + , m_keyframe(keyframe) +{ + setParentRule(parent); +} + +WebKitCSSKeyframeRule::~WebKitCSSKeyframeRule() +{ + if (m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper->clearParentRule(); +} + +CSSStyleDeclaration* WebKitCSSKeyframeRule::style() const +{ + if (!m_propertiesCSSOMWrapper) + m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_keyframe->properties(), const_cast<WebKitCSSKeyframeRule*>(this)); + return m_propertiesCSSOMWrapper.get(); +} + } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSKeyframeRule.h b/Source/WebCore/css/WebKitCSSKeyframeRule.h index 4a98573da..cfa2001e2 100644 --- a/Source/WebCore/css/WebKitCSSKeyframeRule.h +++ b/Source/WebCore/css/WebKitCSSKeyframeRule.h @@ -27,46 +27,63 @@ #define WebKitCSSKeyframeRule_h #include "CSSRule.h" +#include "ExceptionCode.h" #include "StylePropertySet.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> namespace WebCore { -typedef int ExceptionCode; +class StyleRuleCSSStyleDeclaration; +class WebKitCSSKeyframesRule; -class WebKitCSSKeyframeRule : public CSSRule { +class StyleKeyframe : public RefCounted<StyleKeyframe> { public: - static PassRefPtr<WebKitCSSKeyframeRule> create() - { - return adoptRef(new WebKitCSSKeyframeRule(0)); - } - static PassRefPtr<WebKitCSSKeyframeRule> create(CSSStyleSheet* parent) + static PassRefPtr<StyleKeyframe> create() { - return adoptRef(new WebKitCSSKeyframeRule(parent)); + return adoptRef(new StyleKeyframe()); } - ~WebKitCSSKeyframeRule(); - - String keyText() const { return m_key; } - void setKeyText(const String& s) { m_key = s; } + String keyText() const { return m_key; } + void setKeyText(const String& s) { m_key = s; } void getKeys(Vector<float>& keys) const { parseKeyString(m_key, keys); } + + StylePropertySet* properties() const { return m_properties.get(); } + void setProperties(PassRefPtr<StylePropertySet>); + + String cssText() const; + +private: + StyleKeyframe() { } + + static void parseKeyString(const String&, Vector<float>& keys); + + RefPtr<StylePropertySet> m_properties; + // FIXME: This should be a parsed vector of floats. + // comma separated list of keys + String m_key; +}; - CSSStyleDeclaration* style() const { return m_style ? m_style->ensureRuleCSSStyleDeclaration(this) : 0; } +class WebKitCSSKeyframeRule : public CSSRule { +public: + ~WebKitCSSKeyframeRule(); - String cssText() const; + String keyText() const { return m_keyframe->keyText(); } + void setKeyText(const String& s) { m_keyframe->setKeyText(s); } - StylePropertySet* declaration() const { return m_style.get(); } - void setDeclaration(PassRefPtr<StylePropertySet>); + CSSStyleDeclaration* style() const; -private: - static void parseKeyString(const String& s, Vector<float>& keys); + String cssText() const { return m_keyframe->cssText(); } - WebKitCSSKeyframeRule(CSSStyleSheet* parent); +private: + WebKitCSSKeyframeRule(StyleKeyframe*, WebKitCSSKeyframesRule* parent); - RefPtr<StylePropertySet> m_style; - String m_key; // comma separated list of keys + RefPtr<StyleKeyframe> m_keyframe; + + mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper; + + friend class WebKitCSSKeyframesRule; }; } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp index 39492f5e5..cbf97d5fa 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp @@ -31,110 +31,163 @@ #include "StylePropertySet.h" #include "StyleSheet.h" #include "WebKitCSSKeyframeRule.h" +#include <wtf/text/StringBuilder.h> namespace WebCore { -WebKitCSSKeyframesRule::WebKitCSSKeyframesRule(CSSStyleSheet* parent) +StyleRuleKeyframes::StyleRuleKeyframes() + : StyleRuleBase(Keyframes, 0) +{ +} + +StyleRuleKeyframes::StyleRuleKeyframes(const StyleRuleKeyframes& o) + : StyleRuleBase(o) + , m_keyframes(o.m_keyframes) + , m_name(o.m_name) +{ +} + +StyleRuleKeyframes::~StyleRuleKeyframes() +{ +} + +void StyleRuleKeyframes::parserAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe) +{ + if (!keyframe) + return; + m_keyframes.append(keyframe); +} + +void StyleRuleKeyframes::wrapperAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe) +{ + m_keyframes.append(keyframe); +} + +void StyleRuleKeyframes::wrapperRemoveKeyframe(unsigned index) +{ + m_keyframes.remove(index); +} + +int StyleRuleKeyframes::findKeyframeIndex(const String& key) const +{ + String percentageString; + if (equalIgnoringCase(key, "from")) + percentageString = "0%"; + else if (equalIgnoringCase(key, "to")) + percentageString = "100%"; + else + percentageString = key; + + for (unsigned i = 0; i < m_keyframes.size(); ++i) { + if (m_keyframes[i]->keyText() == percentageString) + return i; + } + return -1; +} + +WebKitCSSKeyframesRule::WebKitCSSKeyframesRule(StyleRuleKeyframes* keyframesRule, CSSStyleSheet* parent) : CSSRule(parent, CSSRule::WEBKIT_KEYFRAMES_RULE) - , m_lstCSSRules(CSSRuleList::create()) + , m_keyframesRule(keyframesRule) + , m_childRuleCSSOMWrappers(keyframesRule->keyframes().size()) { } WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule() { - for (unsigned i = 0; i < length(); ++i) { - WebKitCSSKeyframeRule* rule = item(i); - rule->setParentRule(0); + ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); + + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->setParentRule(0); } } void WebKitCSSKeyframesRule::setName(const String& name) { - m_name = name; + m_keyframesRule->setName(name); - // Since the name is used in the keyframe map list in CSSStyleSelector, we need + // Since the name is used in the keyframe map list in StyleResolver, we need // to recompute the style sheet to get the updated name. if (CSSStyleSheet* styleSheet = parentStyleSheet()) styleSheet->styleSheetChanged(); } -WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) -{ - CSSRule* rule = m_lstCSSRules->item(index); - ASSERT(rule->isKeyframeRule()); - return static_cast<WebKitCSSKeyframeRule*>(rule); -} - -const WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) const +void WebKitCSSKeyframesRule::insertRule(const String& ruleText) { - const CSSRule* rule = m_lstCSSRules->item(index); - ASSERT(rule->isKeyframeRule()); - return static_cast<const WebKitCSSKeyframeRule*>(rule); -} + ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); -void WebKitCSSKeyframesRule::append(WebKitCSSKeyframeRule* rule) -{ - if (!rule) + CSSParser parser(parserContext()); + CSSStyleSheet* styleSheet = parentStyleSheet(); + RefPtr<StyleKeyframe> keyframe = parser.parseKeyframeRule(styleSheet ? styleSheet->internal() : 0, ruleText); + if (!keyframe) return; - m_lstCSSRules->append(rule); - rule->setParentRule(this); -} + m_keyframesRule->wrapperAppendKeyframe(keyframe); -void WebKitCSSKeyframesRule::insertRule(const String& rule) -{ - CSSParser p(useStrictParsing()); - RefPtr<WebKitCSSKeyframeRule> newRule = p.parseKeyframeRule(parentStyleSheet(), rule); - if (newRule) - append(newRule.get()); + m_childRuleCSSOMWrappers.grow(length()); } void WebKitCSSKeyframesRule::deleteRule(const String& s) { - int i = findRuleIndex(s); + ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); + + int i = m_keyframesRule->findKeyframeIndex(s); if (i < 0) return; - WebKitCSSKeyframeRule* rule = item(i); - rule->setParentRule(0); - m_lstCSSRules->deleteRule(i); + m_keyframesRule->wrapperRemoveKeyframe(i); + + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->setParentRule(0); + m_childRuleCSSOMWrappers.remove(i); } WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::findRule(const String& s) { - int i = findRuleIndex(s); + int i = m_keyframesRule->findKeyframeIndex(s); return (i >= 0) ? item(i) : 0; } -int WebKitCSSKeyframesRule::findRuleIndex(const String& key) const +String WebKitCSSKeyframesRule::cssText() const { - String percentageString; - if (equalIgnoringCase(key, "from")) - percentageString = "0%"; - else if (equalIgnoringCase(key, "to")) - percentageString = "100%"; - else - percentageString = key; - - for (unsigned i = 0; i < length(); ++i) { - if (item(i)->keyText() == percentageString) - return i; + StringBuilder result; + result.append("@-webkit-keyframes "); + result.append(name()); + result.append(" { \n"); + + unsigned size = length(); + for (unsigned i = 0; i < size; ++i) { + result.append(" "); + result.append(m_keyframesRule->keyframes()[i]->cssText()); + result.append("\n"); } + result.append("}"); + return result.toString(); +} - return -1; +unsigned WebKitCSSKeyframesRule::length() const +{ + return m_keyframesRule->keyframes().size(); } -String WebKitCSSKeyframesRule::cssText() const -{ - String result = "@-webkit-keyframes "; - result += m_name; - result += " { \n"; +WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) const +{ + if (index >= length()) + return 0; - if (m_lstCSSRules) - result += m_lstCSSRules->rulesText(); + ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); + RefPtr<WebKitCSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index]; + if (!rule) + rule = adoptRef(new WebKitCSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<WebKitCSSKeyframesRule*>(this))); - result += "}"; - return result; + return rule.get(); +} + +CSSRuleList* WebKitCSSKeyframesRule::cssRules() +{ + if (!m_ruleListCSSOMWrapper) + m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<WebKitCSSKeyframesRule>(this)); + return m_ruleListCSSOMWrapper.get(); } } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.h b/Source/WebCore/css/WebKitCSSKeyframesRule.h index b1a1b8f10..81abf879a 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.h +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.h @@ -27,6 +27,8 @@ #define WebKitCSSKeyframesRule_h #include "CSSRule.h" +#include "ExceptionCode.h" +#include "StyleRule.h" #include <wtf/Forward.h> #include <wtf/RefPtr.h> #include <wtf/text/AtomicString.h> @@ -34,35 +36,46 @@ namespace WebCore { class CSSRuleList; +class StyleKeyframe; class WebKitCSSKeyframeRule; -typedef int ExceptionCode; +class StyleRuleKeyframes : public StyleRuleBase { +public: + static PassRefPtr<StyleRuleKeyframes> create() { return adoptRef(new StyleRuleKeyframes()); } + + ~StyleRuleKeyframes(); + + const Vector<RefPtr<StyleKeyframe> >& keyframes() const { return m_keyframes; } + + void parserAppendKeyframe(PassRefPtr<StyleKeyframe>); + void wrapperAppendKeyframe(PassRefPtr<StyleKeyframe>); + void wrapperRemoveKeyframe(unsigned); + + String name() const { return m_name; } + void setName(const String& name) { m_name = AtomicString(name); } + + int findKeyframeIndex(const String& key) const; + + PassRefPtr<StyleRuleKeyframes> copy() const { return adoptRef(new StyleRuleKeyframes(*this)); } + +private: + StyleRuleKeyframes(); + StyleRuleKeyframes(const StyleRuleKeyframes&); + + Vector<RefPtr<StyleKeyframe> > m_keyframes; + AtomicString m_name; +}; class WebKitCSSKeyframesRule : public CSSRule { public: - static PassRefPtr<WebKitCSSKeyframesRule> create() - { - return adoptRef(new WebKitCSSKeyframesRule(0)); - } - static PassRefPtr<WebKitCSSKeyframesRule> create(CSSStyleSheet* parent) - { - return adoptRef(new WebKitCSSKeyframesRule(parent)); - } + static PassRefPtr<WebKitCSSKeyframesRule> create(StyleRuleKeyframes* rule, CSSStyleSheet* sheet) { return adoptRef(new WebKitCSSKeyframesRule(rule, sheet)); } ~WebKitCSSKeyframesRule(); - String name() const { return m_name; } + String name() const { return m_keyframesRule->name(); } void setName(const String&); - // This version of setName does not call styleSheetChanged to avoid - // unnecessary work. It assumes callers will either make that call - // themselves, or know that it will get called later. - void setNameInternal(const String& name) - { - m_name = AtomicString(name); - } - - CSSRuleList* cssRules() { return m_lstCSSRules.get(); } + CSSRuleList* cssRules(); void insertRule(const String& rule); void deleteRule(const String& key); @@ -70,19 +83,17 @@ public: String cssText() const; - // Not part of the CSSOM. - unsigned length() const { return m_lstCSSRules->length(); } - WebKitCSSKeyframeRule* item(unsigned index); - const WebKitCSSKeyframeRule* item(unsigned index) const; - void append(WebKitCSSKeyframeRule*); + // For IndexedGetter and CSSRuleList. + unsigned length() const; + WebKitCSSKeyframeRule* item(unsigned index) const; private: - WebKitCSSKeyframesRule(CSSStyleSheet* parent); + WebKitCSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent); - int findRuleIndex(const String& key) const; + RefPtr<StyleRuleKeyframes> m_keyframesRule; - RefPtr<CSSRuleList> m_lstCSSRules; - AtomicString m_name; + mutable Vector<RefPtr<WebKitCSSKeyframeRule> > m_childRuleCSSOMWrappers; + mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper; }; } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSMatrix.cpp b/Source/WebCore/css/WebKitCSSMatrix.cpp index 9aeea7715..92bfce354 100644 --- a/Source/WebCore/css/WebKitCSSMatrix.cpp +++ b/Source/WebCore/css/WebKitCSSMatrix.cpp @@ -27,11 +27,11 @@ #include "WebKitCSSMatrix.h" #include "CSSParser.h" -#include "CSSStyleSelector.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" #include "ExceptionCode.h" #include "StylePropertySet.h" +#include "StyleResolver.h" #include <wtf/MathExtras.h> namespace WebCore { @@ -52,8 +52,11 @@ WebKitCSSMatrix::~WebKitCSSMatrix() void WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec) { + if (string.isEmpty()) + return; + RefPtr<StylePropertySet> styleDeclaration = StylePropertySet::create(); - if (CSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, true, 0)) { + if (CSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, CSSStrictMode, 0)) { // Convert to TransformOperations. This can fail if a property // requires style (i.e., param uses 'ems' or 'exs') RefPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform); @@ -63,7 +66,7 @@ void WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec) return; TransformOperations operations; - if (!CSSStyleSelector::createTransformOperations(value.get(), 0, 0, operations)) { + if (!StyleResolver::createTransformOperations(value.get(), 0, 0, operations)) { ec = SYNTAX_ERR; return; } @@ -80,7 +83,7 @@ void WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec) // set the matrix m_matrix = t; - } else if (!string.isEmpty()) // There is something there but parsing failed + } else // There is something there but parsing failed. ec = SYNTAX_ERR; } diff --git a/Source/WebCore/css/WebKitCSSRegionRule.cpp b/Source/WebCore/css/WebKitCSSRegionRule.cpp index cc377c461..df1c9b079 100644 --- a/Source/WebCore/css/WebKitCSSRegionRule.cpp +++ b/Source/WebCore/css/WebKitCSSRegionRule.cpp @@ -32,43 +32,69 @@ #include "WebKitCSSRegionRule.h" #include "CSSParser.h" -#include "CSSParserValues.h" #include "CSSRuleList.h" -#include "Document.h" -#include "ExceptionCode.h" +#include "StyleRule.h" +#include <wtf/text/StringBuilder.h> namespace WebCore { -WebKitCSSRegionRule::WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules) +WebKitCSSRegionRule::WebKitCSSRegionRule(StyleRuleRegion* regionRule, CSSStyleSheet* parent) : CSSRule(parent, CSSRule::WEBKIT_REGION_RULE) - , m_ruleList(rules) + , m_regionRule(regionRule) + , m_childRuleCSSOMWrappers(regionRule->childRules().size()) { - for (unsigned index = 0; index < m_ruleList->length(); ++index) - m_ruleList->item(index)->setParentRule(this); - - m_selectorList.adoptSelectorVector(*selectors); } WebKitCSSRegionRule::~WebKitCSSRegionRule() { - for (unsigned index = 0; index < m_ruleList->length(); ++index) - m_ruleList->item(index)->setParentRule(0); + for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { + if (m_childRuleCSSOMWrappers[i]) + m_childRuleCSSOMWrappers[i]->setParentRule(0); + } } String WebKitCSSRegionRule::cssText() const { - String result = "@-webkit-region "; + StringBuilder result; + result.append("@-webkit-region "); // First add the selectors. - result += m_selectorList.selectorsText(); + result.append(m_regionRule->selectorList().selectorsText()); // Then add the rules. - result += " { \n"; + result.append(" { \n"); + + unsigned size = length(); + for (unsigned i = 0; i < size; ++i) { + result.append(" "); + result.append(item(i)->cssText()); + result.append("\n"); + } + result.append("}"); + return result.toString(); +} + +unsigned WebKitCSSRegionRule::length() const +{ + return m_regionRule->childRules().size(); +} - if (m_ruleList) - result += m_ruleList->rulesText(); +CSSRule* WebKitCSSRegionRule::item(unsigned index) const +{ + if (index >= length()) + return 0; + ASSERT(m_childRuleCSSOMWrappers.size() == m_regionRule->childRules().size()); + RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index]; + if (!rule) + rule = m_regionRule->childRules()[index]->createCSSOMWrapper(const_cast<WebKitCSSRegionRule*>(this)); + return rule.get(); +} - result += "}"; - return result; +CSSRuleList* WebKitCSSRegionRule::cssRules() const +{ + if (!m_ruleListCSSOMWrapper) + m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<WebKitCSSRegionRule>(const_cast<WebKitCSSRegionRule*>(this))); + return m_ruleListCSSOMWrapper.get(); } + } // namespace WebCore diff --git a/Source/WebCore/css/WebKitCSSRegionRule.h b/Source/WebCore/css/WebKitCSSRegionRule.h index 624ed3f63..ff5762384 100644 --- a/Source/WebCore/css/WebKitCSSRegionRule.h +++ b/Source/WebCore/css/WebKitCSSRegionRule.h @@ -30,36 +30,38 @@ #ifndef WebKitCSSRegionRule_h #define WebKitCSSRegionRule_h -#include "CSSSelectorList.h" -#include "CSSStyleRule.h" - +#include "CSSRule.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> namespace WebCore { -class CSSParserSelector; class CSSRuleList; +class StyleRuleRegion; -class WebKitCSSRegionRule: public CSSRule { +class WebKitCSSRegionRule : public CSSRule { public: - static PassRefPtr<WebKitCSSRegionRule> create(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules) - { - return adoptRef(new WebKitCSSRegionRule(parent, selectors, rules)); - } + static PassRefPtr<WebKitCSSRegionRule> create(StyleRuleRegion* rule, CSSStyleSheet* sheet) { return adoptRef(new WebKitCSSRegionRule(rule, sheet)); } ~WebKitCSSRegionRule(); String cssText() const; - const CSSSelectorList& selectorList() const { return m_selectorList; } - CSSRuleList* cssRules() const { return m_ruleList.get(); } + CSSRuleList* cssRules() const; + + // For CSSRuleList + unsigned length() const; + CSSRule* item(unsigned index) const; private: - WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules); + WebKitCSSRegionRule(StyleRuleRegion*, CSSStyleSheet* parent); - CSSSelectorList m_selectorList; - RefPtr<CSSRuleList> m_ruleList; + RefPtr<StyleRuleRegion> m_regionRule; + + mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers; + mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper; + + friend class StyleRuleBlock; }; } diff --git a/Source/WebCore/css/WebKitCSSRegionRule.idl b/Source/WebCore/css/WebKitCSSRegionRule.idl index 428d0c5bb..6c1a8972b 100644 --- a/Source/WebCore/css/WebKitCSSRegionRule.idl +++ b/Source/WebCore/css/WebKitCSSRegionRule.idl @@ -29,8 +29,7 @@ module css { - interface [ - ] WebKitCSSRegionRule : CSSRule { + interface WebKitCSSRegionRule : CSSRule { readonly attribute CSSRuleList cssRules; }; diff --git a/Source/WebCore/css/WebKitCSSTransformValue.cpp b/Source/WebCore/css/WebKitCSSTransformValue.cpp index 3e2f9e60d..dfdd71e36 100644 --- a/Source/WebCore/css/WebKitCSSTransformValue.cpp +++ b/Source/WebCore/css/WebKitCSSTransformValue.cpp @@ -115,4 +115,15 @@ String WebKitCSSTransformValue::customCssText() const return result; } +WebKitCSSTransformValue::WebKitCSSTransformValue(const WebKitCSSTransformValue& cloneFrom) + : CSSValueList(cloneFrom) + , m_type(cloneFrom.m_type) +{ +} + +PassRefPtr<WebKitCSSTransformValue> WebKitCSSTransformValue::cloneForCSSOM() const +{ + return adoptRef(new WebKitCSSTransformValue(*this)); +} + } diff --git a/Source/WebCore/css/WebKitCSSTransformValue.h b/Source/WebCore/css/WebKitCSSTransformValue.h index 89e014155..647428bf7 100644 --- a/Source/WebCore/css/WebKitCSSTransformValue.h +++ b/Source/WebCore/css/WebKitCSSTransformValue.h @@ -68,9 +68,12 @@ public: String customCssText() const; TransformOperationType operationType() const { return m_type; } + + PassRefPtr<WebKitCSSTransformValue> cloneForCSSOM() const; private: WebKitCSSTransformValue(TransformOperationType); + WebKitCSSTransformValue(const WebKitCSSTransformValue& cloneFrom); TransformOperationType m_type; }; diff --git a/Source/WebCore/css/fullscreen.css b/Source/WebCore/css/fullscreen.css index f4987f53f..8e7c87360 100644 --- a/Source/WebCore/css/fullscreen.css +++ b/Source/WebCore/css/fullscreen.css @@ -11,6 +11,13 @@ z-index: auto !important; opacity: 1 !important; -webkit-transform: none !important; + -webkit-mask: none !important; + clip: none !important; + -webkit-filter: none !important; + -webkit-transition: none !important; + -webkit-box-reflect: none !important; + -webkit-perspective: none !important; + -webkit-transform-style: flat !important; } video:-webkit-full-screen { diff --git a/Source/WebCore/css/fullscreenQuickTime.css b/Source/WebCore/css/fullscreenQuickTime.css index b1b93fcf2..27b088fea 100644 --- a/Source/WebCore/css/fullscreenQuickTime.css +++ b/Source/WebCore/css/fullscreenQuickTime.css @@ -32,6 +32,7 @@ video:-webkit-full-screen::-webkit-media-controls-panel { padding: 12px 0 0 10px !important; width: 430px !important; height: 48px !important; + margin: 0 auto 50px auto !important; background-image: -webkit-gradient( linear, @@ -55,12 +56,6 @@ video:-webkit-full-screen::-webkit-media-controls-panel { -webkit-transition: opacity 0.3s linear !important; } -video:-webkit-full-screen::-webkit-media-controls-panel:not(.dragged) { - bottom: 50px !important; - left: 50% !important; - margin-left: -220px !important; -} - video:-webkit-animating-full-screen-transition::-webkit-media-controls-panel { opacity: 0 ! important; -webkit-transition: opacity 0 ! important; diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css index 60cec9c5f..65217d67f 100644 --- a/Source/WebCore/css/html.css +++ b/Source/WebCore/css/html.css @@ -453,9 +453,8 @@ input[type="search"]::-webkit-search-results-button { } #if defined(ENABLE_DATALIST) && ENABLE_DATALIST -input::-webkit-input-list-button { - -webkit-appearance: list-button; - display: inline-block; +datalist { + display: none; } #endif @@ -625,7 +624,7 @@ input[type="radio"] { -webkit-box-sizing: border-box; } -#if defined(ENABLE_INPUT_COLOR) && ENABLE_INPUT_COLOR +#if defined(ENABLE_INPUT_TYPE_COLOR) && ENABLE_INPUT_TYPE_COLOR input[type="color"] { -webkit-appearance: square-button; @@ -666,7 +665,19 @@ input[type="color"][list]::-webkit-color-swatch { #endif // defined(ENABLE_DATALIST) && ENABLE_DATALIST -#endif // defined(ENABLE_INPUT_COLOR) && ENABLE_INPUT_COLOR +#endif // defined(ENABLE_INPUT_TYPE_COLOR) && ENABLE_INPUT_TYPE_COLOR + +#if defined(ENABLE_CALENDAR_PICKER) && ENABLE_CALENDAR_PICKER +input::-webkit-calendar-picker-indicator { + width: 0.66em; + height: 0.66em; + padding: 0.17em 0.34em; +} + +input::-webkit-calendar-picker-indicator:hover { + background-color: #eee; +} +#endif // ENABLE_CALENDAR_PICKER select { -webkit-appearance: menulist; @@ -972,10 +983,14 @@ frameset { border-color: inherit } -iframe { +iframe:not([seamless]) { border: 2px inset } +iframe[seamless] { + display: block +} + details { display: block } diff --git a/Source/WebCore/css/make-css-file-arrays.pl b/Source/WebCore/css/make-css-file-arrays.pl index 3ac1ece4e..66eb7dfb0 100755 --- a/Source/WebCore/css/make-css-file-arrays.pl +++ b/Source/WebCore/css/make-css-file-arrays.pl @@ -41,7 +41,7 @@ print HEADER "namespace WebCore {\n"; print OUT "namespace WebCore {\n"; for my $in (@ARGV) { - $in =~ /(\w+)\.css$/ or die; + $in =~ /(\w+)\.css$/ or $in =~ /(\w+)\.js$/ or die; my $name = $1; # Slurp in the CSS file. @@ -72,8 +72,13 @@ for my $in (@ARGV) { # Write out a C array of the characters. my $length = length $text; - print HEADER "extern const char ${name}UserAgentStyleSheet[${length}];\n"; - print OUT "extern const char ${name}UserAgentStyleSheet[${length}] = {\n"; + if ($in =~ /(\w+)\.css$/) { + print HEADER "extern const char ${name}UserAgentStyleSheet[${length}];\n"; + print OUT "extern const char ${name}UserAgentStyleSheet[${length}] = {\n"; + } else { + print HEADER "extern const char ${name}JavaScript[${length}];\n"; + print OUT "extern const char ${name}JavaScript[${length}] = {\n"; + } my $i = 0; while ($i < $length) { print OUT " "; diff --git a/Source/WebCore/css/makeprop.pl b/Source/WebCore/css/makeprop.pl index 6de7b7d56..fbf0dd525 100644 --- a/Source/WebCore/css/makeprop.pl +++ b/Source/WebCore/css/makeprop.pl @@ -40,6 +40,8 @@ my @names = (); my @aliases = (); foreach (@NAMES) { next if (m/(^\s*$)/); + next if (/^#/); + # Input may use a different EOL sequence than $/, so avoid chomp. $_ =~ s/[\r\n]+$//g; if (exists $namesHash{$_}) { @@ -151,6 +153,8 @@ print HEADER << "EOF"; #define CSSPropertyNames_h #include <string.h> +#include <wtf/HashFunctions.h> +#include <wtf/HashTraits.h> namespace WTF { class String; @@ -175,10 +179,12 @@ foreach my $name (@names) { } } my $num = $i - $first; +my $last = $i - 1; print HEADER "};\n\n"; print HEADER "const int firstCSSProperty = $first;\n"; print HEADER "const int numCSSProperties = $num;\n"; +print HEADER "const int lastCSSProperty = $last;\n"; print HEADER "const size_t maxCSSPropertyNameLength = $maxLen;\n"; print HEADER "const char* const propertyNameStrings[$num] = {\n"; @@ -192,8 +198,24 @@ print HEADER << "EOF"; const char* getPropertyName(CSSPropertyID); WTF::String getJSPropertyName(CSSPropertyID); +inline CSSPropertyID convertToCSSPropertyID(int value) +{ + ASSERT((value >= firstCSSProperty && value <= lastCSSProperty) || value == CSSPropertyInvalid); + return static_cast<CSSPropertyID>(value); +} + } // namespace WebCore +namespace WTF { +template<> struct DefaultHash<WebCore::CSSPropertyID> { typedef IntHash<unsigned> Hash; }; +template<> struct HashTraits<WebCore::CSSPropertyID> : GenericHashTraits<WebCore::CSSPropertyID> { + static const bool emptyValueIsZero = true; + static const bool needsDestruction = false; + static void constructDeletedValue(WebCore::CSSPropertyID& slot) { slot = static_cast<WebCore::CSSPropertyID>(WebCore::lastCSSProperty + 1); } + static bool isDeletedValue(WebCore::CSSPropertyID value) { return value == (WebCore::lastCSSProperty + 1); } +}; +} + #endif // CSSPropertyNames_h EOF diff --git a/Source/WebCore/css/makevalues.pl b/Source/WebCore/css/makevalues.pl index ced2416aa..353360698 100644 --- a/Source/WebCore/css/makevalues.pl +++ b/Source/WebCore/css/makevalues.pl @@ -39,6 +39,8 @@ my @duplicates = (); my @names = (); foreach (@NAMES) { next if (m/(^\s*$)/); + next if (/^#/); + # Input may use a different EOL sequence than $/, so avoid chomp. $_ =~ s/[\r\n]+$//g; # CSS values need to be lower case. @@ -128,7 +130,8 @@ print HEADER << "EOF"; namespace WebCore { -const int CSSValueInvalid = 0; +enum CSSValueID { + CSSValueInvalid = 0, EOF my $i = 1; @@ -136,12 +139,14 @@ my $maxLen = 0; foreach my $name (@names) { my $id = $name; $id =~ s/(^[^-])|-(.)/uc($1||$2)/ge; - print HEADER "const int CSSValue" . $id . " = " . $i . ";\n"; + print HEADER " CSSValue" . $id . " = " . $i . ",\n"; $i = $i + 1; if (length($name) > $maxLen) { $maxLen = length($name); } } + +print HEADER "};\n\n"; print HEADER "const int numCSSValueKeywords = " . $i . ";\n"; print HEADER "const size_t maxCSSValueKeywordLength = " . $maxLen . ";\n"; print HEADER << "EOF"; diff --git a/Source/WebCore/css/mathml.css b/Source/WebCore/css/mathml.css index b797b21a9..cf178e3cf 100644 --- a/Source/WebCore/css/mathml.css +++ b/Source/WebCore/css/mathml.css @@ -145,28 +145,25 @@ merror { msqrt { display: inline-block; - padding-top: 0.2em; - padding-left: 0.75em; + white-space: nowrap; /* for the anonymous RenderMathMLRow */ } mroot { display: inline-block; position: relative; - padding-top: 0.2em; - padding-left: 0.2em; } mroot > * + * { font-size: 0.75em; - vertical-align: bottom; position: absolute; - left: 0px; + left: 0; + top: 0; padding-right: 0.4em; padding-left: 0.2em; - padding-bottom: 0.2em; + padding-bottom: 0.2em; /* FIXME: change to 0.25em */ } -mroot > * + mrow, mroot > * + mfenced { +mroot > * + mrow, mroot > * + mfenced { /* FIXME: eliminate */ padding-bottom: 0.4em; } diff --git a/Source/WebCore/css/mediaControls.css b/Source/WebCore/css/mediaControls.css index b81332fc7..1b2057f02 100644 --- a/Source/WebCore/css/mediaControls.css +++ b/Source/WebCore/css/mediaControls.css @@ -150,7 +150,7 @@ audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls } audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button { - -webkit-appearance: media-fullscreen-button; + -webkit-appearance: media-enter-fullscreen-button; display: -webkit-box; width: 16px; height: 16px; @@ -221,11 +221,21 @@ video::-webkit-media-text-track-container { text-decoration: none; pointer-events: none; -webkit-user-select: none; + + -webkit-box-flex: 1; } -video::-webkit-media-text-track-display { +video::-webkit-media-text-track-background { display: inline; background-color: rgba(0, 0, 0, 0.8); + padding: 2px 2px; + white-space: pre-wrap; +} + +video::-webkit-media-text-track-display { + position: absolute; color: rgba(255, 255, 255, 1); - padding: 0px 2px; + + top: 100%; + -webkit-transform: translate(0%, -100%); } diff --git a/Source/WebCore/css/mediaControlsBlackBerry.css b/Source/WebCore/css/mediaControlsBlackBerry.css new file mode 100644 index 000000000..b7f486e8d --- /dev/null +++ b/Source/WebCore/css/mediaControlsBlackBerry.css @@ -0,0 +1,152 @@ +/* + * BlackBerry specific overrides for HTML5 media elements. + * + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2011, 2012 Research In Motion Limited. 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, + * 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. + */ + + /* BlackBerry default media controls. */ + +audio { + width: 300px; + height: 32px; +} + +audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: center; + -webkit-user-select: none; + position: absolute; + bottom: 0; + width: 100%; + z-index: 0; + overflow: visible; + height: 32px; + text-align: center; + background-color: rgba(0, 0, 0, 0.6); +} + +video:-webkit-full-page-media::-webkit-media-controls-panel { + bottom: 0px; +} + +audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { + -webkit-appearance: media-play-button; + display: -webkit-box; + width: 32px; + height: 32px; +} + +audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container { + -webkit-appearance: media-controls-background; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: center; + -webkit-box-pack: end; + -webkit-box-flex: 1; + -webkit-user-select: none; + height: 32px; +} + +audio::-webkit-media-controls-current-time-display, video::-webkit-media-controls-current-time-display { + -webkit-appearance: media-current-time-display; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: center; + -webkit-box-pack: end; + -webkit-box-flex: 0; + -webkit-user-select: none; + width: 48px; + height: 32px; + color: white; + padding-right: 2px; +} + +audio::-webkit-media-controls-time-remaining-display, video::-webkit-media-controls-time-remaining-display { + -webkit-appearance: media-time-remaining-display; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: center; + -webkit-box-pack: end; + -webkit-box-flex: 0; + -webkit-user-select: none; + width: 56px; + height: 32px; + color: white; + padding-right: 2px; +} + +audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { + -webkit-appearance: media-slider; + display: -webkit-box; + -webkit-box-flex: 1; + height: 32px; +} + +audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button { + -webkit-appearance: media-fullscreen-button; + display: -webkit-box; + width: 32px; + height: 32px; +} + +audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { + -webkit-appearance: media-mute-button; + display: -webkit-box; + width: 32px; + height: 32px; +} + +audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container { + -webkit-appearance: media-volume-slider-container; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: center; + -webkit-box-pack: end; + -webkit-box-flex: 1; + -webkit-user-select: none; + height: 128px; + width: 32px; + position: absolute; + right: 0px; + background-color: rgba(0, 0, 0, 0.6); +} + +audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volume-slider { + -webkit-appearance: media-volume-slider; + display: -webkit-box; + -webkit-box-flex: 1; + height: 128px; + width: 32px; +} + +audio::-webkit-media-controls-seek-back-button, video::-webkit-media-controls-seek-back-button { + -webkit-appearance: media-seek-back-button; + display: none; +} + +audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls-seek-forward-button { + -webkit-appearance: media-seek-forward-button; + display: none; +} diff --git a/Source/WebCore/css/mediaControlsChromium.css b/Source/WebCore/css/mediaControlsChromium.css index 5fb62cc34..7323f2a46 100644 --- a/Source/WebCore/css/mediaControlsChromium.css +++ b/Source/WebCore/css/mediaControlsChromium.css @@ -41,6 +41,7 @@ audio:-webkit-full-page-media, video:-webkit-full-page-media { audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { -webkit-user-select: none; + -webkit-box-pack: end; position: relative; overflow: visible; bottom: 0; @@ -54,9 +55,13 @@ video:-webkit-full-page-media::-webkit-media-controls-panel { bottom: 0px; } +audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { + -webkit-box-align: end; +} + audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { -webkit-appearance: media-mute-button; - position: absolute; + position: relative; top: auto; bottom: 0; right: 0; @@ -149,7 +154,7 @@ audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container { -webkit-appearance: media-volume-slider-container; - position: absolute; + position: relative; width: 34px; height: 100px; diff --git a/Source/WebCore/css/mediaControlsChromiumAndroid.css b/Source/WebCore/css/mediaControlsChromiumAndroid.css index e0498d886..92f347840 100644 --- a/Source/WebCore/css/mediaControlsChromiumAndroid.css +++ b/Source/WebCore/css/mediaControlsChromiumAndroid.css @@ -40,7 +40,7 @@ audio:-webkit-full-page-media, video:-webkit-full-page-media { audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { -webkit-user-select: none; - position: absolute; + position: relative; overflow: visible; bottom: 0; width: 100%; @@ -161,7 +161,7 @@ audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { video::-webkit-media-controls-fullscreen-button { - -webkit-appearance: media-fullscreen-button; + -webkit-appearance: media-enter-fullscreen-button; position: absolute; top: auto; bottom: 0; @@ -173,7 +173,6 @@ video::-webkit-media-controls-fullscreen-button { } audio::-webkit-media-controls-fullscreen-button { - -webkit-appearance: media-fullscreen-button; display: none; } diff --git a/Source/WebCore/css/mediaControlsEfl.css b/Source/WebCore/css/mediaControlsEfl.css index e5d58089c..3a5a95441 100644 --- a/Source/WebCore/css/mediaControlsEfl.css +++ b/Source/WebCore/css/mediaControlsEfl.css @@ -53,6 +53,8 @@ audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-bu display: -webkit-box; width: 20px; height: 20px; + position: relative; + z-index: 2; background-color: initial; border: initial; color: inherit; @@ -108,10 +110,16 @@ audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { } audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container { - display: none; + -webkit-appearance: media-volume-slider-container; + position: absolute; + height: 100px; + width: 20px; + bottom: 20px; + z-index: 1; } audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volume-slider { + -webkit-appearance: media-volume-slider; display: none; background-color: initial; border: initial; diff --git a/Source/WebCore/css/mediaControlsGtk.css b/Source/WebCore/css/mediaControlsGtk.css index aba4412ef..94c3f1d1d 100644 --- a/Source/WebCore/css/mediaControlsGtk.css +++ b/Source/WebCore/css/mediaControlsGtk.css @@ -26,22 +26,16 @@ audio { } audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { - display: -webkit-box; - -webkit-box-orient: horizontal; -webkit-box-align: end; - -webkit-user-select: none; - position: absolute; - bottom: 0; - width: 100%; - z-index: 0; - overflow: hidden; text-align: right; - height: 100%; + height: 20px; } audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { width: 20px; height: 20px; + position: relative; + z-index: 2; } audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { @@ -91,6 +85,8 @@ audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-cont position: absolute; height: 100px; width: 20px; + bottom: 20px; + z-index: 1; } audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volume-slider { diff --git a/Source/WebCore/css/mediaControlsQuickTime.css b/Source/WebCore/css/mediaControlsQuickTime.css index 5866a916f..a7e5f41bc 100644 --- a/Source/WebCore/css/mediaControlsQuickTime.css +++ b/Source/WebCore/css/mediaControlsQuickTime.css @@ -48,6 +48,9 @@ audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-bu margin-left: 2px; margin-right: 9px; border: none !important; + + position: relative; + z-index: 2; } audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { @@ -200,8 +203,8 @@ audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-cont -webkit-appearance: media-volume-slider-container; position: absolute; - top: 0; - left: 0; + bottom: 0px; + z-index: 1; width: 22px; height: 114px; @@ -218,16 +221,3 @@ audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volum width: 10px; height: 80px; } - -audio::-webkit-media-controls-volume-slider-mute-button, video::-webkit-media-controls-volume-slider-mute-button { - -webkit-appearance: media-volume-slider-mute-button; - display: inline; - position: absolute; - - bottom: 5px; - left: 4px; - - width: 14px; - height: 12px; - border: none !important; -} diff --git a/Source/WebCore/css/svg.css b/Source/WebCore/css/svg.css index bc31269f8..6ec4b23ea 100644 --- a/Source/WebCore/css/svg.css +++ b/Source/WebCore/css/svg.css @@ -26,6 +26,7 @@ */ @namespace "http://www.w3.org/2000/svg"; +@namespace html "http://www.w3.org/1999/xhtml"; /* When an outermost SVG 'svg' element is stand-alone or embedded inline within a parent XML grammar @@ -63,3 +64,13 @@ text, tspan, tref { :focus { outline: auto 5px -webkit-focus-ring-color } + +/* CSS transform specification: "transform-origin 0 0 for SVG elements without associated CSS layout box, 50% 50% for all other elements". */ + +* { + -webkit-transform-origin: 0 0; +} + +html|* > svg { + -webkit-transform-origin: 50% 50%; +} diff --git a/Source/WebCore/css/themeBlackBerry.css b/Source/WebCore/css/themeBlackBerry.css new file mode 100644 index 000000000..c62845c44 --- /dev/null +++ b/Source/WebCore/css/themeBlackBerry.css @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +textarea { + font-family: monospace; +} + +input, textarea { + -webkit-border-radius: 3px; +} + +input[type="datetime"], +input[type="date"], +input[type="week"], +input[type="month"], +input[type="time"], +input[type="datetime-local"], +input[type="number"], +input[type="color"] { + border: solid 2px blue; +} + +select:focus { + border: 1px solid black; + outline: none; +} + +select[size], +select[multiple], +select[size][multiple] { + padding: 5px; + border-radius: 5px; + border: 1px solid rgb(139,139,139); +} + +select[size]:focus, +select[multiple]:focus, +select[size][multiple]:focus { + border: 1px solid black; + outline: none; +} |