#include "config.h"
#include "core/css/resolver/CSSToStyleMap.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/animation/css/CSSAnimationData.h"
#include "core/css/CSSBorderImageSliceValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/rendering/style/BorderImageLengthBox.h"
#include "core/rendering/style/FillLayer.h"
-namespace WebCore {
+namespace blink {
const CSSToLengthConversionData& CSSToStyleMap::cssToLengthConversionData() const
{
return m_state.cssToLengthConversionData();
}
-bool CSSToStyleMap::useSVGZoomRules() const
-{
- return m_state.useSVGZoomRules();
-}
-
PassRefPtr<StyleImage> CSSToStyleMap::styleImage(CSSPropertyID propertyId, CSSValue* value)
{
- return m_elementStyleResources.styleImage(m_state.document().textLinkColors(), m_state.style()->color(), propertyId, value);
+ return m_elementStyleResources.styleImage(m_state.document(), m_state.document().textLinkColors(), m_state.style()->color(), propertyId, value);
}
-void CSSToStyleMap::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillAttachment(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setAttachment(FillLayer::initialFillAttachment(layer->type()));
}
}
-void CSSToStyleMap::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillClip(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setClip(FillLayer::initialFillClip(layer->type()));
layer->setClip(*primitiveValue);
}
-void CSSToStyleMap::mapFillComposite(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillComposite(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setComposite(FillLayer::initialFillComposite(layer->type()));
layer->setComposite(*primitiveValue);
}
-void CSSToStyleMap::mapFillBlendMode(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillBlendMode(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setBlendMode(FillLayer::initialFillBlendMode(layer->type()));
layer->setBlendMode(*primitiveValue);
}
-void CSSToStyleMap::mapFillOrigin(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillOrigin(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setOrigin(FillLayer::initialFillOrigin(layer->type()));
}
-void CSSToStyleMap::mapFillImage(CSSPropertyID property, FillLayer* layer, CSSValue* value)
+void CSSToStyleMap::mapFillImage(FillLayer* layer, CSSValue* value)
{
if (value->isInitialValue()) {
layer->setImage(FillLayer::initialFillImage(layer->type()));
return;
}
+ CSSPropertyID property = layer->type() == BackgroundFillLayer ? CSSPropertyBackgroundImage : CSSPropertyWebkitMaskImage;
layer->setImage(styleImage(property, value));
}
-void CSSToStyleMap::mapFillRepeatX(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillRepeatX(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setRepeatX(FillLayer::initialFillRepeatX(layer->type()));
layer->setRepeatX(*primitiveValue);
}
-void CSSToStyleMap::mapFillRepeatY(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillRepeatY(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setRepeatY(FillLayer::initialFillRepeatY(layer->type()));
layer->setRepeatY(*primitiveValue);
}
-void CSSToStyleMap::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillSize(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setSizeType(FillLayer::initialFillSizeType(layer->type()));
layer->setSizeLength(b);
}
-void CSSToStyleMap::mapFillXPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillXPosition(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setXPosition(FillLayer::initialFillXPosition(layer->type()));
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
Pair* pair = primitiveValue->getPairValue();
- if (pair) {
- ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionX || propertyID == CSSPropertyWebkitMaskPositionX);
+ if (pair)
primitiveValue = pair->second();
- }
Length length = primitiveValue->convertToLength<FixedConversion | PercentConversion>(cssToLengthConversionData());
layer->setBackgroundXOrigin(*(pair->first()));
}
-void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) const
+void CSSToStyleMap::mapFillYPosition(FillLayer* layer, CSSValue* value) const
{
if (value->isInitialValue()) {
layer->setYPosition(FillLayer::initialFillYPosition(layer->type()));
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
Pair* pair = primitiveValue->getPairValue();
- if (pair) {
- ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionY || propertyID == CSSPropertyWebkitMaskPositionY);
+ if (pair)
primitiveValue = pair->second();
- }
Length length = primitiveValue->convertToLength<FixedConversion | PercentConversion>(cssToLengthConversionData());
layer->setBackgroundYOrigin(*(pair->first()));
}
-void CSSToStyleMap::mapFillMaskSourceType(CSSPropertyID, FillLayer* layer, CSSValue* value)
+void CSSToStyleMap::mapFillMaskSourceType(FillLayer* layer, CSSValue* value) const
{
EMaskSourceType type = FillLayer::initialFillMaskSourceType(layer->type());
if (value->isInitialValue()) {
layer->setMaskSourceType(type);
}
-void CSSToStyleMap::mapAnimationDelay(CSSAnimationData* animation, CSSValue* value) const
+double CSSToStyleMap::mapAnimationDelay(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setDelay(CSSAnimationData::initialAnimationDelay());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
- animation->setDelay(toCSSPrimitiveValue(value)->computeTime<double, CSSPrimitiveValue::Seconds>());
+ if (value->isInitialValue())
+ return CSSTimingData::initialDelay();
+ return toCSSPrimitiveValue(value)->computeSeconds();
}
-void CSSToStyleMap::mapAnimationDirection(CSSAnimationData* layer, CSSValue* value) const
+Timing::PlaybackDirection CSSToStyleMap::mapAnimationDirection(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setDirection(CSSAnimationData::initialAnimationDirection());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
+ if (value->isInitialValue())
+ return CSSAnimationData::initialDirection();
switch (toCSSPrimitiveValue(value)->getValueID()) {
case CSSValueNormal:
- layer->setDirection(CSSAnimationData::AnimationDirectionNormal);
- break;
+ return Timing::PlaybackDirectionNormal;
case CSSValueAlternate:
- layer->setDirection(CSSAnimationData::AnimationDirectionAlternate);
- break;
+ return Timing::PlaybackDirectionAlternate;
case CSSValueReverse:
- layer->setDirection(CSSAnimationData::AnimationDirectionReverse);
- break;
+ return Timing::PlaybackDirectionReverse;
case CSSValueAlternateReverse:
- layer->setDirection(CSSAnimationData::AnimationDirectionAlternateReverse);
- break;
+ return Timing::PlaybackDirectionAlternateReverse;
default:
- break;
+ ASSERT_NOT_REACHED();
+ return CSSAnimationData::initialDirection();
}
}
-void CSSToStyleMap::mapAnimationDuration(CSSAnimationData* animation, CSSValue* value) const
+double CSSToStyleMap::mapAnimationDuration(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setDuration(CSSAnimationData::initialAnimationDuration());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- animation->setDuration(primitiveValue->computeTime<double, CSSPrimitiveValue::Seconds>());
+ if (value->isInitialValue())
+ return CSSTimingData::initialDuration();
+ return toCSSPrimitiveValue(value)->computeSeconds();
}
-void CSSToStyleMap::mapAnimationFillMode(CSSAnimationData* layer, CSSValue* value) const
+Timing::FillMode CSSToStyleMap::mapAnimationFillMode(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setFillMode(CSSAnimationData::initialAnimationFillMode());
- return;
- }
+ if (value->isInitialValue())
+ return CSSAnimationData::initialFillMode();
- if (!value->isPrimitiveValue())
- return;
-
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- switch (primitiveValue->getValueID()) {
+ switch (toCSSPrimitiveValue(value)->getValueID()) {
case CSSValueNone:
- layer->setFillMode(AnimationFillModeNone);
- break;
+ return Timing::FillModeNone;
case CSSValueForwards:
- layer->setFillMode(AnimationFillModeForwards);
- break;
+ return Timing::FillModeForwards;
case CSSValueBackwards:
- layer->setFillMode(AnimationFillModeBackwards);
- break;
+ return Timing::FillModeBackwards;
case CSSValueBoth:
- layer->setFillMode(AnimationFillModeBoth);
- break;
+ return Timing::FillModeBoth;
default:
- break;
+ ASSERT_NOT_REACHED();
+ return CSSAnimationData::initialFillMode();
}
}
-void CSSToStyleMap::mapAnimationIterationCount(CSSAnimationData* animation, CSSValue* value) const
+double CSSToStyleMap::mapAnimationIterationCount(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setIterationCount(CSSAnimationData::initialAnimationIterationCount());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
+ if (value->isInitialValue())
+ return CSSAnimationData::initialIterationCount();
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == CSSValueInfinite)
- animation->setIterationCount(CSSAnimationData::IterationCountInfinite);
- else
- animation->setIterationCount(primitiveValue->getFloatValue());
+ return std::numeric_limits<double>::infinity();
+ return primitiveValue->getFloatValue();
}
-void CSSToStyleMap::mapAnimationName(CSSAnimationData* layer, CSSValue* value) const
+AtomicString CSSToStyleMap::mapAnimationName(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setName(CSSAnimationData::initialAnimationName());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
+ if (value->isInitialValue())
+ return CSSAnimationData::initialName();
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == CSSValueNone)
- layer->setIsNoneAnimation(true);
- else
- layer->setName(AtomicString(primitiveValue->getStringValue()));
+ return CSSAnimationData::initialName();
+ return AtomicString(primitiveValue->getStringValue());
}
-void CSSToStyleMap::mapAnimationPlayState(CSSAnimationData* layer, CSSValue* value) const
+EAnimPlayState CSSToStyleMap::mapAnimationPlayState(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setPlayState(CSSAnimationData::initialAnimationPlayState());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- EAnimPlayState playState = (primitiveValue->getValueID() == CSSValuePaused) ? AnimPlayStatePaused : AnimPlayStatePlaying;
- layer->setPlayState(playState);
+ if (value->isInitialValue())
+ return CSSAnimationData::initialPlayState();
+ if (toCSSPrimitiveValue(value)->getValueID() == CSSValuePaused)
+ return AnimPlayStatePaused;
+ ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueRunning);
+ return AnimPlayStatePlaying;
}
-void CSSToStyleMap::mapAnimationProperty(CSSAnimationData* animation, CSSValue* value) const
+CSSTransitionData::TransitionProperty CSSToStyleMap::mapAnimationProperty(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setAnimationMode(CSSAnimationData::AnimateAll);
- animation->setProperty(CSSPropertyInvalid);
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
+ if (value->isInitialValue())
+ return CSSTransitionData::initialProperty();
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->getValueID() == CSSValueAll) {
- animation->setAnimationMode(CSSAnimationData::AnimateAll);
- animation->setProperty(CSSPropertyInvalid);
- } else if (primitiveValue->getValueID() == CSSValueNone) {
- animation->setAnimationMode(CSSAnimationData::AnimateNone);
- animation->setProperty(CSSPropertyInvalid);
- } else {
- animation->setAnimationMode(CSSAnimationData::AnimateSingleProperty);
- animation->setProperty(primitiveValue->getPropertyID());
- }
+ if (primitiveValue->isString())
+ return CSSTransitionData::TransitionProperty(primitiveValue->getStringValue());
+ if (primitiveValue->getValueID() == CSSValueAll)
+ return CSSTransitionData::TransitionProperty(CSSTransitionData::TransitionAll);
+ if (primitiveValue->getValueID() == CSSValueNone)
+ return CSSTransitionData::TransitionProperty(CSSTransitionData::TransitionNone);
+ return CSSTransitionData::TransitionProperty(primitiveValue->getPropertyID());
}
-PassRefPtr<TimingFunction> CSSToStyleMap::animationTimingFunction(CSSValue* value, bool allowInitial)
+PassRefPtr<TimingFunction> CSSToStyleMap::mapAnimationTimingFunction(CSSValue* value, bool allowStepMiddle)
{
- if (allowInitial && value->isInitialValue()) {
- return CSSAnimationData::initialAnimationTimingFunction();
- }
+ // FIXME: We should probably only call into this function with a valid
+ // single timing function value which isn't initial or inherit. We can
+ // currently get into here with initial since the parser expands unset
+ // properties in shorthands to initial.
if (value->isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
switch (primitiveValue->getValueID()) {
case CSSValueLinear:
- return LinearTimingFunction::preset();
- break;
+ return LinearTimingFunction::shared();
case CSSValueEase:
return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
- break;
case CSSValueEaseIn:
return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- break;
case CSSValueEaseOut:
return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
- break;
case CSSValueEaseInOut:
return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
- break;
case CSSValueStepStart:
return StepsTimingFunction::preset(StepsTimingFunction::Start);
- break;
case CSSValueStepMiddle:
- return StepsTimingFunction::preset(StepsTimingFunction::Middle);
- break;
+ if (allowStepMiddle)
+ return StepsTimingFunction::preset(StepsTimingFunction::Middle);
+ return CSSTimingData::initialTimingFunction();
case CSSValueStepEnd:
return StepsTimingFunction::preset(StepsTimingFunction::End);
- break;
default:
- break;
+ ASSERT_NOT_REACHED();
+ return CSSTimingData::initialTimingFunction();
}
- return nullptr;
}
if (value->isCubicBezierTimingFunctionValue()) {
CSSCubicBezierTimingFunctionValue* cubicTimingFunction = toCSSCubicBezierTimingFunctionValue(value);
return CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2());
- } else if (value->isStepsTimingFunctionValue()) {
- CSSStepsTimingFunctionValue* stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
- return StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtPosition());
}
- return nullptr;
-}
+ if (value->isInitialValue())
+ return CSSTimingData::initialTimingFunction();
-void CSSToStyleMap::mapAnimationTimingFunction(CSSAnimationData* animation, CSSValue* value) const
-{
- RefPtr<TimingFunction> timingFunction = animationTimingFunction(value, true);
- if (timingFunction) {
- // Step middle timing functions are supported up to this point for use in the Web Animations API,
- // but should not be supported for CSS Animations and Transitions.
- bool isStepMiddleFunction = (timingFunction->type() == TimingFunction::StepsFunction) && (toStepsTimingFunction(*timingFunction).stepAtPosition() == StepsTimingFunction::StepAtMiddle);
- if (isStepMiddleFunction)
- animation->setTimingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease));
- else
- animation->setTimingFunction(timingFunction);
- }
+ CSSStepsTimingFunctionValue* stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
+ if (stepsTimingFunction->stepAtPosition() == StepsTimingFunction::Middle && !allowStepMiddle)
+ return CSSTimingData::initialTimingFunction();
+ return StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtPosition());
}
void CSSToStyleMap::mapNinePieceImage(RenderStyle* mutableStyle, CSSPropertyID property, CSSValue* value, NinePieceImage& image)
mapNinePieceImageSlice(current, image);
else if (current->isValueList()) {
CSSValueList* slashList = toCSSValueList(current);
+ size_t length = slashList->length();
// Map in the image slices.
- if (slashList->item(0) && slashList->item(0)->isBorderImageSliceValue())
+ if (length && slashList->item(0)->isBorderImageSliceValue())
mapNinePieceImageSlice(slashList->item(0), image);
// Map in the border slices.
- if (slashList->item(1))
+ if (length > 1)
image.setBorderSlices(mapNinePieceImageQuad(slashList->item(1)));
// Map in the outset.
- if (slashList->item(2))
+ if (length > 2)
image.setOutset(mapNinePieceImageQuad(slashList->item(2)));
} else if (current->isPrimitiveValue()) {
// Set the appropriate rules for stretch/round/repeat of the slices.
if (!value || !value->isPrimitiveValue())
return BorderImageLengthBox(Length(Auto));
- float zoom = useSVGZoomRules() ? 1.0f : cssToLengthConversionData().zoom();
Quad* slices = toCSSPrimitiveValue(value)->getQuadValue();
// Set up a border image length box to represent our image slices.
- const CSSToLengthConversionData& conversionData = cssToLengthConversionData().copyWithAdjustedZoom(zoom);
return BorderImageLengthBox(
- toBorderImageLength(*slices->top(), conversionData),
- toBorderImageLength(*slices->right(), conversionData),
- toBorderImageLength(*slices->bottom(), conversionData),
- toBorderImageLength(*slices->left(), conversionData));
+ toBorderImageLength(*slices->top(), cssToLengthConversionData()),
+ toBorderImageLength(*slices->right(), cssToLengthConversionData()),
+ toBorderImageLength(*slices->bottom(), cssToLengthConversionData()),
+ toBorderImageLength(*slices->left(), cssToLengthConversionData()));
}
void CSSToStyleMap::mapNinePieceImageRepeat(CSSValue* value, NinePieceImage& image) const