diff options
author | Ben Murdoch <benm@google.com> | 2011-05-24 11:24:40 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-02 09:53:15 +0100 |
commit | 81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch) | |
tree | 7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/css | |
parent | 94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff) | |
download | external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2 |
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/css')
26 files changed, 1575 insertions, 1026 deletions
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index f1c7fdf..8598d3d 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -25,10 +25,13 @@ #include "CSSComputedStyleDeclaration.h" #include "AnimationController.h" +#include "ContentData.h" +#include "CounterContent.h" #include "CursorList.h" #include "CSSBorderImageValue.h" #include "CSSMutableStyleDeclaration.h" #include "CSSPrimitiveValue.h" +#include "CSSPrimitiveValueCache.h" #include "CSSPrimitiveValueMappings.h" #include "CSSProperty.h" #include "CSSPropertyNames.h" @@ -197,8 +200,13 @@ static const int computedProperties[] = { #endif CSSPropertyWebkitFontSmoothing, CSSPropertyWebkitHighlight, + CSSPropertyWebkitHyphenateCharacter, + CSSPropertyWebkitHyphenateLimitAfter, + CSSPropertyWebkitHyphenateLimitBefore, + CSSPropertyWebkitHyphens, CSSPropertyWebkitLineBreak, CSSPropertyWebkitLineClamp, + CSSPropertyWebkitLocale, CSSPropertyWebkitMarginBeforeCollapse, CSSPropertyWebkitMarginAfterCollapse, CSSPropertyWebkitMarqueeDirection, @@ -220,6 +228,9 @@ static const int computedProperties[] = { CSSPropertyWebkitRtlOrdering, CSSPropertyWebkitTextCombine, CSSPropertyWebkitTextDecorationsInEffect, + CSSPropertyWebkitTextEmphasisColor, + CSSPropertyWebkitTextEmphasisPosition, + CSSPropertyWebkitTextEmphasisStyle, CSSPropertyWebkitTextFillColor, CSSPropertyWebkitTextSecurity, CSSPropertyWebkitTextStrokeColor, @@ -309,10 +320,10 @@ static int valueForRepeatRule(int rule) } } -static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) +static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, CSSPrimitiveValueCache* primitiveValueCache) { if (!image.hasImage()) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); // Image first. RefPtr<CSSValue> imageValue; @@ -322,27 +333,27 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) // Create the slices. RefPtr<CSSPrimitiveValue> top; if (image.slices().top().isPercent()) - top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + top = primitiveValueCache->createValue(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER); + top = primitiveValueCache->createValue(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER); RefPtr<CSSPrimitiveValue> right; if (image.slices().right().isPercent()) - right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + right = primitiveValueCache->createValue(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER); + right = primitiveValueCache->createValue(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER); RefPtr<CSSPrimitiveValue> bottom; if (image.slices().bottom().isPercent()) - bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + bottom = primitiveValueCache->createValue(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER); + bottom = primitiveValueCache->createValue(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER); RefPtr<CSSPrimitiveValue> left; if (image.slices().left().isPercent()) - left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); + left = primitiveValueCache->createValue(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE); else - left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER); + left = primitiveValueCache->createValue(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER); RefPtr<Rect> rect = Rect::create(); rect->setTop(top); @@ -353,38 +364,38 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image) return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.horizontalRule()), valueForRepeatRule(image.verticalRule())); } -inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style) +inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) { - return CSSPrimitiveValue::create(adjustForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); + return primitiveValueCache->createValue(adjustForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); } -inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style) +inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) { - return CSSPrimitiveValue::create(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); } -static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style) +static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) { if (length.isFixed()) - return zoomAdjustedPixelValue(length.value(), style); - return CSSPrimitiveValue::create(length); + return zoomAdjustedPixelValue(length.value(), style, primitiveValueCache); + return primitiveValueCache->createValue(length); } -static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style) +static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) { if (!reflection) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); RefPtr<CSSPrimitiveValue> offset; if (reflection->offset().isPercent()) - offset = CSSPrimitiveValue::create(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + offset = primitiveValueCache->createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); else - offset = zoomAdjustedPixelValue(reflection->offset().value(), style); + offset = zoomAdjustedPixelValue(reflection->offset().value(), style, primitiveValueCache); - return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask())); + return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask(), primitiveValueCache)); } -static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID) +static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID, CSSPrimitiveValueCache* primitiveValueCache) { if (!style) return 0; @@ -409,43 +420,44 @@ 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); - return CSSPrimitiveValue::create(l); + return zoomAdjustedPixelValue(l.value(), style, primitiveValueCache); + return primitiveValueCache->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 CSSPrimitiveValue::create(l); + return primitiveValueCache->createValue(l); - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return primitiveValueCache->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. + CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get(); if (!color.isValid()) - return CSSPrimitiveValue::createColor(style->color().rgb()); - return CSSPrimitiveValue::createColor(color.rgb()); + return primitiveValueCache->createColorValue(style->color().rgb()); + return primitiveValueCache->createColorValue(color.rgb()); } -static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style) +static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (radius.width() == radius.height()) { if (radius.width().type() == Percent) - return CSSPrimitiveValue::create(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); - return zoomAdjustedPixelValue(radius.width().value(), style); + return primitiveValueCache->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); + return zoomAdjustedPixelValue(radius.width().value(), style, primitiveValueCache); } if (radius.width().type() == Percent) - list->append(CSSPrimitiveValue::create(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); + list->append(primitiveValueCache->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); else - list->append(zoomAdjustedPixelValue(radius.width().value(), style)); + list->append(zoomAdjustedPixelValue(radius.width().value(), style, primitiveValueCache)); if (radius.height().type() == Percent) - list->append(CSSPrimitiveValue::create(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); + list->append(primitiveValueCache->createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE)); else - list->append(zoomAdjustedPixelValue(radius.height().value(), style)); + list->append(zoomAdjustedPixelValue(radius.height().value(), style, primitiveValueCache)); return list.release(); } @@ -463,10 +475,10 @@ static inline bool hasCompositedLayer(RenderObject* renderer) return renderer && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->isComposited(); } -static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style) +static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) { if (!renderer || style->transform().operations().isEmpty()) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); IntRect box = sizingBox(renderer); @@ -480,34 +492,34 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend if (transform.isAffine()) { transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation); - transformVal->append(CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(zoomAdjustedNumberValue(transform.e(), style)); - transformVal->append(zoomAdjustedNumberValue(transform.f(), style)); + transformVal->append(primitiveValueCache->createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(zoomAdjustedNumberValue(transform.e(), style, primitiveValueCache)); + transformVal->append(zoomAdjustedNumberValue(transform.f(), style, primitiveValueCache)); } else { transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation); - transformVal->append(CSSPrimitiveValue::create(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); - - transformVal->append(CSSPrimitiveValue::create(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); - - transformVal->append(CSSPrimitiveValue::create(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); - transformVal->append(CSSPrimitiveValue::create(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(CSSPrimitiveValue::create(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); + + transformVal->append(primitiveValueCache->createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); + + transformVal->append(primitiveValueCache->createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); + transformVal->append(primitiveValueCache->createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); + + transformVal->append(zoomAdjustedNumberValue(transform.m41(), style, primitiveValueCache)); + transformVal->append(zoomAdjustedNumberValue(transform.m42(), style, primitiveValueCache)); + transformVal->append(zoomAdjustedNumberValue(transform.m43(), style, primitiveValueCache)); + transformVal->append(primitiveValueCache->createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); } RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); @@ -516,28 +528,28 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend return list.release(); } -static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList) +static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList, CSSPrimitiveValueCache* primitiveValueCache) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); if (animList) { for (size_t i = 0; i < animList->size(); ++i) - list->append(CSSPrimitiveValue::create(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S)); + list->append(primitiveValueCache->createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S)); } else { // Note that initialAnimationDelay() is used for both transitions and animations - list->append(CSSPrimitiveValue::create(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); + list->append(primitiveValueCache->createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S)); } return list.release(); } -static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList) +static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList, CSSPrimitiveValueCache* primitiveValueCache) { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); if (animList) { for (size_t i = 0; i < animList->size(); ++i) - list->append(CSSPrimitiveValue::create(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S)); + list->append(primitiveValueCache->createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S)); } else { // Note that initialAnimationDuration() is used for both transitions and animations - list->append(CSSPrimitiveValue::create(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); + list->append(primitiveValueCache->createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S)); } return list.release(); } @@ -625,12 +637,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringK RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier); if (!style) return 0; + + CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get(); if (int keywordSize = style->fontDescription().keywordSize()) - return CSSPrimitiveValue::createIdentifier(cssIdentifierForFontSizeKeyword(keywordSize)); + return primitiveValueCache->createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize)); - return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get()); + return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), primitiveValueCache); } bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const @@ -647,19 +661,20 @@ bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, int id, RenderStyle* style) const { + CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get(); if (!shadow) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); CSSPropertyID propertyID = static_cast<CSSPropertyID>(id); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const ShadowData* s = shadow; s; s = s->next()) { - 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 ? 0 : zoomAdjustedPixelValue(s->spread(), style); - RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? 0 : CSSPrimitiveValue::createIdentifier(CSSValueInset); - RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color().rgb()); + RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style, primitiveValueCache); + RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style, primitiveValueCache); + RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style, primitiveValueCache); + RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : zoomAdjustedPixelValue(s->spread(), style, primitiveValueCache); + RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? 0 : primitiveValueCache->createIdentifierValue(CSSValueInset); + RefPtr<CSSPrimitiveValue> color = primitiveValueCache->createColorValue(s->color().rgb()); list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release())); } return list.release(); @@ -690,58 +705,88 @@ static int identifierForFamily(const AtomicString& family) return 0; } -static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family) +static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family, CSSPrimitiveValueCache* primitiveValueCache) { if (int familyIdentifier = identifierForFamily(family)) - return CSSPrimitiveValue::createIdentifier(familyIdentifier); - return CSSPrimitiveValue::create(family.string(), CSSPrimitiveValue::CSS_STRING); + return primitiveValueCache->createIdentifierValue(familyIdentifier); + return primitiveValueCache->createValue(family.string(), CSSPrimitiveValue::CSS_STRING); } -static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration) +static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration, CSSPrimitiveValueCache* primitiveValueCache) { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (textDecoration & UNDERLINE) - list->append(CSSPrimitiveValue::createIdentifier(CSSValueUnderline)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueUnderline)); if (textDecoration & OVERLINE) - list->append(CSSPrimitiveValue::createIdentifier(CSSValueOverline)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueOverline)); if (textDecoration & LINE_THROUGH) - list->append(CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueLineThrough)); if (textDecoration & BLINK) - list->append(CSSPrimitiveValue::createIdentifier(CSSValueBlink)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueBlink)); if (!list->length()) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); return list; } -static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat) +static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat, CSSPrimitiveValueCache* primitiveValueCache) { // 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 CSSPrimitiveValue::create(xRepeat); + return primitiveValueCache->createValue(xRepeat); if (xRepeat == RepeatFill && yRepeat == NoRepeatFill) - return CSSPrimitiveValue::createIdentifier(CSSValueRepeatX); + return primitiveValueCache->createIdentifierValue(CSSValueRepeatX); if (xRepeat == NoRepeatFill && yRepeat == RepeatFill) - return CSSPrimitiveValue::createIdentifier(CSSValueRepeatY); + return primitiveValueCache->createIdentifierValue(CSSValueRepeatY); RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(CSSPrimitiveValue::create(xRepeat)); - list->append(CSSPrimitiveValue::create(yRepeat)); + list->append(primitiveValueCache->createValue(xRepeat)); + list->append(primitiveValueCache->createValue(yRepeat)); return list.release(); } -static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize) +static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, CSSPrimitiveValueCache* primitiveValueCache) { if (fillSize.type == Contain) - return CSSPrimitiveValue::createIdentifier(CSSValueContain); + return primitiveValueCache->createIdentifierValue(CSSValueContain); if (fillSize.type == Cover) - return CSSPrimitiveValue::createIdentifier(CSSValueCover); + return primitiveValueCache->createIdentifierValue(CSSValueCover); RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(CSSPrimitiveValue::create(fillSize.size.width())); - list->append(CSSPrimitiveValue::create(fillSize.size.height())); + list->append(primitiveValueCache->createValue(fillSize.size.width())); + list->append(primitiveValueCache->createValue(fillSize.size.height())); + return list.release(); +} + +static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache) +{ + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) { + if (contentData->isCounter()) { + const CounterContent* counter = contentData->counter(); + ASSERT(counter); + list->append(primitiveValueCache->createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); + } else if (contentData->isImage()) { + const StyleImage* image = contentData->image(); + ASSERT(image); + list->append(image->cssValue()); + } else if (contentData->isText()) + list->append(primitiveValueCache->createValue(contentData->text(), CSSPrimitiveValue::CSS_STRING)); + } + return list.release(); +} + +static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, int propertyID, CSSPrimitiveValueCache* primitiveValueCache) +{ + RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); + const CounterDirectiveMap* map = style->counterDirectives(); + for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) { + list->append(primitiveValueCache->createValue(it->first.get(), CSSPrimitiveValue::CSS_STRING)); + short number = propertyID == CSSPropertyCounterIncrement ? it->second.m_incrementValue : it->second.m_resetValue; + list->append(primitiveValueCache->createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); + } return list.release(); } @@ -778,6 +823,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper if (!style) return 0; + + CSSPrimitiveValueCache* primitiveValueCache = node->document()->cssPrimitiveValueCache().get(); propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode()); #ifdef ANDROID_LAYOUT @@ -789,18 +836,18 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper break; case CSSPropertyBackgroundColor: - return CSSPrimitiveValue::createColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb()); + return primitiveValueCache->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 CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); if (!layers->next()) { if (layers->image()) return layers->image()->cssValue(); - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); } RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); @@ -808,7 +855,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper if (currLayer->image()) list->append(currLayer->image()->cssValue()); else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueNone)); } return list.release(); } @@ -817,11 +864,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()); + return fillSizeToCSSValue(layers->size(), primitiveValueCache); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(fillSizeToCSSValue(currLayer->size())); + list->append(fillSizeToCSSValue(currLayer->size(), primitiveValueCache)); return list.release(); } @@ -829,11 +876,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()); + return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY(), primitiveValueCache); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY())); + list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY(), primitiveValueCache)); return list.release(); } @@ -841,11 +888,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskComposite: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return CSSPrimitiveValue::create(layers->composite()); + return primitiveValueCache->createValue(layers->composite()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(CSSPrimitiveValue::create(currLayer->composite())); + list->append(primitiveValueCache->createValue(currLayer->composite())); return list.release(); } @@ -853,11 +900,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskAttachment: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskAttachment ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return CSSPrimitiveValue::create(layers->attachment()); + return primitiveValueCache->createValue(layers->attachment()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(CSSPrimitiveValue::create(currLayer->attachment())); + list->append(primitiveValueCache->createValue(currLayer->attachment())); return list.release(); } @@ -871,13 +918,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 CSSPrimitiveValue::create(box); + return primitiveValueCache->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(CSSPrimitiveValue::create(box)); + list->append(primitiveValueCache->createValue(box)); } return list.release(); @@ -887,16 +934,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(CSSPrimitiveValue::create(layers->xPosition())); - list->append(CSSPrimitiveValue::create(layers->yPosition())); + list->append(primitiveValueCache->createValue(layers->xPosition())); + list->append(primitiveValueCache->createValue(layers->yPosition())); return list.release(); } RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) { RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated(); - positionList->append(CSSPrimitiveValue::create(currLayer->xPosition())); - positionList->append(CSSPrimitiveValue::create(currLayer->yPosition())); + positionList->append(primitiveValueCache->createValue(currLayer->xPosition())); + positionList->append(primitiveValueCache->createValue(currLayer->yPosition())); list->append(positionList); } @@ -906,11 +953,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskPositionX: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return CSSPrimitiveValue::create(layers->xPosition()); + return primitiveValueCache->createValue(layers->xPosition()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(CSSPrimitiveValue::create(currLayer->xPosition())); + list->append(primitiveValueCache->createValue(currLayer->xPosition())); return list.release(); } @@ -918,115 +965,115 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyWebkitMaskPositionY: { const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers(); if (!layers->next()) - return CSSPrimitiveValue::create(layers->yPosition()); + return primitiveValueCache->createValue(layers->yPosition()); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) - list->append(CSSPrimitiveValue::create(currLayer->yPosition())); + list->append(primitiveValueCache->createValue(currLayer->yPosition())); return list.release(); } case CSSPropertyBorderCollapse: if (style->borderCollapse()) - return CSSPrimitiveValue::createIdentifier(CSSValueCollapse); - return CSSPrimitiveValue::createIdentifier(CSSValueSeparate); + return primitiveValueCache->createIdentifierValue(CSSValueCollapse); + return primitiveValueCache->createIdentifierValue(CSSValueSeparate); case CSSPropertyBorderSpacing: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get())); - list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get())); + list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), primitiveValueCache)); + list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), primitiveValueCache)); return list.release(); } case CSSPropertyWebkitBorderHorizontalSpacing: - return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()); + return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), primitiveValueCache); case CSSPropertyWebkitBorderVerticalSpacing: - return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()); + return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), primitiveValueCache); case CSSPropertyBorderTopColor: - return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor()); + return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor()); case CSSPropertyBorderRightColor: - return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor()); + return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor()); case CSSPropertyBorderBottomColor: - return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor()); + return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor()); case CSSPropertyBorderLeftColor: - return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor()); + return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor()); case CSSPropertyBorderTopStyle: - return CSSPrimitiveValue::create(style->borderTopStyle()); + return primitiveValueCache->createValue(style->borderTopStyle()); case CSSPropertyBorderRightStyle: - return CSSPrimitiveValue::create(style->borderRightStyle()); + return primitiveValueCache->createValue(style->borderRightStyle()); case CSSPropertyBorderBottomStyle: - return CSSPrimitiveValue::create(style->borderBottomStyle()); + return primitiveValueCache->createValue(style->borderBottomStyle()); case CSSPropertyBorderLeftStyle: - return CSSPrimitiveValue::create(style->borderLeftStyle()); + return primitiveValueCache->createValue(style->borderLeftStyle()); case CSSPropertyBorderTopWidth: - return zoomAdjustedPixelValue(style->borderTopWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderTopWidth(), style.get(), primitiveValueCache); case CSSPropertyBorderRightWidth: - return zoomAdjustedPixelValue(style->borderRightWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderRightWidth(), style.get(), primitiveValueCache); case CSSPropertyBorderBottomWidth: - return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get(), primitiveValueCache); case CSSPropertyBorderLeftWidth: - return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get()); + return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get(), primitiveValueCache); case CSSPropertyBottom: - return getPositionOffsetValue(style.get(), CSSPropertyBottom); + return getPositionOffsetValue(style.get(), CSSPropertyBottom, primitiveValueCache); case CSSPropertyWebkitBoxAlign: - return CSSPrimitiveValue::create(style->boxAlign()); + return primitiveValueCache->createValue(style->boxAlign()); case CSSPropertyWebkitBoxDirection: - return CSSPrimitiveValue::create(style->boxDirection()); + return primitiveValueCache->createValue(style->boxDirection()); case CSSPropertyWebkitBoxFlex: - return CSSPrimitiveValue::create(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxFlexGroup: - return CSSPrimitiveValue::create(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxLines: - return CSSPrimitiveValue::create(style->boxLines()); + return primitiveValueCache->createValue(style->boxLines()); case CSSPropertyWebkitBoxOrdinalGroup: - return CSSPrimitiveValue::create(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBoxOrient: - return CSSPrimitiveValue::create(style->boxOrient()); + return primitiveValueCache->createValue(style->boxOrient()); case CSSPropertyWebkitBoxPack: { EBoxAlignment boxPack = style->boxPack(); ASSERT(boxPack != BSTRETCH); ASSERT(boxPack != BBASELINE); if (boxPack == BJUSTIFY || boxPack== BBASELINE) return 0; - return CSSPrimitiveValue::create(boxPack); + return primitiveValueCache->createValue(boxPack); } case CSSPropertyWebkitBoxReflect: - return valueForReflection(style->boxReflect(), style.get()); + return valueForReflection(style->boxReflect(), style.get(), primitiveValueCache); case CSSPropertyBoxShadow: case CSSPropertyWebkitBoxShadow: return valueForShadow(style->boxShadow(), propertyID, style.get()); case CSSPropertyCaptionSide: - return CSSPrimitiveValue::create(style->captionSide()); + return primitiveValueCache->createValue(style->captionSide()); case CSSPropertyClear: - return CSSPrimitiveValue::create(style->clear()); + return primitiveValueCache->createValue(style->clear()); case CSSPropertyColor: - return CSSPrimitiveValue::createColor(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb()); + return primitiveValueCache->createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb()); case CSSPropertyWebkitColumnCount: if (style->hasAutoColumnCount()) - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::create(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitColumnGap: if (style->hasNormalColumnGap()) - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); - return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueNormal); + return primitiveValueCache->createValue(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitColumnRuleColor: - return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor()); + return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor()); case CSSPropertyWebkitColumnRuleStyle: - return CSSPrimitiveValue::create(style->columnRuleStyle()); + return primitiveValueCache->createValue(style->columnRuleStyle()); case CSSPropertyWebkitColumnRuleWidth: - return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get()); + return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get(), primitiveValueCache); case CSSPropertyWebkitColumnSpan: if (style->columnSpan()) - return CSSPrimitiveValue::createIdentifier(CSSValueAll); - return CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueAll); + return primitiveValueCache->createValue(1, CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitColumnBreakAfter: - return CSSPrimitiveValue::create(style->columnBreakAfter()); + return primitiveValueCache->createValue(style->columnBreakAfter()); case CSSPropertyWebkitColumnBreakBefore: - return CSSPrimitiveValue::create(style->columnBreakBefore()); + return primitiveValueCache->createValue(style->columnBreakBefore()); case CSSPropertyWebkitColumnBreakInside: - return CSSPrimitiveValue::create(style->columnBreakInside()); + return primitiveValueCache->createValue(style->columnBreakInside()); case CSSPropertyWebkitColumnWidth: if (style->hasAutoColumnWidth()) - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::create(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createValue(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyCursor: { RefPtr<CSSValueList> list; CursorList* cursors = style->cursors(); @@ -1036,7 +1083,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper if (StyleImage* image = cursors->at(i).image()) list->append(image->cssValue()); } - RefPtr<CSSValue> value = CSSPrimitiveValue::create(style->cursor()); + RefPtr<CSSValue> value = primitiveValueCache->createValue(style->cursor()); if (list) { list->append(value); return list.release(); @@ -1044,240 +1091,262 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper return value.release(); } case CSSPropertyDirection: - return CSSPrimitiveValue::create(style->direction()); + return primitiveValueCache->createValue(style->direction()); case CSSPropertyDisplay: - return CSSPrimitiveValue::create(style->display()); + return primitiveValueCache->createValue(style->display()); case CSSPropertyEmptyCells: - return CSSPrimitiveValue::create(style->emptyCells()); + return primitiveValueCache->createValue(style->emptyCells()); case CSSPropertyFloat: +<<<<<<< HEAD #ifdef ANDROID_LAYOUT if (settings && settings->layoutAlgorithm() == Settings::kLayoutSSR) return CSSPrimitiveValue::createIdentifier(CSSValueNone); #endif return CSSPrimitiveValue::create(style->floating()); +======= + return primitiveValueCache->createValue(style->floating()); +>>>>>>> WebKit at r80534 case CSSPropertyFontFamily: { const FontFamily& firstFamily = style->fontDescription().family(); if (!firstFamily.next()) - return valueForFamily(firstFamily.family()); + return valueForFamily(firstFamily.family(), primitiveValueCache); RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (const FontFamily* family = &firstFamily; family; family = family->next()) - list->append(valueForFamily(family->family())); + list->append(valueForFamily(family->family(), primitiveValueCache)); return list.release(); } case CSSPropertyFontSize: - return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get()); + return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), primitiveValueCache); case CSSPropertyFontStyle: if (style->fontDescription().italic()) - return CSSPrimitiveValue::createIdentifier(CSSValueItalic); - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return primitiveValueCache->createIdentifierValue(CSSValueItalic); + return primitiveValueCache->createIdentifierValue(CSSValueNormal); case CSSPropertyFontVariant: if (style->fontDescription().smallCaps()) - return CSSPrimitiveValue::createIdentifier(CSSValueSmallCaps); - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return primitiveValueCache->createIdentifierValue(CSSValueSmallCaps); + return primitiveValueCache->createIdentifierValue(CSSValueNormal); case CSSPropertyFontWeight: switch (style->fontDescription().weight()) { case FontWeight100: - return CSSPrimitiveValue::createIdentifier(CSSValue100); + return primitiveValueCache->createIdentifierValue(CSSValue100); case FontWeight200: - return CSSPrimitiveValue::createIdentifier(CSSValue200); + return primitiveValueCache->createIdentifierValue(CSSValue200); case FontWeight300: - return CSSPrimitiveValue::createIdentifier(CSSValue300); + return primitiveValueCache->createIdentifierValue(CSSValue300); case FontWeightNormal: - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return primitiveValueCache->createIdentifierValue(CSSValueNormal); case FontWeight500: - return CSSPrimitiveValue::createIdentifier(CSSValue500); + return primitiveValueCache->createIdentifierValue(CSSValue500); case FontWeight600: - return CSSPrimitiveValue::createIdentifier(CSSValue600); + return primitiveValueCache->createIdentifierValue(CSSValue600); case FontWeightBold: - return CSSPrimitiveValue::createIdentifier(CSSValueBold); + return primitiveValueCache->createIdentifierValue(CSSValueBold); case FontWeight800: - return CSSPrimitiveValue::createIdentifier(CSSValue800); + return primitiveValueCache->createIdentifierValue(CSSValue800); case FontWeight900: - return CSSPrimitiveValue::createIdentifier(CSSValue900); + return primitiveValueCache->createIdentifierValue(CSSValue900); } ASSERT_NOT_REACHED(); - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return primitiveValueCache->createIdentifierValue(CSSValueNormal); case CSSPropertyHeight: if (renderer) - return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get()); - return zoomAdjustedPixelValueForLength(style->height(), style.get()); + return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get(), primitiveValueCache); + return zoomAdjustedPixelValueForLength(style->height(), style.get(), primitiveValueCache); case CSSPropertyWebkitHighlight: if (style->highlight() == nullAtom) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); - return CSSPrimitiveValue::create(style->highlight(), CSSPrimitiveValue::CSS_STRING); + return primitiveValueCache->createIdentifierValue(CSSValueNone); + return primitiveValueCache->createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyWebkitHyphens: - return CSSPrimitiveValue::create(style->hyphens()); + return primitiveValueCache->createValue(style->hyphens()); case CSSPropertyWebkitHyphenateCharacter: if (style->hyphenationString().isNull()) + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); + case CSSPropertyWebkitHyphenateLimitAfter: + if (style->hyphenationLimitAfter() < 0) return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::create(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING); - case CSSPropertyWebkitHyphenateLocale: - if (style->hyphenationLocale().isNull()) + return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER); + case CSSPropertyWebkitHyphenateLimitBefore: + if (style->hyphenationLimitBefore() < 0) return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::create(style->hyphenationLocale(), CSSPrimitiveValue::CSS_STRING); + return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitBorderFit: if (style->borderFit() == BorderFitBorder) - return CSSPrimitiveValue::createIdentifier(CSSValueBorder); - return CSSPrimitiveValue::createIdentifier(CSSValueLines); + return primitiveValueCache->createIdentifierValue(CSSValueBorder); + return primitiveValueCache->createIdentifierValue(CSSValueLines); case CSSPropertyLeft: - return getPositionOffsetValue(style.get(), CSSPropertyLeft); + return getPositionOffsetValue(style.get(), CSSPropertyLeft, primitiveValueCache); case CSSPropertyLetterSpacing: if (!style->letterSpacing()) - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); - return zoomAdjustedPixelValue(style->letterSpacing(), style.get()); + return primitiveValueCache->createIdentifierValue(CSSValueNormal); + return zoomAdjustedPixelValue(style->letterSpacing(), style.get(), primitiveValueCache); case CSSPropertyWebkitLineClamp: if (style->lineClamp().isNone()) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); - return CSSPrimitiveValue::create(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueNone); + return primitiveValueCache->createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyLineHeight: { Length length = style->lineHeight(); if (length.isNegative()) - return CSSPrimitiveValue::createIdentifier(CSSValueNormal); + return primitiveValueCache->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.get()); - return zoomAdjustedPixelValue(length.value(), style.get()); + return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style.get(), primitiveValueCache); + return zoomAdjustedPixelValue(length.value(), style.get(), primitiveValueCache); } case CSSPropertyListStyleImage: if (style->listStyleImage()) return style->listStyleImage()->cssValue(); - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); case CSSPropertyListStylePosition: - return CSSPrimitiveValue::create(style->listStylePosition()); + return primitiveValueCache->createValue(style->listStylePosition()); case CSSPropertyListStyleType: - return CSSPrimitiveValue::create(style->listStyleType()); + return primitiveValueCache->createValue(style->listStyleType()); + case CSSPropertyWebkitLocale: + if (style->locale().isNull()) + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createValue(style->locale(), CSSPrimitiveValue::CSS_STRING); case CSSPropertyMarginTop: { Length marginTop = style->marginTop(); if (marginTop.isPercent()) - return CSSPrimitiveValue::create(marginTop); - return zoomAdjustedPixelValue(marginTop.value(), style.get()); + return primitiveValueCache->createValue(marginTop); + return zoomAdjustedPixelValue(marginTop.value(), style.get(), primitiveValueCache); } case CSSPropertyMarginRight: { Length marginRight = style->marginRight(); if (marginRight.isPercent()) - return CSSPrimitiveValue::create(marginRight); - return zoomAdjustedPixelValue(marginRight.value(), style.get()); + return primitiveValueCache->createValue(marginRight); + return zoomAdjustedPixelValue(marginRight.value(), style.get(), primitiveValueCache); } case CSSPropertyMarginBottom: { Length marginBottom = style->marginBottom(); if (marginBottom.isPercent()) - return CSSPrimitiveValue::create(marginBottom); - return zoomAdjustedPixelValue(marginBottom.value(), style.get()); + return primitiveValueCache->createValue(marginBottom); + return zoomAdjustedPixelValue(marginBottom.value(), style.get(), primitiveValueCache); } case CSSPropertyMarginLeft: { Length marginLeft = style->marginLeft(); if (marginLeft.isPercent()) - return CSSPrimitiveValue::create(marginLeft); - return zoomAdjustedPixelValue(marginLeft.value(), style.get()); + return primitiveValueCache->createValue(marginLeft); + return zoomAdjustedPixelValue(marginLeft.value(), style.get(), primitiveValueCache); } case CSSPropertyWebkitMarqueeDirection: - return CSSPrimitiveValue::create(style->marqueeDirection()); + return primitiveValueCache->createValue(style->marqueeDirection()); case CSSPropertyWebkitMarqueeIncrement: - return CSSPrimitiveValue::create(style->marqueeIncrement()); + return primitiveValueCache->createValue(style->marqueeIncrement()); case CSSPropertyWebkitMarqueeRepetition: if (style->marqueeLoopCount() < 0) - return CSSPrimitiveValue::createIdentifier(CSSValueInfinite); - return CSSPrimitiveValue::create(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueInfinite); + return primitiveValueCache->createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitMarqueeStyle: - return CSSPrimitiveValue::create(style->marqueeBehavior()); + return primitiveValueCache->createValue(style->marqueeBehavior()); case CSSPropertyWebkitUserModify: - return CSSPrimitiveValue::create(style->userModify()); + return primitiveValueCache->createValue(style->userModify()); case CSSPropertyMaxHeight: { const Length& maxHeight = style->maxHeight(); if (maxHeight.isFixed() && maxHeight.value() == undefinedLength) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); - return CSSPrimitiveValue::create(maxHeight); + return primitiveValueCache->createIdentifierValue(CSSValueNone); + return primitiveValueCache->createValue(maxHeight); } case CSSPropertyMaxWidth: { const Length& maxWidth = style->maxWidth(); if (maxWidth.isFixed() && maxWidth.value() == undefinedLength) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); - return CSSPrimitiveValue::create(maxWidth); + return primitiveValueCache->createIdentifierValue(CSSValueNone); + return primitiveValueCache->createValue(maxWidth); } case CSSPropertyMinHeight: - return CSSPrimitiveValue::create(style->minHeight()); + return primitiveValueCache->createValue(style->minHeight()); case CSSPropertyMinWidth: - return CSSPrimitiveValue::create(style->minWidth()); + return primitiveValueCache->createValue(style->minWidth()); case CSSPropertyOpacity: - return CSSPrimitiveValue::create(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyOrphans: - return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyOutlineColor: - return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor()); + return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor()); + case CSSPropertyOutlineOffset: + return zoomAdjustedPixelValue(style->outlineOffset(), style.get(), primitiveValueCache); case CSSPropertyOutlineStyle: if (style->outlineStyleIsAuto()) - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::create(style->outlineStyle()); + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createValue(style->outlineStyle()); case CSSPropertyOutlineWidth: - return zoomAdjustedPixelValue(style->outlineWidth(), style.get()); + return zoomAdjustedPixelValue(style->outlineWidth(), style.get(), primitiveValueCache); case CSSPropertyOverflow: - return CSSPrimitiveValue::create(max(style->overflowX(), style->overflowY())); + return primitiveValueCache->createValue(max(style->overflowX(), style->overflowY())); case CSSPropertyOverflowX: - return CSSPrimitiveValue::create(style->overflowX()); + return primitiveValueCache->createValue(style->overflowX()); case CSSPropertyOverflowY: +<<<<<<< HEAD #ifdef ANDROID_LAYOUT if (settings && settings->layoutAlgorithm() == Settings::kLayoutSSR) return CSSPrimitiveValue::createIdentifier(CSSValueVisible); #endif return CSSPrimitiveValue::create(style->overflowY()); +======= + return primitiveValueCache->createValue(style->overflowY()); +>>>>>>> WebKit at r80534 case CSSPropertyPaddingTop: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingTop(false), style.get()); - return CSSPrimitiveValue::create(style->paddingTop()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingTop(false), style.get(), primitiveValueCache); + return primitiveValueCache->createValue(style->paddingTop()); case CSSPropertyPaddingRight: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingRight(false), style.get()); - return CSSPrimitiveValue::create(style->paddingRight()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingRight(false), style.get(), primitiveValueCache); + return primitiveValueCache->createValue(style->paddingRight()); case CSSPropertyPaddingBottom: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingBottom(false), style.get()); - return CSSPrimitiveValue::create(style->paddingBottom()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingBottom(false), style.get(), primitiveValueCache); + return primitiveValueCache->createValue(style->paddingBottom()); case CSSPropertyPaddingLeft: if (renderer && renderer->isBox()) - return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingLeft(false), style.get()); - return CSSPrimitiveValue::create(style->paddingLeft()); + return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingLeft(false), style.get(), primitiveValueCache); + return primitiveValueCache->createValue(style->paddingLeft()); case CSSPropertyPageBreakAfter: - return CSSPrimitiveValue::create(style->pageBreakAfter()); + return primitiveValueCache->createValue(style->pageBreakAfter()); case CSSPropertyPageBreakBefore: - return CSSPrimitiveValue::create(style->pageBreakBefore()); + return primitiveValueCache->createValue(style->pageBreakBefore()); case CSSPropertyPageBreakInside: { EPageBreak pageBreak = style->pageBreakInside(); ASSERT(pageBreak != PBALWAYS); if (pageBreak == PBALWAYS) return 0; - return CSSPrimitiveValue::create(style->pageBreakInside()); + return primitiveValueCache->createValue(style->pageBreakInside()); } case CSSPropertyPosition: +<<<<<<< HEAD #ifdef ANDROID_LAYOUT if (settings && settings->layoutAlgorithm() == Settings::kLayoutSSR) return CSSPrimitiveValue::createIdentifier(CSSValueStatic); #endif return CSSPrimitiveValue::create(style->position()); +======= + return primitiveValueCache->createValue(style->position()); +>>>>>>> WebKit at r80534 case CSSPropertyRight: - return getPositionOffsetValue(style.get(), CSSPropertyRight); + return getPositionOffsetValue(style.get(), CSSPropertyRight, primitiveValueCache); case CSSPropertyTableLayout: - return CSSPrimitiveValue::create(style->tableLayout()); + return primitiveValueCache->createValue(style->tableLayout()); case CSSPropertyTextAlign: - return CSSPrimitiveValue::create(style->textAlign()); + return primitiveValueCache->createValue(style->textAlign()); case CSSPropertyTextDecoration: - return renderTextDecorationFlagsToCSSValue(style->textDecoration()); + return renderTextDecorationFlagsToCSSValue(style->textDecoration(), primitiveValueCache); case CSSPropertyWebkitTextDecorationsInEffect: - return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect()); + return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect(), primitiveValueCache); case CSSPropertyWebkitTextFillColor: return currentColorOrValidColor(style.get(), style->textFillColor()); case CSSPropertyWebkitTextEmphasisColor: return currentColorOrValidColor(style.get(), style->textEmphasisColor()); case CSSPropertyWebkitTextEmphasisPosition: - return CSSPrimitiveValue::create(style->textEmphasisPosition()); + return primitiveValueCache->createValue(style->textEmphasisPosition()); case CSSPropertyWebkitTextEmphasisStyle: switch (style->textEmphasisMark()) { case TextEmphasisMarkNone: - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); case TextEmphasisMarkCustom: - return CSSPrimitiveValue::create(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); + return primitiveValueCache->createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); case TextEmphasisMarkAuto: ASSERT_NOT_REACHED(); // Fall through @@ -1287,63 +1356,64 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case TextEmphasisMarkTriangle: case TextEmphasisMarkSesame: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); - list->append(CSSPrimitiveValue::create(style->textEmphasisFill())); - list->append(CSSPrimitiveValue::create(style->textEmphasisMark())); + list->append(primitiveValueCache->createValue(style->textEmphasisFill())); + list->append(primitiveValueCache->createValue(style->textEmphasisMark())); return list.release(); } } case CSSPropertyTextIndent: - return CSSPrimitiveValue::create(style->textIndent()); + return primitiveValueCache->createValue(style->textIndent()); case CSSPropertyTextShadow: return valueForShadow(style->textShadow(), propertyID, style.get()); case CSSPropertyTextRendering: - return CSSPrimitiveValue::create(style->fontDescription().textRenderingMode()); + return primitiveValueCache->createValue(style->fontDescription().textRenderingMode()); case CSSPropertyTextOverflow: if (style->textOverflow()) - return CSSPrimitiveValue::createIdentifier(CSSValueEllipsis); - return CSSPrimitiveValue::createIdentifier(CSSValueClip); + return primitiveValueCache->createIdentifierValue(CSSValueEllipsis); + return primitiveValueCache->createIdentifierValue(CSSValueClip); case CSSPropertyWebkitTextSecurity: - return CSSPrimitiveValue::create(style->textSecurity()); + return primitiveValueCache->createValue(style->textSecurity()); case CSSPropertyWebkitTextSizeAdjust: if (style->textSizeAdjust()) - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createIdentifierValue(CSSValueNone); case CSSPropertyWebkitTextStrokeColor: return currentColorOrValidColor(style.get(), style->textStrokeColor()); case CSSPropertyWebkitTextStrokeWidth: - return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get()); + return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get(), primitiveValueCache); case CSSPropertyTextTransform: - return CSSPrimitiveValue::create(style->textTransform()); + return primitiveValueCache->createValue(style->textTransform()); case CSSPropertyTop: - return getPositionOffsetValue(style.get(), CSSPropertyTop); + return getPositionOffsetValue(style.get(), CSSPropertyTop, primitiveValueCache); case CSSPropertyUnicodeBidi: - return CSSPrimitiveValue::create(style->unicodeBidi()); + return primitiveValueCache->createValue(style->unicodeBidi()); case CSSPropertyVerticalAlign: switch (style->verticalAlign()) { case BASELINE: - return CSSPrimitiveValue::createIdentifier(CSSValueBaseline); + return primitiveValueCache->createIdentifierValue(CSSValueBaseline); case MIDDLE: - return CSSPrimitiveValue::createIdentifier(CSSValueMiddle); + return primitiveValueCache->createIdentifierValue(CSSValueMiddle); case SUB: - return CSSPrimitiveValue::createIdentifier(CSSValueSub); + return primitiveValueCache->createIdentifierValue(CSSValueSub); case SUPER: - return CSSPrimitiveValue::createIdentifier(CSSValueSuper); + return primitiveValueCache->createIdentifierValue(CSSValueSuper); case TEXT_TOP: - return CSSPrimitiveValue::createIdentifier(CSSValueTextTop); + return primitiveValueCache->createIdentifierValue(CSSValueTextTop); case TEXT_BOTTOM: - return CSSPrimitiveValue::createIdentifier(CSSValueTextBottom); + return primitiveValueCache->createIdentifierValue(CSSValueTextBottom); case TOP: - return CSSPrimitiveValue::createIdentifier(CSSValueTop); + return primitiveValueCache->createIdentifierValue(CSSValueTop); case BOTTOM: - return CSSPrimitiveValue::createIdentifier(CSSValueBottom); + return primitiveValueCache->createIdentifierValue(CSSValueBottom); case BASELINE_MIDDLE: - return CSSPrimitiveValue::createIdentifier(CSSValueWebkitBaselineMiddle); + return primitiveValueCache->createIdentifierValue(CSSValueWebkitBaselineMiddle); case LENGTH: - return CSSPrimitiveValue::create(style->verticalAlignLength()); + return primitiveValueCache->createValue(style->verticalAlignLength()); } ASSERT_NOT_REACHED(); return 0; case CSSPropertyVisibility: +<<<<<<< HEAD #ifdef ANDROID_LAYOUT if (settings && settings->layoutAlgorithm() == Settings::kLayoutSSR) return CSSPrimitiveValue::createIdentifier(CSSValueVisible); @@ -1366,45 +1436,50 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper else #endif return CSSPrimitiveValue::create(style->whiteSpace()); +======= + return primitiveValueCache->createValue(style->visibility()); + case CSSPropertyWhiteSpace: + return primitiveValueCache->createValue(style->whiteSpace()); +>>>>>>> WebKit at r80534 case CSSPropertyWidows: - return CSSPrimitiveValue::create(style->widows(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWidth: if (renderer) - return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get()); - return zoomAdjustedPixelValueForLength(style->width(), style.get()); + return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get(), primitiveValueCache); + return zoomAdjustedPixelValueForLength(style->width(), style.get(), primitiveValueCache); case CSSPropertyWordBreak: - return CSSPrimitiveValue::create(style->wordBreak()); + return primitiveValueCache->createValue(style->wordBreak()); case CSSPropertyWordSpacing: - return zoomAdjustedPixelValue(style->wordSpacing(), style.get()); + return zoomAdjustedPixelValue(style->wordSpacing(), style.get(), primitiveValueCache); case CSSPropertyWordWrap: - return CSSPrimitiveValue::create(style->wordWrap()); + return primitiveValueCache->createValue(style->wordWrap()); case CSSPropertyWebkitLineBreak: - return CSSPrimitiveValue::create(style->khtmlLineBreak()); + return primitiveValueCache->createValue(style->khtmlLineBreak()); case CSSPropertyWebkitNbspMode: - return CSSPrimitiveValue::create(style->nbspMode()); + return primitiveValueCache->createValue(style->nbspMode()); case CSSPropertyWebkitMatchNearestMailBlockquoteColor: - return CSSPrimitiveValue::create(style->matchNearestMailBlockquoteColor()); + return primitiveValueCache->createValue(style->matchNearestMailBlockquoteColor()); case CSSPropertyResize: - return CSSPrimitiveValue::create(style->resize()); + return primitiveValueCache->createValue(style->resize()); case CSSPropertyWebkitFontSmoothing: - return CSSPrimitiveValue::create(style->fontDescription().fontSmoothing()); + return primitiveValueCache->createValue(style->fontDescription().fontSmoothing()); case CSSPropertyZIndex: if (style->hasAutoZIndex()) - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); - return CSSPrimitiveValue::create(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueAuto); + return primitiveValueCache->createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyZoom: - return CSSPrimitiveValue::create(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyBoxSizing: if (style->boxSizing() == CONTENT_BOX) - return CSSPrimitiveValue::createIdentifier(CSSValueContentBox); - return CSSPrimitiveValue::createIdentifier(CSSValueBorderBox); + return primitiveValueCache->createIdentifierValue(CSSValueContentBox); + return primitiveValueCache->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 CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache->createIdentifierValue(CSSValueNone); RefPtr<DashboardRegion> firstRegion; DashboardRegion* previousRegion = 0; @@ -1414,10 +1489,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper region->m_label = styleRegion.label; LengthBox offset = styleRegion.offset; - 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->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get(), primitiveValueCache)); + region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get(), primitiveValueCache)); + region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get(), primitiveValueCache)); + region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get(), primitiveValueCache)); region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle); @@ -1427,27 +1502,27 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper firstRegion = region; previousRegion = region.get(); } - return CSSPrimitiveValue::create(firstRegion.release()); + return primitiveValueCache->createValue(firstRegion.release()); } #endif case CSSPropertyWebkitAnimationDelay: - return getDelayValue(style->animations()); + return getDelayValue(style->animations(), primitiveValueCache); 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(CSSPrimitiveValue::createIdentifier(CSSValueAlternate)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueAlternate)); else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueNormal)); } } else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueNormal)); return list.release(); } case CSSPropertyWebkitAnimationDuration: - return getDurationValue(style->animations()); + return getDurationValue(style->animations(), primitiveValueCache); case CSSPropertyWebkitAnimationFillMode: { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->animations(); @@ -1455,21 +1530,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(CSSPrimitiveValue::createIdentifier(CSSValueNone)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueNone)); break; case AnimationFillModeForwards: - list->append(CSSPrimitiveValue::createIdentifier(CSSValueForwards)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueForwards)); break; case AnimationFillModeBackwards: - list->append(CSSPrimitiveValue::createIdentifier(CSSValueBackwards)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueBackwards)); break; case AnimationFillModeBoth: - list->append(CSSPrimitiveValue::createIdentifier(CSSValueBoth)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueBoth)); break; } } } else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueNone)); return list.release(); } case CSSPropertyWebkitAnimationIterationCount: { @@ -1479,12 +1554,12 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper for (size_t i = 0; i < t->size(); ++i) { int iterationCount = t->animation(i)->iterationCount(); if (iterationCount == Animation::IterationCountInfinite) - list->append(CSSPrimitiveValue::createIdentifier(CSSValueInfinite)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueInfinite)); else - list->append(CSSPrimitiveValue::create(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); + list->append(primitiveValueCache->createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); } } else - list->append(CSSPrimitiveValue::create(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); + list->append(primitiveValueCache->createValue(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); return list.release(); } case CSSPropertyWebkitAnimationName: { @@ -1492,9 +1567,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(CSSPrimitiveValue::create(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); + list->append(primitiveValueCache->createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING)); } else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueNone)); return list.release(); } case CSSPropertyWebkitAnimationPlayState: { @@ -1504,103 +1579,103 @@ 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(CSSPrimitiveValue::createIdentifier(CSSValueRunning)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueRunning)); else - list->append(CSSPrimitiveValue::createIdentifier(CSSValuePaused)); + list->append(primitiveValueCache->createIdentifierValue(CSSValuePaused)); } } else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueRunning)); return list.release(); } case CSSPropertyWebkitAnimationTimingFunction: return getTimingFunctionValue(style->animations()); case CSSPropertyWebkitAppearance: - return CSSPrimitiveValue::create(style->appearance()); + return primitiveValueCache->createValue(style->appearance()); case CSSPropertyWebkitBackfaceVisibility: - return CSSPrimitiveValue::createIdentifier((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); + return primitiveValueCache->createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible); case CSSPropertyWebkitBorderImage: - return valueForNinePieceImage(style->borderImage()); + return valueForNinePieceImage(style->borderImage(), primitiveValueCache); case CSSPropertyWebkitMaskBoxImage: - return valueForNinePieceImage(style->maskBoxImage()); + return valueForNinePieceImage(style->maskBoxImage(), primitiveValueCache); case CSSPropertyWebkitFontSizeDelta: // Not a real style property -- used by the editing engine -- so has no computed value. break; case CSSPropertyWebkitMarginBottomCollapse: case CSSPropertyWebkitMarginAfterCollapse: - return CSSPrimitiveValue::create(style->marginAfterCollapse()); + return primitiveValueCache->createValue(style->marginAfterCollapse()); case CSSPropertyWebkitMarginTopCollapse: case CSSPropertyWebkitMarginBeforeCollapse: - return CSSPrimitiveValue::create(style->marginBeforeCollapse()); + return primitiveValueCache->createValue(style->marginBeforeCollapse()); case CSSPropertyWebkitPerspective: if (!style->hasPerspective()) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); - return CSSPrimitiveValue::create(style->perspective(), CSSPrimitiveValue::CSS_NUMBER); + return primitiveValueCache->createIdentifierValue(CSSValueNone); + return primitiveValueCache->createValue(style->perspective(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyWebkitPerspectiveOrigin: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (renderer) { IntRect box = sizingBox(renderer); - list->append(zoomAdjustedPixelValue(style->perspectiveOriginX().calcMinValue(box.width()), style.get())); - list->append(zoomAdjustedPixelValue(style->perspectiveOriginY().calcMinValue(box.height()), style.get())); + list->append(zoomAdjustedPixelValue(style->perspectiveOriginX().calcMinValue(box.width()), style.get(), primitiveValueCache)); + list->append(zoomAdjustedPixelValue(style->perspectiveOriginY().calcMinValue(box.height()), style.get(), primitiveValueCache)); } else { - list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get())); - list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get())); + list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get(), primitiveValueCache)); + list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get(), primitiveValueCache)); } return list.release(); } case CSSPropertyWebkitRtlOrdering: if (style->visuallyOrdered()) - return CSSPrimitiveValue::createIdentifier(CSSValueVisual); - return CSSPrimitiveValue::createIdentifier(CSSValueLogical); + return primitiveValueCache->createIdentifierValue(CSSValueVisual); + return primitiveValueCache->createIdentifierValue(CSSValueLogical); case CSSPropertyWebkitUserDrag: - return CSSPrimitiveValue::create(style->userDrag()); + return primitiveValueCache->createValue(style->userDrag()); case CSSPropertyWebkitUserSelect: - return CSSPrimitiveValue::create(style->userSelect()); + return primitiveValueCache->createValue(style->userSelect()); case CSSPropertyBorderBottomLeftRadius: - return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get()); + return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), primitiveValueCache); case CSSPropertyBorderBottomRightRadius: - return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get()); + return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), primitiveValueCache); case CSSPropertyBorderTopLeftRadius: - return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get()); + return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), primitiveValueCache); case CSSPropertyBorderTopRightRadius: - return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get()); + return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), primitiveValueCache); case CSSPropertyClip: { if (!style->hasClip()) - return CSSPrimitiveValue::createIdentifier(CSSValueAuto); + return primitiveValueCache->createIdentifierValue(CSSValueAuto); RefPtr<Rect> rect = Rect::create(); - 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 CSSPrimitiveValue::create(rect.release()); + rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get(), primitiveValueCache)); + rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get(), primitiveValueCache)); + rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get(), primitiveValueCache)); + rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get(), primitiveValueCache)); + return primitiveValueCache->createValue(rect.release()); } case CSSPropertySpeak: - return CSSPrimitiveValue::create(style->speak()); + return primitiveValueCache->createValue(style->speak()); case CSSPropertyWebkitTransform: - return computedTransform(renderer, style.get()); + return computedTransform(renderer, style.get(), primitiveValueCache); case CSSPropertyWebkitTransformOrigin: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (renderer) { IntRect box = sizingBox(renderer); - list->append(zoomAdjustedPixelValue(style->transformOriginX().calcMinValue(box.width()), style.get())); - list->append(zoomAdjustedPixelValue(style->transformOriginY().calcMinValue(box.height()), style.get())); + list->append(zoomAdjustedPixelValue(style->transformOriginX().calcMinValue(box.width()), style.get(), primitiveValueCache)); + list->append(zoomAdjustedPixelValue(style->transformOriginY().calcMinValue(box.height()), style.get(), primitiveValueCache)); if (style->transformOriginZ() != 0) - list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get())); + list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), primitiveValueCache)); } else { - list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get())); - list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get())); + list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get(), primitiveValueCache)); + list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get(), primitiveValueCache)); if (style->transformOriginZ() != 0) - list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get())); + list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), primitiveValueCache)); } return list.release(); } case CSSPropertyWebkitTransformStyle: - return CSSPrimitiveValue::createIdentifier((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); + return primitiveValueCache->createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat); case CSSPropertyWebkitTransitionDelay: - return getDelayValue(style->transitions()); + return getDelayValue(style->transitions(), primitiveValueCache); case CSSPropertyWebkitTransitionDuration: - return getDurationValue(style->transitions()); + return getDurationValue(style->transitions(), primitiveValueCache); case CSSPropertyWebkitTransitionProperty: { RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); const AnimationList* t = style->transitions(); @@ -1609,27 +1684,34 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper int prop = t->animation(i)->property(); RefPtr<CSSValue> propertyValue; if (prop == cAnimateNone) - propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueNone); + propertyValue = primitiveValueCache->createIdentifierValue(CSSValueNone); else if (prop == cAnimateAll) - propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueAll); + propertyValue = primitiveValueCache->createIdentifierValue(CSSValueAll); else - propertyValue = CSSPrimitiveValue::create(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING); + propertyValue = primitiveValueCache->createValue(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING); list->append(propertyValue); } } else - list->append(CSSPrimitiveValue::createIdentifier(CSSValueAll)); + list->append(primitiveValueCache->createIdentifierValue(CSSValueAll)); return list.release(); } case CSSPropertyWebkitTransitionTimingFunction: return getTimingFunctionValue(style->transitions()); case CSSPropertyPointerEvents: - return CSSPrimitiveValue::create(style->pointerEvents()); + return primitiveValueCache->createValue(style->pointerEvents()); case CSSPropertyWebkitColorCorrection: - return CSSPrimitiveValue::create(style->colorSpace()); + return primitiveValueCache->createValue(style->colorSpace()); case CSSPropertyWebkitWritingMode: - return CSSPrimitiveValue::create(style->writingMode()); + return primitiveValueCache->createValue(style->writingMode()); case CSSPropertyWebkitTextCombine: - return CSSPrimitiveValue::create(style->textCombine()); + return primitiveValueCache->createValue(style->textCombine()); + + case CSSPropertyContent: + return contentToCSSValue(style.get(), primitiveValueCache); + case CSSPropertyCounterIncrement: + return counterToCSSValue(style.get(), propertyID, primitiveValueCache); + case CSSPropertyCounterReset: + return counterToCSSValue(style.get(), propertyID, primitiveValueCache); /* Shorthand properties, currently not supported see bug 13658*/ case CSSPropertyBackground: @@ -1645,9 +1727,15 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper case CSSPropertyFont: case CSSPropertyListStyle: case CSSPropertyMargin: + case CSSPropertyOutline: case CSSPropertyPadding: break; + /* Individual properties not part of the spec */ + case CSSPropertyBackgroundRepeatX: + case CSSPropertyBackgroundRepeatY: + break; + /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */ case CSSPropertyWebkitTextEmphasis: case CSSPropertyTextLineThrough: @@ -1708,13 +1796,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper break; /* Other unimplemented properties */ - case CSSPropertyBackgroundRepeatX: - case CSSPropertyBackgroundRepeatY: - case CSSPropertyContent: // FIXME: needs implementation, bug 23668 - case CSSPropertyCounterIncrement: - case CSSPropertyCounterReset: - case CSSPropertyOutline: // FIXME: needs implementation - case CSSPropertyOutlineOffset: // FIXME: needs implementation case CSSPropertyPage: // for @page case CSSPropertyQuotes: // FIXME: needs implementation case CSSPropertySize: // for @page diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.h b/Source/WebCore/css/CSSComputedStyleDeclaration.h index 718eb2d..4bf5a03 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.h +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.h @@ -22,9 +22,9 @@ #define CSSComputedStyleDeclaration_h #include "CSSStyleDeclaration.h" -#include "PlatformString.h" #include "RenderStyleConstants.h" #include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> namespace WebCore { @@ -34,6 +34,7 @@ class CSSPrimitiveValue; class Node; class RenderStyle; class ShadowData; +class SVGPaint; enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true }; @@ -76,7 +77,10 @@ private: PassRefPtr<CSSValue> valueForShadow(const ShadowData*, int, RenderStyle*) const; PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle*, const Color&) const; - +#if ENABLE(SVG) + PassRefPtr<SVGPaint> adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint>, RenderStyle*) const; +#endif + RefPtr<Node> m_node; PseudoId m_pseudoElementSpecifier; bool m_allowVisitedStyle; diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y index 03d25d9..8658674 100644 --- a/Source/WebCore/css/CSSGrammar.y +++ b/Source/WebCore/css/CSSGrammar.y @@ -857,8 +857,6 @@ selector: end = end->tagHistory(); end->setRelation(CSSSelector::Descendant); end->setTagHistory(p->sinkFloatingSelector($1)); - if (Document* doc = p->document()) - doc->setUsesDescendantRules(true); } } | selector combinator simple_selector { @@ -872,13 +870,6 @@ selector: end = end->tagHistory(); end->setRelation($2); end->setTagHistory(p->sinkFloatingSelector($1)); - if ($2 == CSSSelector::Child) { - if (Document* doc = p->document()) - doc->setUsesDescendantRules(true); - } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) { - if (Document* doc = p->document()) - doc->setUsesSiblingRules(true); - } } } | selector error { @@ -1102,48 +1093,14 @@ pseudo: CSSSelector::PseudoType type = $$->pseudoType(); if (type == CSSSelector::PseudoUnknown) $$ = 0; - else if (type == CSSSelector::PseudoEmpty || - type == CSSSelector::PseudoFirstChild || - type == CSSSelector::PseudoFirstOfType || - type == CSSSelector::PseudoLastChild || - type == CSSSelector::PseudoLastOfType || - type == CSSSelector::PseudoOnlyChild || - type == CSSSelector::PseudoOnlyOfType) { - CSSParser* p = static_cast<CSSParser*>(parser); - Document* doc = p->document(); - if (doc) - doc->setUsesSiblingRules(true); - } else if (type == CSSSelector::PseudoFirstLine) { - CSSParser* p = static_cast<CSSParser*>(parser); - if (Document* doc = p->document()) - doc->setUsesFirstLineRules(true); - } else if (type == CSSSelector::PseudoBefore || - type == CSSSelector::PseudoAfter) { - CSSParser* p = static_cast<CSSParser*>(parser); - if (Document* doc = p->document()) - doc->setUsesBeforeAfterRules(true); - } else if (type == CSSSelector::PseudoLink || type == CSSSelector::PseudoVisited) { - CSSParser* p = static_cast<CSSParser*>(parser); - if (Document* doc = p->document()) - doc->setUsesLinkRules(true); - } } | ':' ':' IDENT { $$ = static_cast<CSSParser*>(parser)->createFloatingSelector(); $$->setMatch(CSSSelector::PseudoElement); $3.lower(); $$->setValue($3); - CSSSelector::PseudoType type = $$->pseudoType(); - if (type == CSSSelector::PseudoFirstLine) { - CSSParser* p = static_cast<CSSParser*>(parser); - if (Document* doc = p->document()) - doc->setUsesFirstLineRules(true); - } else if (type == CSSSelector::PseudoBefore || - type == CSSSelector::PseudoAfter) { - CSSParser* p = static_cast<CSSParser*>(parser); - if (Document* doc = p->document()) - doc->setUsesBeforeAfterRules(true); - } + // FIXME: This call is needed to force selector to compute the pseudoType early enough. + $$->pseudoType(); } // used by :nth-*(ax+b) | ':' FUNCTION maybe_space NTH maybe_space ')' { @@ -1155,13 +1112,6 @@ pseudo: CSSSelector::PseudoType type = $$->pseudoType(); if (type == CSSSelector::PseudoUnknown) $$ = 0; - else if (type == CSSSelector::PseudoNthChild || - type == CSSSelector::PseudoNthOfType || - type == CSSSelector::PseudoNthLastChild || - type == CSSSelector::PseudoNthLastOfType) { - if (p->document()) - p->document()->setUsesSiblingRules(true); - } } // used by :nth-* | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' { @@ -1173,13 +1123,6 @@ pseudo: CSSSelector::PseudoType type = $$->pseudoType(); if (type == CSSSelector::PseudoUnknown) $$ = 0; - else if (type == CSSSelector::PseudoNthChild || - type == CSSSelector::PseudoNthOfType || - type == CSSSelector::PseudoNthLastChild || - type == CSSSelector::PseudoNthLastOfType) { - if (p->document()) - p->document()->setUsesSiblingRules(true); - } } // used by :nth-*(odd/even) and :lang | ':' FUNCTION maybe_space IDENT maybe_space ')' { @@ -1196,10 +1139,7 @@ pseudo: type == CSSSelector::PseudoNthOfType || type == CSSSelector::PseudoNthLastChild || type == CSSSelector::PseudoNthLastOfType) { - if (isValidNthToken($4)) { - if (p->document()) - p->document()->setUsesSiblingRules(true); - } else + if (!isValidNthToken($4)) $$ = 0; } } diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp index 573f4c0..e6a49d3 100644 --- a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp @@ -1,6 +1,7 @@ /* * (C) 1999-2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 Library General Public @@ -22,6 +23,7 @@ #include "CSSMutableStyleDeclaration.h" #include "CSSImageValue.h" +#include "CSSMutableValue.h" #include "CSSParser.h" #include "CSSPropertyLonghand.h" #include "CSSPropertyNames.h" @@ -31,7 +33,9 @@ #include "CSSValueList.h" #include "Document.h" #include "ExceptionCode.h" +#include "InspectorInstrumentation.h" #include "StyledElement.h" +#include <wtf/text/StringConcatenate.h> using namespace std; @@ -90,6 +94,17 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CS } } +CSSMutableStyleDeclaration::~CSSMutableStyleDeclaration() +{ + const CSSMutableStyleDeclarationConstIterator end = this->end(); + for (CSSMutableStyleDeclarationConstIterator it = begin(); it != end; ++it) { + CSSValue* value = it->value(); + if (!value || !value->isMutableValue()) + continue; + static_cast<CSSMutableValue*>(value)->setNode(0); + } +} + CSSMutableStyleDeclaration& CSSMutableStyleDeclaration::operator=(const CSSMutableStyleDeclaration& other) { ASSERT(!m_iteratorCount); @@ -107,6 +122,10 @@ String CSSMutableStyleDeclaration::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 }; @@ -269,6 +288,22 @@ String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const return String(); } +String CSSMutableStyleDeclaration::borderSpacingValue(const int properties[2]) const +{ + RefPtr<CSSValue> horizontalValue = getPropertyCSSValue(properties[0]); + RefPtr<CSSValue> verticalValue = getPropertyCSSValue(properties[1]); + + if (!horizontalValue) + return String(); + ASSERT(verticalValue); // By <http://www.w3.org/TR/CSS21/tables.html#separated-borders>. + + String horizontalValueCSSText = horizontalValue->cssText(); + String verticalValueCSSText = verticalValue->cssText(); + if (horizontalValueCSSText == verticalValueCSSText) + return horizontalValueCSSText; + return makeString(horizontalValueCSSText, ' ', verticalValueCSSText); +} + String CSSMutableStyleDeclaration::get4Values(const int* properties) const { // Assume the properties are in the usual order top, right, bottom, left. @@ -484,6 +519,8 @@ void CSSMutableStyleDeclaration::setNeedsStyleRecalc() if (isInlineStyleDeclaration) { m_node->setNeedsStyleRecalc(InlineStyleChange); static_cast<StyledElement*>(m_node)->invalidateStyleAttribute(); + if (m_node->document()) + InspectorInstrumentation::didInvalidateStyleAttr(m_node->document(), m_node); } else m_node->setNeedsStyleRecalc(FullStyleChange); return; diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.h b/Source/WebCore/css/CSSMutableStyleDeclaration.h index 35f1cc4..0eab1b6 100644 --- a/Source/WebCore/css/CSSMutableStyleDeclaration.h +++ b/Source/WebCore/css/CSSMutableStyleDeclaration.h @@ -57,6 +57,8 @@ private: class CSSMutableStyleDeclaration : public CSSStyleDeclaration { public: + virtual ~CSSMutableStyleDeclaration(); + static PassRefPtr<CSSMutableStyleDeclaration> create() { return adoptRef(new CSSMutableStyleDeclaration); @@ -154,6 +156,7 @@ private: String getCommonValue(const int* properties, int number) const; String getLayeredShorthandValue(const int* properties, unsigned number) const; String get4Values(const int* properties) const; + String borderSpacingValue(const int properties[2]) const; void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0); bool removeShorthandProperty(int propertyID, bool notifyChanged); diff --git a/Source/WebCore/css/CSSMutableValue.h b/Source/WebCore/css/CSSMutableValue.h new file mode 100644 index 0000000..8a3aa72 --- /dev/null +++ b/Source/WebCore/css/CSSMutableValue.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) Research In Motion Limited 2011. 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 CSSMutableValue_h +#define CSSMutableValue_h + +#include "CSSValue.h" +#include "Node.h" + +namespace WebCore { + +class CSSMutableValue : public CSSValue { +public: + CSSMutableValue() + : m_node(0) + { + } + + virtual ~CSSMutableValue() { } + virtual bool isMutableValue() const { return true; } + + Node* node() const { return m_node; } + void setNode(Node* node) { m_node = node; } + + void setNeedsStyleRecalc() + { + if (!m_node) + return; + m_node->setNeedsStyleRecalc(FullStyleChange); + } + +private: + Node* m_node; +}; + +} // namespace WebCore + +#endif // CSSMutableValue_h diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 55175a2..06e06e1 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -40,6 +40,7 @@ #include "CSSMutableStyleDeclaration.h" #include "CSSPageRule.h" #include "CSSPrimitiveValue.h" +#include "CSSPrimitiveValueCache.h" #include "CSSProperty.h" #include "CSSPropertyNames.h" #include "CSSPropertySourceData.h" @@ -225,10 +226,14 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int startLineNumber, StyleRuleRangeMap* ruleRangeMap) { +<<<<<<< HEAD #ifdef ANDROID_INSTRUMENT android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter); #endif m_styleSheet = sheet; +======= + setStyleSheet(sheet); +>>>>>>> WebKit at r80534 m_defaultNamespace = starAtom; // Reset the default namespace. m_ruleRangeMap = ruleRangeMap; if (ruleRangeMap) { @@ -249,10 +254,14 @@ void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int start PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string) { +<<<<<<< HEAD #ifdef ANDROID_INSTRUMENT android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter); #endif m_styleSheet = sheet; +======= + setStyleSheet(sheet); +>>>>>>> WebKit at r80534 m_allowNamespaceDeclarations = false; setupParser("@-webkit-rule{", string, "} "); cssyyparse(this); @@ -264,10 +273,14 @@ PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& str PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string) { +<<<<<<< HEAD #ifdef ANDROID_INSTRUMENT android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter); #endif m_styleSheet = sheet; +======= + setStyleSheet(sheet); +>>>>>>> WebKit at r80534 setupParser("@-webkit-keyframe-rule{ ", string, "} "); cssyyparse(this); #ifdef ANDROID_INSTRUMENT @@ -282,7 +295,7 @@ bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int id, cons android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter); #endif ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); - m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet())); setupParser("@-webkit-value{", string, "} "); @@ -341,7 +354,7 @@ bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter); #endif ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); - m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet())); setupParser("@-webkit-decls{color:", string, "} "); cssyyparse(this); @@ -376,7 +389,7 @@ void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorLi #endif RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc); - m_styleSheet = dummyStyleSheet.get(); + setStyleSheet(dummyStyleSheet.get()); m_selectorListForParseSelector = &selectorList; setupParser("@-webkit-selector{", string, "}"); @@ -403,7 +416,7 @@ bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const static const unsigned prefixLength = 15; ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet()); - m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet()); + setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet())); if (styleSourceData) { m_currentRuleData = CSSRuleSourceData::create(); m_currentRuleData->styleSourceData = CSSStyleSourceData::create(); @@ -501,6 +514,12 @@ void CSSParser::clearProperties() m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES; m_hasFontFaceOnlyValues = false; } + +void CSSParser::setStyleSheet(CSSStyleSheet* styleSheet) +{ + m_styleSheet = styleSheet; + m_primitiveValueCache = document() ? document()->cssPrimitiveValueCache() : CSSPrimitiveValueCache::create(); +} Document* CSSParser::document() const { @@ -688,6 +707,8 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyQuotes: // [<string> <string>]+ | none | inherit if (id) validPrimitive = true; + else + return parseQuotes(propId, important); break; case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | inherit if (id == CSSValueNormal || @@ -958,9 +979,9 @@ bool CSSParser::parseValue(int propId, bool important) if (list->length() != 1) return false; } else if (!m_strict && value->id == CSSValueHand) // MSIE 5 compatibility :/ - list->append(CSSPrimitiveValue::createIdentifier(CSSValuePointer)); + list->append(primitiveValueCache()->createIdentifierValue(CSSValuePointer)); else if (value && ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)) - list->append(CSSPrimitiveValue::createIdentifier(value->id)); + list->append(primitiveValueCache()->createIdentifierValue(value->id)); m_valueList->next(); parsedValue = list.release(); break; @@ -1217,7 +1238,7 @@ bool CSSParser::parseValue(int propId, bool important) case CSSValueUnderline: case CSSValueOverline: case CSSValueLineThrough: - list->append(CSSPrimitiveValue::createIdentifier(value->id)); + list->append(primitiveValueCache()->createIdentifierValue(value->id)); break; default: isValid = false; @@ -1276,19 +1297,19 @@ bool CSSParser::parseValue(int propId, bool important) validPrimitive = validUnit(value, FLength | FPercent, m_strict); if (!validPrimitive) return false; - RefPtr<CSSPrimitiveValue> parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + RefPtr<CSSPrimitiveValue> parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); RefPtr<CSSPrimitiveValue> parsedValue2; if (num == 2) { value = m_valueList->next(); validPrimitive = validUnit(value, FLength | FPercent, m_strict); if (!validPrimitive) return false; - parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); } else parsedValue2 = parsedValue1; RefPtr<Pair> pair = Pair::create(parsedValue1.release(), parsedValue2.release()); - RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(pair.release()); + RefPtr<CSSPrimitiveValue> val = primitiveValueCache()->createValue(pair.release()); addProperty(propId, val.release(), important); return true; } @@ -1467,7 +1488,7 @@ bool CSSParser::parseValue(int propId, bool important) else { // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property. if (validUnit(value, FNumber | FLength | FNonNeg, m_strict)) { - RefPtr<CSSValue> val = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + RefPtr<CSSValue> val = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); if (val) { addProperty(propId, val.release(), important); return true; @@ -1651,7 +1672,13 @@ bool CSSParser::parseValue(int propId, bool important) validPrimitive = true; break; - case CSSPropertyWebkitHyphenateLocale: + case CSSPropertyWebkitHyphenateLimitBefore: + case CSSPropertyWebkitHyphenateLimitAfter: + if (id == CSSValueAuto || validUnit(value, FInteger | FNonNeg, true)) + validPrimitive = true; + break; + + case CSSPropertyWebkitLocale: if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING) validPrimitive = true; break; @@ -1918,13 +1945,13 @@ bool CSSParser::parseValue(int propId, bool important) if (validPrimitive) { if (id != 0) - parsedValue = CSSPrimitiveValue::createIdentifier(id); + parsedValue = primitiveValueCache()->createIdentifierValue(id); else if (value->unit == CSSPrimitiveValue::CSS_STRING) - parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); + parsedValue = primitiveValueCache()->createValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) - parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); else if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS) - parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); else if (value->unit >= CSSParserValue::Q_EMS) parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS); m_valueList->next(); @@ -1948,7 +1975,7 @@ PassRefPtr<CSSValue> CSSParser::parseWCSSInputProperty() inputProperty = String(value->string); if (!inputProperty.isEmpty()) - parsedValue = CSSPrimitiveValue::create(inputProperty, CSSPrimitiveValue::CSS_STRING); + parsedValue = primitiveValueCache()->createValue(inputProperty, CSSPrimitiveValue::CSS_STRING); while (m_valueList->next()) { // pass all other values, if any. If we don't do this, @@ -1976,11 +2003,11 @@ void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval) lval = rval; } -static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue) +static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue, CSSPrimitiveValueCache* primitiveValueCache) { if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) { - cssValue = CSSPrimitiveValue::createIdentifier(parserValue->id); + cssValue = primitiveValueCache->createIdentifierValue(parserValue->id); return true; } return false; @@ -2048,7 +2075,7 @@ 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)) + if (parseBackgroundClip(parserValue, val1, primitiveValueCache())) addFillValue(clipValue, val1.release()); // The property parsed successfully. else addFillValue(clipValue, CSSInitialValue::createImplicit()); // Some value was used for origin that is not supported by clip. Just reset clip instead. @@ -2365,10 +2392,10 @@ bool CSSParser::parsePage(int propId, bool important) return false; if (value->id == CSSValueAuto) { - addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important); + addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important); return true; } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) { - addProperty(propId, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important); + addProperty(propId, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important); return true; } return false; @@ -2410,14 +2437,14 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV switch (value->id) { case CSSValueAuto: if (prevParamType == None) { - parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id)); + parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id)); return Auto; } return None; case CSSValueLandscape: case CSSValuePortrait: if (prevParamType == None || prevParamType == PageSize) { - parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id)); + parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id)); return Orientation; } return None; @@ -2432,13 +2459,13 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV 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(CSSPrimitiveValue::createIdentifier(value->id)); + parsedValues->prepend(primitiveValueCache()->createIdentifierValue(value->id)); return PageSize; } return None; case 0: if (validUnit(value, FLength | FNonNeg, m_strict) && (prevParamType == None || prevParamType == Length)) { - parsedValues->append(CSSPrimitiveValue::create(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); + parsedValues->append(primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit))); return Length; } return None; @@ -2447,6 +2474,28 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV } } +// [ <string> <string> ]+ | inherit | none +// inherit and none are handled in parseValue. +bool CSSParser::parseQuotes(int propId, bool important) +{ + RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated(); + while (CSSParserValue* val = m_valueList->current()) { + RefPtr<CSSValue> parsedValue; + if (val->unit == CSSPrimitiveValue::CSS_STRING) + parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING); + else + break; + values->append(parsedValue.release()); + m_valueList->next(); + } + if (values->length()) { + addProperty(propId, values.release(), important); + m_valueList->next(); + return true; + } + return false; +} + // [ <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 @@ -2499,10 +2548,10 @@ bool CSSParser::parseContent(int propId, bool important) case CSSValueNoCloseQuote: case CSSValueNone: case CSSValueNormal: - parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->createIdentifierValue(val->id); } } else if (val->unit == CSSPrimitiveValue::CSS_STRING) { - parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING); + parsedValue = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING); } if (!parsedValue) break; @@ -2539,7 +2588,7 @@ PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args) if (document() && document()->isHTMLDocument()) attrName = attrName.lower(); - return CSSPrimitiveValue::create(attrName, CSSPrimitiveValue::CSS_ATTR); + return primitiveValueCache()->createValue(attrName, CSSPrimitiveValue::CSS_ATTR); } PassRefPtr<CSSValue> CSSParser::parseBackgroundColor() @@ -2547,7 +2596,7 @@ 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 CSSPrimitiveValue::createIdentifier(id); + return primitiveValueCache()->createIdentifierValue(id); return parseColor(); } @@ -2593,10 +2642,10 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionXY(CSSParserValueList* valueLis else if (id == CSSValueCenter) // Center is ambiguous, so we're not sure which position we've found yet, an x or a y. percent = 50; - return CSSPrimitiveValue::create(percent, CSSPrimitiveValue::CSS_PERCENTAGE); + return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE); } if (validUnit(valueList->current(), FPercent | FLength, m_strict)) - return CSSPrimitiveValue::create(valueList->current()->fValue, + return primitiveValueCache()->createValue(valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)valueList->current()->unit); return 0; @@ -2639,7 +2688,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 = CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PERCENTAGE); + value2 = primitiveValueCache()->createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE); if (value1IsY || value2IsX) value1.swap(value2); @@ -2652,20 +2701,20 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu int id = m_valueList->current()->id; if (id == CSSValueRepeatX) { m_implicitShorthand = true; - value1 = CSSPrimitiveValue::createIdentifier(CSSValueRepeat); - value2 = CSSPrimitiveValue::createIdentifier(CSSValueNoRepeat); + value1 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat); + value2 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat); m_valueList->next(); return; } if (id == CSSValueRepeatY) { m_implicitShorthand = true; - value1 = CSSPrimitiveValue::createIdentifier(CSSValueNoRepeat); - value2 = CSSPrimitiveValue::createIdentifier(CSSValueRepeat); + value1 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat); + value2 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat); m_valueList->next(); return; } if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) - value1 = CSSPrimitiveValue::createIdentifier(id); + value1 = primitiveValueCache()->createIdentifierValue(id); else { value1 = 0; return; @@ -2681,12 +2730,12 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu id = m_valueList->current()->id; if (value && (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)) { - value2 = CSSPrimitiveValue::createIdentifier(id); + value2 = primitiveValueCache()->createIdentifierValue(id); m_valueList->next(); } else { // If only one value was specified, value2 is the same as value1. m_implicitShorthand = true; - value2 = CSSPrimitiveValue::createIdentifier(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent()); + value2 = primitiveValueCache()->createIdentifierValue(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent()); } } @@ -2696,39 +2745,39 @@ PassRefPtr<CSSValue> CSSParser::parseFillSize(int propId, bool& allowComma) CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueContain || value->id == CSSValueCover) - return CSSPrimitiveValue::createIdentifier(value->id); + return primitiveValueCache()->createIdentifierValue(value->id); RefPtr<CSSPrimitiveValue> parsedValue1; if (value->id == CSSValueAuto) - parsedValue1 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN); + parsedValue1 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN); else { if (!validUnit(value, FLength | FPercent, m_strict)) return 0; - parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); } CSSPropertyID property = static_cast<CSSPropertyID>(propId); RefPtr<CSSPrimitiveValue> parsedValue2; if ((value = m_valueList->next())) { if (value->id == CSSValueAuto) - parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN); + parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN); else if (value->unit == CSSParserValue::Operator && value->iValue == ',') allowComma = false; else { if (!validUnit(value, FLength | FPercent, m_strict)) return 0; - parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); } } if (!parsedValue2) { if (property == CSSPropertyWebkitBackgroundSize || property == CSSPropertyWebkitMaskSize) parsedValue2 = parsedValue1; else - parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN); + parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN); } - return CSSPrimitiveValue::create(Pair::create(parsedValue1.release(), parsedValue2.release())); + return primitiveValueCache()->createValue(Pair::create(parsedValue1.release(), parsedValue2.release())); } bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2, @@ -2779,7 +2828,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 = CSSPrimitiveValue::createIdentifier(val->id); + currValue = primitiveValueCache()->createIdentifierValue(val->id); m_valueList->next(); } break; @@ -2798,17 +2847,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 = CSSPrimitiveValue::createIdentifier(val->id); + currValue = primitiveValueCache()->createIdentifierValue(val->id); m_valueList->next(); } break; case CSSPropertyBackgroundClip: - if (parseBackgroundClip(val, currValue)) + if (parseBackgroundClip(val, currValue, primitiveValueCache())) m_valueList->next(); break; case CSSPropertyBackgroundOrigin: if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) { - currValue = CSSPrimitiveValue::createIdentifier(val->id); + currValue = primitiveValueCache()->createIdentifierValue(val->id); m_valueList->next(); } break; @@ -2836,7 +2885,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 = CSSPrimitiveValue::createIdentifier(val->id); + currValue = primitiveValueCache()->createIdentifierValue(val->id); m_valueList->next(); } break; @@ -2903,7 +2952,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDelay() { CSSParserValue* value = m_valueList->current(); if (validUnit(value, FTime, m_strict)) - return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); return 0; } @@ -2911,7 +2960,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDirection() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNormal || value->id == CSSValueAlternate) - return CSSPrimitiveValue::createIdentifier(value->id); + return primitiveValueCache()->createIdentifierValue(value->id); return 0; } @@ -2919,7 +2968,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDuration() { CSSParserValue* value = m_valueList->current(); if (validUnit(value, FTime | FNonNeg, m_strict)) - return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); return 0; } @@ -2927,7 +2976,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth) - return CSSPrimitiveValue::createIdentifier(value->id); + return primitiveValueCache()->createIdentifierValue(value->id); return 0; } @@ -2935,9 +2984,9 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueInfinite) - return CSSPrimitiveValue::createIdentifier(value->id); + return primitiveValueCache()->createIdentifierValue(value->id); if (validUnit(value, FInteger | FNonNeg, m_strict)) - return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); + return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit); return 0; } @@ -2946,9 +2995,9 @@ 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 CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache()->createIdentifierValue(CSSValueNone); } else { - return CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING); + return primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING); } } return 0; @@ -2958,7 +3007,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState() { CSSParserValue* value = m_valueList->current(); if (value->id == CSSValueRunning || value->id == CSSValuePaused) - return CSSPrimitiveValue::createIdentifier(value->id); + return primitiveValueCache()->createIdentifierValue(value->id); return 0; } @@ -2969,11 +3018,11 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationProperty() return 0; int result = cssPropertyID(value->string); if (result) - return CSSPrimitiveValue::createIdentifier(result); + return primitiveValueCache()->createIdentifierValue(result); if (equalIgnoringCase(value->string, "all")) - return CSSPrimitiveValue::createIdentifier(CSSValueAll); + return primitiveValueCache()->createIdentifierValue(CSSValueAll); if (equalIgnoringCase(value->string, "none")) - return CSSPrimitiveValue::createIdentifier(CSSValueNone); + return primitiveValueCache()->createIdentifierValue(CSSValueNone); return 0; } @@ -2984,7 +3033,7 @@ bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<C // now get z if (m_valueList->current()) { if (validUnit(m_valueList->current(), FLength, m_strict)) { - value3 = CSSPrimitiveValue::create(m_valueList->current()->fValue, + value3 = primitiveValueCache()->createValue(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit); m_valueList->next(); return true; @@ -3017,7 +3066,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 CSSPrimitiveValue::createIdentifier(value->id); + return primitiveValueCache()->createIdentifierValue(value->id); // We must be a function. if (value->unit != CSSParserValue::Function) @@ -3207,7 +3256,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) if (value->id == CSSValueNone) { if (m_valueList->next()) return false; - addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important); + addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important); return valid; } @@ -3277,7 +3326,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 = CSSPrimitiveValue::createIdentifier(CSSValueInvalid); + RefPtr<CSSPrimitiveValue> amount = primitiveValueCache()->createIdentifierValue(CSSValueInvalid); region->setTop(amount); region->setRight(amount); @@ -3295,8 +3344,8 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) break; RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ? - CSSPrimitiveValue::createIdentifier(CSSValueAuto) : - CSSPrimitiveValue::create(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit); + primitiveValueCache()->createIdentifierValue(CSSValueAuto) : + primitiveValueCache()->createValue(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit); if (i == 0) region->setTop(amount); @@ -3316,7 +3365,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important) } if (valid) - addProperty(propId, CSSPrimitiveValue::create(firstRegion.release()), important); + addProperty(propId, primitiveValueCache()->createValue(firstRegion.release()), important); return valid; } @@ -3334,11 +3383,11 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo CSSParserValue* i = args->current(); if (i->unit != CSSPrimitiveValue::CSS_IDENT) return 0; - RefPtr<CSSPrimitiveValue> identifier = CSSPrimitiveValue::create(i->string, CSSPrimitiveValue::CSS_STRING); + RefPtr<CSSPrimitiveValue> identifier = primitiveValueCache()->createValue(i->string, CSSPrimitiveValue::CSS_STRING); RefPtr<CSSPrimitiveValue> separator; if (!counters) - separator = CSSPrimitiveValue::create(String(), CSSPrimitiveValue::CSS_STRING); + separator = primitiveValueCache()->createValue(String(), CSSPrimitiveValue::CSS_STRING); else { i = args->next(); if (i->unit != CSSParserValue::Operator || i->iValue != ',') @@ -3348,13 +3397,13 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo if (i->unit != CSSPrimitiveValue::CSS_STRING) return 0; - separator = CSSPrimitiveValue::create(i->string, (CSSPrimitiveValue::UnitTypes) i->unit); + separator = primitiveValueCache()->createValue(i->string, (CSSPrimitiveValue::UnitTypes) i->unit); } RefPtr<CSSPrimitiveValue> listStyle; i = args->next(); if (!i) // Make the list style default decimal - listStyle = CSSPrimitiveValue::create(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER); + listStyle = primitiveValueCache()->createValue(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER); else { if (i->unit != CSSParserValue::Operator || i->iValue != ',') return 0; @@ -3371,10 +3420,10 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo else return 0; - listStyle = CSSPrimitiveValue::create(ls, (CSSPrimitiveValue::UnitTypes) i->unit); + listStyle = primitiveValueCache()->createValue(ls, (CSSPrimitiveValue::UnitTypes) i->unit); } - return CSSPrimitiveValue::create(Counter::create(identifier.release(), listStyle.release(), separator.release())); + return primitiveValueCache()->createValue(Counter::create(identifier.release(), listStyle.release(), separator.release())); } bool CSSParser::parseShape(int propId, bool important) @@ -3397,8 +3446,8 @@ bool CSSParser::parseShape(int propId, bool important) if (!valid) break; RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ? - CSSPrimitiveValue::createIdentifier(CSSValueAuto) : - CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit); + primitiveValueCache()->createIdentifierValue(CSSValueAuto) : + primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit); if (i == 0) rect->setTop(length); else if (i == 1) @@ -3419,7 +3468,7 @@ bool CSSParser::parseShape(int propId, bool important) i++; } if (valid) { - addProperty(propId, CSSPrimitiveValue::create(rect.release()), important); + addProperty(propId, primitiveValueCache()->createValue(rect.release()), important); m_valueList->next(); return true; } @@ -3441,15 +3490,15 @@ bool CSSParser::parseFont(bool important) } else if (id == CSSValueItalic || id == CSSValueOblique) { if (font->style) return false; - font->style = CSSPrimitiveValue::createIdentifier(id); + font->style = primitiveValueCache()->createIdentifierValue(id); } else if (id == CSSValueSmallCaps) { if (font->variant) return false; - font->variant = CSSPrimitiveValue::createIdentifier(id); + font->variant = primitiveValueCache()->createIdentifierValue(id); } else if (id >= CSSValueBold && id <= CSSValueLighter) { if (font->weight) return false; - font->weight = CSSPrimitiveValue::createIdentifier(id); + font->weight = primitiveValueCache()->createIdentifierValue(id); } else { valid = false; } @@ -3476,7 +3525,7 @@ bool CSSParser::parseFont(bool important) val = CSSValue900; if (val) - font->weight = CSSPrimitiveValue::createIdentifier(val); + font->weight = primitiveValueCache()->createIdentifierValue(val); else valid = false; } else { @@ -3491,18 +3540,18 @@ bool CSSParser::parseFont(bool important) // set undefined values to default if (!font->style) - font->style = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + font->style = primitiveValueCache()->createIdentifierValue(CSSValueNormal); if (!font->variant) - font->variant = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + font->variant = primitiveValueCache()->createIdentifierValue(CSSValueNormal); if (!font->weight) - font->weight = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + font->weight = primitiveValueCache()->createIdentifierValue(CSSValueNormal); // now a font size _must_ come // <absolute-size> | <relative-size> | <length> | <percentage> | inherit if (value->id >= CSSValueXxSmall && value->id <= CSSValueLarger) - font->size = CSSPrimitiveValue::createIdentifier(value->id); + font->size = primitiveValueCache()->createIdentifierValue(value->id); else if (validUnit(value, FLength | FPercent | FNonNeg, m_strict)) - font->size = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + font->size = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); value = m_valueList->next(); if (!font->size || !value) return false; @@ -3515,7 +3564,7 @@ bool CSSParser::parseFont(bool important) if (value->id == CSSValueNormal) { // default value, nothing to do } else if (validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict)) - font->lineHeight = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); + font->lineHeight = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); else return false; value = m_valueList->next(); @@ -3524,7 +3573,7 @@ bool CSSParser::parseFont(bool important) } if (!font->lineHeight) - font->lineHeight = CSSPrimitiveValue::createIdentifier(CSSValueNormal); + font->lineHeight = primitiveValueCache()->createIdentifierValue(CSSValueNormal); // font family must come now font->family = parseFontFamily(); @@ -3554,7 +3603,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily() if (currFamily) currFamily->appendSpaceSeparated(value->string.characters, value->string.length); else if (nextValBreaksFont || !nextValIsFontName) - list->append(CSSPrimitiveValue::createIdentifier(value->id)); + list->append(primitiveValueCache()->createIdentifierValue(value->id)); else { RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string); currFamily = newFamily.get(); @@ -3607,12 +3656,12 @@ bool CSSParser::parseFontStyle(bool important) if (!expectComma) { expectComma = true; if (val->id == CSSValueNormal || val->id == CSSValueItalic || val->id == CSSValueOblique) - parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->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 = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->createIdentifierValue(val->id); } } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { expectComma = false; @@ -3654,12 +3703,12 @@ bool CSSParser::parseFontVariant(bool important) if (!expectComma) { expectComma = true; if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps) - parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->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 = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->createIdentifierValue(val->id); } } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { expectComma = false; @@ -3702,17 +3751,17 @@ bool CSSParser::parseFontWeight(bool important) expectComma = true; if (val->unit == CSSPrimitiveValue::CSS_IDENT) { if (val->id >= CSSValueNormal && val->id <= CSSValue900) - parsedValue = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->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 = CSSPrimitiveValue::createIdentifier(val->id); + parsedValue = primitiveValueCache()->createIdentifierValue(val->id); } } else if (validUnit(val, FInteger | FNonNeg, false)) { int weight = static_cast<int>(val->fValue); if (!(weight % 100) && weight >= 100 && weight <= 900) - parsedValue = CSSPrimitiveValue::createIdentifier(CSSValue100 + weight / 100 - 1); + parsedValue = primitiveValueCache()->createIdentifierValue(CSSValue100 + weight / 100 - 1); } } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') { expectComma = false; @@ -3950,46 +3999,75 @@ static inline bool isTenthAlpha(const UChar* string, const int length) return false; } +static inline bool isValidDouble(const UChar* string, const int length) +{ + bool decimalMarkSeen = false; + for (int i = 0; i < length; ++i) { + if (!isASCIIDigit(string[i])) { + if (!decimalMarkSeen && string[i] == '.') + decimalMarkSeen = true; + else + return false; + } + } + return true; +} + static inline bool parseAlphaValue(const UChar*& string, const UChar* end, UChar terminator, int& value) { while (string != end && isHTMLSpace(*string)) string++; + bool negative = false; + + if (string != end && *string == '-') { + negative = true; + string++; + } + value = 0; int length = end - string; if (length < 2) return false; - if (string[0] != '0' && string[0] != '1' && string[0] != '.') + if (string[length - 1] != terminator) return false; - if (string[length - 1] != terminator) + if (string[0] != '0' && string[0] != '1' && string[0] != '.') { + if (isValidDouble(string, length - 1)) { + value = negative ? 0 : 255; + string = end; + return true; + } return false; + } if (length == 2 && string[0] != '.') { - value = string[0] == '1' ? 255 : 0; + value = !negative && string[0] == '1' ? 255 : 0; string = end; return true; } if (isTenthAlpha(string, length - 1)) { static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 }; - value = tenthAlphaValues[string[length - 2] - '0']; + value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0']; string = end; return true; } + if (!isValidDouble(string, length - 1)) + return false; + Vector<char, 8> bytes(length + 1); - for (int i = 0; i < length; ++i) { - if (!isASCIIDigit(string[i]) && string[i] != '.' && string[i] != terminator) - return false; + + for (int i = 0; i < length; ++i) bytes[i] = string[i]; - } + bytes[length] = '\0'; char* foundTerminator; double d = WTF::strtod(bytes.data(), &foundTerminator); - value = static_cast<int>(d * nextafter(256.0, 0.0)); + value = negative ? 0 : static_cast<int>(d * nextafter(256.0, 0.0)); string += (foundTerminator - bytes.data()) + 1; return *foundTerminator == terminator; } @@ -4174,7 +4252,7 @@ PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value) RGBA32 c = Color::transparent; if (!parseColorFromValue(value ? value : m_valueList->current(), c)) return 0; - return CSSPrimitiveValue::createColor(c); + return primitiveValueCache()->createColorValue(c); } bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c) @@ -4232,8 +4310,9 @@ bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c) // This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return) // without the allowBreak bit being set, then it will clean up all of the objects and destroy them. struct ShadowParseContext { - ShadowParseContext(CSSPropertyID prop) + ShadowParseContext(CSSPropertyID prop, CSSPrimitiveValueCache* primitiveValueCache) : property(prop) + , m_primitiveValueCache(primitiveValueCache) , allowX(true) , allowY(false) , allowBlur(false) @@ -4276,7 +4355,7 @@ struct ShadowParseContext { void commitLength(CSSParserValue* v) { - RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit); + RefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit); if (allowX) { x = val.release(); @@ -4318,7 +4397,7 @@ struct ShadowParseContext { void commitStyle(CSSParserValue* v) { - style = CSSPrimitiveValue::createIdentifier(v->id); + style = m_primitiveValueCache->createIdentifierValue(v->id); allowStyle = false; if (allowX) allowBreak = false; @@ -4330,6 +4409,7 @@ struct ShadowParseContext { } CSSPropertyID property; + CSSPrimitiveValueCache* m_primitiveValueCache; RefPtr<CSSValueList> values; RefPtr<CSSPrimitiveValue> x; @@ -4350,7 +4430,7 @@ struct ShadowParseContext { bool CSSParser::parseShadow(int propId, bool important) { - ShadowParseContext context(static_cast<CSSPropertyID>(propId)); + ShadowParseContext context(static_cast<CSSPropertyID>(propId), primitiveValueCache()); CSSParserValue* val; while ((val = m_valueList->current())) { // Check for a comma break first. @@ -4386,7 +4466,7 @@ bool CSSParser::parseShadow(int propId, bool important) if (isColor) { if (!context.allowColor) return false; - parsedColor = CSSPrimitiveValue::createIdentifier(val->id); + parsedColor = primitiveValueCache()->createIdentifierValue(val->id); } if (!parsedColor) @@ -4443,11 +4523,11 @@ bool CSSParser::parseReflect(int propId, bool important) val = m_valueList->next(); RefPtr<CSSPrimitiveValue> offset; if (!val) - offset = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX); + offset = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_PX); else { if (!validUnit(val, FLength | FPercent, m_strict)) return false; - offset = CSSPrimitiveValue::create(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit)); + offset = primitiveValueCache()->createValue(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit)); } // Now for the mask. @@ -4465,8 +4545,9 @@ bool CSSParser::parseReflect(int propId, bool important) } struct BorderImageParseContext { - BorderImageParseContext() - : m_allowBreak(false) + BorderImageParseContext(CSSPrimitiveValueCache* primitiveValueCache) + : m_primitiveValueCache(primitiveValueCache) + , m_allowBreak(false) , m_allowNumber(false) , m_allowSlash(false) , m_allowWidth(false) @@ -4488,7 +4569,7 @@ struct BorderImageParseContext { void commitImage(PassRefPtr<CSSValue> image) { m_image = image; m_allowNumber = true; } void commitNumber(CSSParserValue* v) { - PassRefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit); + PassRefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit); if (!m_top) m_top = val; else if (!m_right) @@ -4532,16 +4613,16 @@ struct BorderImageParseContext { { // We need to clone and repeat values for any omissions. if (!m_right) { - m_right = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); - m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); - m_left = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_right = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_left = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); } if (!m_bottom) { - m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); - m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType()); + m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType()); + m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType()); } if (!m_left) - m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType()); + m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType()); // Now build a rect value to hold all four of our primitive values. RefPtr<Rect> rect = Rect::create(); @@ -4578,6 +4659,8 @@ struct BorderImageParseContext { // Make our new border image value now. return CSSBorderImageValue::create(m_image, rect.release(), m_horizontalRule, m_verticalRule); } + + CSSPrimitiveValueCache* m_primitiveValueCache; bool m_allowBreak; bool m_allowNumber; @@ -4604,7 +4687,7 @@ struct BorderImageParseContext { bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& result) { // Look for an image initially. If the first value is not a URI, then we're done. - BorderImageParseContext context; + BorderImageParseContext context(primitiveValueCache()); CSSParserValue* val = m_valueList->current(); if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) { // FIXME: The completeURL call should be done when using the CSSImageValue, @@ -4638,7 +4721,7 @@ bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& r if (context.allowNumber() && propId != CSSPropertyWebkitBorderImage) { // Allow the slices to be omitted for images that don't fit to a border. We just set the slices to be 0. - context.m_top = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER); + context.m_top = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER); context.m_allowBreak = true; } @@ -4693,7 +4776,7 @@ bool CSSParser::parseBorderRadius(int propId, bool important) if (!validUnit(value, FLength | FPercent, m_strict)) return false; - RefPtr<CSSPrimitiveValue> radius = CSSPrimitiveValue::create(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); + RefPtr<CSSPrimitiveValue> radius = primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)); if (!indexAfterSlash) { radii[0][i] = radius; @@ -4715,10 +4798,10 @@ bool CSSParser::parseBorderRadius(int propId, bool important) completeBorderRadii(radii[1]); m_implicitShorthand = true; - addProperty(CSSPropertyBorderTopLeftRadius, CSSPrimitiveValue::create(Pair::create(radii[0][0].release(), radii[1][0].release())), important); - addProperty(CSSPropertyBorderTopRightRadius, CSSPrimitiveValue::create(Pair::create(radii[0][1].release(), radii[1][1].release())), important); - addProperty(CSSPropertyBorderBottomRightRadius, CSSPrimitiveValue::create(Pair::create(radii[0][2].release(), radii[1][2].release())), important); - addProperty(CSSPropertyBorderBottomLeftRadius, CSSPrimitiveValue::create(Pair::create(radii[0][3].release(), radii[1][3].release())), important); + addProperty(CSSPropertyBorderTopLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][0].release(), radii[1][0].release())), important); + addProperty(CSSPropertyBorderTopRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][1].release(), radii[1][1].release())), important); + addProperty(CSSPropertyBorderBottomRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][2].release(), radii[1][2].release())), important); + addProperty(CSSPropertyBorderBottomLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][3].release(), radii[1][3].release())), important); m_implicitShorthand = false; return true; } @@ -4735,7 +4818,7 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important) switch (state) { case ID: if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) { - counterName = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING); + counterName = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING); state = VAL; m_valueList->next(); continue; @@ -4748,8 +4831,8 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important) m_valueList->next(); } - list->append(CSSPrimitiveValue::create(Pair::create(counterName.release(), - CSSPrimitiveValue::create(i, CSSPrimitiveValue::CSS_NUMBER)))); + list->append(primitiveValueCache()->createValue(Pair::create(counterName.release(), + primitiveValueCache()->createValue(i, CSSPrimitiveValue::CSS_NUMBER)))); state = ID; continue; } @@ -4766,20 +4849,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) +static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal, CSSPrimitiveValueCache* primitiveValueCache) { RefPtr<CSSPrimitiveValue> result; if (a->unit == CSSPrimitiveValue::CSS_IDENT) { if ((equalIgnoringCase(a->string, "left") && horizontal) || (equalIgnoringCase(a->string, "top") && !horizontal)) - result = CSSPrimitiveValue::create(0., CSSPrimitiveValue::CSS_PERCENTAGE); + result = primitiveValueCache->createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE); else if ((equalIgnoringCase(a->string, "right") && horizontal) || (equalIgnoringCase(a->string, "bottom") && !horizontal)) - result = CSSPrimitiveValue::create(100., CSSPrimitiveValue::CSS_PERCENTAGE); + result = primitiveValueCache->createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE); else if (equalIgnoringCase(a->string, "center")) - result = CSSPrimitiveValue::create(50., CSSPrimitiveValue::CSS_PERCENTAGE); + result = primitiveValueCache->createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE); } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - result = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit); + result = primitiveValueCache->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit); return result; } @@ -4804,13 +4887,13 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS return false; if (equalIgnoringCase(a->function->name, "from(")) - stop.m_position = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = p->primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER); else - stop.m_position = CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = p->primitiveValueCache()->createValue(1, CSSPrimitiveValue::CSS_NUMBER); int id = args->current()->id; if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) - stop.m_color = CSSPrimitiveValue::createIdentifier(id); + stop.m_color = p->primitiveValueCache()->createIdentifierValue(id); else stop.m_color = p->parseColor(args->current()); if (!stop.m_color) @@ -4824,9 +4907,9 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS CSSParserValue* stopArg = args->current(); if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE) - stop.m_position = CSSPrimitiveValue::create(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER); else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER) - stop.m_position = CSSPrimitiveValue::create(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER); + stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER); else return false; @@ -4837,7 +4920,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 = CSSPrimitiveValue::createIdentifier(id); + stop.m_color = p->primitiveValueCache()->createIdentifierValue(id); else stop.m_color = p->parseColor(stopArg); if (!stop.m_color) @@ -4887,7 +4970,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) a = args->next(); if (!a) return false; - RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true); + RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true, primitiveValueCache()); if (!point) return false; result->setFirstX(point.release()); @@ -4896,7 +4979,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) a = args->next(); if (!a) return false; - point = parseDeprecatedGradientPoint(a, false); + point = parseDeprecatedGradientPoint(a, false, primitiveValueCache()); if (!point) return false; result->setFirstY(point.release()); @@ -4911,7 +4994,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) a = args->next(); if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER) return false; - static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER)); + static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER)); // Comma after the first radius. a = args->next(); @@ -4924,7 +5007,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) a = args->next(); if (!a) return false; - point = parseDeprecatedGradientPoint(a, true); + point = parseDeprecatedGradientPoint(a, true, primitiveValueCache()); if (!point) return false; result->setSecondX(point.release()); @@ -4933,7 +5016,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) a = args->next(); if (!a) return false; - point = parseDeprecatedGradientPoint(a, false); + point = parseDeprecatedGradientPoint(a, false, primitiveValueCache()); if (!point) return false; result->setSecondY(point.release()); @@ -4948,7 +5031,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) a = args->next(); if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER) return false; - static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER)); + static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER)); } // We now will accept any number of stops (0 or more). @@ -4977,7 +5060,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient) return true; } -static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal) +static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal, CSSPrimitiveValueCache* primitiveValueCache) { if (a->unit != CSSPrimitiveValue::CSS_IDENT) return 0; @@ -4994,14 +5077,14 @@ static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, boo default: return 0; } - return CSSPrimitiveValue::createIdentifier(a->id); + return primitiveValueCache->createIdentifierValue(a->id); } static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value) { int id = value->id; if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu) - return CSSPrimitiveValue::createIdentifier(id); + return p->primitiveValueCache()->createIdentifierValue(id); return p->parseColor(value); } @@ -5022,7 +5105,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea bool expectComma = false; // Look for angle. if (validUnit(a, FAngle, true)) { - result->setAngle(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit)); + result->setAngle(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit)); a = args->next(); expectComma = true; @@ -5032,7 +5115,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea RefPtr<CSSPrimitiveValue> location; bool isHorizontal = false; - if ((location = valueFromSideKeyword(a, isHorizontal))) { + if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) { if (isHorizontal) startX = location; else @@ -5040,7 +5123,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea a = args->next(); if (a) { - if ((location = valueFromSideKeyword(a, isHorizontal))) { + if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) { if (isHorizontal) { if (startX) return false; @@ -5059,7 +5142,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea } if (!startX && !startY) - startY = CSSPrimitiveValue::createIdentifier(CSSValueTop); + startY = primitiveValueCache()->createIdentifierValue(CSSValueTop); result->setFirstX(startX.release()); result->setFirstY(startY.release()); @@ -5129,7 +5212,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea switch (a->id) { case CSSValueCircle: case CSSValueEllipse: - shapeValue = CSSPrimitiveValue::createIdentifier(a->id); + shapeValue = primitiveValueCache()->createIdentifierValue(a->id); foundValue = true; break; case CSSValueClosestSide: @@ -5138,7 +5221,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea case CSSValueFarthestCorner: case CSSValueContain: case CSSValueCover: - sizeValue = CSSPrimitiveValue::createIdentifier(a->id); + sizeValue = primitiveValueCache()->createIdentifierValue(a->id); foundValue = true; break; } @@ -5161,7 +5244,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea if (!shapeValue && !sizeValue) { if (validUnit(a, FLength | FPercent, m_strict)) { - horizontalSize = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit); + horizontalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit); a = args->next(); if (!a) return false; @@ -5170,7 +5253,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea } if (validUnit(a, FLength | FPercent, m_strict)) { - verticalSize = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit); + verticalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit); a = args->next(); if (!a) @@ -5218,7 +5301,7 @@ bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradie a = valueList->next(); if (a) { if (validUnit(a, FLength | FPercent, m_strict)) { - stop.m_position = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit); + stop.m_position = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit); a = valueList->next(); } } @@ -5439,7 +5522,7 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform() return 0; // Add the value to the current transform operation. - transformValue->append(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit)); + transformValue->append(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit)); a = args->next(); if (!a) @@ -5488,7 +5571,7 @@ bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int } case CSSPropertyWebkitTransformOriginZ: { if (validUnit(m_valueList->current(), FLength, m_strict)) - value = CSSPrimitiveValue::create(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit); + value = primitiveValueCache()->createValue(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit); if (value) m_valueList->next(); break; @@ -5541,7 +5624,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->unit == CSSPrimitiveValue::CSS_STRING) { if (fill || shape || (valueListSize != 1 && !inShorthand())) return false; - addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important); + addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important); m_valueList->next(); return true; } @@ -5549,7 +5632,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->id == CSSValueNone) { if (fill || shape || (valueListSize != 1 && !inShorthand())) return false; - addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::createIdentifier(CSSValueNone), important); + addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createIdentifierValue(CSSValueNone), important); m_valueList->next(); return true; } @@ -5557,11 +5640,11 @@ bool CSSParser::parseTextEmphasisStyle(bool important) if (value->id == CSSValueOpen || value->id == CSSValueFilled) { if (fill) return false; - fill = CSSPrimitiveValue::createIdentifier(value->id); + fill = primitiveValueCache()->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 = CSSPrimitiveValue::createIdentifier(value->id); + shape = primitiveValueCache()->createIdentifierValue(value->id); } else if (!inShorthand()) return false; else @@ -6041,9 +6124,6 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre return; } - if (Document* doc = document()) - doc->setUsesDescendantRules(true); - specifiers->setRelation(CSSSelector::ShadowDescendant); if (CSSParserSelector* history = specifiers->tagHistory()) { history->setTag(tag); @@ -6266,6 +6346,13 @@ static int cssPropertyID(const UChar* propertyName, unsigned length) const char* const opacity = "opacity"; name = opacity; length = strlen(opacity); +#if PLATFORM(IOS) + } else if (!strcmp(buffer, "-webkit-hyphenate-locale")) { + // Worked in iOS 4.2. + const char* const webkitLocale = "-webkit-locale"; + name = webkitLocale; + length = strlen(webkitLocale); +#endif } else if (hasPrefix(buffer + 7, length - 7, "-border-")) { // -webkit-border-*-*-radius worked in Safari 4 and earlier. -webkit-border-radius syntax // differs from border-radius, so it is remains as a distinct property. diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h index 6ccfbe2..230e699 100644 --- a/Source/WebCore/css/CSSParser.h +++ b/Source/WebCore/css/CSSParser.h @@ -38,6 +38,7 @@ namespace WebCore { class CSSMutableStyleDeclaration; class CSSPrimitiveValue; + class CSSPrimitiveValueCache; class CSSProperty; class CSSRule; class CSSRuleList; @@ -70,6 +71,8 @@ namespace WebCore { bool parseMediaQuery(MediaList*, const String&); Document* document() const; + + CSSPrimitiveValueCache* primitiveValueCache() const { return m_primitiveValueCache.get(); } void addProperty(int propId, PassRefPtr<CSSValue>, bool important); void rollbackLastProperties(int num); @@ -79,6 +82,7 @@ namespace WebCore { 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); PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args); @@ -225,6 +229,7 @@ namespace WebCore { CSSParserValueList* m_valueList; CSSProperty** m_parsedProperties; CSSSelectorList* m_selectorListForParseSelector; + RefPtr<CSSPrimitiveValueCache> m_primitiveValueCache; unsigned m_numParsedProperties; unsigned m_maxParsedProperties; unsigned m_numParsedPropertiesBeforeMarginBox; @@ -261,6 +266,8 @@ namespace WebCore { int lex(); private: + void setStyleSheet(CSSStyleSheet*); + void recheckAtKeyword(const UChar* str, int len); void setupParser(const char* prefix, const String&, const char* suffix); diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index 6d930bd..04f1089 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -87,103 +87,6 @@ static CSSTextCache& cssTextCache() return cache; } -// A more stylish solution than sharing would be to turn CSSPrimitiveValue (or CSSValues in general) into non-virtual, -// non-refcounted simple type with value semantics. In practice these sharing tricks get similar memory benefits -// with less need for refactoring. - -inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedIdentifier(int identifier) -{ - return adoptRef(new CSSPrimitiveValue(identifier)); -} - -inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedColor(unsigned rgbValue) -{ - return adoptRef(new CSSPrimitiveValue(rgbValue)); -} - -inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncached(double value, UnitTypes type) -{ - return adoptRef(new CSSPrimitiveValue(value, type)); -} - -PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createIdentifier(int ident) -{ - static RefPtr<CSSPrimitiveValue>* identValueCache = new RefPtr<CSSPrimitiveValue>[numCSSValueKeywords]; - if (ident >= 0 && ident < numCSSValueKeywords) { - RefPtr<CSSPrimitiveValue> primitiveValue = identValueCache[ident]; - if (!primitiveValue) { - primitiveValue = createUncachedIdentifier(ident); - identValueCache[ident] = primitiveValue; - } - return primitiveValue.release(); - } - return createUncachedIdentifier(ident); -} - -PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createColor(unsigned rgbValue) -{ - typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache; - static ColorValueCache* colorValueCache = new ColorValueCache; - // These are the empty and deleted values of the hash table. - if (rgbValue == Color::transparent) { - static CSSPrimitiveValue* colorTransparent = createUncachedColor(Color::transparent).releaseRef(); -#if CPU(ARM) && OS(LINUX) - // A workaround for gcc bug on ARM. - if (!colorTransparent) - return 0; -#endif - return colorTransparent; - } - if (rgbValue == Color::white) { - static CSSPrimitiveValue* colorWhite = createUncachedColor(Color::white).releaseRef(); -#if CPU(ARM) && OS(LINUX) - // A workaround for gcc bug on ARM. - if (!colorWhite) - return 0; -#endif - return colorWhite; - } - RefPtr<CSSPrimitiveValue> primitiveValue = colorValueCache->get(rgbValue); - if (primitiveValue) - return primitiveValue.release(); - primitiveValue = createUncachedColor(rgbValue); - // Just wipe out the cache and start rebuilding when it gets too big. - const int maxColorCacheSize = 512; - if (colorValueCache->size() >= maxColorCacheSize) - colorValueCache->clear(); - colorValueCache->add(rgbValue, primitiveValue); - - return primitiveValue.release(); -} - -PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(double value, UnitTypes type) -{ - // Small integers are very common. Try to share them. - const int cachedIntegerCount = 128; - // Other common primitive types have UnitTypes smaller than this. - const int maxCachedUnitType = CSS_PX; - typedef RefPtr<CSSPrimitiveValue>(* IntegerValueCache)[maxCachedUnitType + 1]; - static IntegerValueCache integerValueCache = new RefPtr<CSSPrimitiveValue>[cachedIntegerCount][maxCachedUnitType + 1]; - if (type <= maxCachedUnitType && value >= 0 && value < cachedIntegerCount) { - int intValue = static_cast<int>(value); - if (value == intValue) { - RefPtr<CSSPrimitiveValue> primitiveValue = integerValueCache[intValue][type]; - if (!primitiveValue) { - primitiveValue = createUncached(value, type); - integerValueCache[intValue][type] = primitiveValue; - } - return primitiveValue.release(); - } - } - - return createUncached(value, type); -} - -PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(const String& value, UnitTypes type) -{ - return adoptRef(new CSSPrimitiveValue(value, type)); -} - static const AtomicString& valueOrPropertyName(int valueOrPropertyID) { ASSERT_ARG(valueOrPropertyID, valueOrPropertyID >= 0); @@ -270,7 +173,6 @@ CSSPrimitiveValue::CSSPrimitiveValue(const Length& length) m_value.num = length.percent(); break; case Relative: - case Static: ASSERT_NOT_REACHED(); break; } @@ -809,6 +711,11 @@ String CSSPrimitiveValue::cssText() const text = String::adopt(result); break; } + case CSS_COUNTER_NAME: + text = "counter("; + text += m_value.string; + text += ")"; + break; case CSS_COUNTER: text = "counter("; text += String::number(m_value.num); diff --git a/Source/WebCore/css/CSSPrimitiveValue.h b/Source/WebCore/css/CSSPrimitiveValue.h index c9892e8..499e95c 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.h +++ b/Source/WebCore/css/CSSPrimitiveValue.h @@ -90,7 +90,10 @@ public: // These are from CSS3 Values and Units, but that isn't a finished standard yet CSS_TURN = 107, - CSS_REMS = 108 + CSS_REMS = 108, + + // This is used internally for counter names (as opposed to counter values) + CSS_COUNTER_NAME = 109 }; // This enum follows the CSSParser::Units enum augmented with UNIT_FREQUENCY for frequencies. @@ -107,10 +110,10 @@ public: static bool isUnitTypeLength(int type) { return (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) || type == CSSPrimitiveValue::CSS_REMS; } - static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident); - static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue); - static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type); - static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type); + static PassRefPtr<CSSPrimitiveValue> createIdentifier(int identifier) { return adoptRef(new CSSPrimitiveValue(identifier)); } + static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); } + static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); } + static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); } template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value) { diff --git a/Source/WebCore/css/CSSPrimitiveValueCache.cpp b/Source/WebCore/css/CSSPrimitiveValueCache.cpp new file mode 100644 index 0000000..6b3eebe --- /dev/null +++ b/Source/WebCore/css/CSSPrimitiveValueCache.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2011 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 "CSSPrimitiveValueCache.h" + +namespace WebCore { + +CSSPrimitiveValueCache::CSSPrimitiveValueCache() + : 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)) +{ +} + +CSSPrimitiveValueCache::~CSSPrimitiveValueCache() +{ +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::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; +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createColorValue(unsigned rgbValue) +{ + // These are the empty and deleted values of the hash table. + if (rgbValue == Color::transparent) + return m_colorTransparent; + if (rgbValue == Color::white) + return m_colorWhite; + // Just because it is common. + if (rgbValue == Color::black) + return m_colorBlack; + + // Just wipe out the cache and start rebuilding if it gets too big. + const int maximumColorCacheSize = 512; + if (m_colorValueCache.size() > maximumColorCacheSize) + 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; +} + +PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createValue(double value, CSSPrimitiveValue::UnitTypes type) +{ + // Small positive integers repeat often. + static const int maximumCacheableValue = 256; + if (value < 0 || value > maximumCacheableValue) + return CSSPrimitiveValue::create(value, type); + + int intValue = static_cast<int>(value); + if (value != intValue) + return CSSPrimitiveValue::create(value, type); + + IntegerValueCache* cache; + switch (type) { + case CSSPrimitiveValue::CSS_PX: + if (intValue == 0) + return m_pixelZero; + cache = &m_pixelValueCache; + break; + case CSSPrimitiveValue::CSS_PERCENTAGE: + if (intValue == 0) + return m_percentZero; + cache = &m_percentValueCache; + break; + case CSSPrimitiveValue::CSS_NUMBER: + if (intValue == 0) + return m_numberZero; + 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; +} + +} diff --git a/Source/WebCore/css/CSSPrimitiveValueCache.h b/Source/WebCore/css/CSSPrimitiveValueCache.h new file mode 100644 index 0000000..0290e40 --- /dev/null +++ b/Source/WebCore/css/CSSPrimitiveValueCache.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011 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 CSSPrimitiveValueCache_h +#define CSSPrimitiveValueCache_h + +#include "CSSPrimitiveValue.h" +#include "CSSValueKeywords.h" +#include <wtf/HashMap.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class CSSPrimitiveValue; + +class CSSPrimitiveValueCache : public RefCounted<CSSPrimitiveValueCache> { +public: + static PassRefPtr<CSSPrimitiveValueCache> create() { return adoptRef(new CSSPrimitiveValueCache); } + ~CSSPrimitiveValueCache(); + + PassRefPtr<CSSPrimitiveValue> createIdentifierValue(int identifier); + PassRefPtr<CSSPrimitiveValue> createColorValue(unsigned rgbValue); + PassRefPtr<CSSPrimitiveValue> createValue(double value, CSSPrimitiveValue::UnitTypes); + PassRefPtr<CSSPrimitiveValue> createValue(String value, CSSPrimitiveValue::UnitTypes type) { return CSSPrimitiveValue::create(value, type); } + template<typename T> static PassRefPtr<CSSPrimitiveValue> createValue(T value) { return CSSPrimitiveValue::create(value); } + +private: + CSSPrimitiveValueCache(); + + typedef HashMap<int, RefPtr<CSSPrimitiveValue> > IdentifierValueCache; + IdentifierValueCache m_identifierValueCache; + + typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache; + ColorValueCache m_colorValueCache; + RefPtr<CSSPrimitiveValue> m_colorTransparent; + 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; +}; + +} + +#endif diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index b04c6d6..d1fdcd3 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -227,10 +227,12 @@ z-index -webkit-font-size-delta -webkit-highlight -webkit-hyphenate-character --webkit-hyphenate-locale +-webkit-hyphenate-limit-after +-webkit-hyphenate-limit-before -webkit-hyphens -webkit-line-break -webkit-line-clamp +-webkit-locale -webkit-logical-width -webkit-logical-height -webkit-margin-after-collapse diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h index ea161c3..c04c27b 100644 --- a/Source/WebCore/css/CSSSelector.h +++ b/Source/WebCore/css/CSSSelector.h @@ -43,6 +43,7 @@ namespace WebCore { , m_isLastInTagHistory(true) , m_hasRareData(false) , m_isForPage(false) + , m_deleted(false) , m_tag(anyQName()) { } @@ -56,12 +57,16 @@ namespace WebCore { , m_isLastInTagHistory(true) , m_hasRareData(false) , m_isForPage(false) + , m_deleted(false) , m_tag(qName) { } ~CSSSelector() { + if (m_deleted) + CRASH(); + m_deleted = true; if (m_hasRareData) delete m_data.m_rareData; else if (m_data.m_value) @@ -279,6 +284,8 @@ namespace WebCore { bool m_isLastInTagHistory : 1; bool m_hasRareData : 1; bool m_isForPage : 1; + // FIXME: Remove once http://webkit.org/b/53045 is fixed. + bool m_deleted : 1; unsigned specificityForOneSelector() const; unsigned specificityForPage() const; diff --git a/Source/WebCore/css/CSSSelectorList.cpp b/Source/WebCore/css/CSSSelectorList.cpp index f4a8165..6f307ee 100644 --- a/Source/WebCore/css/CSSSelectorList.cpp +++ b/Source/WebCore/css/CSSSelectorList.cpp @@ -31,6 +31,8 @@ namespace WebCore { +static CSSSelector* const freedSelectorArrayMarker = reinterpret_cast<CSSSelector*>(0xbbadbeef); + CSSSelectorList::~CSSSelectorList() { deleteSelectors(); @@ -85,6 +87,10 @@ void CSSSelectorList::deleteSelectors() if (!m_selectorArray) return; + // FIXME: Remove once http://webkit.org/b/53045 is fixed. + if (m_selectorArray == freedSelectorArrayMarker) + CRASH(); + // We had two cases in adoptSelectVector. The fast case of a 1 element // vector took the CSSSelector directly, which was allocated with new. // The second case we allocated a new fastMalloc buffer, which should be @@ -103,6 +109,8 @@ void CSSSelectorList::deleteSelectors() } fastFree(m_selectorArray); } + + m_selectorArray = freedSelectorArrayMarker; } diff --git a/Source/WebCore/css/CSSStyleDeclaration.cpp b/Source/WebCore/css/CSSStyleDeclaration.cpp index 422dd0d..0a7aa1c 100644 --- a/Source/WebCore/css/CSSStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSStyleDeclaration.cpp @@ -22,10 +22,13 @@ #include "CSSStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" +#include "CSSMutableValue.h" #include "CSSParser.h" #include "CSSProperty.h" #include "CSSPropertyNames.h" #include "CSSRule.h" +#include "Node.h" +#include "SVGElement.h" #include <wtf/ASCIICType.h> using namespace WTF; @@ -42,7 +45,28 @@ PassRefPtr<CSSValue> CSSStyleDeclaration::getPropertyCSSValue(const String& prop int propID = cssPropertyID(propertyName); if (!propID) return 0; - return getPropertyCSSValue(propID); + + // Short-cut, not involving any change to the refcount. + if (!isMutableStyleDeclaration()) + return getPropertyCSSValue(propID); + + // Slow path. + RefPtr<CSSValue> value = getPropertyCSSValue(propID); + if (!value || !value->isMutableValue()) + return value.release(); + + Node* node = static_cast<CSSMutableStyleDeclaration*>(this)->node(); + if (!node || !node->isStyledElement()) + return value.release(); + + Node* associatedNode = static_cast<CSSMutableValue*>(value.get())->node(); + if (associatedNode) { + ASSERT(associatedNode == node); + return value.release(); + } + + static_cast<CSSMutableValue*>(value.get())->setNode(node); + return value.release(); } String CSSStyleDeclaration::getPropertyValue(const String &propertyName) diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp index 02cf8d3..bcf7756 100644 --- a/Source/WebCore/css/CSSStyleSelector.cpp +++ b/Source/WebCore/css/CSSStyleSelector.cpp @@ -6,6 +6,7 @@ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (c) 2011, Code Aurora Forum. 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 @@ -70,6 +71,7 @@ #include "PageGroup.h" #include "Pair.h" #include "PerspectiveTransformOperation.h" +#include "QuotesData.h" #include "Rect.h" #include "RenderScrollbar.h" #include "RenderScrollbarTheme.h" @@ -363,6 +365,7 @@ public: bool hasFastCheckableSelector() const { return m_hasFastCheckableSelector; } bool hasMultipartSelector() const { return m_hasMultipartSelector; } bool hasTopSelectorMatchingHTMLBasedOnRuleHash() const { return m_hasTopSelectorMatchingHTMLBasedOnRuleHash; } + unsigned specificity() const { return m_specificity; } // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance. static const unsigned maximumIdentifierCount = 4; @@ -374,6 +377,7 @@ private: CSSStyleRule* m_rule; CSSSelector* m_selector; + unsigned m_specificity; unsigned m_position : 29; bool m_hasFastCheckableSelector : 1; bool m_hasMultipartSelector : 1; @@ -399,8 +403,8 @@ public: CSSStyleRule* rule, CSSSelector* sel); void shrinkToFit(); void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; } - - void collectIdsAndSiblingRules(HashSet<AtomicStringImpl*>& ids, OwnPtr<RuleSet>& siblingRules) const; + + void collectFeatures(CSSStyleSelector::Features&) const; const Vector<RuleData>* getIDRules(AtomicStringImpl* key) const { return m_idRules.get(key); } const Vector<RuleData>* getClassRules(AtomicStringImpl* key) const { return m_classRules.get(key); } @@ -445,12 +449,11 @@ static inline bool elementCanUseSimpleDefaultStyle(Element* e) static inline void collectSiblingRulesInDefaultStyle() { - OwnPtr<RuleSet> siblingRules; - HashSet<AtomicStringImpl*> ids; - defaultStyle->collectIdsAndSiblingRules(ids, siblingRules); - ASSERT(ids.isEmpty()); + CSSStyleSelector::Features features; + defaultStyle->collectFeatures(features); + ASSERT(features.idsInRules.isEmpty()); delete siblingRulesInDefaultStyle; - siblingRulesInDefaultStyle = siblingRules.leakPtr(); + siblingRulesInDefaultStyle = features.siblingRules.leakPtr(); } static inline void assertNoSiblingRulesInDefaultStyle() @@ -475,6 +478,26 @@ static const MediaQueryEvaluator& printEval() return staticPrintEval; } +static CSSMutableStyleDeclaration* leftToRightDeclaration() +{ + DEFINE_STATIC_LOCAL(RefPtr<CSSMutableStyleDeclaration>, leftToRightDecl, (CSSMutableStyleDeclaration::create())); + if (!leftToRightDecl->length()) { + leftToRightDecl->setProperty(CSSPropertyDirection, "ltr", false, false); + leftToRightDecl->setStrictParsing(false); + } + return leftToRightDecl.get(); +} + +static CSSMutableStyleDeclaration* rightToLeftDeclaration() +{ + DEFINE_STATIC_LOCAL(RefPtr<CSSMutableStyleDeclaration>, rightToLeftDecl, (CSSMutableStyleDeclaration::create())); + if (!rightToLeftDecl->length()) { + rightToLeftDecl->setProperty(CSSPropertyDirection, "rtl", false, false); + rightToLeftDecl->setStrictParsing(false); + } + return rightToLeftDecl.get(); +} + CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet, CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets, bool strictParsing, bool matchAuthorAndUserStyles) @@ -555,14 +578,14 @@ CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleShee // sharing candidates. // Usually there are no sibling rules in the default style but the MathML sheet has some. if (siblingRulesInDefaultStyle) - siblingRulesInDefaultStyle->collectIdsAndSiblingRules(m_idsInRules, m_siblingRules); - m_authorStyle->collectIdsAndSiblingRules(m_idsInRules, m_siblingRules); + siblingRulesInDefaultStyle->collectFeatures(m_features); + m_authorStyle->collectFeatures(m_features); if (m_userStyle) - m_userStyle->collectIdsAndSiblingRules(m_idsInRules, m_siblingRules); + m_userStyle->collectFeatures(m_features); m_authorStyle->shrinkToFit(); - if (m_siblingRules) - m_siblingRules->shrinkToFit(); + if (m_features.siblingRules) + m_features.siblingRules->shrinkToFit(); if (document->renderer() && document->renderer()->style()) document->renderer()->style()->font().update(fontSelector()); @@ -580,6 +603,17 @@ CSSStyleSelector::~CSSStyleSelector() m_fontSelector->clearDocument(); deleteAllValues(m_viewportDependentMediaQueryResults); } + +CSSStyleSelector::Features::Features() + : usesFirstLineRules(false) + , usesBeforeAfterRules(false) + , usesLinkRules(false) +{ +} + +CSSStyleSelector::Features::~Features() +{ +} static CSSStyleSheet* parseUASheet(const String& str) { @@ -772,7 +806,7 @@ void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& last return; // Sort the set of matched rules. - sortMatchedRules(0, m_matchedRules.size()); + sortMatchedRules(); // Now transfer the set of matched rules over to our list of decls. if (!m_checker.m_collectRulesOnly) { @@ -839,80 +873,16 @@ void CSSStyleSelector::matchRulesForList(const Vector<RuleData>* rules, int& fir } } -static bool operator >(const RuleData& r1, const RuleData& r2) -{ - int spec1 = r1.selector()->specificity(); - int spec2 = r2.selector()->specificity(); - return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2; -} - -static bool operator <=(const RuleData& r1, const RuleData& r2) +static inline bool compareRules(const RuleData* r1, const RuleData* r2) { - return !(r1 > r2); + unsigned specificity1 = r1->specificity(); + unsigned specificity2 = r2->specificity(); + return (specificity1 == specificity2) ? r1->position() < r2->position() : specificity1 < specificity2; } -void CSSStyleSelector::sortMatchedRules(unsigned start, unsigned end) +void CSSStyleSelector::sortMatchedRules() { - if (start >= end || (end - start == 1)) - return; // Sanity check. - - if (end - start <= 6) { - // Apply a bubble sort for smaller lists. - for (unsigned i = end - 1; i > start; i--) { - bool sorted = true; - for (unsigned j = start; j < i; j++) { - const RuleData* elt = m_matchedRules[j]; - const RuleData* elt2 = m_matchedRules[j + 1]; - if (*elt > *elt2) { - sorted = false; - m_matchedRules[j] = elt2; - m_matchedRules[j + 1] = elt; - } - } - if (sorted) - return; - } - return; - } - - // Perform a merge sort for larger lists. - unsigned mid = (start + end) / 2; - sortMatchedRules(start, mid); - sortMatchedRules(mid, end); - - const RuleData* elt = m_matchedRules[mid - 1]; - const RuleData* elt2 = m_matchedRules[mid]; - - // Handle the fast common case (of equal specificity). The list may already - // be completely sorted. - if (*elt <= *elt2) - return; - - // We have to merge sort. Ensure our merge buffer is big enough to hold - // all the items. - Vector<const RuleData*> rulesMergeBuffer; - rulesMergeBuffer.reserveInitialCapacity(end - start); - - unsigned i1 = start; - unsigned i2 = mid; - - elt = m_matchedRules[i1]; - elt2 = m_matchedRules[i2]; - - while (i1 < mid || i2 < end) { - if (i1 < mid && (i2 == end || *elt <= *elt2)) { - rulesMergeBuffer.append(elt); - if (++i1 < mid) - elt = m_matchedRules[i1]; - } else { - rulesMergeBuffer.append(elt2); - if (++i2 < end) - elt2 = m_matchedRules[i2]; - } - } - - for (unsigned i = start; i < end; i++) - m_matchedRules[i] = rulesMergeBuffer[i - start]; + std::sort(m_matchedRules.begin(), m_matchedRules.end(), compareRules); } inline EInsideLink CSSStyleSelector::SelectorChecker::determineLinkState(Element* element) const @@ -1054,142 +1024,173 @@ bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* } static const unsigned cStyleSearchThreshold = 10; +static const unsigned cStyleSearchLevelThreshold = 10; -Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned depth) const +Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned& visitedNodeCount) const { + if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold) + return 0; if (!parent || !parent->isStyledElement()) return 0; StyledElement* p = static_cast<StyledElement*>(parent); if (p->inlineStyleDecl()) return 0; - if (p->hasID() && m_idsInRules.contains(p->idForStyleResolution().impl())) + if (p->hasID() && m_features.idsInRules.contains(p->idForStyleResolution().impl())) return 0; - Node* r = p->previousSibling(); + + RenderStyle* parentStyle = p->renderStyle(); unsigned subcount = 0; - RenderStyle* st = p->renderStyle(); - while (r) { - if (r->renderStyle() == st) - return r->lastChild(); - if (subcount++ == cStyleSearchThreshold) - return 0; - r = r->previousSibling(); - } - if (!r && depth < cStyleSearchThreshold) - r = locateCousinList(parent->parentElement(), depth + 1); - while (r) { - if (r->renderStyle() == st) - return r->lastChild(); - if (subcount++ == cStyleSearchThreshold) - return 0; - r = r->previousSibling(); + Node* thisCousin = p; + Node* currentNode = p->previousSibling(); + + // Reserve the tries for this level. This effectively makes sure that the algorithm + // will never go deeper than cStyleSearchLevelThreshold levels into recursion. + visitedNodeCount += cStyleSearchThreshold; + while (thisCousin) { + while (currentNode) { + ++subcount; + if (currentNode->renderStyle() == parentStyle && currentNode->lastChild()) { + // Adjust for unused reserved tries. + visitedNodeCount -= cStyleSearchThreshold - subcount; + return currentNode->lastChild(); + } + if (subcount >= cStyleSearchThreshold) + return 0; + currentNode = currentNode->previousSibling(); + } + currentNode = locateCousinList(thisCousin->parentElement(), visitedNodeCount); + thisCousin = currentNode; } + return 0; } bool CSSStyleSelector::matchesSiblingRules() { int firstSiblingRule = -1, lastSiblingRule = -1; - matchRules(m_siblingRules.get(), firstSiblingRule, lastSiblingRule, false); + matchRules(m_features.siblingRules.get(), firstSiblingRule, lastSiblingRule, false); if (m_matchedDecls.isEmpty()) return false; m_matchedDecls.clear(); return true; } -bool CSSStyleSelector::canShareStyleWithElement(Node* n) const -{ - if (n->isStyledElement()) { - StyledElement* s = static_cast<StyledElement*>(n); - RenderStyle* style = s->renderStyle(); - if (style && !style->unique() && - (s->tagQName() == m_element->tagQName()) && - (s->hasClass() == m_element->hasClass()) && !s->inlineStyleDecl() && - (s->hasMappedAttributes() == m_styledElement->hasMappedAttributes()) && - (s->isLink() == m_element->isLink()) && - !style->affectedByAttributeSelectors() && - (s->hovered() == m_element->hovered()) && - (s->active() == m_element->active()) && - (s->focused() == m_element->focused()) && - (s->shadowPseudoId() == m_element->shadowPseudoId()) && - (s != s->document()->cssTarget() && m_element != m_element->document()->cssTarget()) && - (s->fastGetAttribute(typeAttr) == m_element->fastGetAttribute(typeAttr)) && - (s->fastGetAttribute(XMLNames::langAttr) == m_element->fastGetAttribute(XMLNames::langAttr)) && - (s->fastGetAttribute(langAttr) == m_element->fastGetAttribute(langAttr)) && - (s->fastGetAttribute(readonlyAttr) == m_element->fastGetAttribute(readonlyAttr)) && - (s->fastGetAttribute(cellpaddingAttr) == m_element->fastGetAttribute(cellpaddingAttr))) { - - if (s->hasID() && m_idsInRules.contains(s->idForStyleResolution().impl())) - return 0; - - bool isControl = s->isFormControlElement(); - if (isControl != m_element->isFormControlElement()) - return false; - if (isControl) { - InputElement* thisInputElement = toInputElement(s); - InputElement* otherInputElement = toInputElement(m_element); - if (thisInputElement && otherInputElement) { - if ((thisInputElement->isAutofilled() != otherInputElement->isAutofilled()) || - (thisInputElement->isChecked() != otherInputElement->isChecked()) || - (thisInputElement->isIndeterminate() != otherInputElement->isIndeterminate())) - return false; - } else - return false; +bool CSSStyleSelector::canShareStyleWithElement(Node* node) const +{ + if (!node->isStyledElement()) + return false; - if (s->isEnabledFormControl() != m_element->isEnabledFormControl()) - return false; + StyledElement* element = static_cast<StyledElement*>(node); + RenderStyle* style = element->renderStyle(); - if (s->isDefaultButtonForForm() != m_element->isDefaultButtonForForm()) - return false; - - if (!m_element->document()->containsValidityStyleRules()) - return false; - - bool willValidate = s->willValidate(); - if (willValidate != m_element->willValidate()) - return false; - - if (willValidate && (s->isValidFormControlElement() != m_element->isValidFormControlElement())) - return false; + if (!style) + return false; + if (style->unique()) + return false; + if (element->tagQName() != m_element->tagQName()) + return false; + if (element->hasClass() != m_element->hasClass()) + return false; + if (element->inlineStyleDecl()) + return false; + if (element->hasMappedAttributes() != m_styledElement->hasMappedAttributes()) + return false; + if (element->isLink() != m_element->isLink()) + return false; + if (style->affectedByAttributeSelectors()) + return false; + if (element->hovered() != m_element->hovered()) + return false; + if (element->active() != m_element->active()) + return false; + if (element->focused() != m_element->focused()) + return false; + if (element->shadowPseudoId() != m_element->shadowPseudoId()) + return false; + if (element == element->document()->cssTarget()) + return false; + if (m_element == m_element->document()->cssTarget()) + return false; + if (element->fastGetAttribute(typeAttr) != m_element->fastGetAttribute(typeAttr)) + return false; + if (element->fastGetAttribute(XMLNames::langAttr) != m_element->fastGetAttribute(XMLNames::langAttr)) + return false; + if (element->fastGetAttribute(langAttr) != m_element->fastGetAttribute(langAttr)) + return false; + if (element->fastGetAttribute(readonlyAttr) != m_element->fastGetAttribute(readonlyAttr)) + return false; + if (element->fastGetAttribute(cellpaddingAttr) != m_element->fastGetAttribute(cellpaddingAttr)) + return false; - if (s->isInRange() != m_element->isInRange()) - return false; + if (element->hasID() && m_features.idsInRules.contains(element->idForStyleResolution().impl())) + return false; - if (s->isOutOfRange() != m_element->isOutOfRange()) - return false; - } + bool isControl = element->isFormControlElement(); - if (style->transitions() || style->animations()) - return false; + if (isControl != m_element->isFormControlElement()) + return false; + + if (isControl) { + InputElement* thisInputElement = toInputElement(element); + InputElement* otherInputElement = toInputElement(m_element); + + if (!thisInputElement || !otherInputElement) + return false; + + if (thisInputElement->isAutofilled() != otherInputElement->isAutofilled()) + return false; + if (thisInputElement->isChecked() != otherInputElement->isChecked()) + return false; + if (thisInputElement->isIndeterminate() != otherInputElement->isIndeterminate()) + return false; + + if (element->isEnabledFormControl() != m_element->isEnabledFormControl()) + return false; + + if (element->isDefaultButtonForForm() != m_element->isDefaultButtonForForm()) + return false; + + if (!m_element->document()->containsValidityStyleRules()) + return false; + + bool willValidate = element->willValidate(); + + if (willValidate != m_element->willValidate()) + return false; + + if (willValidate && (element->isValidFormControlElement() != m_element->isValidFormControlElement())) + return false; + + if (element->isInRange() != m_element->isInRange()) + return false; + + if (element->isOutOfRange() != m_element->isOutOfRange()) + return false; + } + + if (style->transitions() || style->animations()) + return false; #if USE(ACCELERATED_COMPOSITING) - // Turn off style sharing for elements that can gain layers for reasons outside of the style system. - // See comments in RenderObject::setStyle(). - if (s->hasTagName(iframeTag) || s->hasTagName(embedTag) || s->hasTagName(objectTag) || s->hasTagName(appletTag)) - return false; + // Turn off style sharing for elements that can gain layers for reasons outside of the style system. + // See comments in RenderObject::setStyle(). + if (element->hasTagName(iframeTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag) || element->hasTagName(appletTag)) + return false; #endif - bool classesMatch = true; - if (s->hasClass()) { - const AtomicString& class1 = m_element->fastGetAttribute(classAttr); - const AtomicString& class2 = s->fastGetAttribute(classAttr); - classesMatch = (class1 == class2); - } - - if (classesMatch) { - bool mappedAttrsMatch = true; - if (s->hasMappedAttributes()) - mappedAttrsMatch = s->attributeMap()->mappedMapsEquivalent(m_styledElement->attributeMap()); - if (mappedAttrsMatch) { - if (s->isLink()) { - if (m_elementLinkState != style->insideLink()) - return false; - } - return true; - } - } - } - } - return false; + if (equalIgnoringCase(element->fastGetAttribute(dirAttr), "auto") || equalIgnoringCase(m_element->fastGetAttribute(dirAttr), "auto")) + return false; + + if (element->hasClass() && m_element->fastGetAttribute(classAttr) != element->fastGetAttribute(classAttr)) + return false; + + if (element->hasMappedAttributes() && !element->attributeMap()->mappedMapsEquivalent(m_styledElement->attributeMap())) + return false; + + if (element->isLink() && m_elementLinkState != style->insideLink()) + return false; + + return true; } inline Node* CSSStyleSelector::findSiblingForStyleSharing(Node* node, unsigned& count) const @@ -1221,19 +1222,27 @@ ALWAYS_INLINE RenderStyle* CSSStyleSelector::locateSharedStyle() if (m_styledElement->inlineStyleDecl()) return 0; // Ids stop style sharing if they show up in the stylesheets. - if (m_styledElement->hasID() && m_idsInRules.contains(m_styledElement->idForStyleResolution().impl())) + if (m_styledElement->hasID() && m_features.idsInRules.contains(m_styledElement->idForStyleResolution().impl())) return 0; if (parentStylePreventsSharing(m_parentStyle)) return 0; - // Check previous siblings. + + // Check previous siblings and their cousins. unsigned count = 0; - Node* shareNode = findSiblingForStyleSharing(m_styledElement->previousSibling(), count); - if (!shareNode) { - Node* cousinList = locateCousinList(m_styledElement->parentElement()); - shareNode = findSiblingForStyleSharing(cousinList, count); - if (!shareNode) - return 0; + unsigned visitedNodeCount = 0; + Node* shareNode = 0; + Node* cousinList = m_styledElement->previousSibling(); + while (cousinList) { + shareNode = findSiblingForStyleSharing(cousinList, count); + if (shareNode) + break; + cousinList = locateCousinList(cousinList->parentElement(), visitedNodeCount); } + + // If we have exhausted all our budget or our cousins. + if (!shareNode) + return 0; + // Can't share if sibling rules apply. This is checked at the end as it should rarely fail. if (matchesSiblingRules()) return 0; @@ -1254,8 +1263,8 @@ void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule) if (!m_checker.m_strictParsing) matchRules(defaultQuirksStyle, firstUARule, lastUARule, false); - // If we're in view source mode, then we match rules from the view source style sheet. - if (m_checker.m_document->frame() && m_checker.m_document->frame()->inViewSourceMode()) { + // If document uses view source styles (in view source mode or in xml viewer mode), then we match rules from the view source style sheet. + if (m_checker.m_document->usesViewSourceStyles()) { if (!defaultViewSourceStyle) loadViewSourceStyle(); matchRules(defaultViewSourceStyle, firstUARule, lastUARule, false); @@ -1475,6 +1484,12 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl addMatchedDeclaration(m_additionalAttributeStyleDecls[i]); } } + if (m_styledElement->isHTMLElement()) { + bool isAuto; + TextDirection textDirection = toHTMLElement(m_styledElement)->directionalityIfhasDirAutoAttribute(isAuto); + if (isAuto) + addMatchedDeclaration(textDirection == LTR ? leftToRightDeclaration() : rightToLeftDeclaration()); + } } // 6. Check the rules in author sheets next. @@ -2100,7 +2115,8 @@ inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData) { m_dynamicPseudo = NOPSEUDO; - if (ruleData.hasFastCheckableSelector()) { + // Let the slow path handle SVG as it has some additional rules regarding shadow trees. + if (ruleData.hasFastCheckableSelector() && !m_element->isSVGElement()) { // We know this selector does not include any pseudo selectors. if (m_checker.m_pseudoStyle != NOPSEUDO) return false; @@ -2134,13 +2150,67 @@ static inline bool selectorTagMatches(const Element* element, const CSSSelector* static inline bool isFastCheckableSelector(const CSSSelector* selector) { for (; selector; selector = selector->tagHistory()) { - if (selector->relation() != CSSSelector::Descendant) + if (selector->relation() != CSSSelector::Descendant && selector->relation() != CSSSelector::Child && selector->relation() != CSSSelector::SubSelector) return false; if (selector->m_match != CSSSelector::None && selector->m_match != CSSSelector::Id && selector->m_match != CSSSelector::Class) return false; } return true; } + +template <class ValueChecker> +inline bool fastCheckSingleSelector(const CSSSelector*& selector, const Element*& element, const CSSSelector*& topChildOrSubselector, const Element*& topChildOrSubselectorMatchElement) +{ + AtomicStringImpl* value = selector->value().impl(); + for (; element; element = element->parentElement()) { + if (ValueChecker::checkValue(element, value) && selectorTagMatches(element, selector)) { + if (selector->relation() == CSSSelector::Descendant) + topChildOrSubselector = 0; + else if (!topChildOrSubselector) { + ASSERT(selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector); + topChildOrSubselector = selector; + topChildOrSubselectorMatchElement = element; + } + if (selector->relation() != CSSSelector::SubSelector) + element = element->parentElement(); + selector = selector->tagHistory(); + return true; + } + if (topChildOrSubselector) { + // Child or subselector check failed. + // If the match element is null, topChildOrSubselector was also the very topmost selector and had to match + // the original element we were checking. + if (!topChildOrSubselectorMatchElement) + return false; + // There may be other matches down the ancestor chain. + // Rewind to the topmost child or subselector and the element it matched, continue checking ancestors. + selector = topChildOrSubselector; + element = topChildOrSubselectorMatchElement->parentElement(); + topChildOrSubselector = 0; + return true; + } + } + return false; +} + +struct ClassCheck { + static bool checkValue(const Element* element, AtomicStringImpl* value) + { + return element->hasClass() && static_cast<const StyledElement*>(element)->classNames().contains(value); + } +}; +struct IdCheck { + static bool checkValue(const Element* element, AtomicStringImpl* value) + { + return element->hasID() && element->idForStyleResolution().impl() == value; + } +}; +struct TagCheck { + static bool checkValue(const Element*, AtomicStringImpl*) + { + return true; + } +}; bool CSSStyleSelector::SelectorChecker::fastCheckSelector(const CSSSelector* selector, const Element* element) { @@ -2150,40 +2220,30 @@ bool CSSStyleSelector::SelectorChecker::fastCheckSelector(const CSSSelector* sel if (!selectorTagMatches(element, selector)) return false; + const CSSSelector* topChildOrSubselector = 0; + const Element* topChildOrSubselectorMatchElement = 0; + if (selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector) + topChildOrSubselector = selector; + + if (selector->relation() != CSSSelector::SubSelector) + element = element->parentElement(); + selector = selector->tagHistory(); - if (!selector) - return true; - const Element* ancestor = element; - // We know this compound selector has descendant combinators only and all components are simple. - for (; selector; selector = selector->tagHistory()) { - AtomicStringImpl* value; + + // We know this compound selector has descendant, child and subselector combinators only and all components are simple. + while (selector) { switch (selector->m_match) { case CSSSelector::Class: - value = selector->value().impl(); - while (true) { - if (!(ancestor = ancestor->parentElement())) - return false; - const StyledElement* styledElement = static_cast<const StyledElement*>(ancestor); - if (ancestor->hasClass() && styledElement->classNames().contains(value) && selectorTagMatches(ancestor, selector)) - break; - } + if (!fastCheckSingleSelector<ClassCheck>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) + return false; break; case CSSSelector::Id: - value = selector->value().impl(); - while (true) { - if (!(ancestor = ancestor->parentElement())) - return false; - if (ancestor->hasID() && ancestor->idForStyleResolution().impl() == value && selectorTagMatches(ancestor, selector)) - break; - } + if (!fastCheckSingleSelector<IdCheck>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) + return false; break; case CSSSelector::None: - while (true) { - if (!(ancestor = ancestor->parentElement())) - return false; - if (selectorTagMatches(ancestor, selector)) - break; - } + if (!fastCheckSingleSelector<TagCheck>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement)) + return false; break; default: ASSERT_NOT_REACHED(); @@ -2191,7 +2251,6 @@ bool CSSStyleSelector::SelectorChecker::fastCheckSelector(const CSSSelector* sel } return true; } - // Recursive check of selectors and combinators // It can return 3 different values: @@ -3052,6 +3111,7 @@ static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector* sele RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position) : m_rule(rule) , m_selector(selector) + , m_specificity(selector->specificity()) , m_position(position) , m_hasFastCheckableSelector(isFastCheckableSelector(selector)) , m_hasMultipartSelector(selector->tagHistory()) @@ -3223,47 +3283,64 @@ void RuleSet::addStyleRule(CSSStyleRule* rule) addRule(rule, s); } } + +static inline void collectFeaturesFromSelector(CSSStyleSelector::Features& features, const CSSSelector* selector) +{ + if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty()) + features.idsInRules.add(selector->value().impl()); + switch (selector->pseudoType()) { + case CSSSelector::PseudoFirstLine: + features.usesFirstLineRules = true; + break; + case CSSSelector::PseudoBefore: + case CSSSelector::PseudoAfter: + features.usesBeforeAfterRules = true; + break; + case CSSSelector::PseudoLink: + case CSSSelector::PseudoVisited: + features.usesLinkRules = true; + break; + default: + break; + } +} -static void collectIdsAndSiblingRulesFromList(HashSet<AtomicStringImpl*>& ids, OwnPtr<RuleSet>& siblingRules, const Vector<RuleData>& rules) +static void collectFeaturesFromList(CSSStyleSelector::Features& features, const Vector<RuleData>& rules) { unsigned size = rules.size(); for (unsigned i = 0; i < size; ++i) { const RuleData& ruleData = rules[i]; bool foundSiblingSelector = false; for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) { - if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty()) - ids.add(selector->value().impl()); - if (CSSSelector* simpleSelector = selector->simpleSelector()) { - ASSERT(!simpleSelector->simpleSelector()); - if (simpleSelector->m_match == CSSSelector::Id && !simpleSelector->value().isEmpty()) - ids.add(simpleSelector->value().impl()); - } + collectFeaturesFromSelector(features, selector); + if (CSSSelector* simpleSelector = selector->simpleSelector()) + collectFeaturesFromSelector(features, simpleSelector); if (selector->isSiblingSelector()) foundSiblingSelector = true; } if (foundSiblingSelector) { - if (!siblingRules) - siblingRules = adoptPtr(new RuleSet); - siblingRules->addRule(ruleData.rule(), ruleData.selector()); + if (!features.siblingRules) + features.siblingRules = adoptPtr(new RuleSet); + features.siblingRules->addRule(ruleData.rule(), ruleData.selector()); } } } -void RuleSet::collectIdsAndSiblingRules(HashSet<AtomicStringImpl*>& ids, OwnPtr<RuleSet>& siblingRules) const +void RuleSet::collectFeatures(CSSStyleSelector::Features& features) const { AtomRuleMap::const_iterator end = m_idRules.end(); for (AtomRuleMap::const_iterator it = m_idRules.begin(); it != end; ++it) - collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second); + collectFeaturesFromList(features, *it->second); end = m_classRules.end(); for (AtomRuleMap::const_iterator it = m_classRules.begin(); it != end; ++it) - collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second); + collectFeaturesFromList(features, *it->second); end = m_tagRules.end(); for (AtomRuleMap::const_iterator it = m_tagRules.begin(); it != end; ++it) - collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second); + collectFeaturesFromList(features, *it->second); end = m_pseudoRules.end(); for (AtomRuleMap::const_iterator it = m_pseudoRules.begin(); it != end; ++it) - collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second); - collectIdsAndSiblingRulesFromList(ids, siblingRules, m_universalRules); + collectFeaturesFromList(features, *it->second); + collectFeaturesFromList(features, m_universalRules); } static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map) @@ -3363,7 +3440,7 @@ void CSSStyleSelector::matchPageRules(RuleSet* rules, bool isLeftPage, bool isFi return; // Sort the set of matched rules. - sortMatchedRules(0, m_matchedRules.size()); + sortMatchedRules(); // Now transfer the set of matched rules over to our list of decls. for (unsigned i = 0; i < m_matchedRules.size(); i++) @@ -4220,8 +4297,10 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) // length, percent case CSSPropertyMaxWidth: // +none +inherit - if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) + if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) { + l = Length(undefinedLength, Fixed); apply = true; + } case CSSPropertyTop: case CSSPropertyLeft: case CSSPropertyRight: @@ -4675,36 +4754,59 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item); switch (contentValue->primitiveType()) { - case CSSPrimitiveValue::CSS_STRING: - m_style->setContent(contentValue->getStringValue().impl(), didSet); + case CSSPrimitiveValue::CSS_STRING: + m_style->setContent(contentValue->getStringValue().impl(), didSet); + didSet = true; + break; + case CSSPrimitiveValue::CSS_ATTR: { + // 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); + m_style->setContent(m_element->getAttribute(attr).impl(), didSet); + didSet = true; + // register the fact that the attribute value affects the style + m_selectorAttrs.add(attr.localName().impl()); + break; + } + case CSSPrimitiveValue::CSS_URI: { + if (!contentValue->isImageValue()) + break; + m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(contentValue)), didSet); + didSet = true; + break; + } + case CSSPrimitiveValue::CSS_COUNTER: { + Counter* counterValue = contentValue->getCounterValue(); + OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), + (EListStyleType)counterValue->listStyleNumber(), counterValue->separator())); + m_style->setContent(counter.release(), didSet); + didSet = true; + break; + } + case CSSPrimitiveValue::CSS_IDENT: + switch (contentValue->getIdent()) { + case CSSValueOpenQuote: + m_style->setContent(OPEN_QUOTE, didSet); didSet = true; break; - case CSSPrimitiveValue::CSS_ATTR: { - // 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); - m_style->setContent(m_element->getAttribute(attr).impl(), didSet); + case CSSValueCloseQuote: + m_style->setContent(CLOSE_QUOTE, didSet); didSet = true; - // register the fact that the attribute value affects the style - m_selectorAttrs.add(attr.localName().impl()); break; - } - case CSSPrimitiveValue::CSS_URI: { - if (!contentValue->isImageValue()) - break; - m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(contentValue)), didSet); + case CSSValueNoOpenQuote: + m_style->setContent(NO_OPEN_QUOTE, didSet); didSet = true; break; - } - case CSSPrimitiveValue::CSS_COUNTER: { - Counter* counterValue = contentValue->getCounterValue(); - OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), - (EListStyleType)counterValue->listStyleNumber(), counterValue->separator())); - m_style->setContent(counter.release(), didSet); + case CSSValueNoCloseQuote: + m_style->setContent(NO_CLOSE_QUOTE, didSet); didSet = true; + break; + default: + // normal and none do not have any effect. + {} } } } @@ -4712,6 +4814,37 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) m_style->clearContent(); return; } + case CSSPropertyQuotes: + if (isInherit) { + if (m_parentStyle) + m_style->setQuotes(m_parentStyle->quotes()); + return; + } + if (isInitial) { + m_style->setQuotes(0); + return; + } + if (value->isValueList()) { + CSSValueList* list = static_cast<CSSValueList*>(value); + size_t length = list->length(); + QuotesData* data = QuotesData::create(length); + if (!data) + return; // Out of memory + String* quotes = data->data(); + for (size_t i = 0; i < length; i++) { + CSSValue* item = list->itemWithoutBoundsCheck(i); + ASSERT(item->isPrimitiveValue()); + primitiveValue = static_cast<CSSPrimitiveValue*>(item); + ASSERT(primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_STRING); + quotes[i] = primitiveValue->getStringValue(); + } + m_style->setQuotes(adoptRef(data)); + } else if (primitiveValue) { + ASSERT(primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT); + if (primitiveValue->getIdent() == CSSValueNone) + m_style->setQuotes(adoptRef(QuotesData::create(0))); + } + return; case CSSPropertyCounterIncrement: applyCounterList(style(), value->isValueList() ? static_cast<CSSValueList*>(value) : 0, false); @@ -5626,12 +5759,28 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) m_style->setHyphenationString(primitiveValue->getStringValue()); return; } - case CSSPropertyWebkitHyphenateLocale: { - HANDLE_INHERIT_AND_INITIAL(hyphenationLocale, HyphenationLocale); + case CSSPropertyWebkitHyphenateLimitAfter: { + HANDLE_INHERIT_AND_INITIAL(hyphenationLimitAfter, HyphenationLimitAfter); + if (primitiveValue->getIdent() == CSSValueAuto) + m_style->setHyphenationLimitAfter(-1); + else + m_style->setHyphenationLimitAfter(min(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_NUMBER), static_cast<int>(numeric_limits<short>::max()))); + return; + } + case CSSPropertyWebkitHyphenateLimitBefore: { + HANDLE_INHERIT_AND_INITIAL(hyphenationLimitBefore, HyphenationLimitBefore); if (primitiveValue->getIdent() == CSSValueAuto) - m_style->setHyphenationLocale(nullAtom); + m_style->setHyphenationLimitBefore(-1); else - m_style->setHyphenationLocale(primitiveValue->getStringValue()); + m_style->setHyphenationLimitBefore(min(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_NUMBER), static_cast<int>(numeric_limits<short>::max()))); + return; + } + case CSSPropertyWebkitLocale: { + HANDLE_INHERIT_AND_INITIAL(locale, Locale); + if (primitiveValue->getIdent() == CSSValueAuto) + m_style->setLocale(nullAtom); + else + m_style->setLocale(primitiveValue->getStringValue()); return; } case CSSPropertyWebkitBorderFit: { @@ -5953,7 +6102,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) case CSSPropertyFontStretch: case CSSPropertyPage: - case CSSPropertyQuotes: case CSSPropertyTextLineThrough: case CSSPropertyTextLineThroughColor: case CSSPropertyTextLineThroughMode: diff --git a/Source/WebCore/css/CSSStyleSelector.h b/Source/WebCore/css/CSSStyleSelector.h index 6065c2c..9f83f82 100644 --- a/Source/WebCore/css/CSSStyleSelector.h +++ b/Source/WebCore/css/CSSStyleSelector.h @@ -116,7 +116,7 @@ public: void initElement(Element*); RenderStyle* locateSharedStyle(); bool matchesSiblingRules(); - Node* locateCousinList(Element* parent, unsigned depth = 1) const; + Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const; Node* findSiblingForStyleSharing(Node*, unsigned& count) const; bool canShareStyleWithElement(Node*) const; @@ -174,8 +174,23 @@ public: void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule); void addPageStyle(PassRefPtr<CSSPageRule>); + bool usesSiblingRules() const { return m_features.siblingRules; } + bool usesFirstLineRules() const { return m_features.usesFirstLineRules; } + bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; } + bool usesLinkRules() const { return m_features.usesLinkRules; } + static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations); + struct Features { + Features(); + ~Features(); + HashSet<AtomicStringImpl*> idsInRules; + OwnPtr<RuleSet> siblingRules; + bool usesFirstLineRules; + bool usesBeforeAfterRules; + bool usesLinkRules; + }; + private: enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely }; @@ -192,7 +207,7 @@ public: void matchRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules); void matchRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules); bool fastRejectSelector(const RuleData&) const; - void sortMatchedRules(unsigned start, unsigned end); + void sortMatchedRules(); bool checkSelector(const RuleData&); @@ -208,10 +223,9 @@ public: OwnPtr<RuleSet> m_authorStyle; OwnPtr<RuleSet> m_userStyle; - - OwnPtr<RuleSet> m_siblingRules; - HashSet<AtomicStringImpl*> m_idsInRules; - + + Features m_features; + struct ParentStackFrame { ParentStackFrame() {} ParentStackFrame(Element* element) : element(element) {} diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h index e8053fe..a101c66 100644 --- a/Source/WebCore/css/CSSValue.h +++ b/Source/WebCore/css/CSSValue.h @@ -50,6 +50,8 @@ public: virtual String cssText() const = 0; void setCssText(const String&, ExceptionCode&) { } // FIXME: Not implemented. + virtual bool isMutableValue() const { return false; } + virtual bool isBorderImageValue() const { return false; } virtual bool isCursorImageValue() const { return false; } virtual bool isFontFamilyValue() const { return false; } diff --git a/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp b/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp index 0cf6181..5dfe03e 100644 --- a/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp @@ -27,6 +27,7 @@ #include "CSSPropertyNames.h" #include "Document.h" #include "RenderStyle.h" +#include "SVGPaint.h" namespace WebCore { @@ -59,6 +60,14 @@ static PassRefPtr<CSSValue> strokeDashArrayToCSSValueList(const Vector<SVGLength return list.release(); } +PassRefPtr<SVGPaint> CSSComputedStyleDeclaration::adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint> newPaint, RenderStyle* style) const +{ + RefPtr<SVGPaint> paint = newPaint; + if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR || paint->paintType() == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR) + paint->setColor(style->color()); + return paint.release(); +} + PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const { Node* node = m_node.get(); @@ -127,13 +136,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int pro return CSSPrimitiveValue::create(svgStyle->filterResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyFloodColor: - return CSSPrimitiveValue::createColor(svgStyle->floodColor().rgb()); + return currentColorOrValidColor(style, svgStyle->floodColor()); case CSSPropertyLightingColor: - return CSSPrimitiveValue::createColor(svgStyle->lightingColor().rgb()); + return currentColorOrValidColor(style, svgStyle->lightingColor()); case CSSPropertyStopColor: - return CSSPrimitiveValue::createColor(svgStyle->stopColor().rgb()); + return currentColorOrValidColor(style, svgStyle->stopColor()); case CSSPropertyFill: - return svgStyle->fillPaint(); + return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->fillPaintType(), svgStyle->fillPaintUri(), svgStyle->fillPaintColor()), style); case CSSPropertyKerning: return SVGLength::toCSSPrimitiveValue(svgStyle->kerning()); case CSSPropertyMarkerEnd: @@ -149,7 +158,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int pro return CSSPrimitiveValue::create(svgStyle->markerStartResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyStroke: - return svgStyle->strokePaint(); + return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->strokePaintType(), svgStyle->strokePaintUri(), svgStyle->strokePaintColor()), style); case CSSPropertyStrokeDasharray: return strokeDashArrayToCSSValueList(svgStyle->strokeDashArray()); case CSSPropertyStrokeDashoffset: diff --git a/Source/WebCore/css/SVGCSSParser.cpp b/Source/WebCore/css/SVGCSSParser.cpp index 3c42d40..47f9845 100644 --- a/Source/WebCore/css/SVGCSSParser.cpp +++ b/Source/WebCore/css/SVGCSSParser.cpp @@ -179,17 +179,17 @@ bool CSSParser::parseSVGValue(int propId, bool important) case CSSPropertyStroke: // <paint> | inherit { if (id == CSSValueNone) - parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_NONE); + parsedValue = SVGPaint::createNone(); else if (id == CSSValueCurrentcolor) - parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR); + parsedValue = SVGPaint::createCurrentColor(); else if ((id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSSValueMenu) - parsedValue = SVGPaint::create(RenderTheme::defaultTheme()->systemColor(id)); + parsedValue = SVGPaint::createColor(RenderTheme::defaultTheme()->systemColor(id)); else if (value->unit == CSSPrimitiveValue::CSS_URI) { RGBA32 c = Color::transparent; if (m_valueList->next() && parseColorFromValue(m_valueList->current(), c)) { - parsedValue = SVGPaint::create(value->string, c); + parsedValue = SVGPaint::createURIAndColor(value->string, c); } else - parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_URI, value->string); + parsedValue = SVGPaint::createURI(value->string); } else parsedValue = parseSVGPaint(); @@ -201,7 +201,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) case CSSPropertyColor: // <color> | inherit if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) - parsedValue = SVGColor::create(value->string); + parsedValue = SVGColor::createFromString(value->string); else parsedValue = parseSVGColor(); @@ -214,7 +214,7 @@ bool CSSParser::parseSVGValue(int propId, bool important) case CSSPropertyLightingColor: if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) - parsedValue = SVGColor::create(value->string); + parsedValue = SVGColor::createFromString(value->string); else if (id == CSSValueCurrentcolor) parsedValue = SVGColor::createCurrentColor(); else // TODO : svgcolor (iccColor) @@ -339,8 +339,8 @@ PassRefPtr<CSSValue> CSSParser::parseSVGPaint() { RGBA32 c = Color::transparent; if (!parseColorFromValue(m_valueList->current(), c)) - return SVGPaint::create(); - return SVGPaint::create(Color(c)); + return SVGPaint::createUnknown(); + return SVGPaint::createColor(Color(c)); } PassRefPtr<CSSValue> CSSParser::parseSVGColor() @@ -348,11 +348,9 @@ PassRefPtr<CSSValue> CSSParser::parseSVGColor() RGBA32 c = Color::transparent; if (!parseColorFromValue(m_valueList->current(), c)) return 0; - return SVGColor::create(Color(c)); + return SVGColor::createFromColor(Color(c)); } } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/css/SVGCSSStyleSelector.cpp b/Source/WebCore/css/SVGCSSStyleSelector.cpp index 64665d4..47e3fc3 100644 --- a/Source/WebCore/css/SVGCSSStyleSelector.cpp +++ b/Source/WebCore/css/SVGCSSStyleSelector.cpp @@ -231,17 +231,36 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value) // end of ident only properties case CSSPropertyFill: { - HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint) - if (value->isSVGPaint()) - svgstyle->setFillPaint(static_cast<SVGPaint*>(value)); + if (isInherit) { + const SVGRenderStyle* svgParentStyle = m_parentStyle->svgStyle(); + svgstyle->setFillPaint(svgParentStyle->fillPaintType(), svgParentStyle->fillPaintColor(), svgParentStyle->fillPaintUri()); + return; + } + if (isInitial) { + svgstyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri()); + return; + } + if (value->isSVGPaint()) { + SVGPaint* svgPaint = static_cast<SVGPaint*>(value); + svgstyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, m_style->color()), svgPaint->uri()); + } break; } case CSSPropertyStroke: { - HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint) - if (value->isSVGPaint()) - svgstyle->setStrokePaint(static_cast<SVGPaint*>(value)); - + if (isInherit) { + const SVGRenderStyle* svgParentStyle = m_parentStyle->svgStyle(); + svgstyle->setStrokePaint(svgParentStyle->strokePaintType(), svgParentStyle->strokePaintColor(), svgParentStyle->strokePaintUri()); + return; + } + if (isInitial) { + svgstyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri()); + return; + } + if (value->isSVGPaint()) { + SVGPaint* svgPaint = static_cast<SVGPaint*>(value); + svgstyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, m_style->color()), svgPaint->uri()); + } break; } case CSSPropertyStrokeWidth: diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp index bf0c463..3b41f43 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp @@ -88,7 +88,14 @@ const WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) const void WebKitCSSKeyframesRule::append(WebKitCSSKeyframeRule* rule) { - m_lstCSSRules.get()->append(rule); + if (!rule) + return; + + m_lstCSSRules->append(rule); + rule->setParent(this); + + if (CSSMutableStyleDeclaration* style = rule->style()) + style->setParent(this); } void WebKitCSSKeyframesRule::insertRule(const String& rule) diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css index 0f13fcb..61178d0 100644 --- a/Source/WebCore/css/html.css +++ b/Source/WebCore/css/html.css @@ -113,13 +113,11 @@ q { } q:before { - content: '"' - /* FIXME: content: open-quote; */ + content: open-quote; } q:after { - content: '"' - /* FIXME: content: close-quote; */ + content: close-quote; } center { @@ -832,7 +830,7 @@ rt { ruby > rt { display: block; font-size: 50%; - text-align: center; + text-align: -webkit-auto; } ruby > rp { diff --git a/Source/WebCore/css/mediaControlsChromium.css b/Source/WebCore/css/mediaControlsChromium.css index b8adc2c..60c7d62 100644 --- a/Source/WebCore/css/mediaControlsChromium.css +++ b/Source/WebCore/css/mediaControlsChromium.css @@ -42,7 +42,7 @@ audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { } video:-webkit-full-page-media::-webkit-media-controls-panel { - bottom: -32px; + bottom: 0px; } audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { diff --git a/Source/WebCore/css/themeChromiumLinux.css b/Source/WebCore/css/themeChromiumLinux.css index bd7f961..cb7e900 100644 --- a/Source/WebCore/css/themeChromiumLinux.css +++ b/Source/WebCore/css/themeChromiumLinux.css @@ -32,7 +32,6 @@ select { background-color: #dddddd; - border: 0px; } select[size="0"] option, |