/*
* Copyright (C) 2004 Zack Rusin <zack@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
* Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
*
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSReflectValue.h"
+#include "CSSSelector.h"
#include "CSSTimingFunctionValue.h"
#include "CSSValueList.h"
#include "Document.h"
CSSPropertyWebkitAnimationDelay,
CSSPropertyWebkitAnimationDirection,
CSSPropertyWebkitAnimationDuration,
+ CSSPropertyWebkitAnimationFillMode,
CSSPropertyWebkitAnimationIterationCount,
CSSPropertyWebkitAnimationName,
CSSPropertyWebkitAnimationPlayState,
CSSPropertyWebkitColumnRuleColor,
CSSPropertyWebkitColumnRuleStyle,
CSSPropertyWebkitColumnRuleWidth,
+ CSSPropertyWebkitColumnSpan,
CSSPropertyWebkitColumnWidth,
#if ENABLE(DASHBOARD_SUPPORT)
CSSPropertyWebkitDashboardRegion,
CSSPropertyWritingMode,
CSSPropertyGlyphOrientationHorizontal,
CSSPropertyGlyphOrientationVertical,
- CSSPropertyWebkitShadow
+ CSSPropertyWebkitSvgShadow,
+ CSSPropertyVectorEffect
#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
,
// Create the slices.
RefPtr<CSSPrimitiveValue> top;
- if (image.m_slices.top().isPercent())
- top = CSSPrimitiveValue::create(image.m_slices.top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+ if (image.slices().top().isPercent())
+ top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
else
- top = CSSPrimitiveValue::create(image.m_slices.top().value(), CSSPrimitiveValue::CSS_NUMBER);
+ top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
RefPtr<CSSPrimitiveValue> right;
- if (image.m_slices.right().isPercent())
- right = CSSPrimitiveValue::create(image.m_slices.right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+ if (image.slices().right().isPercent())
+ right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
else
- right = CSSPrimitiveValue::create(image.m_slices.right().value(), CSSPrimitiveValue::CSS_NUMBER);
+ right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
RefPtr<CSSPrimitiveValue> bottom;
- if (image.m_slices.bottom().isPercent())
- bottom = CSSPrimitiveValue::create(image.m_slices.bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+ if (image.slices().bottom().isPercent())
+ bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
else
- bottom = CSSPrimitiveValue::create(image.m_slices.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
+ bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
RefPtr<CSSPrimitiveValue> left;
- if (image.m_slices.left().isPercent())
- left = CSSPrimitiveValue::create(image.m_slices.left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+ if (image.slices().left().isPercent())
+ left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
else
- left = CSSPrimitiveValue::create(image.m_slices.left().value(), CSSPrimitiveValue::CSS_NUMBER);
+ left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
RefPtr<Rect> rect = Rect::create();
rect->setTop(top);
rect->setBottom(bottom);
rect->setLeft(left);
- return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.m_horizontalRule), valueForRepeatRule(image.m_verticalRule));
+ return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.horizontalRule()), valueForRepeatRule(image.verticalRule()));
}
static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection)
return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
}
-static PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle* style, const Color& color)
+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.
if (!color.isValid())
return CSSPrimitiveValue::createColor(style->color().rgb());
return CSSPrimitiveValue::createColor(color.rgb());
return list.release();
}
-CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n)
+CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
: m_node(n)
+ , m_allowVisitedStyle(allowVisitedStyle)
{
+ unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
+ m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
+ AtomicString(pseudoElementName.substring(nameWithoutColonsStart))));
}
CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
node->document()->updateLayoutIgnorePendingStylesheets();
- RefPtr<RenderStyle> style = node->computedStyle();
+ RefPtr<RenderStyle> style = node->computedStyle(m_pseudoElementSpecifier);
if (!style)
return 0;
CSSPropertyID propertyID = static_cast<CSSPropertyID>(id);
RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- for (const ShadowData* s = shadow; s; s = s->next) {
- RefPtr<CSSPrimitiveValue> x = CSSPrimitiveValue::create(s->x, CSSPrimitiveValue::CSS_PX);
- RefPtr<CSSPrimitiveValue> y = CSSPrimitiveValue::create(s->y, CSSPrimitiveValue::CSS_PX);
- RefPtr<CSSPrimitiveValue> blur = CSSPrimitiveValue::create(s->blur, CSSPrimitiveValue::CSS_PX);
- RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : CSSPrimitiveValue::create(s->spread, CSSPrimitiveValue::CSS_PX);
- RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style == Normal ? 0 : CSSPrimitiveValue::createIdentifier(CSSValueInset);
- RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color.rgb());
+ for (const ShadowData* s = shadow; s; s = s->next()) {
+ RefPtr<CSSPrimitiveValue> x = CSSPrimitiveValue::create(s->x(), CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> y = CSSPrimitiveValue::create(s->y(), CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> blur = CSSPrimitiveValue::create(s->blur(), CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : CSSPrimitiveValue::create(s->spread(), CSSPrimitiveValue::CSS_PX);
+ RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? 0 : CSSPrimitiveValue::createIdentifier(CSSValueInset);
+ RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color().rgb());
list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
}
return list.release();
// if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
if (xRepeat == yRepeat)
return CSSPrimitiveValue::create(xRepeat);
- if (xRepeat == CSSValueRepeat && yRepeat == CSSValueNoRepeat)
+ if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
return CSSPrimitiveValue::createIdentifier(CSSValueRepeatX);
- if (xRepeat == CSSValueNoRepeat && yRepeat == CSSValueRepeat)
+ if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
return CSSPrimitiveValue::createIdentifier(CSSValueRepeatY);
RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
RenderObject* renderer = node->renderer();
RefPtr<RenderStyle> style;
- if (renderer && hasCompositedLayer(renderer) && AnimationController::supportsAcceleratedAnimationOfProperty(static_cast<CSSPropertyID>(propertyID)))
+ if (renderer && hasCompositedLayer(renderer) && AnimationController::supportsAcceleratedAnimationOfProperty(static_cast<CSSPropertyID>(propertyID))) {
style = renderer->animation()->getAnimatedStyleForRenderer(renderer);
- else
- style = node->computedStyle();
+ if (m_pseudoElementSpecifier) {
+ // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
+ style = style->getCachedPseudoStyle(m_pseudoElementSpecifier);
+ }
+ } else
+ style = node->computedStyle(m_pseudoElementSpecifier);
+
if (!style)
return 0;
+ propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction());
#ifdef ANDROID_LAYOUT
const Settings * settings = node->document()->frame() ? node->document()->frame()->settings() : 0;
#endif
break;
case CSSPropertyBackgroundColor:
- return CSSPrimitiveValue::createColor(style->backgroundColor().rgb());
+ return CSSPrimitiveValue::createColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
case CSSPropertyBackgroundImage:
if (style->backgroundImage())
return style->backgroundImage()->cssValue();
case CSSPropertyWebkitBorderVerticalSpacing:
return CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
case CSSPropertyBorderTopColor:
- return currentColorOrValidColor(style.get(), style->borderTopColor());
+ return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
case CSSPropertyBorderRightColor:
- return currentColorOrValidColor(style.get(), style->borderRightColor());
+ return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
case CSSPropertyBorderBottomColor:
- return currentColorOrValidColor(style.get(), style->borderBottomColor());
+ return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
case CSSPropertyBorderLeftColor:
- return currentColorOrValidColor(style.get(), style->borderLeftColor());
+ return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
case CSSPropertyBorderTopStyle:
return CSSPrimitiveValue::create(style->borderTopStyle());
case CSSPropertyBorderRightStyle:
case CSSPropertyClear:
return CSSPrimitiveValue::create(style->clear());
case CSSPropertyColor:
- return CSSPrimitiveValue::createColor(style->color().rgb());
+ return CSSPrimitiveValue::createColor(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
case CSSPropertyWebkitColumnCount:
if (style->hasAutoColumnCount())
return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyWebkitColumnRuleColor:
- return currentColorOrValidColor(style.get(), style->columnRuleColor());
+ return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
case CSSPropertyWebkitColumnRuleStyle:
return CSSPrimitiveValue::create(style->columnRuleStyle());
case CSSPropertyWebkitColumnRuleWidth:
return CSSPrimitiveValue::create(style->columnRuleWidth(), CSSPrimitiveValue::CSS_PX);
+ case CSSPropertyWebkitColumnSpan:
+ if (style->columnSpan())
+ return CSSPrimitiveValue::createIdentifier(CSSValueAll);
+ return CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyWebkitColumnBreakAfter:
return CSSPrimitiveValue::create(style->columnBreakAfter());
case CSSPropertyWebkitColumnBreakBefore:
if (cursors && cursors->size() > 0) {
list = CSSValueList::createCommaSeparated();
for (unsigned i = 0; i < cursors->size(); ++i)
- list->append(CSSPrimitiveValue::create((*cursors)[i].cursorImage->url(), CSSPrimitiveValue::CSS_URI));
+ list->append(CSSPrimitiveValue::create((*cursors)[i].image()->url(), CSSPrimitiveValue::CSS_URI));
}
RefPtr<CSSValue> value = CSSPrimitiveValue::create(style->cursor());
if (list) {
if (style->highlight() == nullAtom)
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
return CSSPrimitiveValue::create(style->highlight(), CSSPrimitiveValue::CSS_STRING);
+ case CSSPropertyWebkitHyphens:
+ return CSSPrimitiveValue::create(style->hyphens());
+ case CSSPropertyWebkitHyphenateCharacter:
+ if (style->hyphenationString().isNull())
+ return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
+ return CSSPrimitiveValue::create(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
+ case CSSPropertyWebkitHyphenateLocale:
+ if (style->hyphenationLocale().isNull())
+ return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
+ return CSSPrimitiveValue::create(style->hyphenationLocale(), CSSPrimitiveValue::CSS_STRING);
case CSSPropertyWebkitBorderFit:
if (style->borderFit() == BorderFitBorder)
return CSSPrimitiveValue::createIdentifier(CSSValueBorder);
// 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.
- // The line height returned is rounded to the nearest integer.
- return CSSPrimitiveValue::create(length.calcMinValue(style->fontDescription().specifiedSize(), true), CSSPrimitiveValue::CSS_PX);
+ return CSSPrimitiveValue::create(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, CSSPrimitiveValue::CSS_PX);
return CSSPrimitiveValue::create(length.value(), CSSPrimitiveValue::CSS_PX);
}
case CSSPropertyListStyleImage:
return style->maskImage()->cssValue();
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyWebkitMaskSize: {
+ EFillSizeType size = style->maskSizeType();
+ if (size == Contain)
+ return CSSPrimitiveValue::createIdentifier(CSSValueContain);
+ if (size == Cover)
+ return CSSPrimitiveValue::createIdentifier(CSSValueCover);
RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- list->append(CSSPrimitiveValue::create(style->maskSize().width()));
- list->append(CSSPrimitiveValue::create(style->maskSize().height()));
+ list->append(CSSPrimitiveValue::create(style->maskSizeLength().width()));
+ list->append(CSSPrimitiveValue::create(style->maskSizeLength().height()));
return list.release();
}
case CSSPropertyWebkitMaskRepeat:
case CSSPropertyOrphans:
return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyOutlineColor:
- return currentColorOrValidColor(style.get(), style->outlineColor());
+ return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
case CSSPropertyOutlineStyle:
if (style->outlineStyleIsAuto())
return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
}
case CSSPropertyWebkitAnimationDuration:
return getDurationValue(style->animations());
+ case CSSPropertyWebkitAnimationFillMode: {
+ RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ const AnimationList* t = style->animations();
+ if (t) {
+ for (size_t i = 0; i < t->size(); ++i) {
+ switch (t->animation(i)->fillMode()) {
+ case AnimationFillModeNone:
+ list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
+ break;
+ case AnimationFillModeForwards:
+ list->append(CSSPrimitiveValue::createIdentifier(CSSValueForwards));
+ break;
+ case AnimationFillModeBackwards:
+ list->append(CSSPrimitiveValue::createIdentifier(CSSValueBackwards));
+ break;
+ case AnimationFillModeBoth:
+ list->append(CSSPrimitiveValue::createIdentifier(CSSValueBoth));
+ break;
+ }
+ }
+ } else
+ list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
+ return list.release();
+ }
case CSSPropertyWebkitAnimationIterationCount: {
RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
const AnimationList* t = style->animations();
case CSSPropertyTextUnderlineWidth:
break;
+ /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
+ case CSSPropertyWebkitBorderEnd:
+ case CSSPropertyWebkitBorderEndColor:
+ case CSSPropertyWebkitBorderEndStyle:
+ case CSSPropertyWebkitBorderEndWidth:
+ case CSSPropertyWebkitBorderStart:
+ case CSSPropertyWebkitBorderStartColor:
+ case CSSPropertyWebkitBorderStartStyle:
+ case CSSPropertyWebkitBorderStartWidth:
+ case CSSPropertyWebkitMarginEnd:
+ case CSSPropertyWebkitMarginStart:
+ case CSSPropertyWebkitPaddingEnd:
+ case CSSPropertyWebkitPaddingStart:
+ ASSERT_NOT_REACHED();
+ break;
+
/* Unimplemented @font-face properties */
case CSSPropertyFontStretch:
case CSSPropertySrc:
break;
/* Other unimplemented properties */
+ case CSSPropertyBackgroundRepeatX:
+ case CSSPropertyBackgroundRepeatY:
case CSSPropertyContent: // FIXME: needs implementation, bug 23668
case CSSPropertyCounterIncrement:
case CSSPropertyCounterReset:
case CSSPropertyWebkitColumns:
case CSSPropertyWebkitColumnRule:
case CSSPropertyWebkitMarginCollapse:
- case CSSPropertyWebkitMarginStart:
case CSSPropertyWebkitMarquee:
case CSSPropertyWebkitMarqueeSpeed:
case CSSPropertyWebkitMask:
- case CSSPropertyWebkitPaddingStart:
+ case CSSPropertyWebkitMaskRepeatX:
+ case CSSPropertyWebkitMaskRepeatY:
case CSSPropertyWebkitPerspectiveOriginX:
case CSSPropertyWebkitPerspectiveOriginY:
case CSSPropertyWebkitTextStroke:
ec = NO_MODIFICATION_ALLOWED_ERR;
}
-unsigned CSSComputedStyleDeclaration::length() const
+unsigned CSSComputedStyleDeclaration::virtualLength() const
{
Node* node = m_node.get();
if (!node)
return 0;
- RenderStyle* style = node->computedStyle();
+ RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
if (!style)
return 0;
{
if (property->id() == CSSPropertyFontSize && property->value()->isPrimitiveValue() && m_node) {
m_node->document()->updateLayoutIgnorePendingStylesheets();
- RenderStyle* style = m_node->computedStyle();
+ RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
if (style && style->fontDescription().keywordSize()) {
int sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(property->value());