diff options
Diffstat (limited to 'Source/WebCore/css/StyleResolver.cpp')
-rw-r--r-- | Source/WebCore/css/StyleResolver.cpp | 604 |
1 files changed, 8 insertions, 596 deletions
diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 252298fc5..de3a0a9bd 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -8,6 +8,7 @@ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2012 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -374,6 +375,7 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) , m_scopeStackParent(0) , m_scopeStackParentBoundsIndex(0) #endif + , m_styleMap(this) { Element* root = document->documentElement(); @@ -3740,7 +3742,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) reflection->setOffset(reflectValue->offset()->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(style(), m_rootElementStyle, zoomFactor)); NinePieceImage mask; mask.setMaskDefaults(); - mapNinePieceImage(id, reflectValue->mask(), mask); + m_styleMap.mapNinePieceImage(id, reflectValue->mask(), mask); reflection->setMask(mask); m_style->setBoxReflect(reflection.release()); @@ -4158,7 +4160,11 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) m_style->setGridItemRow(row); return; } - +#if ENABLE(CSS_VARIABLES) + case CSSPropertyVariable: + // FIXME: This should have an actual implementation. + return; +#endif // These properties are implemented in the StyleBuilder lookup table. case CSSPropertyBackgroundAttachment: case CSSPropertyBackgroundClip: @@ -4428,74 +4434,6 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) } } -void StyleResolver::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setAttachment(FillLayer::initialFillAttachment(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - switch (primitiveValue->getIdent()) { - case CSSValueFixed: - layer->setAttachment(FixedBackgroundAttachment); - break; - case CSSValueScroll: - layer->setAttachment(ScrollBackgroundAttachment); - break; - case CSSValueLocal: - layer->setAttachment(LocalBackgroundAttachment); - break; - default: - return; - } -} - -void StyleResolver::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setClip(FillLayer::initialFillClip(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - layer->setClip(*primitiveValue); -} - -void StyleResolver::mapFillComposite(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setComposite(FillLayer::initialFillComposite(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - layer->setComposite(*primitiveValue); -} - -void StyleResolver::mapFillOrigin(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setOrigin(FillLayer::initialFillOrigin(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - layer->setOrigin(*primitiveValue); -} - PassRefPtr<StyleImage> StyleResolver::styleImage(CSSPropertyID property, CSSValue* value) { if (value->isImageValue()) @@ -4539,532 +4477,6 @@ PassRefPtr<StyleImage> StyleResolver::setOrPendingFromValue(CSSPropertyID proper } #endif -void StyleResolver::mapFillImage(CSSPropertyID property, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setImage(FillLayer::initialFillImage(layer->type())); - return; - } - - layer->setImage(styleImage(property, value)); -} - -void StyleResolver::mapFillRepeatX(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setRepeatX(FillLayer::initialFillRepeatX(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - layer->setRepeatX(*primitiveValue); -} - -void StyleResolver::mapFillRepeatY(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setRepeatY(FillLayer::initialFillRepeatY(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - layer->setRepeatY(*primitiveValue); -} - -void StyleResolver::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (!value->isPrimitiveValue()) { - layer->setSizeType(SizeNone); - return; - } - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->getIdent() == CSSValueContain) - layer->setSizeType(Contain); - else if (primitiveValue->getIdent() == CSSValueCover) - layer->setSizeType(Cover); - else - layer->setSizeType(SizeLength); - - LengthSize b = FillLayer::initialFillSizeLength(layer->type()); - - if (value->isInitialValue() || primitiveValue->getIdent() == CSSValueContain || primitiveValue->getIdent() == CSSValueCover) { - layer->setSizeLength(b); - return; - } - - float zoomFactor = m_style->effectiveZoom(); - - Length firstLength; - Length secondLength; - - if (Pair* pair = primitiveValue->getPairValue()) { - CSSPrimitiveValue* first = static_cast<CSSPrimitiveValue*>(pair->first()); - CSSPrimitiveValue* second = static_cast<CSSPrimitiveValue*>(pair->second()); - firstLength = first->convertToLength<AnyConversion>(style(), m_rootElementStyle, zoomFactor); - secondLength = second->convertToLength<AnyConversion>(style(), m_rootElementStyle, zoomFactor); - } else { - firstLength = primitiveValue->convertToLength<AnyConversion>(style(), m_rootElementStyle, zoomFactor); - secondLength = Length(); - } - - if (firstLength.isUndefined() || secondLength.isUndefined()) - return; - - b.setWidth(firstLength); - b.setHeight(secondLength); - layer->setSizeLength(b); -} - -void StyleResolver::mapFillXPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setXPosition(FillLayer::initialFillXPosition(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - float zoomFactor = m_style->effectiveZoom(); - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - Length length; - if (primitiveValue->isLength()) - length = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); - else if (primitiveValue->isPercentage()) - length = Length(primitiveValue->getDoubleValue(), Percent); - else if (primitiveValue->isCalculatedPercentageWithLength()) - length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), m_rootElementStyle, zoomFactor)); - else if (primitiveValue->isViewportPercentageLength()) - length = primitiveValue->viewportPercentageLength(); - else - return; - layer->setXPosition(length); -} - -void StyleResolver::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); - return; - } - - if (!value->isPrimitiveValue()) - return; - - float zoomFactor = m_style->effectiveZoom(); - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - Length length; - if (primitiveValue->isLength()) - length = primitiveValue->computeLength<Length>(style(), m_rootElementStyle, zoomFactor); - else if (primitiveValue->isPercentage()) - length = Length(primitiveValue->getDoubleValue(), Percent); - else if (primitiveValue->isCalculatedPercentageWithLength()) - length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), m_rootElementStyle, zoomFactor)); - else if (primitiveValue->isViewportPercentageLength()) - length = primitiveValue->viewportPercentageLength(); - else - return; - layer->setYPosition(length); -} - -void StyleResolver::mapAnimationDelay(Animation* animation, CSSValue* value) -{ - if (value->isInitialValue()) { - animation->setDelay(Animation::initialAnimationDelay()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - animation->setDelay(primitiveValue->computeTime<float, CSSPrimitiveValue::Seconds>()); -} - -void StyleResolver::mapAnimationDirection(Animation* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setDirection(Animation::initialAnimationDirection()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - switch (primitiveValue->getIdent()) { - case CSSValueNormal: - layer->setDirection(Animation::AnimationDirectionNormal); - break; - case CSSValueAlternate: - layer->setDirection(Animation::AnimationDirectionAlternate); - break; - case CSSValueReverse: - layer->setDirection(Animation::AnimationDirectionReverse); - break; - case CSSValueAlternateReverse: - layer->setDirection(Animation::AnimationDirectionAlternateReverse); - break; - } -} - -void StyleResolver::mapAnimationDuration(Animation* animation, CSSValue* value) -{ - if (value->isInitialValue()) { - animation->setDuration(Animation::initialAnimationDuration()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - animation->setDuration(primitiveValue->computeTime<float, CSSPrimitiveValue::Seconds>()); -} - -void StyleResolver::mapAnimationFillMode(Animation* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setFillMode(Animation::initialAnimationFillMode()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - switch (primitiveValue->getIdent()) { - case CSSValueNone: - layer->setFillMode(AnimationFillModeNone); - break; - case CSSValueForwards: - layer->setFillMode(AnimationFillModeForwards); - break; - case CSSValueBackwards: - layer->setFillMode(AnimationFillModeBackwards); - break; - case CSSValueBoth: - layer->setFillMode(AnimationFillModeBoth); - break; - } -} - -void StyleResolver::mapAnimationIterationCount(Animation* animation, CSSValue* value) -{ - if (value->isInitialValue()) { - animation->setIterationCount(Animation::initialAnimationIterationCount()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->getIdent() == CSSValueInfinite) - animation->setIterationCount(-1); - else - animation->setIterationCount(primitiveValue->getFloatValue()); -} - -void StyleResolver::mapAnimationName(Animation* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setName(Animation::initialAnimationName()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->getIdent() == CSSValueNone) - layer->setIsNoneAnimation(true); - else - layer->setName(primitiveValue->getStringValue()); -} - -void StyleResolver::mapAnimationPlayState(Animation* layer, CSSValue* value) -{ - if (value->isInitialValue()) { - layer->setPlayState(Animation::initialAnimationPlayState()); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - EAnimPlayState playState = (primitiveValue->getIdent() == CSSValuePaused) ? AnimPlayStatePaused : AnimPlayStatePlaying; - layer->setPlayState(playState); -} - -void StyleResolver::mapAnimationProperty(Animation* animation, CSSValue* value) -{ - if (value->isInitialValue()) { - animation->setAnimationMode(Animation::AnimateAll); - animation->setProperty(CSSPropertyInvalid); - return; - } - - if (!value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - if (primitiveValue->getIdent() == CSSValueAll) { - animation->setAnimationMode(Animation::AnimateAll); - animation->setProperty(CSSPropertyInvalid); - } else if (primitiveValue->getIdent() == CSSValueNone) { - animation->setAnimationMode(Animation::AnimateNone); - animation->setProperty(CSSPropertyInvalid); - } else { - animation->setAnimationMode(Animation::AnimateSingleProperty); - animation->setProperty(static_cast<CSSPropertyID>(primitiveValue->getIdent())); - } -} - -void StyleResolver::mapAnimationTimingFunction(Animation* animation, CSSValue* value) -{ - if (value->isInitialValue()) { - animation->setTimingFunction(Animation::initialAnimationTimingFunction()); - return; - } - - if (value->isPrimitiveValue()) { - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - switch (primitiveValue->getIdent()) { - case CSSValueLinear: - animation->setTimingFunction(LinearTimingFunction::create()); - break; - case CSSValueEase: - animation->setTimingFunction(CubicBezierTimingFunction::create()); - break; - case CSSValueEaseIn: - animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0)); - break; - case CSSValueEaseOut: - animation->setTimingFunction(CubicBezierTimingFunction::create(0.0, 0.0, 0.58, 1.0)); - break; - case CSSValueEaseInOut: - animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 0.58, 1.0)); - break; - case CSSValueStepStart: - animation->setTimingFunction(StepsTimingFunction::create(1, true)); - break; - case CSSValueStepEnd: - animation->setTimingFunction(StepsTimingFunction::create(1, false)); - break; - } - return; - } - - if (value->isCubicBezierTimingFunctionValue()) { - CSSCubicBezierTimingFunctionValue* cubicTimingFunction = static_cast<CSSCubicBezierTimingFunctionValue*>(value); - animation->setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2())); - } else if (value->isStepsTimingFunctionValue()) { - CSSStepsTimingFunctionValue* stepsTimingFunction = static_cast<CSSStepsTimingFunctionValue*>(value); - animation->setTimingFunction(StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart())); - } else if (value->isLinearTimingFunctionValue()) - animation->setTimingFunction(LinearTimingFunction::create()); -} - -void StyleResolver::mapNinePieceImage(CSSPropertyID property, CSSValue* value, NinePieceImage& image) -{ - // If we're not a value list, then we are "none" and don't need to alter the empty image at all. - if (!value || !value->isValueList()) - return; - - // Retrieve the border image value. - CSSValueList* borderImage = static_cast<CSSValueList*>(value); - - // Set the image (this kicks off the load). - CSSPropertyID imageProperty; - if (property == CSSPropertyWebkitBorderImage) - imageProperty = CSSPropertyBorderImageSource; - else if (property == CSSPropertyWebkitMaskBoxImage) - imageProperty = CSSPropertyWebkitMaskBoxImageSource; - else - imageProperty = property; - - for (unsigned i = 0 ; i < borderImage->length() ; ++i) { - CSSValue* current = borderImage->item(i); - - if (current->isImageValue() || current->isImageGeneratorValue() -#if ENABLE(CSS_IMAGE_SET) - || current->isImageSetValue() -#endif - ) - image.setImage(styleImage(imageProperty, current)); - else if (current->isBorderImageSliceValue()) - mapNinePieceImageSlice(current, image); - else if (current->isValueList()) { - CSSValueList* slashList = static_cast<CSSValueList*>(current); - // Map in the image slices. - if (slashList->item(0) && slashList->item(0)->isBorderImageSliceValue()) - mapNinePieceImageSlice(slashList->item(0), image); - - // Map in the border slices. - if (slashList->item(1)) - image.setBorderSlices(mapNinePieceImageQuad(slashList->item(1))); - - // Map in the outset. - if (slashList->item(2)) - image.setOutset(mapNinePieceImageQuad(slashList->item(2))); - } else if (current->isPrimitiveValue()) { - // Set the appropriate rules for stretch/round/repeat of the slices. - mapNinePieceImageRepeat(current, image); - } - } - - if (property == CSSPropertyWebkitBorderImage) { - // We have to preserve the legacy behavior of -webkit-border-image and make the border slices - // also set the border widths. We don't need to worry about percentages, since we don't even support - // those on real borders yet. - if (image.borderSlices().top().isFixed()) - style()->setBorderTopWidth(image.borderSlices().top().value()); - if (image.borderSlices().right().isFixed()) - style()->setBorderRightWidth(image.borderSlices().right().value()); - if (image.borderSlices().bottom().isFixed()) - style()->setBorderBottomWidth(image.borderSlices().bottom().value()); - if (image.borderSlices().left().isFixed()) - style()->setBorderLeftWidth(image.borderSlices().left().value()); - } -} - -void StyleResolver::mapNinePieceImageSlice(CSSValue* value, NinePieceImage& image) -{ - if (!value || !value->isBorderImageSliceValue()) - return; - - // Retrieve the border image value. - CSSBorderImageSliceValue* borderImageSlice = static_cast<CSSBorderImageSliceValue*>(value); - - // Set up a length box to represent our image slices. - LengthBox box; - Quad* slices = borderImageSlice->slices(); - if (slices->top()->isPercentage()) - box.m_top = Length(slices->top()->getDoubleValue(), Percent); - else - box.m_top = Length(slices->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); - if (slices->bottom()->isPercentage()) - box.m_bottom = Length(slices->bottom()->getDoubleValue(), Percent); - else - box.m_bottom = Length((int)slices->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); - if (slices->left()->isPercentage()) - box.m_left = Length(slices->left()->getDoubleValue(), Percent); - else - box.m_left = Length(slices->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); - if (slices->right()->isPercentage()) - box.m_right = Length(slices->right()->getDoubleValue(), Percent); - else - box.m_right = Length(slices->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed); - image.setImageSlices(box); - - // Set our fill mode. - image.setFill(borderImageSlice->m_fill); -} - -LengthBox StyleResolver::mapNinePieceImageQuad(CSSValue* value) -{ - if (!value || !value->isPrimitiveValue()) - return LengthBox(); - - // Get our zoom value. - float zoom = useSVGZoomRules() ? 1.0f : style()->effectiveZoom(); - - // Retrieve the primitive value. - CSSPrimitiveValue* borderWidths = static_cast<CSSPrimitiveValue*>(value); - - // Set up a length box to represent our image slices. - LengthBox box; // Defaults to 'auto' so we don't have to handle that explicitly below. - Quad* slices = borderWidths->getQuadValue(); - if (slices->top()->isNumber()) - box.m_top = Length(slices->top()->getIntValue(), Relative); - else if (slices->top()->isPercentage()) - box.m_top = Length(slices->top()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); - else if (slices->top()->getIdent() != CSSValueAuto) - box.m_top = slices->top()->computeLength<Length>(style(), rootElementStyle(), zoom); - - if (slices->right()->isNumber()) - box.m_right = Length(slices->right()->getIntValue(), Relative); - else if (slices->right()->isPercentage()) - box.m_right = Length(slices->right()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); - else if (slices->right()->getIdent() != CSSValueAuto) - box.m_right = slices->right()->computeLength<Length>(style(), rootElementStyle(), zoom); - - if (slices->bottom()->isNumber()) - box.m_bottom = Length(slices->bottom()->getIntValue(), Relative); - else if (slices->bottom()->isPercentage()) - box.m_bottom = Length(slices->bottom()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); - else if (slices->bottom()->getIdent() != CSSValueAuto) - box.m_bottom = slices->bottom()->computeLength<Length>(style(), rootElementStyle(), zoom); - - if (slices->left()->isNumber()) - box.m_left = Length(slices->left()->getIntValue(), Relative); - else if (slices->left()->isPercentage()) - box.m_left = Length(slices->left()->getDoubleValue(CSSPrimitiveValue::CSS_PERCENTAGE), Percent); - else if (slices->left()->getIdent() != CSSValueAuto) - box.m_left = slices->left()->computeLength<Length>(style(), rootElementStyle(), zoom); - - return box; -} - -void StyleResolver::mapNinePieceImageRepeat(CSSValue* value, NinePieceImage& image) -{ - if (!value || !value->isPrimitiveValue()) - return; - - CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); - Pair* pair = primitiveValue->getPairValue(); - if (!pair || !pair->first() || !pair->second()) - return; - - int firstIdentifier = pair->first()->getIdent(); - int secondIdentifier = pair->second()->getIdent(); - - ENinePieceImageRule horizontalRule; - switch (firstIdentifier) { - case CSSValueStretch: - horizontalRule = StretchImageRule; - break; - case CSSValueRound: - horizontalRule = RoundImageRule; - break; - case CSSValueSpace: - horizontalRule = SpaceImageRule; - break; - default: // CSSValueRepeat - horizontalRule = RepeatImageRule; - break; - } - image.setHorizontalRule(horizontalRule); - - ENinePieceImageRule verticalRule; - switch (secondIdentifier) { - case CSSValueStretch: - verticalRule = StretchImageRule; - break; - case CSSValueRound: - verticalRule = RoundImageRule; - break; - case CSSValueSpace: - verticalRule = SpaceImageRule; - break; - default: // CSSValueRepeat - verticalRule = RepeatImageRule; - break; - } - image.setVerticalRule(verticalRule); -} - void StyleResolver::checkForTextSizeAdjust() { if (m_style->textSizeAdjust()) |