| /* |
| * Copyright (C) 2013 Google Inc. All rights reserved. |
| * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
| * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
| * 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. |
| * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * 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. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT |
| * OWNER OR 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 "core/css/resolver/StyleBuilderCustom.h" |
| |
| #include "CSSPropertyNames.h" |
| #include "CSSValueKeywords.h" |
| #include "StyleBuilderFunctions.h" |
| #include "StylePropertyShorthand.h" |
| #include "core/css/BasicShapeFunctions.h" |
| #include "core/css/CSSAspectRatioValue.h" |
| #include "core/css/CSSCursorImageValue.h" |
| #include "core/css/CSSFontValue.h" |
| #include "core/css/CSSFunctionValue.h" |
| #include "core/css/CSSGradientValue.h" |
| #include "core/css/CSSGridTemplateValue.h" |
| #include "core/css/CSSImageSetValue.h" |
| #include "core/css/CSSLineBoxContainValue.h" |
| #include "core/css/CSSParser.h" |
| #include "core/css/CSSPrimitiveValueMappings.h" |
| #include "core/css/CSSProperty.h" |
| #include "core/css/CSSReflectValue.h" |
| #include "core/css/CSSShadowValue.h" |
| #include "core/css/CSSVariableValue.h" |
| #include "core/css/Counter.h" |
| #include "core/css/Pair.h" |
| #include "core/css/Rect.h" |
| #include "core/css/StylePropertySet.h" |
| #include "core/css/StyleRule.h" |
| #include "core/css/resolver/ElementStyleResources.h" |
| #include "core/css/resolver/FilterOperationResolver.h" |
| #include "core/css/resolver/FontBuilder.h" |
| #include "core/css/resolver/StyleBuilder.h" |
| #include "core/css/resolver/StyleResolverState.h" |
| #include "core/css/resolver/TransformBuilder.h" |
| #include "core/frame/Frame.h" |
| #include "core/page/Settings.h" |
| #include "core/rendering/style/CounterContent.h" |
| #include "core/rendering/style/CursorList.h" |
| #include "core/rendering/style/QuotesData.h" |
| #include "core/rendering/style/RenderStyle.h" |
| #include "core/rendering/style/RenderStyleConstants.h" |
| #include "core/rendering/style/SVGRenderStyle.h" |
| #include "core/rendering/style/SVGRenderStyleDefs.h" |
| #include "core/rendering/style/StyleGeneratedImage.h" |
| #include "core/svg/SVGColor.h" |
| #include "core/svg/SVGPaint.h" |
| #include "core/svg/SVGURIReference.h" |
| #include "platform/fonts/FontDescription.h" |
| #include "wtf/MathExtras.h" |
| #include "wtf/StdLibExtras.h" |
| #include "wtf/Vector.h" |
| |
| namespace WebCore { |
| |
| static Length clipConvertToLength(StyleResolverState& state, CSSPrimitiveValue* value) |
| { |
| return value->convertToLength<FixedIntegerConversion | PercentConversion | FractionConversion | AutoConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyClip(StyleResolverState& state) |
| { |
| state.style()->setClip(Length(), Length(), Length(), Length()); |
| state.style()->setHasClip(false); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyClip(StyleResolverState& state) |
| { |
| RenderStyle* parentStyle = state.parentStyle(); |
| if (!parentStyle->hasClip()) |
| return applyInitialCSSPropertyClip(state); |
| state.style()->setClip(parentStyle->clipTop(), parentStyle->clipRight(), parentStyle->clipBottom(), parentStyle->clipLeft()); |
| state.style()->setHasClip(true); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyClip(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| |
| if (Rect* rect = primitiveValue->getRectValue()) { |
| Length top = clipConvertToLength(state, rect->top()); |
| Length right = clipConvertToLength(state, rect->right()); |
| Length bottom = clipConvertToLength(state, rect->bottom()); |
| Length left = clipConvertToLength(state, rect->left()); |
| state.style()->setClip(top, right, bottom, left); |
| state.style()->setHasClip(true); |
| } else if (primitiveValue->getValueID() == CSSValueAuto) { |
| state.style()->setClip(Length(), Length(), Length(), Length()); |
| state.style()->setHasClip(false); |
| } |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state) |
| { |
| state.style()->clearCursorList(); |
| state.style()->setCursor(RenderStyle::initialCursor()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyCursor(StyleResolverState& state) |
| { |
| state.style()->setCursor(state.parentStyle()->cursor()); |
| state.style()->setCursorList(state.parentStyle()->cursors()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& state, CSSValue* value) |
| { |
| state.style()->clearCursorList(); |
| if (value->isValueList()) { |
| CSSValueList* list = toCSSValueList(value); |
| int len = list->length(); |
| state.style()->setCursor(CURSOR_AUTO); |
| for (int i = 0; i < len; i++) { |
| CSSValue* item = list->itemWithoutBoundsCheck(i); |
| if (item->isCursorImageValue()) { |
| CSSCursorImageValue* image = toCSSCursorImageValue(item); |
| if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style. |
| state.style()->setUnique(); |
| state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot()); |
| } else if (item->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item); |
| if (primitiveValue->isValueID()) |
| state.style()->setCursor(*primitiveValue); |
| } |
| } |
| } else if (value->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->isValueID() && state.style()->cursor() != ECursor(*primitiveValue)) |
| state.style()->setCursor(*primitiveValue); |
| } |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyDirection(StyleResolverState& state, CSSValue* value) |
| { |
| state.style()->setDirection(*toCSSPrimitiveValue(value)); |
| Element* element = state.element(); |
| if (element && element == element->document().documentElement()) |
| element->document().setDirectionSetOnDocumentElement(true); |
| } |
| |
| static inline bool isValidDisplayValue(StyleResolverState& state, EDisplay displayPropertyValue) |
| { |
| if (state.element() && state.element()->isSVGElement() && state.style()->styleType() == NOPSEUDO) |
| return (displayPropertyValue == INLINE || displayPropertyValue == BLOCK || displayPropertyValue == NONE); |
| return true; |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyDisplay(StyleResolverState& state) |
| { |
| EDisplay display = state.parentStyle()->display(); |
| if (!isValidDisplayValue(state, display)) |
| return; |
| state.style()->setDisplay(display); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyDisplay(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| EDisplay display = *toCSSPrimitiveValue(value); |
| |
| if (!isValidDisplayValue(state, display)) |
| return; |
| |
| state.style()->setDisplay(display); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state) |
| { |
| state.fontBuilder().setFontFamilyInitial(state.style()->effectiveZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state) |
| { |
| state.fontBuilder().setFontFamilyInherit(state.parentFontDescription()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value) |
| { |
| state.fontBuilder().setFontFamilyValue(value, state.style()->effectiveZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyFontSize(StyleResolverState& state) |
| { |
| state.fontBuilder().setFontSizeInitial(state.style()->effectiveZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyFontSize(StyleResolverState& state) |
| { |
| state.fontBuilder().setFontSizeInherit(state.parentFontDescription(), state.style()->effectiveZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyFontSize(StyleResolverState& state, CSSValue* value) |
| { |
| state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyFontWeight(StyleResolverState& state) |
| { |
| state.fontBuilder().setWeight(FontWeightNormal); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyFontWeight(StyleResolverState& state) |
| { |
| state.fontBuilder().setWeight(state.parentFontDescription().weight()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyFontWeight(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| switch (primitiveValue->getValueID()) { |
| case CSSValueInvalid: |
| ASSERT_NOT_REACHED(); |
| break; |
| case CSSValueBolder: |
| state.fontBuilder().setWeightBolder(); |
| break; |
| case CSSValueLighter: |
| state.fontBuilder().setWeightLighter(); |
| break; |
| default: |
| state.fontBuilder().setWeight(*primitiveValue); |
| } |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| Length lineHeight; |
| |
| if (primitiveValue->getValueID() == CSSValueNormal) { |
| lineHeight = RenderStyle::initialLineHeight(); |
| } else if (primitiveValue->isLength()) { |
| double multiplier = state.style()->effectiveZoom(); |
| if (Frame* frame = state.document().frame()) |
| multiplier *= frame->textZoomFactor(); |
| lineHeight = primitiveValue->computeLength<Length>(state.style(), state.rootElementStyle(), multiplier); |
| } else if (primitiveValue->isPercentage()) { |
| lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed); |
| } else if (primitiveValue->isNumber()) { |
| lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent); |
| } else if (primitiveValue->isViewportPercentageLength()) { |
| lineHeight = primitiveValue->viewportPercentageLength(); |
| } else if (primitiveValue->isCalculated()) { |
| double multiplier = state.style()->effectiveZoom(); |
| if (Frame* frame = state.document().frame()) |
| multiplier *= frame->textZoomFactor(); |
| Length zoomedLength = Length(primitiveValue->cssCalcValue()->toCalcValue(state.style(), state.rootElementStyle(), multiplier)); |
| lineHeight = Length(valueForLength(zoomedLength, state.style()->fontSize()), Fixed); |
| } else { |
| return; |
| } |
| state.style()->setLineHeight(lineHeight); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyListStyleImage(StyleResolverState& state, CSSValue* value) |
| { |
| state.style()->setListStyleImage(state.styleImage(CSSPropertyListStyleImage, value)); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyOutlineStyle(StyleResolverState& state) |
| { |
| state.style()->setOutlineStyleIsAuto(RenderStyle::initialOutlineStyleIsAuto()); |
| state.style()->setOutlineStyle(RenderStyle::initialBorderStyle()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyOutlineStyle(StyleResolverState& state) |
| { |
| state.style()->setOutlineStyleIsAuto(state.parentStyle()->outlineStyleIsAuto()); |
| state.style()->setOutlineStyle(state.parentStyle()->outlineStyle()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| state.style()->setOutlineStyleIsAuto(*primitiveValue); |
| state.style()->setOutlineStyle(*primitiveValue); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyResize(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| |
| EResize r = RESIZE_NONE; |
| switch (primitiveValue->getValueID()) { |
| case 0: |
| return; |
| case CSSValueAuto: |
| if (Settings* settings = state.document().settings()) |
| r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE; |
| break; |
| default: |
| r = *primitiveValue; |
| } |
| state.style()->setResize(r); |
| } |
| |
| static Length mmLength(double mm) { return CSSPrimitiveValue::create(mm, CSSPrimitiveValue::CSS_MM)->computeLength<Length>(0, 0); } |
| static Length inchLength(double inch) { return CSSPrimitiveValue::create(inch, CSSPrimitiveValue::CSS_IN)->computeLength<Length>(0, 0); } |
| static bool getPageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height) |
| { |
| DEFINE_STATIC_LOCAL(Length, a5Width, (mmLength(148))); |
| DEFINE_STATIC_LOCAL(Length, a5Height, (mmLength(210))); |
| DEFINE_STATIC_LOCAL(Length, a4Width, (mmLength(210))); |
| DEFINE_STATIC_LOCAL(Length, a4Height, (mmLength(297))); |
| DEFINE_STATIC_LOCAL(Length, a3Width, (mmLength(297))); |
| DEFINE_STATIC_LOCAL(Length, a3Height, (mmLength(420))); |
| DEFINE_STATIC_LOCAL(Length, b5Width, (mmLength(176))); |
| DEFINE_STATIC_LOCAL(Length, b5Height, (mmLength(250))); |
| DEFINE_STATIC_LOCAL(Length, b4Width, (mmLength(250))); |
| DEFINE_STATIC_LOCAL(Length, b4Height, (mmLength(353))); |
| DEFINE_STATIC_LOCAL(Length, letterWidth, (inchLength(8.5))); |
| DEFINE_STATIC_LOCAL(Length, letterHeight, (inchLength(11))); |
| DEFINE_STATIC_LOCAL(Length, legalWidth, (inchLength(8.5))); |
| DEFINE_STATIC_LOCAL(Length, legalHeight, (inchLength(14))); |
| DEFINE_STATIC_LOCAL(Length, ledgerWidth, (inchLength(11))); |
| DEFINE_STATIC_LOCAL(Length, ledgerHeight, (inchLength(17))); |
| |
| if (!pageSizeName) |
| return false; |
| |
| switch (pageSizeName->getValueID()) { |
| case CSSValueA5: |
| width = a5Width; |
| height = a5Height; |
| break; |
| case CSSValueA4: |
| width = a4Width; |
| height = a4Height; |
| break; |
| case CSSValueA3: |
| width = a3Width; |
| height = a3Height; |
| break; |
| case CSSValueB5: |
| width = b5Width; |
| height = b5Height; |
| break; |
| case CSSValueB4: |
| width = b4Width; |
| height = b4Height; |
| break; |
| case CSSValueLetter: |
| width = letterWidth; |
| height = letterHeight; |
| break; |
| case CSSValueLegal: |
| width = legalWidth; |
| height = legalHeight; |
| break; |
| case CSSValueLedger: |
| width = ledgerWidth; |
| height = ledgerHeight; |
| break; |
| default: |
| return false; |
| } |
| |
| if (pageOrientation) { |
| switch (pageOrientation->getValueID()) { |
| case CSSValueLandscape: |
| std::swap(width, height); |
| break; |
| case CSSValuePortrait: |
| // Nothing to do. |
| break; |
| default: |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertySize(StyleResolverState&) { } |
| void StyleBuilderFunctions::applyInheritCSSPropertySize(StyleResolverState&) { } |
| void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state, CSSValue* value) |
| { |
| state.style()->resetPageSizeType(); |
| Length width; |
| Length height; |
| PageSizeType pageSizeType = PAGE_SIZE_AUTO; |
| CSSValueListInspector inspector(value); |
| switch (inspector.length()) { |
| case 2: { |
| // <length>{2} | <page-size> <orientation> |
| if (!inspector.first()->isPrimitiveValue() || !inspector.second()->isPrimitiveValue()) |
| return; |
| CSSPrimitiveValue* first = toCSSPrimitiveValue(inspector.first()); |
| CSSPrimitiveValue* second = toCSSPrimitiveValue(inspector.second()); |
| if (first->isLength()) { |
| // <length>{2} |
| if (!second->isLength()) |
| return; |
| width = first->computeLength<Length>(state.style(), state.rootElementStyle()); |
| height = second->computeLength<Length>(state.style(), state.rootElementStyle()); |
| } else { |
| // <page-size> <orientation> |
| // The value order is guaranteed. See CSSParser::parseSizeParameter. |
| if (!getPageSizeFromName(first, second, width, height)) |
| return; |
| } |
| pageSizeType = PAGE_SIZE_RESOLVED; |
| break; |
| } |
| case 1: { |
| // <length> | auto | <page-size> | [ portrait | landscape] |
| if (!inspector.first()->isPrimitiveValue()) |
| return; |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(inspector.first()); |
| if (primitiveValue->isLength()) { |
| // <length> |
| pageSizeType = PAGE_SIZE_RESOLVED; |
| width = height = primitiveValue->computeLength<Length>(state.style(), state.rootElementStyle()); |
| } else { |
| switch (primitiveValue->getValueID()) { |
| case 0: |
| return; |
| case CSSValueAuto: |
| pageSizeType = PAGE_SIZE_AUTO; |
| break; |
| case CSSValuePortrait: |
| pageSizeType = PAGE_SIZE_AUTO_PORTRAIT; |
| break; |
| case CSSValueLandscape: |
| pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE; |
| break; |
| default: |
| // <page-size> |
| pageSizeType = PAGE_SIZE_RESOLVED; |
| if (!getPageSizeFromName(primitiveValue, 0, width, height)) |
| return; |
| } |
| } |
| break; |
| } |
| default: |
| return; |
| } |
| state.style()->setPageSizeType(pageSizeType); |
| state.style()->setPageSize(LengthSize(width, height)); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyTextAlign(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| // FIXME : Per http://www.w3.org/TR/css3-text/#text-align0 can now take <string> but this is not implemented in the |
| // rendering code. |
| if (primitiveValue->isString()) |
| return; |
| |
| if (primitiveValue->isValueID() && primitiveValue->getValueID() != CSSValueWebkitMatchParent) |
| state.style()->setTextAlign(*primitiveValue); |
| else if (state.parentStyle()->textAlign() == TASTART) |
| state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? LEFT : RIGHT); |
| else if (state.parentStyle()->textAlign() == TAEND) |
| state.style()->setTextAlign(state.parentStyle()->isLeftToRightDirection() ? RIGHT : LEFT); |
| else |
| state.style()->setTextAlign(state.parentStyle()->textAlign()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyTextDecoration(StyleResolverState& state, CSSValue* value) |
| { |
| TextDecoration t = RenderStyle::initialTextDecoration(); |
| for (CSSValueListIterator i(value); i.hasMore(); i.advance()) { |
| CSSValue* item = i.value(); |
| t |= *toCSSPrimitiveValue(item); |
| } |
| state.style()->setTextDecoration(t); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyTextIndent(StyleResolverState& state) |
| { |
| state.style()->setTextIndent(state.parentStyle()->textIndent()); |
| state.style()->setTextIndentLine(state.parentStyle()->textIndentLine()); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyTextIndent(StyleResolverState& state) |
| { |
| state.style()->setTextIndent(RenderStyle::initialTextIndent()); |
| state.style()->setTextIndentLine(RenderStyle::initialTextIndentLine()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isValueList()) |
| return; |
| |
| // [ <length> | <percentage> ] each-line |
| // The order is guaranteed. See CSSParser::parseTextIndent. |
| // The second value, each-line is handled only when css3TextEnabled() returns true. |
| |
| CSSValueList* valueList = toCSSValueList(value); |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(valueList->itemWithoutBoundsCheck(0)); |
| Length lengthOrPercentageValue = primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| ASSERT(!lengthOrPercentageValue.isUndefined()); |
| state.style()->setTextIndent(lengthOrPercentageValue); |
| |
| ASSERT(valueList->length() <= 2); |
| CSSPrimitiveValue* eachLineValue = toCSSPrimitiveValue(valueList->item(1)); |
| if (eachLineValue) { |
| ASSERT(eachLineValue->getValueID() == CSSValueEachLine); |
| state.style()->setTextIndentLine(TextIndentEachLine); |
| } else |
| state.style()->setTextIndentLine(TextIndentFirstLine); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| |
| if (primitiveValue->getValueID()) |
| return state.style()->setVerticalAlign(*primitiveValue); |
| |
| state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom())); |
| } |
| |
| static void resetEffectiveZoom(StyleResolverState& state) |
| { |
| // Reset the zoom in effect. This allows the setZoom method to accurately compute a new zoom in effect. |
| state.setEffectiveZoom(state.parentStyle() ? state.parentStyle()->effectiveZoom() : RenderStyle::initialZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyZoom(StyleResolverState& state) |
| { |
| resetEffectiveZoom(state); |
| state.setZoom(RenderStyle::initialZoom()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyZoom(StyleResolverState& state) |
| { |
| resetEffectiveZoom(state); |
| state.setZoom(state.parentStyle()->zoom()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyZoom(StyleResolverState& state, CSSValue* value) |
| { |
| ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue()); |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| |
| if (primitiveValue->getValueID() == CSSValueNormal) { |
| resetEffectiveZoom(state); |
| state.setZoom(RenderStyle::initialZoom()); |
| } else if (primitiveValue->getValueID() == CSSValueReset) { |
| state.setEffectiveZoom(RenderStyle::initialZoom()); |
| state.setZoom(RenderStyle::initialZoom()); |
| } else if (primitiveValue->getValueID() == CSSValueDocument) { |
| float docZoom = state.rootElementStyle() ? state.rootElementStyle()->zoom() : RenderStyle::initialZoom(); |
| state.setEffectiveZoom(docZoom); |
| state.setZoom(docZoom); |
| } else if (primitiveValue->isPercentage()) { |
| resetEffectiveZoom(state); |
| if (float percent = primitiveValue->getFloatValue()) |
| state.setZoom(percent / 100.0f); |
| } else if (primitiveValue->isNumber()) { |
| resetEffectiveZoom(state); |
| if (float number = primitiveValue->getFloatValue()) |
| state.setZoom(number); |
| } |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAspectRatio(StyleResolverState& state) |
| { |
| state.style()->setHasAspectRatio(RenderStyle::initialHasAspectRatio()); |
| state.style()->setAspectRatioDenominator(RenderStyle::initialAspectRatioDenominator()); |
| state.style()->setAspectRatioNumerator(RenderStyle::initialAspectRatioNumerator()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAspectRatio(StyleResolverState& state) |
| { |
| if (!state.parentStyle()->hasAspectRatio()) |
| return; |
| state.style()->setHasAspectRatio(true); |
| state.style()->setAspectRatioDenominator(state.parentStyle()->aspectRatioDenominator()); |
| state.style()->setAspectRatioNumerator(state.parentStyle()->aspectRatioNumerator()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyWebkitAspectRatio(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isAspectRatioValue()) { |
| state.style()->setHasAspectRatio(false); |
| return; |
| } |
| CSSAspectRatioValue* aspectRatioValue = toCSSAspectRatioValue(value); |
| state.style()->setHasAspectRatio(true); |
| state.style()->setAspectRatioDenominator(aspectRatioValue->denominatorValue()); |
| state.style()->setAspectRatioNumerator(aspectRatioValue->numeratorValue()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyWebkitClipPath(StyleResolverState& state, CSSValue* value) |
| { |
| if (value->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID() == CSSValueNone) { |
| state.style()->setClipPath(0); |
| } else if (primitiveValue->isShape()) { |
| state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue()))); |
| } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) { |
| String cssURLValue = primitiveValue->getStringValue(); |
| KURL url = state.document().completeURL(cssURLValue); |
| // FIXME: It doesn't work with forward or external SVG references (see https://bugs.webkit.org/show_bug.cgi?id=90405) |
| state.style()->setClipPath(ReferenceClipPathOperation::create(cssURLValue, url.fragmentIdentifier())); |
| } |
| } |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state) |
| { |
| state.fontBuilder().setFontVariantLigaturesInitial(); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state) |
| { |
| state.fontBuilder().setFontVariantLigaturesInherit(state.parentFontDescription()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state, CSSValue* value) |
| { |
| state.fontBuilder().setFontVariantLigaturesValue(value); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeIncrement(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID()) { |
| switch (primitiveValue->getValueID()) { |
| case CSSValueSmall: |
| state.style()->setMarqueeIncrement(Length(1, Fixed)); // 1px. |
| break; |
| case CSSValueNormal: |
| state.style()->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default. |
| break; |
| case CSSValueLarge: |
| state.style()->setMarqueeIncrement(Length(36, Fixed)); // 36px. |
| break; |
| default: |
| break; |
| } |
| } else { |
| Length marqueeLength = primitiveValue ? primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | FractionConversion>(state.style(), state.rootElementStyle()) : Length(Undefined); |
| if (!marqueeLength.isUndefined()) |
| state.style()->setMarqueeIncrement(marqueeLength); |
| } |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeSpeed(StyleResolverState& state, CSSValue* value) |
| { |
| if (!value->isPrimitiveValue()) |
| return; |
| |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (CSSValueID valueID = primitiveValue->getValueID()) { |
| switch (valueID) { |
| case CSSValueSlow: |
| state.style()->setMarqueeSpeed(500); // 500 msec. |
| break; |
| case CSSValueNormal: |
| state.style()->setMarqueeSpeed(85); // 85msec. The WinIE default. |
| break; |
| case CSSValueFast: |
| state.style()->setMarqueeSpeed(10); // 10msec. Super fast. |
| break; |
| default: |
| break; |
| } |
| } else if (primitiveValue->isTime()) { |
| state.style()->setMarqueeSpeed(primitiveValue->computeTime<int, CSSPrimitiveValue::Milliseconds>()); |
| } else if (primitiveValue->isNumber()) { // For scrollamount support. |
| state.style()->setMarqueeSpeed(primitiveValue->getIntValue()); |
| } |
| } |
| |
| // FIXME: We should use the same system for this as the rest of the pseudo-shorthands (e.g. background-position) |
| void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state) |
| { |
| applyInitialCSSPropertyWebkitPerspectiveOriginX(state); |
| applyInitialCSSPropertyWebkitPerspectiveOriginY(state); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspectiveOrigin(StyleResolverState& state) |
| { |
| applyInheritCSSPropertyWebkitPerspectiveOriginX(state); |
| applyInheritCSSPropertyWebkitPerspectiveOriginY(state); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspectiveOrigin(StyleResolverState&, CSSValue* value) |
| { |
| // This is expanded in the parser |
| ASSERT_NOT_REACHED(); |
| } |
| |
| void StyleBuilderFunctions::applyInitialCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state) |
| { |
| state.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill()); |
| state.style()->setTextEmphasisMark(RenderStyle::initialTextEmphasisMark()); |
| state.style()->setTextEmphasisCustomMark(RenderStyle::initialTextEmphasisCustomMark()); |
| } |
| |
| void StyleBuilderFunctions::applyInheritCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state) |
| { |
| state.style()->setTextEmphasisFill(state.parentStyle()->textEmphasisFill()); |
| state.style()->setTextEmphasisMark(state.parentStyle()->textEmphasisMark()); |
| state.style()->setTextEmphasisCustomMark(state.parentStyle()->textEmphasisCustomMark()); |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state, CSSValue* value) |
| { |
| if (value->isValueList()) { |
| CSSValueList* list = toCSSValueList(value); |
| ASSERT(list->length() == 2); |
| if (list->length() != 2) |
| return; |
| for (unsigned i = 0; i < 2; ++i) { |
| CSSValue* item = list->itemWithoutBoundsCheck(i); |
| if (!item->isPrimitiveValue()) |
| continue; |
| |
| CSSPrimitiveValue* value = toCSSPrimitiveValue(item); |
| if (value->getValueID() == CSSValueFilled || value->getValueID() == CSSValueOpen) |
| state.style()->setTextEmphasisFill(*value); |
| else |
| state.style()->setTextEmphasisMark(*value); |
| } |
| state.style()->setTextEmphasisCustomMark(nullAtom); |
| return; |
| } |
| |
| if (!value->isPrimitiveValue()) |
| return; |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| |
| if (primitiveValue->isString()) { |
| state.style()->setTextEmphasisFill(TextEmphasisFillFilled); |
| state.style()->setTextEmphasisMark(TextEmphasisMarkCustom); |
| state.style()->setTextEmphasisCustomMark(primitiveValue->getStringValue()); |
| return; |
| } |
| |
| state.style()->setTextEmphasisCustomMark(nullAtom); |
| |
| if (primitiveValue->getValueID() == CSSValueFilled || primitiveValue->getValueID() == CSSValueOpen) { |
| state.style()->setTextEmphasisFill(*primitiveValue); |
| state.style()->setTextEmphasisMark(TextEmphasisMarkAuto); |
| } else { |
| state.style()->setTextEmphasisFill(TextEmphasisFillFilled); |
| state.style()->setTextEmphasisMark(*primitiveValue); |
| } |
| } |
| |
| void StyleBuilderFunctions::applyValueCSSPropertyTextUnderlinePosition(StyleResolverState& state, CSSValue* value) |
| { |
| // This is true if value is 'auto' or 'alphabetic'. |
| if (value->isPrimitiveValue()) { |
| TextUnderlinePosition t = *toCSSPrimitiveValue(value); |
| state.style()->setTextUnderlinePosition(t); |
| return; |
| } |
| |
| unsigned t = 0; |
| for (CSSValueListIterator i(value); i.hasMore(); i.advance()) { |
| CSSValue* item = i.value(); |
| TextUnderlinePosition t2 = *toCSSPrimitiveValue(item); |
| t |= t2; |
| } |
| state.style()->setTextUnderlinePosition(static_cast<TextUnderlinePosition>(t)); |
| } |
| |
| Length StyleBuilderConverter::convertLength(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| Length result = primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| ASSERT(!result.isUndefined()); |
| result.setQuirk(primitiveValue->isQuirkValue()); |
| return result; |
| } |
| |
| Length StyleBuilderConverter::convertLengthOrAuto(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| Length result = primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| ASSERT(!result.isUndefined()); |
| result.setQuirk(primitiveValue->isQuirkValue()); |
| return result; |
| } |
| |
| Length StyleBuilderConverter::convertLengthSizing(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| switch (primitiveValue->getValueID()) { |
| case CSSValueInvalid: |
| return convertLength(state, value); |
| case CSSValueIntrinsic: |
| return Length(Intrinsic); |
| case CSSValueMinIntrinsic: |
| return Length(MinIntrinsic); |
| case CSSValueWebkitMinContent: |
| return Length(MinContent); |
| case CSSValueWebkitMaxContent: |
| return Length(MaxContent); |
| case CSSValueWebkitFillAvailable: |
| return Length(FillAvailable); |
| case CSSValueWebkitFitContent: |
| return Length(FitContent); |
| case CSSValueAuto: |
| return Length(Auto); |
| default: |
| ASSERT_NOT_REACHED(); |
| return Length(); |
| } |
| } |
| |
| Length StyleBuilderConverter::convertLengthMaxSizing(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID() == CSSValueNone) |
| return Length(Undefined); |
| return convertLengthSizing(state, value); |
| } |
| |
| LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| Pair* pair = primitiveValue->getPairValue(); |
| Length x = pair->first()->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| Length y = pair->second()->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| return LengthPoint(x, y); |
| } |
| |
| LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| Pair* pair = primitiveValue->getPairValue(); |
| Length radiusWidth = pair->first()->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| Length radiusHeight = pair->second()->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| float width = radiusWidth.value(); |
| float height = radiusHeight.value(); |
| ASSERT(width >= 0 && height >= 0); |
| if (width <= 0 || height <= 0) |
| return LengthSize(Length(0, Fixed), Length(0, Fixed)); |
| return LengthSize(radiusWidth, radiusHeight); |
| } |
| |
| PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState& state, CSSValue* value) |
| { |
| if (value->isPrimitiveValue()) { |
| ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); |
| return PassRefPtr<ShadowList>(); |
| } |
| |
| const CSSValueList* valueList = toCSSValueList(value); |
| size_t shadowCount = valueList->length(); |
| float zoom = state.style()->effectiveZoom(); |
| ShadowDataVector shadows; |
| for (size_t i = 0; i < shadowCount; ++i) { |
| const CSSShadowValue* item = toCSSShadowValue(valueList->item(i)); |
| int x = item->x->computeLength<int>(state.style(), state.rootElementStyle(), zoom); |
| int y = item->y->computeLength<int>(state.style(), state.rootElementStyle(), zoom); |
| int blur = item->blur ? item->blur->computeLength<int>(state.style(), state.rootElementStyle(), zoom) : 0; |
| int spread = item->spread ? item->spread->computeLength<int>(state.style(), state.rootElementStyle(), zoom) : 0; |
| ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal; |
| Color color; |
| if (item->color) |
| color = state.document().textLinkColors().colorFromPrimitiveValue(item->color.get(), state.style()->visitedDependentColor(CSSPropertyColor)); |
| else |
| color = state.style()->color(); |
| |
| if (!color.isValid()) |
| color = Color::transparent; |
| shadows.append(ShadowData(IntPoint(x, y), blur, spread, shadowStyle, color)); |
| } |
| return ShadowList::adopt(shadows); |
| } |
| |
| float StyleBuilderConverter::convertSpacing(StyleResolverState& state, CSSValue* value) |
| { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| if (primitiveValue->getValueID() == CSSValueNormal) |
| return 0; |
| float zoom = state.useSVGZoomRules() ? 1.0f : state.style()->effectiveZoom(); |
| return primitiveValue->computeLength<float>(state.style(), state.rootElementStyle(), zoom); |
| } |
| |
| |
| // Everything below this line is from the old StyleResolver::applyProperty |
| // and eventually needs to move into new StyleBuilderFunctions calls intead. |
| |
| #define HANDLE_INHERIT(prop, Prop) \ |
| if (isInherit) { \ |
| state.style()->set##Prop(state.parentStyle()->prop()); \ |
| return; \ |
| } |
| |
| #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \ |
| HANDLE_INHERIT(prop, Prop) \ |
| if (isInitial) { \ |
| state.style()->set##Prop(RenderStyle::initial##Prop()); \ |
| return; \ |
| } |
| |
| #define HANDLE_SVG_INHERIT(prop, Prop) \ |
| if (isInherit) { \ |
| state.style()->accessSVGStyle()->set##Prop(state.parentStyle()->svgStyle()->prop()); \ |
| return; \ |
| } |
| |
| #define HANDLE_SVG_INHERIT_AND_INITIAL(prop, Prop) \ |
| HANDLE_SVG_INHERIT(prop, Prop) \ |
| if (isInitial) { \ |
| state.style()->accessSVGStyle()->set##Prop(SVGRenderStyle::initial##Prop()); \ |
| return; \ |
| } |
| |
| static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, const StyleResolverState& state, GridLength& workingLength) |
| { |
| if (primitiveValue->getValueID() == CSSValueMinContent) { |
| workingLength = Length(MinContent); |
| return true; |
| } |
| |
| if (primitiveValue->getValueID() == CSSValueMaxContent) { |
| workingLength = Length(MaxContent); |
| return true; |
| } |
| |
| if (primitiveValue->isFlex()) { |
| // Fractional unit. |
| workingLength.setFlex(primitiveValue->getDoubleValue()); |
| return true; |
| } |
| |
| workingLength = primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | AutoConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom()); |
| if (workingLength.length().isUndefined()) |
| return false; |
| |
| if (primitiveValue->isLength()) |
| workingLength.length().setQuirk(primitiveValue->isQuirkValue()); |
| |
| return true; |
| } |
| |
| static bool createGridTrackSize(CSSValue* value, GridTrackSize& trackSize, const StyleResolverState& state) |
| { |
| if (value->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| GridLength workingLength; |
| if (!createGridTrackBreadth(primitiveValue, state, workingLength)) |
| return false; |
| |
| trackSize.setLength(workingLength); |
| return true; |
| } |
| |
| CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value); |
| CSSValueList* arguments = minmaxFunction->arguments(); |
| ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2); |
| GridLength minTrackBreadth; |
| GridLength maxTrackBreadth; |
| if (!createGridTrackBreadth(toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(0)), state, minTrackBreadth) || !createGridTrackBreadth(toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(1)), state, maxTrackBreadth)) |
| return false; |
| |
| trackSize.setMinMax(minTrackBreadth, maxTrackBreadth); |
| return true; |
| } |
| |
| static bool createGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, const StyleResolverState& state) |
| { |
| // Handle 'none'. |
| if (value->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| return primitiveValue->getValueID() == CSSValueNone; |
| } |
| |
| if (!value->isValueList()) |
| return false; |
| |
| size_t currentNamedGridLine = 0; |
| for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { |
| CSSValue* currValue = i.value(); |
| if (currValue->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(currValue); |
| if (primitiveValue->isString()) { |
| String namedGridLine = primitiveValue->getStringValue(); |
| NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>()); |
| result.iterator->value.append(currentNamedGridLine); |
| OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>()); |
| orderedInsertionResult.iterator->value.append(namedGridLine); |
| continue; |
| } |
| } |
| |
| ++currentNamedGridLine; |
| GridTrackSize trackSize; |
| if (!createGridTrackSize(currValue, trackSize, state)) |
| return false; |
| |
| trackSizes.append(trackSize); |
| } |
| |
| // The parser should have rejected any <track-list> without any <track-size> as |
| // this is not conformant to the syntax. |
| ASSERT(!trackSizes.isEmpty()); |
| return true; |
| } |
| |
| static bool createGridPosition(CSSValue* value, GridPosition& position) |
| { |
| // We accept the specification's grammar: |
| // 'auto' | [ <integer> || <string> ] | [ span && [ <integer> || string ] ] | <ident> |
| |
| if (value->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| // We translate <ident> to <string> during parsing as it |
| // makes handling it more simple. |
| if (primitiveValue->isString()) { |
| position.setNamedGridArea(primitiveValue->getStringValue()); |
| return true; |
| } |
| |
| ASSERT(primitiveValue->getValueID() == CSSValueAuto); |
| return true; |
| } |
| |
| CSSValueList* values = toCSSValueList(value); |
| ASSERT(values->length()); |
| |
| bool isSpanPosition = false; |
| // The specification makes the <integer> optional, in which case it default to '1'. |
| int gridLineNumber = 1; |
| String gridLineName; |
| |
| CSSValueListIterator it = values; |
| CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value()); |
| if (currentValue->getValueID() == CSSValueSpan) { |
| isSpanPosition = true; |
| it.advance(); |
| currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0; |
| } |
| |
| if (currentValue && currentValue->isNumber()) { |
| gridLineNumber = currentValue->getIntValue(); |
| it.advance(); |
| currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0; |
| } |
| |
| if (currentValue && currentValue->isString()) { |
| gridLineName = currentValue->getStringValue(); |
| it.advance(); |
| } |
| |
| ASSERT(!it.hasMore()); |
| if (isSpanPosition) |
| position.setSpanPosition(gridLineNumber, gridLineName); |
| else |
| position.setExplicitPosition(gridLineNumber, gridLineName); |
| |
| return true; |
| } |
| |
| static bool degreeToGlyphOrientation(CSSPrimitiveValue* primitiveValue, EGlyphOrientation& orientation) |
| { |
| if (!primitiveValue) |
| return false; |
| |
| if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG) |
| return false; |
| |
| float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f)); |
| |
| if (angle <= 45.0f || angle > 315.0f) { |
| orientation = GO_0DEG; |
| return true; |
| } |
| if (angle > 45.0f && angle <= 135.0f) { |
| orientation = GO_90DEG; |
| return true; |
| } |
| if (angle > 135.0f && angle <= 225.0f) { |
| orientation = GO_180DEG; |
| return true; |
| } |
| orientation = GO_270DEG; |
| return true; |
| } |
| |
| static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor) |
| { |
| Color color; |
| if (svgColor->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR) |
| color = fgColor; |
| else |
| color = svgColor->color(); |
| return color; |
| } |
| |
| static EPaintOrder paintOrderFlattened(CSSValue* cssPaintOrder) |
| { |
| if (cssPaintOrder->isValueList()) { |
| int paintOrder = 0; |
| CSSValueListInspector iter(cssPaintOrder); |
| for (size_t i = 0; i < iter.length(); i++) { |
| CSSPrimitiveValue* value = toCSSPrimitiveValue(iter.item(i)); |
| |
| EPaintOrderType paintOrderType = PT_NONE; |
| switch (value->getValueID()) { |
| case CSSValueFill: |
| paintOrderType = PT_FILL; |
| break; |
| case CSSValueStroke: |
| paintOrderType = PT_STROKE; |
| break; |
| case CSSValueMarkers: |
| paintOrderType = PT_MARKERS; |
| break; |
| default: |
| ASSERT_NOT_REACHED(); |
| break; |
| } |
| |
| paintOrder |= (paintOrderType << kPaintOrderBitwidth*i); |
| } |
| return (EPaintOrder)paintOrder; |
| } |
| |
| return PO_NORMAL; |
| } |
| |
| static bool numberToFloat(const CSSPrimitiveValue* primitiveValue, float& out) |
| { |
| if (!primitiveValue) |
| return false; |
| if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER) |
| return false; |
| out = primitiveValue->getFloatValue(); |
| return true; |
| } |
| |
| static bool percentageOrNumberToFloat(const CSSPrimitiveValue* primitiveValue, float& out) |
| { |
| if (!primitiveValue) |
| return false; |
| int type = primitiveValue->primitiveType(); |
| if (type == CSSPrimitiveValue::CSS_PERCENTAGE) { |
| out = primitiveValue->getFloatValue() / 100.0f; |
| return true; |
| } |
| return numberToFloat(primitiveValue, out); |
| } |
| |
| static String fragmentIdentifier(const CSSPrimitiveValue* primitiveValue, Document& document) |
| { |
| if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_URI) |
| return String(); |
| return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), document); |
| } |
| |
| static inline bool isValidVisitedLinkProperty(CSSPropertyID id) |
| { |
| switch (id) { |
| case CSSPropertyBackgroundColor: |
| case CSSPropertyBorderLeftColor: |
| case CSSPropertyBorderRightColor: |
| case CSSPropertyBorderTopColor: |
| case CSSPropertyBorderBottomColor: |
| case CSSPropertyColor: |
| case CSSPropertyFill: |
| case CSSPropertyOutlineColor: |
| case CSSPropertyStroke: |
| case CSSPropertyTextDecorationColor: |
| case CSSPropertyWebkitColumnRuleColor: |
| case CSSPropertyWebkitTextEmphasisColor: |
| case CSSPropertyWebkitTextFillColor: |
| case CSSPropertyWebkitTextStrokeColor: |
| return true; |
| default: |
| break; |
| } |
| |
| return false; |
| } |
| |
| static bool hasVariableReference(CSSValue* value) |
| { |
| if (value->isPrimitiveValue()) { |
| CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
| return primitiveValue->hasVariableReference(); |
| } |
| |
| if (value->isCalcValue()) |
| return toCSSCalcValue(value)->hasVariableReference(); |
| |
| if (value->isReflectValue()) { |
| CSSReflectValue* reflectValue = toCSSReflectValue(value); |
| CSSPrimitiveValue* direction = reflectValue->direction(); |
| CSSPrimitiveValue* offset = reflectValue->offset(); |
| CSSValue* mask = reflectValue->mask(); |
| return (direction && hasVariableReference(direction)) || (offset && hasVariableReference(offset)) || (mask && hasVariableReference(mask)); |
| } |
| |
| for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { |
| if (hasVariableReference(i.value())) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| // FIXME: Resolving variables should be factored better. Maybe a resover-style class? |
| static void resolveVariables(StyleResolverState& state, CSSPropertyID id, CSSValue* value, Vector<std::pair<CSSPropertyID, String> >& knownExpressions) |
| { |
| std::pair<CSSPropertyID, String> expression(id, value->serializeResolvingVariables(*state.style()->variables())); |
| |
| if (knownExpressions.contains(expression)) |
| return; // cycle detected. |
| |
| knownExpressions.append(expression); |
| |
| // FIXME: It would be faster not to re-parse from strings, but for now CSS property validation lives inside the parser so we do it there. |
| RefPtr<MutableStylePropertySet> resultSet = MutableStylePropertySet::create(); |
| if (!CSSParser::parseValue(resultSet.get(), id, expression.second, false, state.document())) |
| return; // expression failed to parse. |
| |
| for (unsigned i = 0; i < resultSet->propertyCount(); i++) { |
| StylePropertySet::PropertyReference property = resultSet->propertyAt(i); |
| if (property.id() != CSSPropertyVariable && hasVariableReference(property.value())) { |
| resolveVariables(state, property.id(), property.value(), knownExpressions); |
| } else { |
| StyleBuilder::applyProperty(property.id(), state, property.value()); |
| // All properties become dependent on their parent style when they use variables. |
| state.style()->setHasExplicitlyInheritedProperties(); |
| } |
| } |
| } |
| |
| void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value) |
| { |
| if (RuntimeEnabledFeatures::cssVariablesEnabled() && id != CSSPropertyVariable && hasVariableReference(value)) { |
| Vector<std::pair<CSSPropertyID, String> > knownExpressions; |
| resolveVariables(state, id, value, knownExpressions); |
| return; |
| } |
| |
| // CSS variables don't resolve shorthands at parsing time, so this should be *after* handling variables. |
| ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id); |
| |
| bool isInherit = state.parentNode() && value->isInheritedValue(); |
| bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue()); |
| |
| ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit |
| ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle()) |
| |
| if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) { |
| // Limit the properties that can be applied to only the ones honored by :visited. |
| return; |
| } |
| |
| CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0; |
| if (primitiveValue && primitiveValue->getValueID() == CSSValueCurrentcolor) |
| state.style()->setHasCurrentColor(); |
| |
| if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id)) |
| state.parentStyle()->setHasExplicitlyInheritedProperties(); |
| |
| if (id == CSSPropertyVariable) { |
| ASSERT_WITH_SECURITY_IMPLICATION(value->isVariableValue()); |
| CSSVariableValue* variable = toCSSVariableValue(value); |
| ASSERT(!variable->name().isEmpty()); |
| ASSERT(!variable->value().isEmpty()); |
| state.style()->setVariable(variable->name(), variable->value()); |
| return; |
| } |
| |
| if (StyleBuilder::applyProperty(id, state, value, isInitial, isInherit)) |
| return; |
| |
| // Fall back to the old switch statement, which is now in StyleBuilderCustom.cpp |
| StyleBuilder::oldApplyProperty(id, state, value, isInitial, isInherit); |
| } |
| |
| |
| void StyleBuilder::oldApplyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value, bool isInitial, bool isInherit) |
| { |
| CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0; |
| |
| float zoomFactor = state.style()->effectiveZoom(); |
| |
| // What follows is a list that maps the CSS properties into their corresponding front-end |
| // RenderStyle values. |
| switch (id) { |
| case CSSPropertyContent: |
| // list of string, uri, counter, attr, i |
| { |
| // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This |
| // note is a reminder that eventually "inherit" needs to be supported. |
| |
| if (isInitial) { |
| state.style()->clearContent(); |
| return; |
| } |
| |
| if (!value->isValueList()) |
| return; |
| |
| bool didSet = false; |
| for (CSSValueListIterator i = value; i.hasMore(); i.advance()) { |
| CSSValue* item = i.value(); |
| if (item->isImageGeneratorValue()) { |
| if (item->isGradientValue()) |
| state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet); |
| else |
| state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet); |
| didSet = true; |
| } else if (item->isImageSetValue()) { |
| state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet); |
| didSet = true; |
| } |
| |
| if (item->isImageValue()) { |
| state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(CSSPropertyContent, toCSSImageValue(item)), didSet); |
| didSet = true; |
| continue; |
| } |
| |
| if (!item->isPrimitiveValue()) |
| continue; |
| |
| CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item); |
| |
| if (contentValue->isString()) { |
| state.style()->setContent(contentValue->getStringValue().impl(), didSet); |
| didSet = true; |
| } else if (contentValue->isAttr()) { |
| // FIXME: Can a namespace be specified for an attr(foo)? |
| if (state.style()->styleType() == NOPSEUDO) |
| state.style()->setUnique(); |
| else |
| state.parentStyle()->setUnique(); |
| QualifiedName attr(nullAtom, contentValue->getStringValue().impl(), nullAtom); |
| const AtomicString& value = state.element()->getAttribute(attr); |
| state.style()->setContent(value.isNull() ? emptyAtom : value.impl(), didSet); |
| didSet = true; |
| // register the fact that the attribute value affects the style |
| state.contentAttrValues().append(attr.localName()); |
| } else if (contentValue->isCounter()) { |
| Counter* counterValue = contentValue->getCounterValue(); |
| EListStyleType listStyleType = NoneListStyle; |
| CSSValueID listStyleIdent = counterValue->listStyleIdent(); |
| if (listStyleIdent != CSSValueNone) |
| listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc); |
| OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), listStyleType, counterValue->separator())); |
| state.style()->setContent(counter.release(), didSet); |
| didSet = true; |
| } else { |
| switch (contentValue->getValueID()) { |
| case CSSValueOpenQuote: |
| state.style()->setContent(OPEN_QUOTE, didSet); |
| didSet = true; |
| break; |
| case CSSValueCloseQuote: |
| state.style()->setContent(CLOSE_QUOTE, didSet); |
| didSet = true; |
| break; |
| case CSSValueNoOpenQuote: |
| state.style()->setContent(NO_OPEN_QUOTE, didSet); |
| didSet = true; |
| break; |
| case CSSValueNoCloseQuote: |
| state.style()->setContent(NO_CLOSE_QUOTE, didSet); |
| didSet = true; |
| break; |
| default: |
| // normal and none do not have any effect. |
| { } |
| } |
| } |
| } |
| if (!didSet) |
| state.style()->clearContent(); |
| return; |
| } |
| case CSSPropertyQuotes: |
| HANDLE_INHERIT_AND_INITIAL(quotes, Quotes); |
| if (value->isValueList()) { |
| CSSValueList* list = toCSSValueList(value); |
| RefPtr<QuotesData> quotes = QuotesData::create(); |
| for (size_t i = 0; i < list->length(); i += 2) { |
| CSSValue* first = list->itemWithoutBoundsCheck(i); |
| // item() returns null if out of bounds so this is safe. |
| CSSValue* second = list->item(i + 1); |
| if (!second) |
| continue; |
| String startQuote = toCSSPrimitiveValue(first)->getStringValue(); |
| String endQuote = toCSSPrimitiveValue(second)->getStringValue(); |
| quotes->addPair(std::make_pair(startQuote, endQuote)); |
| } |
| state.style()->setQuotes(quotes); |
| return; |
| } |
| if (primitiveValue) { |
| if (primitiveValue->getValueID() == CSSValueNone) |
| state.style()->setQuotes(QuotesData::create()); |
| } |
| return; |
| // Shorthand properties. |
| case CSSPropertyFont: |
| // Only System Font identifiers should come through this method |
| // all other values should have been handled when the shorthand |
| // was expanded by the parser. |
| // FIXME: System Font identifiers should not hijack this |
| // short-hand CSSProperty like this. |
| ASSERT(!isInitial); |
| ASSERT(!isInherit); |
| ASSERT(primitiveValue); |
| state.style()->setLineHeight(RenderStyle::initialLineHeight()); |
| state.setLineHeightValue(0); |
| state.fontBuilder().fromSystemFont(primitiveValue->getValueID(), state.style()->effectiveZoom()); |
| return; |
| case CSSPropertyAnimation: |
| case CSSPropertyBackground: |
| case CSSPropertyBackgroundPosition: |
| case CSSPropertyBackgroundRepeat: |
| case CSSPropertyBorder: |
| case CSSPropertyBorderBottom: |
| case CSSPropertyBorderColor: |
| case CSSPropertyBorderImage: |
| case CSSPropertyBorderLeft: |
| case CSSPropertyBorderRadius: |
| case CSSPropertyBorderRight: |
| case CSSPropertyBorderSpacing: |
| case CSSPropertyBorderStyle: |
| case CSSPropertyBorderTop: |
| case CSSPropertyBorderWidth: |
| case CSSPropertyListStyle: |
| case CSSPropertyMargin: |
| case CSSPropertyObjectPosition: |
| case CSSPropertyOutline: |
| case CSSPropertyOverflow: |
| case CSSPropertyPadding: |
| case CSSPropertyTransition: |
| case CSSPropertyWebkitAnimation: |
| case CSSPropertyWebkitBorderAfter: |
| case CSSPropertyWebkitBorderBefore: |
| case CSSPropertyWebkitBorderEnd: |
| case CSSPropertyWebkitBorderStart: |
| case CSSPropertyWebkitBorderRadius: |
| case CSSPropertyWebkitColumns: |
| case CSSPropertyWebkitColumnRule: |
| case CSSPropertyFlex: |
| case CSSPropertyFlexFlow: |
| case CSSPropertyGridColumn: |
| case CSSPropertyGridRow: |
| case CSSPropertyGridArea: |
| case CSSPropertyWebkitMarginCollapse: |
| case CSSPropertyWebkitMask: |
| case CSSPropertyWebkitMaskPosition: |
| case CSSPropertyWebkitMaskRepeat: |
| case CSSPropertyWebkitTextEmphasis: |
| case CSSPropertyWebkitTextStroke: |
| case CSSPropertyWebkitTransition: |
| case CSSPropertyWebkitTransformOrigin: |
| ASSERT(isExpandedShorthand(id)); |
| ASSERT_NOT_REACHED(); |
| break; |
| |
| // CSS3 Properties |
| case CSSPropertyWebkitBoxReflect: { |
| HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect) |
| if (primitiveValue) { |
| state.style()->setBoxReflect(RenderStyle::initialBoxReflect()); |
| return; |
| } |
| |
| if (!value->isReflectValue()) |
| return; |
| |
| CSSReflectValue* reflectValue = toCSSReflectValue(value); |
| RefPtr<StyleReflection> reflection = StyleReflection::create(); |
| reflection->setDirection(*reflectValue->direction()); |
| if (reflectValue->offset()) |
| reflection->setOffset(reflectValue->offset()->convertToLength<FixedIntegerConversion | PercentConversion>(state.style(), state.rootElementStyle(), zoomFactor)); |
| NinePieceImage mask; |
| mask.setMaskDefaults(); |
| state.styleMap().mapNinePieceImage(state.style(), id, reflectValue->mask(), mask); |
| reflection->setMask(mask); |
| |
| state.style()->setBoxReflect(reflection.release()); |
| return; |
| } |
| case CSSPropertySrc: // Only used in @font-face rules. |
| return; |
| case CSSPropertyUnicodeRange: // Only used in @font-face rules. |
| return; |
| case CSSPropertyWebkitLocale: { |
| HANDLE_INHERIT_AND_INITIAL(locale, Locale); |
| if (!primitiveValue) |
| return; |
| if (primitiveValue->getValueID() == CSSValueAuto) |
| state.style()->setLocale(nullAtom); |
| else |
| state.style()->setLocale(primitiveValue->getStringValue()); |
| state.fontBuilder().setScript(state.style()->locale()); |
| return; |
| } |
| case CSSPropertyWebkitAppRegion: { |
| if (!primitiveValue || !primitiveValue->getValueID()) |
| return; |
| state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag); |
| state.document().setHasAnnotatedRegions(true); |
| return; |
| } |
| case CSSPropertyWebkitTextStrokeWidth: { |
| HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth) |
| float width = 0; |
| switch (primitiveValue->getValueID()) { |
| case CSSValueThin: |
| case CSSValueMedium: |
| case CSSValueThick: { |
| double result = 1.0 / 48; |
| if (primitiveValue->getValueID() == CSSValueMedium) |
| result *= 3; |
| else if (primitiveValue->getValueID() == CSSValueThick) |
| result *= 5; |
| width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor); |
| break; |
| } |
| default: |
| width = primitiveValue->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor); |
| break; |
| } |
| state.style()->setTextStrokeWidth(width); |
| return; |
| } |
| case CSSPropertyWebkitTransform: { |
| HANDLE_INHERIT_AND_INITIAL(transform, Transform); |
| TransformOperations operations; |
| TransformBuilder::createTransformOperations(value, state.style(), state.rootElementStyle(), operations); |
| state.style()->setTransform(operations); |
| return; |
| } |
| case CSSPropertyWebkitPerspective: { |
| HANDLE_INHERIT_AND_INITIAL(perspective, Perspective) |
| |
| if (!primitiveValue) |
| return; |
| |
| if (primitiveValue->getValueID() == CSSValueNone) { |
| state.style()->setPerspective(0); |
| return; |
| } |
| |
| float perspectiveValue; |
| if (primitiveValue->isLength()) { |
| perspectiveValue = primitiveValue->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor); |
| } else if (primitiveValue->isNumber()) { |
| // For backward compatibility, treat valueless numbers as px. |
| perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor); |
| } else { |
| return; |
| } |
| |
| if (perspectiveValue >= 0.0f) |
| state.style()->setPerspective(perspectiveValue); |
| return; |
| } |
| case CSSPropertyWebkitTapHighlightColor: { |
| HANDLE_INHERIT_AND_INITIAL(tapHighlightColor, TapHighlightColor); |
| if (!primitiveValue) |
| break; |
| |
| Color col = state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->visitedDependentColor(CSSPropertyColor)); |
| state.style()->setTapHighlightColor(col); |
| return; |
| } |
| case CSSPropertyInternalCallback: { |
| if (isInherit || isInitial) |
| return; |
| if (primitiveValue && primitiveValue->getValueID() == CSSValueInternalPresence) { |
| state.style()->addCallbackSelector(state.currentRule()->selectorList().selectorsText()); |
| return; |
| } |
| break; |
| } |
| case CSSPropertyInvalid: |
| return; |
| // Directional properties are resolved by resolveDirectionAwareProperty() before the switch. |
| case CSSPropertyWebkitBorderEndColor: |
| case CSSPropertyWebkitBorderEndStyle: |
| case CSSPropertyWebkitBorderEndWidth: |
| case CSSPropertyWebkitBorderStartColor: |
| case CSSPropertyWebkitBorderStartStyle: |
| case CSSPropertyWebkitBorderStartWidth: |
| case CSSPropertyWebkitBorderBeforeColor: |
| case CSSPropertyWebkitBorderBeforeStyle: |
| case CSSPropertyWebkitBorderBeforeWidth: |
| case CSSPropertyWebkitBorderAfterColor: |
| case CSSPropertyWebkitBorderAfterStyle: |
| case CSSPropertyWebkitBorderAfterWidth: |
| case CSSPropertyWebkitMarginEnd: |
| case CSSPropertyWebkitMarginStart: |
| case CSSPropertyWebkitMarginBefore: |
| case CSSPropertyWebkitMarginAfter: |
| case CSSPropertyWebkitMarginBeforeCollapse: |
| case CSSPropertyWebkitMarginTopCollapse: |
| case CSSPropertyWebkitMarginAfterCollapse: |
| case CSSPropertyWebkitMarginBottomCollapse: |
| case CSSPropertyWebkitPaddingEnd: |
| case CSSPropertyWebkitPaddingStart: |
| case CSSPropertyWebkitPaddingBefore: |
| case CSSPropertyWebkitPaddingAfter: |
| case CSSPropertyWebkitLogicalWidth: |
| case CSSPropertyWebkitLogicalHeight: |
| case CSSPropertyWebkitMinLogicalWidth: |
| case CSSPropertyWebkitMinLogicalHeight: |
| case CSSPropertyWebkitMaxLogicalWidth: |
| case CSSPropertyWebkitMaxLogicalHeight: |
| { |
| CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode()); |
| ASSERT(newId != id); |
| return applyProperty(newId, state, value); |
| } |
| case CSSPropertyFontStretch: |
| case CSSPropertyPage: |
| case CSSPropertyTextLineThroughColor: |
| case CSSPropertyTextLineThroughMode: |
| case CSSPropertyTextLineThroughStyle: |
| case CSSPropertyTextLineThroughWidth: |
| case CSSPropertyTextOverlineColor: |
| case CSSPropertyTextOverlineMode: |
| case CSSPropertyTextOverlineStyle: |
| case CSSPropertyTextOverlineWidth: |
| case CSSPropertyTextUnderlineColor: |
| case CSSPropertyTextUnderlineMode: |
| case CSSPropertyTextUnderlineStyle: |
| case CSSPropertyTextUnderlineWidth: |
| case CSSPropertyWebkitFontSizeDelta: |
| case CSSPropertyWebkitTextDecorationsInEffect: |
| return; |
| |
| // CSS Text Layout Module Level 3: Vertical writing support |
| case CSSPropertyWebkitWritingMode: { |
| HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode); |
| |
| if (primitiveValue) |
| state.setWritingMode(*primitiveValue); |
| |
| // FIXME: It is not ok to modify document state while applying style. |
| if (state.element() && state.element() == state.document().documentElement()) |
| state.document().setWritingModeSetOnDocumentElement(true); |
| return; |
| } |
| |
| case CSSPropertyWebkitTextOrientation: { |
| HANDLE_INHERIT_AND_INITIAL(textOrientation, TextOrientation); |
| |
| if (primitiveValue) |
| state.setTextOrientation(*primitiveValue); |
| |
| return; |
| } |
| |
| case CSSPropertyWebkitLineBoxContain: { |
| HANDLE_INHERIT_AND_INITIAL(lineBoxContain, LineBoxContain) |
| if (primitiveValue && primitiveValue->getValueID() == CSSValueNone) { |
| state.style()->setLineBoxContain(LineBoxContainNone); |
| return; |
| } |
| |
| if (!value->isLineBoxContainValue()) |
| return; |
| |
| state.style()->setLineBoxContain(toCSSLineBoxContainValue(value)->value()); |
| return; |
| } |
| |
| // CSS Fonts Module Level 3 |
| case CSSPropertyWebkitFontFeatureSettings: { |
| if (primitiveValue && primitiveValue->getValueID() == CSSValueNormal) { |
| state.fontBuilder().setFeatureSettingsNormal(); |
| return; |
| } |
| |
| if (!value->isValueList()) |
| return; |
| |
| state.fontBuilder().setFeatureSettingsValue(value); |
| return; |
| } |
| |
| case CSSPropertyWebkitFilter: { |
| HANDLE_INHERIT_AND_INITIAL(filter, Filter); |
| FilterOperations operations; |
| if (FilterOperationResolver::createFilterOperations(value, state.style(), state.rootElementStyle(), operations, state)) |
| state.style()->setFilter(operations); |
| return; |
| } |
| case CSSPropertyGridAutoColumns: { |
| HANDLE_INHERIT_AND_INITIAL(gridAutoColumns, GridAutoColumns); |
| GridTrackSize trackSize; |
| if (!createGridTrackSize(value, trackSize, state)) |
| return; |
| state.style()->setGridAutoColumns(trackSize); |
| return; |
| } |
| case CSSPropertyGridAutoRows: { |
| HANDLE_INHERIT_AND_INITIAL(gridAutoRows, GridAutoRows); |
| GridTrackSize trackSize; |
| if (!createGridTrackSize(value, trackSize, state)) |
| return; |
| state.style()->setGridAutoRows(trackSize); |
| return; |
| } |
| case CSSPropertyGridDefinitionColumns: { |
| if (isInherit) { |
| state.style()->setGridDefinitionColumns(state.parentStyle()->gridDefinitionColumns()); |
| state.style()->setNamedGridColumnLines(state.parentStyle()->namedGridColumnLines()); |
| state.style()->setOrderedNamedGridColumnLines(state.parentStyle()->orderedNamedGridColumnLines()); |
| return; |
| } |
| if (isInitial) { |
| state.style()->setGridDefinitionColumns(RenderStyle::initialGridDefinitionColumns()); |
| state.style()->setNamedGridColumnLines(RenderStyle::initialNamedGridColumnLines()); |
| state.style()->setOrderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines()); |
| return; |
| } |
| |
| Vector<GridTrackSize> trackSizes; |
| NamedGridLinesMap namedGridLines; |
| OrderedNamedGridLines orderedNamedGridLines; |
| if (!createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state)) |
| return; |
| state.style()->setGridDefinitionColumns(trackSizes); |
| state.style()->setNamedGridColumnLines(namedGridLines); |
| state.style()->setOrderedNamedGridColumnLines(orderedNamedGridLines); |
| return; |
| } |
| case CSSPropertyGridDefinitionRows: { |
| if (isInherit) { |
| state.style()->setGridDefinitionRows(state.parentStyle()->gridDefinitionRows()); |
| state.style()->setNamedGridRowLines(state.parentStyle()->namedGridRowLines()); |
| state.style()->setOrderedNamedGridRowLines(state.parentStyle()->orderedNamedGridRowLines()); |
| return; |
| } |
| if (isInitial) { |
| state.style()->setGridDefinitionRows(RenderStyle::initialGridDefinitionRows()); |
| state.style()->setNamedGridRowLines(RenderStyle::initialNamedGridRowLines()); |
| state.style()->setOrderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines()); |
| return; |
| } |
| |
| Vector<GridTrackSize> trackSizes; |
| NamedGridLinesMap namedGridLines; |
| OrderedNamedGridLines orderedNamedGridLines; |
| if (!createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state)) |
| return; |
| state.style()->setGridDefinitionRows(trackSizes); |
| state.style()->setNamedGridRowLines(namedGridLines); |
| state.style()->setOrderedNamedGridRowLines(orderedNamedGridLines); |
| return; |
| } |
| |
| case CSSPropertyGridColumnStart: { |
| HANDLE_INHERIT_AND_INITIAL(gridColumnStart, GridColumnStart); |
| GridPosition startPosition; |
| if (!createGridPosition(value, startPosition)) |
| return; |
| state.style()->setGridColumnStart(startPosition); |
| return; |
| } |
| case CSSPropertyGridColumnEnd: { |
| HANDLE_INHERIT_AND_INITIAL(gridColumnEnd, GridColumnEnd); |
| GridPosition endPosition; |
| if (!createGridPosition(value, endPosition)) |
| return; |
| state.style()->setGridColumnEnd(endPosition); |
| return; |
| } |
| |
| case CSSPropertyGridRowStart: { |
| HANDLE_INHERIT_AND_INITIAL(gridRowStart, GridRowStart); |
| GridPosition beforePosition; |
| if (!createGridPosition(value, beforePosition)) |
| return; |
| state.style()->setGridRowStart(beforePosition); |
| return; |
| } |
| case CSSPropertyGridRowEnd: { |
| HANDLE_INHERIT_AND_INITIAL(gridRowEnd, GridRowEnd); |
| GridPosition afterPosition; |
| if (!createGridPosition(value, afterPosition)) |
| return; |
| state.style()->setGridRowEnd(afterPosition); |
| return; |
| } |
| |
| case CSSPropertyGridTemplate: { |
| if (isInherit) { |
| state.style()->setNamedGridArea(state.parentStyle()->namedGridArea()); |
| state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount()); |
| state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount()); |
| return; |
| } |
| if (isInitial) { |
| state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea()); |
| state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount()); |
| state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount()); |
| return; |
| } |
| |
| if (value->isPrimitiveValue()) { |
| ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone); |
| return; |
| } |
| |
| CSSGridTemplateValue* gridTemplateValue = toCSSGridTemplateValue(value); |
| state.style()->setNamedGridArea(gridTemplateValue->gridAreaMap()); |
| state.style()->setNamedGridAreaRowCount(gridTemplateValue->rowCount()); |
| state.style()->setNamedGridAreaColumnCount(gridTemplateValue->columnCount()); |
| return; |
| } |
| |
| // These properties are aliased and we already applied the property on the prefixed version. |
| case CSSPropertyAnimationDelay: |
| case CSSPropertyAnimationDirection: |
| case CSSPropertyAnimationDuration: |
| case CSSPropertyAnimationFillMode: |
| case CSSPropertyAnimationIterationCount: |
| case CSSPropertyAnimationName: |
| case CSSPropertyAnimationPlayState: |
| case CSSPropertyAnimationTimingFunction: |
| case CSSPropertyTransitionDelay: |
| case CSSPropertyTransitionDuration: |
| case CSSPropertyTransitionProperty: |
| case CSSPropertyTransitionTimingFunction: |
| return; |
| // These properties are implemented in StyleBuilder::applyProperty. |
| case CSSPropertyBackgroundAttachment: |
| case CSSPropertyBackgroundBlendMode: |
| case CSSPropertyBackgroundClip: |
| case CSSPropertyBackgroundColor: |
| case CSSPropertyBackgroundImage: |
| case CSSPropertyBackgroundOrigin: |
| case CSSPropertyBackgroundPositionX: |
| case CSSPropertyBackgroundPositionY: |
| case CSSPropertyBackgroundRepeatX: |
| case CSSPropertyBackgroundRepeatY: |
| case CSSPropertyBackgroundSize: |
| case CSSPropertyBorderBottomColor: |
| case CSSPropertyBorderBottomLeftRadius: |
| case CSSPropertyBorderBottomRightRadius: |
| case CSSPropertyBorderBottomStyle: |
| case CSSPropertyBorderBottomWidth: |
| case CSSPropertyBorderCollapse: |
| case CSSPropertyBorderImageOutset: |
| case CSSPropertyBorderImageRepeat: |
| case CSSPropertyBorderImageSlice: |
| case CSSPropertyBorderImageSource: |
| case CSSPropertyBorderImageWidth: |
| case CSSPropertyBorderLeftColor: |
| case CSSPropertyBorderLeftStyle: |
| case CSSPropertyBorderLeftWidth: |
| case CSSPropertyBorderRightColor: |
| case CSSPropertyBorderRightStyle: |
| case CSSPropertyBorderRightWidth: |
| case CSSPropertyBorderTopColor: |
| case CSSPropertyBorderTopLeftRadius: |
| case CSSPropertyBorderTopRightRadius: |
| case CSSPropertyBorderTopStyle: |
| case CSSPropertyBorderTopWidth: |
| case CSSPropertyBottom: |
| case CSSPropertyBoxShadow: |
| case CSSPropertyBoxSizing: |
| case CSSPropertyCaptionSide: |
| case CSSPropertyClear: |
| case CSSPropertyClip: |
| case CSSPropertyColor: |
| case CSSPropertyCounterIncrement: |
| case CSSPropertyCounterReset: |
| case CSSPropertyCursor: |
| case CSSPropertyDirection: |
| case CSSPropertyDisplay: |
| case CSSPropertyEmptyCells: |
| case CSSPropertyFloat: |
| case CSSPropertyFontSize: |
| case CSSPropertyFontStyle: |
| case CSSPropertyFontVariant: |
| case CSSPropertyFontWeight: |
| case CSSPropertyHeight: |
| case CSSPropertyImageRendering: |
| case CSSPropertyIsolation: |
| case CSSPropertyLeft: |
| case CSSPropertyLetterSpacing: |
| case CSSPropertyLineHeight: |
| case CSSPropertyListStyleImage: |
| case CSSPropertyListStylePosition: |
| case CSSPropertyListStyleType: |
| case CSSPropertyMarginBottom: |
| case CSSPropertyMarginLeft: |
| case CSSPropertyMarginRight: |
| case CSSPropertyMarginTop: |
| case CSSPropertyMaxHeight: |
| case CSSPropertyMaxWidth: |
| case CSSPropertyMinHeight: |
| case CSSPropertyMixBlendMode: |
| case CSSPropertyMinWidth: |
| case CSSPropertyObjectFit: |
| case CSSPropertyOpacity: |
| case CSSPropertyOrphans: |
| case CSSPropertyOutlineColor: |
| case CSSPropertyOutlineOffset: |
| case CSSPropertyOutlineStyle: |
| case CSSPropertyOutlineWidth: |
| case CSSPropertyOverflowWrap: |
| case CSSPropertyOverflowX: |
| case CSSPropertyOverflowY: |
| case CSSPropertyPaddingBottom: |
| case CSSPropertyPaddingLeft: |
| case CSSPropertyPaddingRight: |
| case CSSPropertyPaddingTop: |
| case CSSPropertyPageBreakAfter: |
| case CSSPropertyPageBreakBefore: |
| case CSSPropertyPageBreakInside: |
| case CSSPropertyPointerEvents: |
| case CSSPropertyPosition: |
| case CSSPropertyResize: |
| case CSSPropertyRight: |
| case CSSPropertySize: |
| case CSSPropertySpeak: |
| case CSSPropertyTabSize: |
| case CSSPropertyTableLayout: |
| case CSSPropertyTextAlign: |
| case CSSPropertyTextAlignLast: |
| case CSSPropertyTextDecoration: |
| case CSSPropertyTextDecorationLine: |
| case CSSPropertyTextDecorationStyle: |
| case CSSPropertyTextDecorationColor: |
| case CSSPropertyTextIndent: |
| case CSSPropertyTextJustify: |
| case CSSPropertyTextOverflow: |
| case CSSPropertyTextRendering: |
| case CSSPropertyTextShadow: |
| case CSSPropertyTextTransform: |
| case CSSPropertyTop: |
| case CSSPropertyTouchAction: |
| case CSSPropertyTouchActionDelay: |
| case CSSPropertyUnicodeBidi: |
| case CSSPropertyVariable: |
| case CSSPropertyVerticalAlign: |
| case CSSPropertyVisibility: |
| case CSSPropertyWebkitAnimationDelay: |
| case CSSPropertyWebkitAnimationDirection: |
| case CSSPropertyWebkitAnimationDuration: |
| case CSSPropertyWebkitAnimationFillMode: |
| case CSSPropertyWebkitAnimationIterationCount: |
| case CSSPropertyWebkitAnimationName: |
| case CSSPropertyWebkitAnimationPlayState: |
| case CSSPropertyWebkitAnimationTimingFunction: |
| case CSSPropertyWebkitAppearance: |
| case CSSPropertyWebkitAspectRatio: |
| case CSSPropertyWebkitBackfaceVisibility: |
| case CSSPropertyWebkitBackgroundClip: |
| case CSSPropertyWebkitBackgroundComposite: |
| case CSSPropertyWebkitBackgroundOrigin: |
| case CSSPropertyWebkitBackgroundSize: |
| case CSSPropertyWebkitBorderFit: |
| case CSSPropertyWebkitBorderHorizontalSpacing: |
| case CSSPropertyWebkitBorderImage: |
| case CSSPropertyWebkitBorderVerticalSpacing: |
| case CSSPropertyWebkitBoxAlign: |
| case CSSPropertyWebkitBoxDecorationBreak: |
| case CSSPropertyWebkitBoxDirection: |
| case CSSPropertyWebkitBoxFlex: |
| case CSSPropertyWebkitBoxFlexGroup: |
| case CSSPropertyWebkitBoxLines: |
| case CSSPropertyWebkitBoxOrdinalGroup: |
| case CSSPropertyWebkitBoxOrient: |
| case CSSPropertyWebkitBoxPack: |
| case CSSPropertyWebkitBoxShadow: |
| case CSSPropertyWebkitColumnAxis: |
| case CSSPropertyWebkitColumnBreakAfter: |
| case CSSPropertyWebkitColumnBreakBefore: |
| case CSSPropertyWebkitColumnBreakInside: |
| case CSSPropertyWebkitColumnCount: |
| case CSSPropertyColumnFill: |
| case CSSPropertyWebkitColumnGap: |
| case CSSPropertyWebkitColumnProgression: |
| case CSSPropertyWebkitColumnRuleColor: |
| case CSSPropertyWebkitColumnRuleStyle: |
| case CSSPropertyWebkitColumnRuleWidth: |
| case CSSPropertyWebkitColumnSpan: |
| case CSSPropertyWebkitColumnWidth: |
| case CSSPropertyAlignContent: |
| case CSSPropertyAlignItems: |
| case CSSPropertyAlignSelf: |
| case CSSPropertyFlexBasis: |
| case CSSPropertyFlexDirection: |
| case CSSPropertyFlexGrow: |
| case CSSPropertyFlexShrink: |
| case CSSPropertyFlexWrap: |
| case CSSPropertyJustifyContent: |
| case CSSPropertyOrder: |
| case CSSPropertyWebkitFlowFrom: |
| case CSSPropertyWebkitFlowInto: |
| case CSSPropertyWebkitFontKerning: |
| case CSSPropertyWebkitFontSmoothing: |
| case CSSPropertyWebkitFontVariantLigatures: |
| case CSSPropertyWebkitHighlight: |
| case CSSPropertyWebkitHyphenateCharacter: |
| case CSSPropertyWebkitLineAlign: |
| case CSSPropertyWebkitLineBreak: |
| case CSSPropertyWebkitLineClamp: |
| case CSSPropertyWebkitLineGrid: |
| case CSSPropertyWebkitLineSnap: |
| case CSSPropertyInternalMarqueeDirection: |
| case CSSPropertyInternalMarqueeIncrement: |
| case CSSPropertyInternalMarqueeRepetition: |
| case CSSPropertyInternalMarqueeSpeed: |
| case CSSPropertyInternalMarqueeStyle: |
| case CSSPropertyWebkitMaskBoxImage: |
| case CSSPropertyWebkitMaskBoxImageOutset: |
| case CSSPropertyWebkitMaskBoxImageRepeat: |
| case CSSPropertyWebkitMaskBoxImageSlice: |
| case CSSPropertyWebkitMaskBoxImageSource: |
| case CSSPropertyWebkitMaskBoxImageWidth: |
| case CSSPropertyWebkitMaskClip: |
| case CSSPropertyWebkitMaskComposite: |
| case CSSPropertyWebkitMaskImage: |
| case CSSPropertyWebkitMaskOrigin: |
| case CSSPropertyWebkitMaskPositionX: |
| case CSSPropertyWebkitMaskPositionY: |
| case CSSPropertyWebkitMaskRepeatX: |
| case CSSPropertyWebkitMaskRepeatY: |
| case CSSPropertyWebkitMaskSize: |
| case CSSPropertyWebkitPerspectiveOrigin: |
| case CSSPropertyWebkitPerspectiveOriginX: |
| case CSSPropertyWebkitPerspectiveOriginY: |
| case CSSPropertyWebkitPrintColorAdjust: |
| case CSSPropertyWebkitRegionBreakAfter: |
| case CSSPropertyWebkitRegionBreakBefore: |
| case CSSPropertyWebkitRegionBreakInside: |
| case CSSPropertyWebkitRegionFragment: |
| case CSSPropertyWebkitRtlOrdering: |
| case CSSPropertyWebkitRubyPosition: |
| case CSSPropertyWebkitTextCombine: |
| case CSSPropertyTextUnderlinePosition: |
| case CSSPropertyWebkitTextEmphasisColor: |
| case CSSPropertyWebkitTextEmphasisPosition: |
| case CSSPropertyWebkitTextEmphasisStyle: |
| case CSSPropertyWebkitTextFillColor: |
| case CSSPropertyWebkitTextSecurity: |
| case CSSPropertyWebkitTextStrokeColor: |
| case CSSPropertyWebkitTransformOriginX: |
| case CSSPropertyWebkitTransformOriginY: |
| case CSSPropertyWebkitTransformOriginZ: |
| case CSSPropertyWebkitTransformStyle: |
| case CSSPropertyWebkitTransitionDelay: |
| case CSSPropertyWebkitTransitionDuration: |
| case CSSPropertyWebkitTransitionProperty: |
| case CSSPropertyWebkitTransitionTimingFunction: |
| case CSSPropertyWebkitUserDrag: |
| case CSSPropertyWebkitUserModify: |
| case CSSPropertyWebkitUserSelect: |
| case CSSPropertyWebkitClipPath: |
| case CSSPropertyWebkitWrapFlow: |
| case CSSPropertyShapeMargin: |
| case CSSPropertyShapePadding: |
| case CSSPropertyShapeImageThreshold: |
| case CSSPropertyWebkitWrapThrough: |
| case CSSPropertyShapeInside: |
| case CSSPropertyShapeOutside: |
| case CSSPropertyWhiteSpace: |
| case CSSPropertyWidows: |
| case CSSPropertyWidth: |
| case CSSPropertyWordBreak: |
| case CSSPropertyWordSpacing: |
| case CSSPropertyWordWrap: |
| case CSSPropertyZIndex: |
| case CSSPropertyZoom: |
| case CSSPropertyFontFamily: |
| case CSSPropertyGridAutoFlow: |
| case CSSPropertyMarker: |
| case CSSPropertyAlignmentBaseline: |
| case CSSPropertyBufferedRendering: |
| case CSSPropertyClipRule: |
| case CSSPropertyColorInterpolation: |
| case CSSPropertyColorInterpolationFilters: |
| case CSSPropertyColorRendering: |
| case CSSPropertyDominantBaseline: |
| case CSSPropertyFillRule: |
| case CSSPropertyMaskSourceType: |
| case CSSPropertyMaskType: |
| case CSSPropertyShapeRendering: |
| case CSSPropertyStrokeLinecap: |
| case CSSPropertyStrokeLinejoin: |
| case CSSPropertyTextAnchor: |
| case CSSPropertyVectorEffect: |
| case CSSPropertyWritingMode: |
| ASSERT_NOT_REACHED(); |
| return; |
| // Only used in @viewport rules |
| case CSSPropertyMaxZoom: |
| case CSSPropertyMinZoom: |
| case CSSPropertyOrientation: |
| case CSSPropertyUserZoom: |
| return; |
| |
| case CSSPropertyBaselineShift: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(baselineShift, BaselineShift); |
| if (!primitiveValue) |
| break; |
| |
| SVGRenderStyle* svgStyle = state.style()->accessSVGStyle(); |
| if (primitiveValue->getValueID()) { |
| switch (primitiveValue->getValueID()) { |
| case CSSValueBaseline: |
| svgStyle->setBaselineShift(BS_BASELINE); |
| break; |
| case CSSValueSub: |
| svgStyle->setBaselineShift(BS_SUB); |
| break; |
| case CSSValueSuper: |
| svgStyle->setBaselineShift(BS_SUPER); |
| break; |
| default: |
| break; |
| } |
| } else { |
| svgStyle->setBaselineShift(BS_LENGTH); |
| svgStyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue)); |
| } |
| |
| break; |
| } |
| case CSSPropertyKerning: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(kerning, Kerning); |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setKerning(SVGLength::fromCSSPrimitiveValue(primitiveValue)); |
| break; |
| } |
| case CSSPropertyColorProfile: |
| { |
| // Not implemented. |
| break; |
| } |
| // end of ident only properties |
| case CSSPropertyFill: |
| { |
| SVGRenderStyle* svgStyle = state.style()->accessSVGStyle(); |
| if (isInherit) { |
| const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle(); |
| svgStyle->setFillPaint(svgParentStyle->fillPaintType(), svgParentStyle->fillPaintColor(), svgParentStyle->fillPaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle()); |
| return; |
| } |
| if (isInitial) { |
| svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle()); |
| return; |
| } |
| if (value->isSVGPaint()) { |
| SVGPaint* svgPaint = toSVGPaint(value); |
| svgStyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle()); |
| } |
| break; |
| } |
| case CSSPropertyStroke: |
| { |
| SVGRenderStyle* svgStyle = state.style()->accessSVGStyle(); |
| if (isInherit) { |
| const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle(); |
| svgStyle->setStrokePaint(svgParentStyle->strokePaintType(), svgParentStyle->strokePaintColor(), svgParentStyle->strokePaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle()); |
| return; |
| } |
| if (isInitial) { |
| svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle()); |
| return; |
| } |
| if (value->isSVGPaint()) { |
| SVGPaint* svgPaint = toSVGPaint(value); |
| svgStyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle()); |
| } |
| break; |
| } |
| case CSSPropertyStrokeWidth: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setStrokeWidth(SVGLength::fromCSSPrimitiveValue(primitiveValue)); |
| break; |
| } |
| case CSSPropertyStrokeDasharray: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray) |
| if (!value->isValueList()) { |
| state.style()->accessSVGStyle()->setStrokeDashArray(SVGRenderStyle::initialStrokeDashArray()); |
| break; |
| } |
| |
| CSSValueList* dashes = toCSSValueList(value); |
| |
| Vector<SVGLength> array; |
| size_t length = dashes->length(); |
| for (size_t i = 0; i < length; ++i) { |
| CSSValue* currValue = dashes->itemWithoutBoundsCheck(i); |
| if (!currValue->isPrimitiveValue()) |
| continue; |
| |
| CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->itemWithoutBoundsCheck(i)); |
| array.append(SVGLength::fromCSSPrimitiveValue(dash)); |
| } |
| |
| state.style()->accessSVGStyle()->setStrokeDashArray(array); |
| break; |
| } |
| case CSSPropertyStrokeDashoffset: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setStrokeDashOffset(SVGLength::fromCSSPrimitiveValue(primitiveValue)); |
| break; |
| } |
| case CSSPropertyFillOpacity: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(fillOpacity, FillOpacity) |
| float f = 0.0f; |
| if (percentageOrNumberToFloat(primitiveValue, f)) |
| state.style()->accessSVGStyle()->setFillOpacity(f); |
| break; |
| } |
| case CSSPropertyStrokeOpacity: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity) |
| float f = 0.0f; |
| if (percentageOrNumberToFloat(primitiveValue, f)) |
| state.style()->accessSVGStyle()->setStrokeOpacity(f); |
| break; |
| } |
| case CSSPropertyStopOpacity: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(stopOpacity, StopOpacity) |
| float f = 0.0f; |
| if (percentageOrNumberToFloat(primitiveValue, f)) |
| state.style()->accessSVGStyle()->setStopOpacity(f); |
| break; |
| } |
| case CSSPropertyMarkerStart: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(markerStartResource, MarkerStartResource) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setMarkerStartResource(fragmentIdentifier(primitiveValue, state.document())); |
| break; |
| } |
| case CSSPropertyMarkerMid: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(markerMidResource, MarkerMidResource) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setMarkerMidResource(fragmentIdentifier(primitiveValue, state.document())); |
| break; |
| } |
| case CSSPropertyMarkerEnd: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(markerEndResource, MarkerEndResource) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setMarkerEndResource(fragmentIdentifier(primitiveValue, state.document())); |
| break; |
| } |
| case CSSPropertyStrokeMiterlimit: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit) |
| float f = 0.0f; |
| if (numberToFloat(primitiveValue, f)) |
| state.style()->accessSVGStyle()->setStrokeMiterLimit(f); |
| break; |
| } |
| case CSSPropertyFilter: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(filterResource, FilterResource) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setFilterResource(fragmentIdentifier(primitiveValue, state.document())); |
| break; |
| } |
| case CSSPropertyMask: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(maskerResource, MaskerResource) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setMaskerResource(fragmentIdentifier(primitiveValue, state.document())); |
| break; |
| } |
| case CSSPropertyClipPath: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(clipperResource, ClipperResource) |
| if (primitiveValue) |
| state.style()->accessSVGStyle()->setClipperResource(fragmentIdentifier(primitiveValue, state.document())); |
| break; |
| } |
| case CSSPropertyStopColor: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(stopColor, StopColor); |
| if (value->isSVGColor()) |
| state.style()->accessSVGStyle()->setStopColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color())); |
| break; |
| } |
| case CSSPropertyLightingColor: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(lightingColor, LightingColor); |
| if (value->isSVGColor()) |
| state.style()->accessSVGStyle()->setLightingColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color())); |
| break; |
| } |
| case CSSPropertyFloodOpacity: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity) |
| float f = 0.0f; |
| if (percentageOrNumberToFloat(primitiveValue, f)) |
| state.style()->accessSVGStyle()->setFloodOpacity(f); |
| break; |
| } |
| case CSSPropertyFloodColor: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(floodColor, FloodColor); |
| if (value->isSVGColor()) |
| state.style()->accessSVGStyle()->setFloodColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color())); |
| break; |
| } |
| case CSSPropertyGlyphOrientationHorizontal: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal) |
| EGlyphOrientation orientation; |
| if (degreeToGlyphOrientation(primitiveValue, orientation)) |
| state.style()->accessSVGStyle()->setGlyphOrientationHorizontal(orientation); |
| break; |
| } |
| case CSSPropertyPaintOrder: { |
| HANDLE_SVG_INHERIT_AND_INITIAL(paintOrder, PaintOrder) |
| if (value->isValueList()) |
| state.style()->accessSVGStyle()->setPaintOrder(paintOrderFlattened(value)); |
| break; |
| } |
| case CSSPropertyGlyphOrientationVertical: |
| { |
| HANDLE_SVG_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical) |
| if (primitiveValue->getValueID() == CSSValueAuto) { |
| state.style()->accessSVGStyle()->setGlyphOrientationVertical(GO_AUTO); |
| break; |
| } |
| EGlyphOrientation orientation; |
| if (degreeToGlyphOrientation(primitiveValue, orientation)) |
| state.style()->accessSVGStyle()->setGlyphOrientationVertical(orientation); |
| break; |
| } |
| case CSSPropertyEnableBackground: |
| // Silently ignoring this property for now |
| // http://bugs.webkit.org/show_bug.cgi?id=6022 |
| break; |
| } |
| } |
| |
| } // namespace WebCore |