| /* |
| * Copyright (C) 2004 Zack Rusin <zack@kde.org> |
| * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. |
| * All rights reserved. |
| * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
| * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
| * Copyright (C) 2011 Sencha, Inc. All rights reserved. |
| * Copyright (C) 2015 Google Inc. All rights reserved. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| * 02110-1301 USA |
| */ |
| |
| #include "core/css/ComputedStyleCSSValueMapping.h" |
| |
| #include "core/StylePropertyShorthand.h" |
| #include "core/animation/css/CSSAnimationData.h" |
| #include "core/animation/css/CSSTransitionData.h" |
| #include "core/css/BasicShapeFunctions.h" |
| #include "core/css/CSSBasicShapeValues.h" |
| #include "core/css/CSSBorderImage.h" |
| #include "core/css/CSSBorderImageSliceValue.h" |
| #include "core/css/CSSColorValue.h" |
| #include "core/css/CSSCounterValue.h" |
| #include "core/css/CSSCursorImageValue.h" |
| #include "core/css/CSSCustomIdentValue.h" |
| #include "core/css/CSSCustomPropertyDeclaration.h" |
| #include "core/css/CSSFontFamilyValue.h" |
| #include "core/css/CSSFontFeatureValue.h" |
| #include "core/css/CSSFontVariationValue.h" |
| #include "core/css/CSSFunctionValue.h" |
| #include "core/css/CSSGridLineNamesValue.h" |
| #include "core/css/CSSGridTemplateAreasValue.h" |
| #include "core/css/CSSIdentifierValue.h" |
| #include "core/css/CSSInitialValue.h" |
| #include "core/css/CSSPathValue.h" |
| #include "core/css/CSSPrimitiveValue.h" |
| #include "core/css/CSSPrimitiveValueMappings.h" |
| #include "core/css/CSSQuadValue.h" |
| #include "core/css/CSSReflectValue.h" |
| #include "core/css/CSSShadowValue.h" |
| #include "core/css/CSSStringValue.h" |
| #include "core/css/CSSTimingFunctionValue.h" |
| #include "core/css/CSSURIValue.h" |
| #include "core/css/CSSValueList.h" |
| #include "core/css/CSSValuePair.h" |
| #include "core/css/PropertyRegistry.h" |
| #include "core/css/zoomAdjustedPixelValue.h" |
| #include "core/layout/LayoutBlock.h" |
| #include "core/layout/LayoutBox.h" |
| #include "core/layout/LayoutGrid.h" |
| #include "core/layout/LayoutObject.h" |
| #include "core/style/ComputedStyle.h" |
| #include "core/style/ContentData.h" |
| #include "core/style/CursorData.h" |
| #include "core/style/QuotesData.h" |
| #include "core/style/ShadowList.h" |
| #include "core/style/StyleInheritedVariables.h" |
| #include "core/style/StyleNonInheritedVariables.h" |
| #include "platform/LengthFunctions.h" |
| |
| namespace blink { |
| |
| using namespace cssvalue; |
| |
| inline static bool IsFlexOrGrid(const ComputedStyle* style) { |
| return style && style->IsDisplayFlexibleOrGridBox(); |
| } |
| |
| inline static CSSValue* ZoomAdjustedPixelValueOrAuto( |
| const Length& length, |
| const ComputedStyle& style) { |
| if (length.IsAuto()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValue(length.Value(), style); |
| } |
| |
| static CSSValue* ZoomAdjustedPixelValueForLength(const Length& length, |
| const ComputedStyle& style) { |
| if (length.IsFixed()) |
| return ZoomAdjustedPixelValue(length.Value(), style); |
| return CSSValue::Create(length, style.EffectiveZoom()); |
| } |
| |
| static CSSValue* PixelValueForUnzoomedLength( |
| const UnzoomedLength& unzoomed_length, |
| const ComputedStyle& style) { |
| const Length& length = unzoomed_length.length(); |
| if (length.IsFixed()) |
| return CSSPrimitiveValue::Create(length.Value(), |
| CSSPrimitiveValue::UnitType::kPixels); |
| return CSSValue::Create(length, style.EffectiveZoom()); |
| } |
| |
| static CSSValueList* CreatePositionListForLayer(CSSPropertyID property_id, |
| const FillLayer& layer, |
| const ComputedStyle& style) { |
| CSSValueList* position_list = CSSValueList::CreateSpaceSeparated(); |
| if (layer.IsBackgroundXOriginSet()) { |
| DCHECK(property_id == CSSPropertyBackgroundPosition || |
| property_id == CSSPropertyWebkitMaskPosition); |
| position_list->Append( |
| *CSSIdentifierValue::Create(layer.BackgroundXOrigin())); |
| } |
| position_list->Append( |
| *ZoomAdjustedPixelValueForLength(layer.XPosition(), style)); |
| if (layer.IsBackgroundYOriginSet()) { |
| DCHECK(property_id == CSSPropertyBackgroundPosition || |
| property_id == CSSPropertyWebkitMaskPosition); |
| position_list->Append( |
| *CSSIdentifierValue::Create(layer.BackgroundYOrigin())); |
| } |
| position_list->Append( |
| *ZoomAdjustedPixelValueForLength(layer.YPosition(), style)); |
| return position_list; |
| } |
| |
| CSSValue* ComputedStyleCSSValueMapping::CurrentColorOrValidColor( |
| const ComputedStyle& style, |
| const StyleColor& color) { |
| // This function does NOT look at visited information, so that computed style |
| // doesn't expose that. |
| return CSSColorValue::Create(color.Resolve(style.GetColor()).Rgb()); |
| } |
| |
| static CSSValue* ValueForFillSize(const FillSize& fill_size, |
| const ComputedStyle& style) { |
| if (fill_size.type == kContain) |
| return CSSIdentifierValue::Create(CSSValueContain); |
| |
| if (fill_size.type == kCover) |
| return CSSIdentifierValue::Create(CSSValueCover); |
| |
| if (fill_size.size.Height().IsAuto()) |
| return ZoomAdjustedPixelValueForLength(fill_size.size.Width(), style); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ZoomAdjustedPixelValueForLength(fill_size.size.Width(), style)); |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(fill_size.size.Height(), style)); |
| return list; |
| } |
| |
| static CSSValue* ValueForFillRepeat(EFillRepeat x_repeat, |
| EFillRepeat y_repeat) { |
| // For backwards compatibility, if both values are equal, just return one of |
| // them. And if the two values are equivalent to repeat-x or repeat-y, just |
| // return the shorthand. |
| if (x_repeat == y_repeat) |
| return CSSIdentifierValue::Create(x_repeat); |
| if (x_repeat == kRepeatFill && y_repeat == kNoRepeatFill) |
| return CSSIdentifierValue::Create(CSSValueRepeatX); |
| if (x_repeat == kNoRepeatFill && y_repeat == kRepeatFill) |
| return CSSIdentifierValue::Create(CSSValueRepeatY); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*CSSIdentifierValue::Create(x_repeat)); |
| list->Append(*CSSIdentifierValue::Create(y_repeat)); |
| return list; |
| } |
| |
| static CSSValue* ValueForFillSourceType(EMaskSourceType type) { |
| switch (type) { |
| case kMaskAlpha: |
| return CSSIdentifierValue::Create(CSSValueAlpha); |
| case kMaskLuminance: |
| return CSSIdentifierValue::Create(CSSValueLuminance); |
| } |
| |
| NOTREACHED(); |
| |
| return nullptr; |
| } |
| |
| static CSSValue* ValueForPositionOffset(const ComputedStyle& style, |
| CSSPropertyID property_id, |
| const LayoutObject* layout_object) { |
| Length offset, opposite; |
| switch (property_id) { |
| case CSSPropertyLeft: |
| offset = style.Left(); |
| opposite = style.Right(); |
| break; |
| case CSSPropertyRight: |
| offset = style.Right(); |
| opposite = style.Left(); |
| break; |
| case CSSPropertyTop: |
| offset = style.Top(); |
| opposite = style.Bottom(); |
| break; |
| case CSSPropertyBottom: |
| offset = style.Bottom(); |
| opposite = style.Top(); |
| break; |
| default: |
| return nullptr; |
| } |
| |
| if (offset.IsPercentOrCalc() && layout_object && layout_object->IsBox() && |
| layout_object->IsPositioned()) { |
| LayoutUnit containing_block_size = |
| (property_id == CSSPropertyLeft || property_id == CSSPropertyRight) |
| ? ToLayoutBox(layout_object) |
| ->ContainingBlockLogicalWidthForContent() |
| : ToLayoutBox(layout_object) |
| ->ContainingBlockLogicalHeightForGetComputedStyle(); |
| return ZoomAdjustedPixelValue(ValueForLength(offset, containing_block_size), |
| style); |
| } |
| |
| if (offset.IsAuto() && layout_object) { |
| // If the property applies to a positioned element and the resolved value of |
| // the display property is not none, the resolved value is the used value. |
| // Position offsets have special meaning for position sticky so we return |
| // auto when offset.isAuto() on a sticky position object: |
| // https://crbug.com/703816. |
| if (layout_object->IsRelPositioned()) { |
| // If e.g. left is auto and right is not auto, then left's computed value |
| // is negative right. So we get the opposite length unit and see if it is |
| // auto. |
| if (opposite.IsAuto()) |
| return CSSPrimitiveValue::Create(0, |
| CSSPrimitiveValue::UnitType::kPixels); |
| |
| if (opposite.IsPercentOrCalc()) { |
| if (layout_object->IsBox()) { |
| LayoutUnit containing_block_size = |
| (property_id == CSSPropertyLeft || |
| property_id == CSSPropertyRight) |
| ? ToLayoutBox(layout_object) |
| ->ContainingBlockLogicalWidthForContent() |
| : ToLayoutBox(layout_object) |
| ->ContainingBlockLogicalHeightForGetComputedStyle(); |
| return ZoomAdjustedPixelValue( |
| -FloatValueForLength(opposite, containing_block_size), style); |
| } |
| // FIXME: fall back to auto for position:relative, display:inline |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| } |
| |
| // Length doesn't provide operator -, so multiply by -1. |
| opposite *= -1.f; |
| return ZoomAdjustedPixelValueForLength(opposite, style); |
| } |
| |
| if (layout_object->IsOutOfFlowPositioned() && layout_object->IsBox()) { |
| // For fixed and absolute positioned elements, the top, left, bottom, and |
| // right are defined relative to the corresponding sides of the containing |
| // block. |
| LayoutBlock* container = layout_object->ContainingBlock(); |
| const LayoutBox* layout_box = ToLayoutBox(layout_object); |
| |
| // clientOffset is the distance from this object's border edge to the |
| // container's padding edge. Thus it includes margins which we subtract |
| // below. |
| const LayoutSize client_offset = |
| layout_box->LocationOffset() - |
| LayoutSize(container->ClientLeft(), container->ClientTop()); |
| LayoutUnit position; |
| |
| switch (property_id) { |
| case CSSPropertyLeft: |
| position = client_offset.Width() - layout_box->MarginLeft(); |
| break; |
| case CSSPropertyTop: |
| position = client_offset.Height() - layout_box->MarginTop(); |
| break; |
| case CSSPropertyRight: |
| position = container->ClientWidth() - layout_box->MarginRight() - |
| (layout_box->OffsetWidth() + client_offset.Width()); |
| break; |
| case CSSPropertyBottom: |
| position = container->ClientHeight() - layout_box->MarginBottom() - |
| (layout_box->OffsetHeight() + client_offset.Height()); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| return ZoomAdjustedPixelValue(position, style); |
| } |
| } |
| |
| if (offset.IsAuto()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| |
| return ZoomAdjustedPixelValueForLength(offset, style); |
| } |
| |
| static CSSBorderImageSliceValue* ValueForNinePieceImageSlice( |
| const NinePieceImage& image) { |
| // Create the slices. |
| CSSPrimitiveValue* top = nullptr; |
| CSSPrimitiveValue* right = nullptr; |
| CSSPrimitiveValue* bottom = nullptr; |
| CSSPrimitiveValue* left = nullptr; |
| |
| // TODO(alancutter): Make this code aware of calc lengths. |
| if (image.ImageSlices().Top().IsPercentOrCalc()) |
| top = CSSPrimitiveValue::Create(image.ImageSlices().Top().Value(), |
| CSSPrimitiveValue::UnitType::kPercentage); |
| else |
| top = CSSPrimitiveValue::Create(image.ImageSlices().Top().Value(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| |
| if (image.ImageSlices().Right() == image.ImageSlices().Top() && |
| image.ImageSlices().Bottom() == image.ImageSlices().Top() && |
| image.ImageSlices().Left() == image.ImageSlices().Top()) { |
| right = top; |
| bottom = top; |
| left = top; |
| } else { |
| if (image.ImageSlices().Right().IsPercentOrCalc()) |
| right = |
| CSSPrimitiveValue::Create(image.ImageSlices().Right().Value(), |
| CSSPrimitiveValue::UnitType::kPercentage); |
| else |
| right = CSSPrimitiveValue::Create(image.ImageSlices().Right().Value(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| |
| if (image.ImageSlices().Bottom() == image.ImageSlices().Top() && |
| image.ImageSlices().Right() == image.ImageSlices().Left()) { |
| bottom = top; |
| left = right; |
| } else { |
| if (image.ImageSlices().Bottom().IsPercentOrCalc()) |
| bottom = |
| CSSPrimitiveValue::Create(image.ImageSlices().Bottom().Value(), |
| CSSPrimitiveValue::UnitType::kPercentage); |
| else |
| bottom = |
| CSSPrimitiveValue::Create(image.ImageSlices().Bottom().Value(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| |
| if (image.ImageSlices().Left() == image.ImageSlices().Right()) { |
| left = right; |
| } else { |
| if (image.ImageSlices().Left().IsPercentOrCalc()) |
| left = CSSPrimitiveValue::Create( |
| image.ImageSlices().Left().Value(), |
| CSSPrimitiveValue::UnitType::kPercentage); |
| else |
| left = |
| CSSPrimitiveValue::Create(image.ImageSlices().Left().Value(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| } |
| } |
| } |
| |
| return CSSBorderImageSliceValue::Create( |
| CSSQuadValue::Create(top, right, bottom, left, |
| CSSQuadValue::kSerializeAsQuad), |
| image.Fill()); |
| } |
| |
| static CSSValue* ValueForBorderImageLength( |
| const BorderImageLength& border_image_length, |
| const ComputedStyle& style) { |
| if (border_image_length.IsNumber()) |
| return CSSPrimitiveValue::Create(border_image_length.Number(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| return CSSValue::Create(border_image_length.length(), style.EffectiveZoom()); |
| } |
| |
| static CSSQuadValue* ValueForNinePieceImageQuad(const BorderImageLengthBox& box, |
| const ComputedStyle& style) { |
| // Create the slices. |
| CSSValue* top = nullptr; |
| CSSValue* right = nullptr; |
| CSSValue* bottom = nullptr; |
| CSSValue* left = nullptr; |
| |
| top = ValueForBorderImageLength(box.Top(), style); |
| |
| if (box.Right() == box.Top() && box.Bottom() == box.Top() && |
| box.Left() == box.Top()) { |
| right = top; |
| bottom = top; |
| left = top; |
| } else { |
| right = ValueForBorderImageLength(box.Right(), style); |
| |
| if (box.Bottom() == box.Top() && box.Right() == box.Left()) { |
| bottom = top; |
| left = right; |
| } else { |
| bottom = ValueForBorderImageLength(box.Bottom(), style); |
| |
| if (box.Left() == box.Right()) |
| left = right; |
| else |
| left = ValueForBorderImageLength(box.Left(), style); |
| } |
| } |
| return CSSQuadValue::Create(top, right, bottom, left, |
| CSSQuadValue::kSerializeAsQuad); |
| } |
| |
| static CSSValueID ValueForRepeatRule(int rule) { |
| switch (rule) { |
| case kRepeatImageRule: |
| return CSSValueRepeat; |
| case kRoundImageRule: |
| return CSSValueRound; |
| case kSpaceImageRule: |
| return CSSValueSpace; |
| default: |
| return CSSValueStretch; |
| } |
| } |
| |
| static CSSValue* ValueForNinePieceImageRepeat(const NinePieceImage& image) { |
| CSSIdentifierValue* horizontal_repeat = nullptr; |
| CSSIdentifierValue* vertical_repeat = nullptr; |
| |
| horizontal_repeat = |
| CSSIdentifierValue::Create(ValueForRepeatRule(image.HorizontalRule())); |
| if (image.HorizontalRule() == image.VerticalRule()) { |
| vertical_repeat = horizontal_repeat; |
| } else { |
| vertical_repeat = |
| CSSIdentifierValue::Create(ValueForRepeatRule(image.VerticalRule())); |
| } |
| return CSSValuePair::Create(horizontal_repeat, vertical_repeat, |
| CSSValuePair::kDropIdenticalValues); |
| } |
| |
| static CSSValue* ValueForNinePieceImage(const NinePieceImage& image, |
| const ComputedStyle& style) { |
| if (!image.HasImage()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| // Image first. |
| CSSValue* image_value = nullptr; |
| if (image.GetImage()) |
| image_value = image.GetImage()->ComputedCSSValue(); |
| |
| // Create the image slice. |
| CSSBorderImageSliceValue* image_slices = ValueForNinePieceImageSlice(image); |
| |
| // Create the border area slices. |
| CSSValue* border_slices = |
| ValueForNinePieceImageQuad(image.BorderSlices(), style); |
| |
| // Create the border outset. |
| CSSValue* outset = ValueForNinePieceImageQuad(image.Outset(), style); |
| |
| // Create the repeat rules. |
| CSSValue* repeat = ValueForNinePieceImageRepeat(image); |
| |
| return CreateBorderImageValue(image_value, image_slices, border_slices, |
| outset, repeat); |
| } |
| |
| static CSSValue* ValueForReflection(const StyleReflection* reflection, |
| const ComputedStyle& style) { |
| if (!reflection) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSPrimitiveValue* offset = nullptr; |
| // TODO(alancutter): Make this work correctly for calc lengths. |
| if (reflection->Offset().IsPercentOrCalc()) |
| offset = |
| CSSPrimitiveValue::Create(reflection->Offset().Percent(), |
| CSSPrimitiveValue::UnitType::kPercentage); |
| else |
| offset = ZoomAdjustedPixelValue(reflection->Offset().Value(), style); |
| |
| CSSIdentifierValue* direction = nullptr; |
| switch (reflection->Direction()) { |
| case kReflectionBelow: |
| direction = CSSIdentifierValue::Create(CSSValueBelow); |
| break; |
| case kReflectionAbove: |
| direction = CSSIdentifierValue::Create(CSSValueAbove); |
| break; |
| case kReflectionLeft: |
| direction = CSSIdentifierValue::Create(CSSValueLeft); |
| break; |
| case kReflectionRight: |
| direction = CSSIdentifierValue::Create(CSSValueRight); |
| break; |
| } |
| |
| return CSSReflectValue::Create( |
| direction, offset, ValueForNinePieceImage(reflection->Mask(), style)); |
| } |
| |
| static CSSValueList* ValueForItemPositionWithOverflowAlignment( |
| const StyleSelfAlignmentData& data) { |
| CSSValueList* result = CSSValueList::CreateSpaceSeparated(); |
| if (data.PositionType() == kLegacyPosition) |
| result->Append(*CSSIdentifierValue::Create(CSSValueLegacy)); |
| if (data.GetPosition() == kItemPositionAuto) { |
| // To avoid needing to copy the RareNonInheritedData, we repurpose the |
| // 'auto' flag to not just mean 'auto' prior to running the StyleAdjuster |
| // but also mean 'normal' after running it. |
| result->Append(*CSSIdentifierValue::Create( |
| ComputedStyle::InitialDefaultAlignment().GetPosition())); |
| } else if (data.GetPosition() == kItemPositionBaseline) { |
| result->Append( |
| *CSSValuePair::Create(CSSIdentifierValue::Create(CSSValueBaseline), |
| CSSIdentifierValue::Create(CSSValueBaseline), |
| CSSValuePair::kDropIdenticalValues)); |
| } else if (data.GetPosition() == kItemPositionLastBaseline) { |
| result->Append( |
| *CSSValuePair::Create(CSSIdentifierValue::Create(CSSValueLast), |
| CSSIdentifierValue::Create(CSSValueBaseline), |
| CSSValuePair::kDropIdenticalValues)); |
| } else { |
| result->Append(*CSSIdentifierValue::Create(data.GetPosition())); |
| } |
| if (data.GetPosition() >= kItemPositionCenter && |
| data.Overflow() != kOverflowAlignmentDefault) |
| result->Append(*CSSIdentifierValue::Create(data.Overflow())); |
| DCHECK_LE(result->length(), 2u); |
| return result; |
| } |
| |
| static CSSValueList* ValuesForGridShorthand( |
| const StylePropertyShorthand& shorthand, |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| Node* styled_node, |
| bool allow_visited_style) { |
| CSSValueList* list = CSSValueList::CreateSlashSeparated(); |
| for (size_t i = 0; i < shorthand.length(); ++i) { |
| const CSSValue* value = ComputedStyleCSSValueMapping::Get( |
| shorthand.properties()[i], style, layout_object, styled_node, |
| allow_visited_style); |
| DCHECK(value); |
| list->Append(*value); |
| } |
| return list; |
| } |
| |
| static CSSValueList* ValuesForShorthandProperty( |
| const StylePropertyShorthand& shorthand, |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| Node* styled_node, |
| bool allow_visited_style) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (size_t i = 0; i < shorthand.length(); ++i) { |
| const CSSValue* value = ComputedStyleCSSValueMapping::Get( |
| shorthand.properties()[i], style, layout_object, styled_node, |
| allow_visited_style); |
| DCHECK(value); |
| list->Append(*value); |
| } |
| return list; |
| } |
| |
| static CSSValue* ExpandNoneLigaturesValue() { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*CSSIdentifierValue::Create(CSSValueNoCommonLigatures)); |
| list->Append(*CSSIdentifierValue::Create(CSSValueNoDiscretionaryLigatures)); |
| list->Append(*CSSIdentifierValue::Create(CSSValueNoHistoricalLigatures)); |
| list->Append(*CSSIdentifierValue::Create(CSSValueNoContextual)); |
| return list; |
| } |
| |
| static CSSValue* ValuesForFontVariantProperty(const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| Node* styled_node, |
| bool allow_visited_style) { |
| enum VariantShorthandCases { |
| kAllNormal, |
| kNoneLigatures, |
| kConcatenateNonNormal |
| }; |
| VariantShorthandCases shorthand_case = kAllNormal; |
| for (size_t i = 0; i < fontVariantShorthand().length(); ++i) { |
| const CSSValue* value = ComputedStyleCSSValueMapping::Get( |
| fontVariantShorthand().properties()[i], style, layout_object, |
| styled_node, allow_visited_style); |
| |
| if (shorthand_case == kAllNormal && value->IsIdentifierValue() && |
| ToCSSIdentifierValue(value)->GetValueID() == CSSValueNone && |
| fontVariantShorthand().properties()[i] == |
| CSSPropertyFontVariantLigatures) { |
| shorthand_case = kNoneLigatures; |
| } else if (!(value->IsIdentifierValue() && |
| ToCSSIdentifierValue(value)->GetValueID() == CSSValueNormal)) { |
| shorthand_case = kConcatenateNonNormal; |
| break; |
| } |
| } |
| |
| switch (shorthand_case) { |
| case kAllNormal: |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| case kNoneLigatures: |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case kConcatenateNonNormal: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (size_t i = 0; i < fontVariantShorthand().length(); ++i) { |
| const CSSValue* value = ComputedStyleCSSValueMapping::Get( |
| fontVariantShorthand().properties()[i], style, layout_object, |
| styled_node, allow_visited_style); |
| DCHECK(value); |
| if (value->IsIdentifierValue() && |
| ToCSSIdentifierValue(value)->GetValueID() == CSSValueNone) { |
| list->Append(*ExpandNoneLigaturesValue()); |
| } else if (!(value->IsIdentifierValue() && |
| ToCSSIdentifierValue(value)->GetValueID() == |
| CSSValueNormal)) { |
| list->Append(*value); |
| } |
| } |
| return list; |
| } |
| default: |
| NOTREACHED(); |
| return nullptr; |
| } |
| } |
| |
| static CSSValueList* ValuesForBackgroundShorthand( |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| Node* styled_node, |
| bool allow_visited_style) { |
| CSSValueList* ret = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) { |
| CSSValueList* list = CSSValueList::CreateSlashSeparated(); |
| CSSValueList* before_slash = CSSValueList::CreateSpaceSeparated(); |
| if (!curr_layer->Next()) { // color only for final layer |
| const CSSValue* value = ComputedStyleCSSValueMapping::Get( |
| CSSPropertyBackgroundColor, style, layout_object, styled_node, |
| allow_visited_style); |
| DCHECK(value); |
| before_slash->Append(*value); |
| } |
| before_slash->Append(curr_layer->GetImage() |
| ? *curr_layer->GetImage()->ComputedCSSValue() |
| : *CSSIdentifierValue::Create(CSSValueNone)); |
| before_slash->Append( |
| *ValueForFillRepeat(curr_layer->RepeatX(), curr_layer->RepeatY())); |
| before_slash->Append(*CSSIdentifierValue::Create(curr_layer->Attachment())); |
| before_slash->Append(*CreatePositionListForLayer( |
| CSSPropertyBackgroundPosition, *curr_layer, style)); |
| list->Append(*before_slash); |
| CSSValueList* after_slash = CSSValueList::CreateSpaceSeparated(); |
| after_slash->Append(*ValueForFillSize(curr_layer->Size(), style)); |
| after_slash->Append(*CSSIdentifierValue::Create(curr_layer->Origin())); |
| after_slash->Append(*CSSIdentifierValue::Create(curr_layer->Clip())); |
| list->Append(*after_slash); |
| ret->Append(*list); |
| } |
| return ret; |
| } |
| |
| static CSSValueList* |
| ValueForContentPositionAndDistributionWithOverflowAlignment( |
| const StyleContentAlignmentData& data, |
| CSSValueID normal_behavior_value_id) { |
| CSSValueList* result = CSSValueList::CreateSpaceSeparated(); |
| // Handle content-distribution values |
| if (data.Distribution() != kContentDistributionDefault) |
| result->Append(*CSSIdentifierValue::Create(data.Distribution())); |
| |
| // Handle content-position values (either as fallback or actual value) |
| switch (data.GetPosition()) { |
| case kContentPositionNormal: |
| // Handle 'normal' value, not valid as content-distribution fallback. |
| if (data.Distribution() == kContentDistributionDefault) { |
| result->Append(*CSSIdentifierValue::Create( |
| RuntimeEnabledFeatures::cssGridLayoutEnabled() |
| ? CSSValueNormal |
| : normal_behavior_value_id)); |
| } |
| break; |
| case kContentPositionLastBaseline: |
| result->Append( |
| *CSSValuePair::Create(CSSIdentifierValue::Create(CSSValueLast), |
| CSSIdentifierValue::Create(CSSValueBaseline), |
| CSSValuePair::kDropIdenticalValues)); |
| break; |
| default: |
| result->Append(*CSSIdentifierValue::Create(data.GetPosition())); |
| } |
| |
| // Handle overflow-alignment (only allowed for content-position values) |
| if ((data.GetPosition() >= kContentPositionCenter || |
| data.Distribution() != kContentDistributionDefault) && |
| data.Overflow() != kOverflowAlignmentDefault) |
| result->Append(*CSSIdentifierValue::Create(data.Overflow())); |
| DCHECK_GT(result->length(), 0u); |
| DCHECK_LE(result->length(), 3u); |
| return result; |
| } |
| |
| static CSSValue* ValueForLineHeight(const ComputedStyle& style) { |
| Length length = style.LineHeight(); |
| if (length.IsNegative()) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| |
| return ZoomAdjustedPixelValue( |
| FloatValueForLength(length, style.GetFontDescription().ComputedSize()), |
| style); |
| } |
| |
| static CSSValue* ValueForPosition(const LengthPoint& position, |
| const ComputedStyle& style) { |
| DCHECK((position.X() == kAuto) == (position.Y() == kAuto)); |
| if (position.X() == kAuto) { |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| } |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ZoomAdjustedPixelValueForLength(position.X(), style)); |
| list->Append(*ZoomAdjustedPixelValueForLength(position.Y(), style)); |
| return list; |
| } |
| |
| static CSSValueID IdentifierForFamily(const AtomicString& family) { |
| if (family == FontFamilyNames::webkit_cursive) |
| return CSSValueCursive; |
| if (family == FontFamilyNames::webkit_fantasy) |
| return CSSValueFantasy; |
| if (family == FontFamilyNames::webkit_monospace) |
| return CSSValueMonospace; |
| if (family == FontFamilyNames::webkit_pictograph) |
| return CSSValueWebkitPictograph; |
| if (family == FontFamilyNames::webkit_sans_serif) |
| return CSSValueSansSerif; |
| if (family == FontFamilyNames::webkit_serif) |
| return CSSValueSerif; |
| return CSSValueInvalid; |
| } |
| |
| static CSSValue* ValueForFamily(const AtomicString& family) { |
| if (CSSValueID family_identifier = IdentifierForFamily(family)) |
| return CSSIdentifierValue::Create(family_identifier); |
| return CSSFontFamilyValue::Create(family.GetString()); |
| } |
| |
| static CSSValueList* ValueForFontFamily(const ComputedStyle& style) { |
| const FontFamily& first_family = style.GetFontDescription().Family(); |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const FontFamily* family = &first_family; family; |
| family = family->Next()) |
| list->Append(*ValueForFamily(family->Family())); |
| return list; |
| } |
| |
| static CSSPrimitiveValue* ValueForFontSize(const ComputedStyle& style) { |
| return ZoomAdjustedPixelValue(style.GetFontDescription().ComputedSize(), |
| style); |
| } |
| |
| static CSSIdentifierValue* ValueForFontStretch(const ComputedStyle& style) { |
| return CSSIdentifierValue::Create(style.GetFontDescription().Stretch()); |
| } |
| |
| static CSSIdentifierValue* ValueForFontStyle(const ComputedStyle& style) { |
| return CSSIdentifierValue::Create(style.GetFontDescription().Style()); |
| } |
| |
| static CSSIdentifierValue* ValueForFontWeight(const ComputedStyle& style) { |
| return CSSIdentifierValue::Create(style.GetFontDescription().Weight()); |
| } |
| |
| static CSSIdentifierValue* ValueForFontVariantCaps(const ComputedStyle& style) { |
| FontDescription::FontVariantCaps variant_caps = |
| style.GetFontDescription().VariantCaps(); |
| switch (variant_caps) { |
| case FontDescription::kCapsNormal: |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| case FontDescription::kSmallCaps: |
| return CSSIdentifierValue::Create(CSSValueSmallCaps); |
| case FontDescription::kAllSmallCaps: |
| return CSSIdentifierValue::Create(CSSValueAllSmallCaps); |
| case FontDescription::kPetiteCaps: |
| return CSSIdentifierValue::Create(CSSValuePetiteCaps); |
| case FontDescription::kAllPetiteCaps: |
| return CSSIdentifierValue::Create(CSSValueAllPetiteCaps); |
| case FontDescription::kUnicase: |
| return CSSIdentifierValue::Create(CSSValueUnicase); |
| case FontDescription::kTitlingCaps: |
| return CSSIdentifierValue::Create(CSSValueTitlingCaps); |
| default: |
| NOTREACHED(); |
| return nullptr; |
| } |
| } |
| |
| static CSSValue* ValueForFontVariantLigatures(const ComputedStyle& style) { |
| FontDescription::LigaturesState common_ligatures_state = |
| style.GetFontDescription().CommonLigaturesState(); |
| FontDescription::LigaturesState discretionary_ligatures_state = |
| style.GetFontDescription().DiscretionaryLigaturesState(); |
| FontDescription::LigaturesState historical_ligatures_state = |
| style.GetFontDescription().HistoricalLigaturesState(); |
| FontDescription::LigaturesState contextual_ligatures_state = |
| style.GetFontDescription().ContextualLigaturesState(); |
| if (common_ligatures_state == FontDescription::kNormalLigaturesState && |
| discretionary_ligatures_state == FontDescription::kNormalLigaturesState && |
| historical_ligatures_state == FontDescription::kNormalLigaturesState && |
| contextual_ligatures_state == FontDescription::kNormalLigaturesState) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| |
| if (common_ligatures_state == FontDescription::kDisabledLigaturesState && |
| discretionary_ligatures_state == |
| FontDescription::kDisabledLigaturesState && |
| historical_ligatures_state == FontDescription::kDisabledLigaturesState && |
| contextual_ligatures_state == FontDescription::kDisabledLigaturesState) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* value_list = CSSValueList::CreateSpaceSeparated(); |
| if (common_ligatures_state != FontDescription::kNormalLigaturesState) |
| value_list->Append(*CSSIdentifierValue::Create( |
| common_ligatures_state == FontDescription::kDisabledLigaturesState |
| ? CSSValueNoCommonLigatures |
| : CSSValueCommonLigatures)); |
| if (discretionary_ligatures_state != FontDescription::kNormalLigaturesState) |
| value_list->Append(*CSSIdentifierValue::Create( |
| discretionary_ligatures_state == |
| FontDescription::kDisabledLigaturesState |
| ? CSSValueNoDiscretionaryLigatures |
| : CSSValueDiscretionaryLigatures)); |
| if (historical_ligatures_state != FontDescription::kNormalLigaturesState) |
| value_list->Append(*CSSIdentifierValue::Create( |
| historical_ligatures_state == FontDescription::kDisabledLigaturesState |
| ? CSSValueNoHistoricalLigatures |
| : CSSValueHistoricalLigatures)); |
| if (contextual_ligatures_state != FontDescription::kNormalLigaturesState) |
| value_list->Append(*CSSIdentifierValue::Create( |
| contextual_ligatures_state == FontDescription::kDisabledLigaturesState |
| ? CSSValueNoContextual |
| : CSSValueContextual)); |
| return value_list; |
| } |
| |
| static CSSValue* ValueForFontVariantNumeric(const ComputedStyle& style) { |
| FontVariantNumeric variant_numeric = |
| style.GetFontDescription().VariantNumeric(); |
| if (variant_numeric.IsAllNormal()) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| |
| CSSValueList* value_list = CSSValueList::CreateSpaceSeparated(); |
| if (variant_numeric.NumericFigureValue() != FontVariantNumeric::kNormalFigure) |
| value_list->Append(*CSSIdentifierValue::Create( |
| variant_numeric.NumericFigureValue() == FontVariantNumeric::kLiningNums |
| ? CSSValueLiningNums |
| : CSSValueOldstyleNums)); |
| if (variant_numeric.NumericSpacingValue() != |
| FontVariantNumeric::kNormalSpacing) { |
| value_list->Append(*CSSIdentifierValue::Create( |
| variant_numeric.NumericSpacingValue() == |
| FontVariantNumeric::kProportionalNums |
| ? CSSValueProportionalNums |
| : CSSValueTabularNums)); |
| } |
| if (variant_numeric.NumericFractionValue() != |
| FontVariantNumeric::kNormalFraction) |
| value_list->Append(*CSSIdentifierValue::Create( |
| variant_numeric.NumericFractionValue() == |
| FontVariantNumeric::kDiagonalFractions |
| ? CSSValueDiagonalFractions |
| : CSSValueStackedFractions)); |
| if (variant_numeric.OrdinalValue() == FontVariantNumeric::kOrdinalOn) |
| value_list->Append(*CSSIdentifierValue::Create(CSSValueOrdinal)); |
| if (variant_numeric.SlashedZeroValue() == FontVariantNumeric::kSlashedZeroOn) |
| value_list->Append(*CSSIdentifierValue::Create(CSSValueSlashedZero)); |
| |
| return value_list; |
| } |
| |
| static CSSValue* SpecifiedValueForGridTrackBreadth( |
| const GridLength& track_breadth, |
| const ComputedStyle& style) { |
| if (!track_breadth.IsLength()) |
| return CSSPrimitiveValue::Create(track_breadth.Flex(), |
| CSSPrimitiveValue::UnitType::kFraction); |
| |
| const Length& track_breadth_length = track_breadth.length(); |
| if (track_breadth_length.IsAuto()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValueForLength(track_breadth_length, style); |
| } |
| |
| static CSSValue* SpecifiedValueForGridTrackSize(const GridTrackSize& track_size, |
| const ComputedStyle& style) { |
| switch (track_size.GetType()) { |
| case kLengthTrackSizing: |
| return SpecifiedValueForGridTrackBreadth(track_size.MinTrackBreadth(), |
| style); |
| case kMinMaxTrackSizing: { |
| if (track_size.MinTrackBreadth().IsAuto() && |
| track_size.MaxTrackBreadth().IsFlex()) { |
| return CSSPrimitiveValue::Create( |
| track_size.MaxTrackBreadth().Flex(), |
| CSSPrimitiveValue::UnitType::kFraction); |
| } |
| |
| auto* min_max_track_breadths = CSSFunctionValue::Create(CSSValueMinmax); |
| min_max_track_breadths->Append(*SpecifiedValueForGridTrackBreadth( |
| track_size.MinTrackBreadth(), style)); |
| min_max_track_breadths->Append(*SpecifiedValueForGridTrackBreadth( |
| track_size.MaxTrackBreadth(), style)); |
| return min_max_track_breadths; |
| } |
| case kFitContentTrackSizing: { |
| auto* fit_content_track_breadth = |
| CSSFunctionValue::Create(CSSValueFitContent); |
| fit_content_track_breadth->Append(*SpecifiedValueForGridTrackBreadth( |
| track_size.FitContentTrackBreadth(), style)); |
| return fit_content_track_breadth; |
| } |
| } |
| NOTREACHED(); |
| return nullptr; |
| } |
| |
| class OrderedNamedLinesCollector { |
| STACK_ALLOCATED(); |
| WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector); |
| |
| public: |
| OrderedNamedLinesCollector(const ComputedStyle& style, |
| bool is_row_axis, |
| size_t auto_repeat_tracks_count) |
| : ordered_named_grid_lines_(is_row_axis |
| ? style.OrderedNamedGridColumnLines() |
| : style.OrderedNamedGridRowLines()), |
| ordered_named_auto_repeat_grid_lines_( |
| is_row_axis ? style.AutoRepeatOrderedNamedGridColumnLines() |
| : style.AutoRepeatOrderedNamedGridRowLines()), |
| insertion_point_(is_row_axis |
| ? style.GridAutoRepeatColumnsInsertionPoint() |
| : style.GridAutoRepeatRowsInsertionPoint()), |
| auto_repeat_total_tracks_(auto_repeat_tracks_count), |
| auto_repeat_track_list_length_( |
| is_row_axis ? style.GridAutoRepeatColumns().size() |
| : style.GridAutoRepeatRows().size()) {} |
| |
| bool IsEmpty() const { |
| return ordered_named_grid_lines_.IsEmpty() && |
| ordered_named_auto_repeat_grid_lines_.IsEmpty(); |
| } |
| void CollectLineNamesForIndex(CSSGridLineNamesValue&, size_t index) const; |
| |
| private: |
| enum NamedLinesType { kNamedLines, kAutoRepeatNamedLines }; |
| void AppendLines(CSSGridLineNamesValue&, size_t index, NamedLinesType) const; |
| |
| const OrderedNamedGridLines& ordered_named_grid_lines_; |
| const OrderedNamedGridLines& ordered_named_auto_repeat_grid_lines_; |
| size_t insertion_point_; |
| size_t auto_repeat_total_tracks_; |
| size_t auto_repeat_track_list_length_; |
| }; |
| |
| void OrderedNamedLinesCollector::AppendLines( |
| CSSGridLineNamesValue& line_names_value, |
| size_t index, |
| NamedLinesType type) const { |
| auto iter = type == kNamedLines |
| ? ordered_named_grid_lines_.find(index) |
| : ordered_named_auto_repeat_grid_lines_.find(index); |
| auto end_iter = type == kNamedLines |
| ? ordered_named_grid_lines_.end() |
| : ordered_named_auto_repeat_grid_lines_.end(); |
| if (iter == end_iter) |
| return; |
| |
| for (auto line_name : iter->value) |
| line_names_value.Append( |
| *CSSCustomIdentValue::Create(AtomicString(line_name))); |
| } |
| |
| void OrderedNamedLinesCollector::CollectLineNamesForIndex( |
| CSSGridLineNamesValue& line_names_value, |
| size_t i) const { |
| DCHECK(!IsEmpty()); |
| if (ordered_named_auto_repeat_grid_lines_.IsEmpty() || i < insertion_point_) { |
| AppendLines(line_names_value, i, kNamedLines); |
| return; |
| } |
| |
| DCHECK(auto_repeat_total_tracks_); |
| |
| if (i > insertion_point_ + auto_repeat_total_tracks_) { |
| AppendLines(line_names_value, i - (auto_repeat_total_tracks_ - 1), |
| kNamedLines); |
| return; |
| } |
| |
| if (i == insertion_point_) { |
| AppendLines(line_names_value, i, kNamedLines); |
| AppendLines(line_names_value, 0, kAutoRepeatNamedLines); |
| return; |
| } |
| |
| if (i == insertion_point_ + auto_repeat_total_tracks_) { |
| AppendLines(line_names_value, auto_repeat_track_list_length_, |
| kAutoRepeatNamedLines); |
| AppendLines(line_names_value, insertion_point_ + 1, kNamedLines); |
| return; |
| } |
| |
| size_t auto_repeat_index_in_first_repetition = |
| (i - insertion_point_) % auto_repeat_track_list_length_; |
| if (!auto_repeat_index_in_first_repetition && i > insertion_point_) |
| AppendLines(line_names_value, auto_repeat_track_list_length_, |
| kAutoRepeatNamedLines); |
| AppendLines(line_names_value, auto_repeat_index_in_first_repetition, |
| kAutoRepeatNamedLines); |
| } |
| |
| static void AddValuesForNamedGridLinesAtIndex( |
| OrderedNamedLinesCollector& collector, |
| size_t i, |
| CSSValueList& list) { |
| if (collector.IsEmpty()) |
| return; |
| |
| CSSGridLineNamesValue* line_names = CSSGridLineNamesValue::Create(); |
| collector.CollectLineNamesForIndex(*line_names, i); |
| if (line_names->length()) |
| list.Append(*line_names); |
| } |
| |
| static CSSValue* ValueForGridTrackSizeList(GridTrackSizingDirection direction, |
| const ComputedStyle& style) { |
| const Vector<GridTrackSize>& auto_track_sizes = |
| direction == kForColumns ? style.GridAutoColumns() : style.GridAutoRows(); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (auto& track_size : auto_track_sizes) |
| list->Append(*SpecifiedValueForGridTrackSize(track_size, style)); |
| return list; |
| } |
| |
| static CSSValue* ValueForGridTrackList(GridTrackSizingDirection direction, |
| const LayoutObject* layout_object, |
| const ComputedStyle& style) { |
| bool is_row_axis = direction == kForColumns; |
| const Vector<GridTrackSize>& track_sizes = |
| is_row_axis ? style.GridTemplateColumns() : style.GridTemplateRows(); |
| const Vector<GridTrackSize>& auto_repeat_track_sizes = |
| is_row_axis ? style.GridAutoRepeatColumns() : style.GridAutoRepeatRows(); |
| bool is_layout_grid = layout_object && layout_object->IsLayoutGrid(); |
| |
| // Handle the 'none' case. |
| bool track_list_is_empty = |
| track_sizes.IsEmpty() && auto_repeat_track_sizes.IsEmpty(); |
| if (is_layout_grid && track_list_is_empty) { |
| // For grids we should consider every listed track, whether implicitly or |
| // explicitly created. Empty grids have a sole grid line per axis. |
| auto& positions = is_row_axis |
| ? ToLayoutGrid(layout_object)->ColumnPositions() |
| : ToLayoutGrid(layout_object)->RowPositions(); |
| track_list_is_empty = positions.size() == 1; |
| } |
| |
| if (track_list_is_empty) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| size_t auto_repeat_total_tracks = |
| is_layout_grid |
| ? ToLayoutGrid(layout_object)->AutoRepeatCountForDirection(direction) |
| : 0; |
| OrderedNamedLinesCollector collector(style, is_row_axis, |
| auto_repeat_total_tracks); |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| size_t insertion_index; |
| if (is_layout_grid) { |
| const auto* grid = ToLayoutGrid(layout_object); |
| Vector<LayoutUnit> computed_track_sizes = |
| grid->TrackSizesForComputedStyle(direction); |
| size_t num_tracks = computed_track_sizes.size(); |
| |
| for (size_t i = 0; i < num_tracks; ++i) { |
| AddValuesForNamedGridLinesAtIndex(collector, i, *list); |
| list->Append(*ZoomAdjustedPixelValue(computed_track_sizes[i], style)); |
| } |
| AddValuesForNamedGridLinesAtIndex(collector, num_tracks + 1, *list); |
| |
| insertion_index = num_tracks; |
| } else { |
| for (size_t i = 0; i < track_sizes.size(); ++i) { |
| AddValuesForNamedGridLinesAtIndex(collector, i, *list); |
| list->Append(*SpecifiedValueForGridTrackSize(track_sizes[i], style)); |
| } |
| insertion_index = track_sizes.size(); |
| } |
| // Those are the trailing <string>* allowed in the syntax. |
| AddValuesForNamedGridLinesAtIndex(collector, insertion_index, *list); |
| return list; |
| } |
| |
| static CSSValue* ValueForGridPosition(const GridPosition& position) { |
| if (position.IsAuto()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| |
| if (position.IsNamedGridArea()) |
| return CSSCustomIdentValue::Create(position.NamedGridLine()); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (position.IsSpan()) { |
| list->Append(*CSSIdentifierValue::Create(CSSValueSpan)); |
| list->Append(*CSSPrimitiveValue::Create( |
| position.SpanPosition(), CSSPrimitiveValue::UnitType::kNumber)); |
| } else { |
| list->Append(*CSSPrimitiveValue::Create( |
| position.IntegerPosition(), CSSPrimitiveValue::UnitType::kNumber)); |
| } |
| |
| if (!position.NamedGridLine().IsNull()) |
| list->Append(*CSSCustomIdentValue::Create(position.NamedGridLine())); |
| return list; |
| } |
| |
| static LayoutRect SizingBox(const LayoutObject* layout_object) { |
| if (!layout_object->IsBox()) |
| return LayoutRect(); |
| |
| const LayoutBox* box = ToLayoutBox(layout_object); |
| return box->Style()->BoxSizing() == EBoxSizing::kBorderBox |
| ? box->BorderBoxRect() |
| : box->ComputedCSSContentBoxRect(); |
| } |
| |
| static CSSValue* RenderTextDecorationFlagsToCSSValue( |
| TextDecoration text_decoration) { |
| // Blink value is ignored. |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (EnumHasFlags(text_decoration, TextDecoration::kUnderline)) |
| list->Append(*CSSIdentifierValue::Create(CSSValueUnderline)); |
| if (EnumHasFlags(text_decoration, TextDecoration::kOverline)) |
| list->Append(*CSSIdentifierValue::Create(CSSValueOverline)); |
| if (EnumHasFlags(text_decoration, TextDecoration::kLineThrough)) |
| list->Append(*CSSIdentifierValue::Create(CSSValueLineThrough)); |
| |
| if (!list->length()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return list; |
| } |
| |
| static CSSValue* ValueForTextDecorationStyle( |
| TextDecorationStyle text_decoration_style) { |
| switch (text_decoration_style) { |
| case kTextDecorationStyleSolid: |
| return CSSIdentifierValue::Create(CSSValueSolid); |
| case kTextDecorationStyleDouble: |
| return CSSIdentifierValue::Create(CSSValueDouble); |
| case kTextDecorationStyleDotted: |
| return CSSIdentifierValue::Create(CSSValueDotted); |
| case kTextDecorationStyleDashed: |
| return CSSIdentifierValue::Create(CSSValueDashed); |
| case kTextDecorationStyleWavy: |
| return CSSIdentifierValue::Create(CSSValueWavy); |
| } |
| |
| NOTREACHED(); |
| return CSSInitialValue::Create(); |
| } |
| |
| static CSSValue* ValueForTextDecorationSkip( |
| TextDecorationSkip text_decoration_skip) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (EnumHasFlags(text_decoration_skip, TextDecorationSkip::kObjects)) |
| list->Append(*CSSIdentifierValue::Create(CSSValueObjects)); |
| if (EnumHasFlags(text_decoration_skip, TextDecorationSkip::kInk)) |
| list->Append(*CSSIdentifierValue::Create(CSSValueInk)); |
| |
| DCHECK(list->length()); |
| return list; |
| } |
| |
| static CSSValue* TouchActionFlagsToCSSValue(TouchAction touch_action) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (touch_action == TouchAction::kTouchActionAuto) { |
| list->Append(*CSSIdentifierValue::Create(CSSValueAuto)); |
| } else if (touch_action == TouchAction::kTouchActionNone) { |
| list->Append(*CSSIdentifierValue::Create(CSSValueNone)); |
| } else if (touch_action == TouchAction::kTouchActionManipulation) { |
| list->Append(*CSSIdentifierValue::Create(CSSValueManipulation)); |
| } else { |
| if ((touch_action & TouchAction::kTouchActionPanX) == |
| TouchAction::kTouchActionPanX) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePanX)); |
| else if (touch_action & TouchAction::kTouchActionPanLeft) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePanLeft)); |
| else if (touch_action & TouchAction::kTouchActionPanRight) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePanRight)); |
| if ((touch_action & TouchAction::kTouchActionPanY) == |
| TouchAction::kTouchActionPanY) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePanY)); |
| else if (touch_action & TouchAction::kTouchActionPanUp) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePanUp)); |
| else if (touch_action & TouchAction::kTouchActionPanDown) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePanDown)); |
| |
| if ((touch_action & TouchAction::kTouchActionPinchZoom) == |
| TouchAction::kTouchActionPinchZoom) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePinchZoom)); |
| } |
| |
| DCHECK(list->length()); |
| return list; |
| } |
| |
| static CSSValue* ValueForWillChange( |
| const Vector<CSSPropertyID>& will_change_properties, |
| bool will_change_contents, |
| bool will_change_scroll_position) { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| if (will_change_contents) |
| list->Append(*CSSIdentifierValue::Create(CSSValueContents)); |
| if (will_change_scroll_position) |
| list->Append(*CSSIdentifierValue::Create(CSSValueScrollPosition)); |
| for (size_t i = 0; i < will_change_properties.size(); ++i) |
| list->Append(*CSSCustomIdentValue::Create(will_change_properties[i])); |
| if (!list->length()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueAuto)); |
| return list; |
| } |
| |
| static CSSValue* ValueForAnimationDelay(const CSSTimingData* timing_data) { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| if (timing_data) { |
| for (size_t i = 0; i < timing_data->DelayList().size(); ++i) |
| list->Append(*CSSPrimitiveValue::Create( |
| timing_data->DelayList()[i], CSSPrimitiveValue::UnitType::kSeconds)); |
| } else { |
| list->Append(*CSSPrimitiveValue::Create( |
| CSSTimingData::InitialDelay(), CSSPrimitiveValue::UnitType::kSeconds)); |
| } |
| return list; |
| } |
| |
| static CSSValue* ValueForAnimationDirection( |
| Timing::PlaybackDirection direction) { |
| switch (direction) { |
| case Timing::PlaybackDirection::NORMAL: |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| case Timing::PlaybackDirection::ALTERNATE_NORMAL: |
| return CSSIdentifierValue::Create(CSSValueAlternate); |
| case Timing::PlaybackDirection::REVERSE: |
| return CSSIdentifierValue::Create(CSSValueReverse); |
| case Timing::PlaybackDirection::ALTERNATE_REVERSE: |
| return CSSIdentifierValue::Create(CSSValueAlternateReverse); |
| default: |
| NOTREACHED(); |
| return nullptr; |
| } |
| } |
| |
| static CSSValue* ValueForAnimationDuration(const CSSTimingData* timing_data) { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| if (timing_data) { |
| for (size_t i = 0; i < timing_data->DurationList().size(); ++i) |
| list->Append( |
| *CSSPrimitiveValue::Create(timing_data->DurationList()[i], |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| } else { |
| list->Append( |
| *CSSPrimitiveValue::Create(CSSTimingData::InitialDuration(), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| } |
| return list; |
| } |
| |
| static CSSValue* ValueForAnimationFillMode(Timing::FillMode fill_mode) { |
| switch (fill_mode) { |
| case Timing::FillMode::NONE: |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case Timing::FillMode::FORWARDS: |
| return CSSIdentifierValue::Create(CSSValueForwards); |
| case Timing::FillMode::BACKWARDS: |
| return CSSIdentifierValue::Create(CSSValueBackwards); |
| case Timing::FillMode::BOTH: |
| return CSSIdentifierValue::Create(CSSValueBoth); |
| default: |
| NOTREACHED(); |
| return nullptr; |
| } |
| } |
| |
| static CSSValue* ValueForAnimationIterationCount(double iteration_count) { |
| if (iteration_count == std::numeric_limits<double>::infinity()) |
| return CSSIdentifierValue::Create(CSSValueInfinite); |
| return CSSPrimitiveValue::Create(iteration_count, |
| CSSPrimitiveValue::UnitType::kNumber); |
| } |
| |
| static CSSValue* ValueForAnimationPlayState(EAnimPlayState play_state) { |
| if (play_state == kAnimPlayStatePlaying) |
| return CSSIdentifierValue::Create(CSSValueRunning); |
| DCHECK_EQ(play_state, kAnimPlayStatePaused); |
| return CSSIdentifierValue::Create(CSSValuePaused); |
| } |
| |
| static CSSValue* CreateTimingFunctionValue( |
| const TimingFunction* timing_function) { |
| switch (timing_function->GetType()) { |
| case TimingFunction::Type::CUBIC_BEZIER: { |
| const CubicBezierTimingFunction* bezier_timing_function = |
| ToCubicBezierTimingFunction(timing_function); |
| if (bezier_timing_function->GetEaseType() != |
| CubicBezierTimingFunction::EaseType::CUSTOM) { |
| CSSValueID value_id = CSSValueInvalid; |
| switch (bezier_timing_function->GetEaseType()) { |
| case CubicBezierTimingFunction::EaseType::EASE: |
| value_id = CSSValueEase; |
| break; |
| case CubicBezierTimingFunction::EaseType::EASE_IN: |
| value_id = CSSValueEaseIn; |
| break; |
| case CubicBezierTimingFunction::EaseType::EASE_OUT: |
| value_id = CSSValueEaseOut; |
| break; |
| case CubicBezierTimingFunction::EaseType::EASE_IN_OUT: |
| value_id = CSSValueEaseInOut; |
| break; |
| default: |
| NOTREACHED(); |
| return nullptr; |
| } |
| return CSSIdentifierValue::Create(value_id); |
| } |
| return CSSCubicBezierTimingFunctionValue::Create( |
| bezier_timing_function->X1(), bezier_timing_function->Y1(), |
| bezier_timing_function->X2(), bezier_timing_function->Y2()); |
| } |
| |
| case TimingFunction::Type::STEPS: { |
| const StepsTimingFunction* steps_timing_function = |
| ToStepsTimingFunction(timing_function); |
| StepsTimingFunction::StepPosition position = |
| steps_timing_function->GetStepPosition(); |
| int steps = steps_timing_function->NumberOfSteps(); |
| DCHECK(position == StepsTimingFunction::StepPosition::START || |
| position == StepsTimingFunction::StepPosition::END); |
| |
| if (steps > 1) |
| return CSSStepsTimingFunctionValue::Create(steps, position); |
| CSSValueID value_id = position == StepsTimingFunction::StepPosition::START |
| ? CSSValueStepStart |
| : CSSValueStepEnd; |
| return CSSIdentifierValue::Create(value_id); |
| } |
| |
| case TimingFunction::Type::FRAMES: { |
| const FramesTimingFunction* frames_timing_function = |
| ToFramesTimingFunction(timing_function); |
| int frames = frames_timing_function->NumberOfFrames(); |
| return CSSFramesTimingFunctionValue::Create(frames); |
| } |
| |
| default: |
| return CSSIdentifierValue::Create(CSSValueLinear); |
| } |
| } |
| |
| static CSSValue* ValueForAnimationTimingFunction( |
| const CSSTimingData* timing_data) { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| if (timing_data) { |
| for (size_t i = 0; i < timing_data->TimingFunctionList().size(); ++i) |
| list->Append(*CreateTimingFunctionValue( |
| timing_data->TimingFunctionList()[i].Get())); |
| } else { |
| list->Append(*CreateTimingFunctionValue( |
| CSSTimingData::InitialTimingFunction().Get())); |
| } |
| return list; |
| } |
| |
| static CSSValueList* ValuesForBorderRadiusCorner(LengthSize radius, |
| const ComputedStyle& style) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (radius.Width().GetType() == kPercent) |
| list->Append(*CSSPrimitiveValue::Create( |
| radius.Width().Percent(), CSSPrimitiveValue::UnitType::kPercentage)); |
| else |
| list->Append(*ZoomAdjustedPixelValueForLength(radius.Width(), style)); |
| if (radius.Height().GetType() == kPercent) |
| list->Append(*CSSPrimitiveValue::Create( |
| radius.Height().Percent(), CSSPrimitiveValue::UnitType::kPercentage)); |
| else |
| list->Append(*ZoomAdjustedPixelValueForLength(radius.Height(), style)); |
| return list; |
| } |
| |
| static const CSSValue& ValueForBorderRadiusCorner(LengthSize radius, |
| const ComputedStyle& style) { |
| CSSValueList& list = *ValuesForBorderRadiusCorner(radius, style); |
| if (list.Item(0) == list.Item(1)) |
| return list.Item(0); |
| return list; |
| } |
| |
| static CSSFunctionValue* ValueForMatrixTransform(TransformationMatrix transform, |
| const ComputedStyle& style) { |
| CSSFunctionValue* transform_value = nullptr; |
| transform.Zoom(1 / style.EffectiveZoom()); |
| if (transform.IsAffine()) { |
| transform_value = CSSFunctionValue::Create(CSSValueMatrix); |
| |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.A(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.B(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.C(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.D(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.E(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.F(), CSSPrimitiveValue::UnitType::kNumber)); |
| } else { |
| transform_value = CSSFunctionValue::Create(CSSValueMatrix3d); |
| |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M11(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M12(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M13(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M14(), CSSPrimitiveValue::UnitType::kNumber)); |
| |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M21(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M22(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M23(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M24(), CSSPrimitiveValue::UnitType::kNumber)); |
| |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M31(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M32(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M33(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M34(), CSSPrimitiveValue::UnitType::kNumber)); |
| |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M41(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M42(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M43(), CSSPrimitiveValue::UnitType::kNumber)); |
| transform_value->Append(*CSSPrimitiveValue::Create( |
| transform.M44(), CSSPrimitiveValue::UnitType::kNumber)); |
| } |
| |
| return transform_value; |
| } |
| |
| static CSSValue* ComputedTransform(const LayoutObject* layout_object, |
| const ComputedStyle& style) { |
| if (!layout_object || !style.HasTransform()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| IntRect box; |
| if (layout_object->IsBox()) |
| box = PixelSnappedIntRect(ToLayoutBox(layout_object)->BorderBoxRect()); |
| |
| TransformationMatrix transform; |
| style.ApplyTransform(transform, LayoutSize(box.Size()), |
| ComputedStyle::kExcludeTransformOrigin, |
| ComputedStyle::kExcludeMotionPath, |
| ComputedStyle::kExcludeIndependentTransformProperties); |
| |
| // FIXME: Need to print out individual functions |
| // (https://bugs.webkit.org/show_bug.cgi?id=23924) |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ValueForMatrixTransform(transform, style)); |
| |
| return list; |
| } |
| |
| static CSSValue* CreateTransitionPropertyValue( |
| const CSSTransitionData::TransitionProperty& property) { |
| if (property.property_type == CSSTransitionData::kTransitionNone) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| if (property.property_type == CSSTransitionData::kTransitionUnknownProperty) |
| return CSSCustomIdentValue::Create(property.property_string); |
| DCHECK_EQ(property.property_type, |
| CSSTransitionData::kTransitionKnownProperty); |
| return CSSCustomIdentValue::Create( |
| getPropertyNameAtomicString(property.unresolved_property)); |
| } |
| |
| static CSSValue* ValueForTransitionProperty( |
| const CSSTransitionData* transition_data) { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| if (transition_data) { |
| for (size_t i = 0; i < transition_data->PropertyList().size(); ++i) |
| list->Append( |
| *CreateTransitionPropertyValue(transition_data->PropertyList()[i])); |
| } else { |
| list->Append(*CSSIdentifierValue::Create(CSSValueAll)); |
| } |
| return list; |
| } |
| |
| CSSValueID ValueForQuoteType(const QuoteType quote_type) { |
| switch (quote_type) { |
| case NO_OPEN_QUOTE: |
| return CSSValueNoOpenQuote; |
| case NO_CLOSE_QUOTE: |
| return CSSValueNoCloseQuote; |
| case CLOSE_QUOTE: |
| return CSSValueCloseQuote; |
| case OPEN_QUOTE: |
| return CSSValueOpenQuote; |
| } |
| NOTREACHED(); |
| return CSSValueInvalid; |
| } |
| |
| static CSSValue* ValueForContentData(const ComputedStyle& style) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (const ContentData* content_data = style.GetContentData(); content_data; |
| content_data = content_data->Next()) { |
| if (content_data->IsCounter()) { |
| const CounterContent* counter = |
| ToCounterContentData(content_data)->Counter(); |
| DCHECK(counter); |
| CSSCustomIdentValue* identifier = |
| CSSCustomIdentValue::Create(counter->Identifier()); |
| CSSStringValue* separator = CSSStringValue::Create(counter->Separator()); |
| CSSValueID list_style_ident = CSSValueNone; |
| if (counter->ListStyle() != EListStyleType::kNone) { |
| // TODO(sashab): Change this to use a converter instead of |
| // CSSPrimitiveValueMappings. |
| list_style_ident = |
| CSSIdentifierValue::Create(counter->ListStyle())->GetValueID(); |
| } |
| CSSIdentifierValue* list_style = |
| CSSIdentifierValue::Create(list_style_ident); |
| list->Append(*CSSCounterValue::Create(identifier, list_style, separator)); |
| } else if (content_data->IsImage()) { |
| const StyleImage* image = ToImageContentData(content_data)->GetImage(); |
| DCHECK(image); |
| list->Append(*image->ComputedCSSValue()); |
| } else if (content_data->IsText()) { |
| list->Append( |
| *CSSStringValue::Create(ToTextContentData(content_data)->GetText())); |
| } else if (content_data->IsQuote()) { |
| const QuoteType quote_type = ToQuoteContentData(content_data)->Quote(); |
| list->Append(*CSSIdentifierValue::Create(ValueForQuoteType(quote_type))); |
| } else { |
| NOTREACHED(); |
| } |
| } |
| return list; |
| } |
| |
| static CSSValue* ValueForCounterDirectives(const ComputedStyle& style, |
| CSSPropertyID property_id) { |
| const CounterDirectiveMap* map = style.GetCounterDirectives(); |
| if (!map) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (const auto& item : *map) { |
| bool is_valid_counter_value = property_id == CSSPropertyCounterIncrement |
| ? item.value.IsIncrement() |
| : item.value.IsReset(); |
| if (!is_valid_counter_value) |
| continue; |
| |
| list->Append(*CSSCustomIdentValue::Create(item.key)); |
| short number = property_id == CSSPropertyCounterIncrement |
| ? item.value.IncrementValue() |
| : item.value.ResetValue(); |
| list->Append(*CSSPrimitiveValue::Create( |
| (double)number, CSSPrimitiveValue::UnitType::kInteger)); |
| } |
| |
| if (!list->length()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| return list; |
| } |
| |
| static CSSValue* ValueForShape(const ComputedStyle& style, |
| ShapeValue* shape_value) { |
| if (!shape_value) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| if (shape_value->GetType() == ShapeValue::kBox) |
| return CSSIdentifierValue::Create(shape_value->CssBox()); |
| if (shape_value->GetType() == ShapeValue::kImage) { |
| if (shape_value->GetImage()) |
| return shape_value->GetImage()->ComputedCSSValue(); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| } |
| |
| DCHECK_EQ(shape_value->GetType(), ShapeValue::kShape); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ValueForBasicShape(style, shape_value->Shape())); |
| if (shape_value->CssBox() != kBoxMissing) |
| list->Append(*CSSIdentifierValue::Create(shape_value->CssBox())); |
| return list; |
| } |
| |
| static CSSValueList* ValuesForSidesShorthand( |
| const StylePropertyShorthand& shorthand, |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| Node* styled_node, |
| bool allow_visited_style) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| // Assume the properties are in the usual order top, right, bottom, left. |
| const CSSValue* top_value = ComputedStyleCSSValueMapping::Get( |
| shorthand.properties()[0], style, layout_object, styled_node, |
| allow_visited_style); |
| const CSSValue* right_value = ComputedStyleCSSValueMapping::Get( |
| shorthand.properties()[1], style, layout_object, styled_node, |
| allow_visited_style); |
| const CSSValue* bottom_value = ComputedStyleCSSValueMapping::Get( |
| shorthand.properties()[2], style, layout_object, styled_node, |
| allow_visited_style); |
| const CSSValue* left_value = ComputedStyleCSSValueMapping::Get( |
| shorthand.properties()[3], style, layout_object, styled_node, |
| allow_visited_style); |
| |
| // All 4 properties must be specified. |
| if (!top_value || !right_value || !bottom_value || !left_value) |
| return nullptr; |
| |
| bool show_left = !DataEquivalent(right_value, left_value); |
| bool show_bottom = !DataEquivalent(top_value, bottom_value) || show_left; |
| bool show_right = !DataEquivalent(top_value, right_value) || show_bottom; |
| |
| list->Append(*top_value); |
| if (show_right) |
| list->Append(*right_value); |
| if (show_bottom) |
| list->Append(*bottom_value); |
| if (show_left) |
| list->Append(*left_value); |
| |
| return list; |
| } |
| |
| static CSSValueList* ValueForBorderRadiusShorthand(const ComputedStyle& style) { |
| CSSValueList* list = CSSValueList::CreateSlashSeparated(); |
| |
| bool show_horizontal_bottom_left = style.BorderTopRightRadius().Width() != |
| style.BorderBottomLeftRadius().Width(); |
| bool show_horizontal_bottom_right = |
| show_horizontal_bottom_left || (style.BorderBottomRightRadius().Width() != |
| style.BorderTopLeftRadius().Width()); |
| bool show_horizontal_top_right = |
| show_horizontal_bottom_right || (style.BorderTopRightRadius().Width() != |
| style.BorderTopLeftRadius().Width()); |
| |
| bool show_vertical_bottom_left = style.BorderTopRightRadius().Height() != |
| style.BorderBottomLeftRadius().Height(); |
| bool show_vertical_bottom_right = |
| show_vertical_bottom_left || (style.BorderBottomRightRadius().Height() != |
| style.BorderTopLeftRadius().Height()); |
| bool show_vertical_top_right = |
| show_vertical_bottom_right || (style.BorderTopRightRadius().Height() != |
| style.BorderTopLeftRadius().Height()); |
| |
| CSSValueList* top_left_radius = |
| ValuesForBorderRadiusCorner(style.BorderTopLeftRadius(), style); |
| CSSValueList* top_right_radius = |
| ValuesForBorderRadiusCorner(style.BorderTopRightRadius(), style); |
| CSSValueList* bottom_right_radius = |
| ValuesForBorderRadiusCorner(style.BorderBottomRightRadius(), style); |
| CSSValueList* bottom_left_radius = |
| ValuesForBorderRadiusCorner(style.BorderBottomLeftRadius(), style); |
| |
| CSSValueList* horizontal_radii = CSSValueList::CreateSpaceSeparated(); |
| horizontal_radii->Append(top_left_radius->Item(0)); |
| if (show_horizontal_top_right) |
| horizontal_radii->Append(top_right_radius->Item(0)); |
| if (show_horizontal_bottom_right) |
| horizontal_radii->Append(bottom_right_radius->Item(0)); |
| if (show_horizontal_bottom_left) |
| horizontal_radii->Append(bottom_left_radius->Item(0)); |
| |
| list->Append(*horizontal_radii); |
| |
| CSSValueList* vertical_radii = CSSValueList::CreateSpaceSeparated(); |
| vertical_radii->Append(top_left_radius->Item(1)); |
| if (show_vertical_top_right) |
| vertical_radii->Append(top_right_radius->Item(1)); |
| if (show_vertical_bottom_right) |
| vertical_radii->Append(bottom_right_radius->Item(1)); |
| if (show_vertical_bottom_left) |
| vertical_radii->Append(bottom_left_radius->Item(1)); |
| |
| if (!vertical_radii->Equals(ToCSSValueList(list->Item(0)))) |
| list->Append(*vertical_radii); |
| |
| return list; |
| } |
| |
| static CSSValue* StrokeDashArrayToCSSValueList(const SVGDashArray& dashes, |
| const ComputedStyle& style) { |
| if (dashes.IsEmpty()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const Length& dash_length : dashes.GetVector()) |
| list->Append(*ZoomAdjustedPixelValueForLength(dash_length, style)); |
| |
| return list; |
| } |
| |
| static CSSValue* PaintOrderToCSSValueList(const SVGComputedStyle& svg_style) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (int i = 0; i < 3; i++) { |
| EPaintOrderType paint_order_type = svg_style.PaintOrderType(i); |
| switch (paint_order_type) { |
| case PT_FILL: |
| case PT_STROKE: |
| case PT_MARKERS: |
| list->Append(*CSSIdentifierValue::Create(paint_order_type)); |
| break; |
| case PT_NONE: |
| default: |
| NOTREACHED(); |
| break; |
| } |
| } |
| |
| return list; |
| } |
| |
| static CSSValue* AdjustSVGPaintForCurrentColor(SVGPaintType paint_type, |
| const String& url, |
| const Color& color, |
| const Color& current_color) { |
| if (paint_type >= SVG_PAINTTYPE_URI_NONE) { |
| CSSValueList* values = CSSValueList::CreateSpaceSeparated(); |
| values->Append(*CSSURIValue::Create(AtomicString(url))); |
| if (paint_type == SVG_PAINTTYPE_URI_NONE) |
| values->Append(*CSSIdentifierValue::Create(CSSValueNone)); |
| else if (paint_type == SVG_PAINTTYPE_URI_CURRENTCOLOR) |
| values->Append(*CSSColorValue::Create(current_color.Rgb())); |
| else if (paint_type == SVG_PAINTTYPE_URI_RGBCOLOR) |
| values->Append(*CSSColorValue::Create(color.Rgb())); |
| return values; |
| } |
| if (paint_type == SVG_PAINTTYPE_NONE) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| if (paint_type == SVG_PAINTTYPE_CURRENTCOLOR) |
| return CSSColorValue::Create(current_color.Rgb()); |
| |
| return CSSColorValue::Create(color.Rgb()); |
| } |
| |
| static inline AtomicString SerializeAsFragmentIdentifier( |
| const AtomicString& resource) { |
| return "#" + resource; |
| } |
| |
| CSSValue* ComputedStyleCSSValueMapping::ValueForShadowData( |
| const ShadowData& shadow, |
| const ComputedStyle& style, |
| bool use_spread) { |
| CSSPrimitiveValue* x = ZoomAdjustedPixelValue(shadow.X(), style); |
| CSSPrimitiveValue* y = ZoomAdjustedPixelValue(shadow.Y(), style); |
| CSSPrimitiveValue* blur = ZoomAdjustedPixelValue(shadow.Blur(), style); |
| CSSPrimitiveValue* spread = |
| use_spread ? ZoomAdjustedPixelValue(shadow.Spread(), style) : nullptr; |
| CSSIdentifierValue* shadow_style = |
| shadow.Style() == kNormal ? nullptr |
| : CSSIdentifierValue::Create(CSSValueInset); |
| CSSValue* color = CurrentColorOrValidColor(style, shadow.GetColor()); |
| return CSSShadowValue::Create(x, y, blur, spread, shadow_style, color); |
| } |
| |
| CSSValue* ComputedStyleCSSValueMapping::ValueForShadowList( |
| const ShadowList* shadow_list, |
| const ComputedStyle& style, |
| bool use_spread) { |
| if (!shadow_list) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| size_t shadow_count = shadow_list->Shadows().size(); |
| for (size_t i = 0; i < shadow_count; ++i) |
| list->Append( |
| *ValueForShadowData(shadow_list->Shadows()[i], style, use_spread)); |
| return list; |
| } |
| |
| CSSValue* ComputedStyleCSSValueMapping::ValueForFilter( |
| const ComputedStyle& style, |
| const FilterOperations& filter_operations) { |
| if (filter_operations.Operations().IsEmpty()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| |
| CSSFunctionValue* filter_value = nullptr; |
| |
| for (const auto& operation : filter_operations.Operations()) { |
| FilterOperation* filter_operation = operation.Get(); |
| switch (filter_operation->GetType()) { |
| case FilterOperation::REFERENCE: |
| filter_value = CSSFunctionValue::Create(CSSValueUrl); |
| filter_value->Append(*CSSStringValue::Create( |
| ToReferenceFilterOperation(filter_operation)->Url())); |
| break; |
| case FilterOperation::GRAYSCALE: |
| filter_value = CSSFunctionValue::Create(CSSValueGrayscale); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicColorMatrixFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::SEPIA: |
| filter_value = CSSFunctionValue::Create(CSSValueSepia); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicColorMatrixFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::SATURATE: |
| filter_value = CSSFunctionValue::Create(CSSValueSaturate); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicColorMatrixFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::HUE_ROTATE: |
| filter_value = CSSFunctionValue::Create(CSSValueHueRotate); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicColorMatrixFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kDegrees)); |
| break; |
| case FilterOperation::INVERT: |
| filter_value = CSSFunctionValue::Create(CSSValueInvert); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicComponentTransferFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::OPACITY: |
| filter_value = CSSFunctionValue::Create(CSSValueOpacity); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicComponentTransferFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::BRIGHTNESS: |
| filter_value = CSSFunctionValue::Create(CSSValueBrightness); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicComponentTransferFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::CONTRAST: |
| filter_value = CSSFunctionValue::Create(CSSValueContrast); |
| filter_value->Append(*CSSPrimitiveValue::Create( |
| ToBasicComponentTransferFilterOperation(filter_operation)->Amount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| break; |
| case FilterOperation::BLUR: |
| filter_value = CSSFunctionValue::Create(CSSValueBlur); |
| filter_value->Append(*ZoomAdjustedPixelValue( |
| ToBlurFilterOperation(filter_operation)->StdDeviation().Value(), |
| style)); |
| break; |
| case FilterOperation::DROP_SHADOW: { |
| const auto& drop_shadow_operation = |
| ToDropShadowFilterOperation(*filter_operation); |
| filter_value = CSSFunctionValue::Create(CSSValueDropShadow); |
| // We want our computed style to look like that of a text shadow (has |
| // neither spread nor inset style). |
| filter_value->Append( |
| *ValueForShadowData(drop_shadow_operation.Shadow(), style, false)); |
| break; |
| } |
| default: |
| NOTREACHED(); |
| break; |
| } |
| list->Append(*filter_value); |
| } |
| |
| return list; |
| } |
| |
| CSSValue* ComputedStyleCSSValueMapping::ValueForFont( |
| const ComputedStyle& style) { |
| // Add a slash between size and line-height. |
| CSSValueList* size_and_line_height = CSSValueList::CreateSlashSeparated(); |
| size_and_line_height->Append(*ValueForFontSize(style)); |
| size_and_line_height->Append(*ValueForLineHeight(style)); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ValueForFontStyle(style)); |
| |
| // Check that non-initial font-variant subproperties are not conflicting with |
| // this serialization. |
| CSSValue* ligatures_value = ValueForFontVariantLigatures(style); |
| CSSValue* numeric_value = ValueForFontVariantNumeric(style); |
| if (!DataEquivalent<CSSValue>(ligatures_value, |
| CSSIdentifierValue::Create(CSSValueNormal)) || |
| !DataEquivalent<CSSValue>(numeric_value, |
| CSSIdentifierValue::Create(CSSValueNormal))) |
| return nullptr; |
| |
| CSSIdentifierValue* caps_value = ValueForFontVariantCaps(style); |
| if (caps_value->GetValueID() != CSSValueNormal && |
| caps_value->GetValueID() != CSSValueSmallCaps) |
| return nullptr; |
| list->Append(*caps_value); |
| |
| list->Append(*ValueForFontWeight(style)); |
| list->Append(*ValueForFontStretch(style)); |
| list->Append(*size_and_line_height); |
| list->Append(*ValueForFontFamily(style)); |
| |
| return list; |
| } |
| |
| static CSSValue* ValueForScrollSnapDestination(const LengthPoint& destination, |
| const ComputedStyle& style) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ZoomAdjustedPixelValueForLength(destination.X(), style)); |
| list->Append(*ZoomAdjustedPixelValueForLength(destination.Y(), style)); |
| return list; |
| } |
| |
| static CSSValue* ValueForScrollSnapPoints(const ScrollSnapPoints& points, |
| const ComputedStyle& style) { |
| if (points.has_repeat) { |
| CSSFunctionValue* repeat = CSSFunctionValue::Create(CSSValueRepeat); |
| repeat->Append( |
| *ZoomAdjustedPixelValueForLength(points.repeat_offset, style)); |
| return repeat; |
| } |
| |
| return CSSIdentifierValue::Create(CSSValueNone); |
| } |
| |
| static CSSValue* ValueForScrollSnapCoordinate( |
| const Vector<LengthPoint>& coordinates, |
| const ComputedStyle& style) { |
| if (coordinates.IsEmpty()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| |
| for (auto& coordinate : coordinates) { |
| auto pair = CSSValueList::CreateSpaceSeparated(); |
| pair->Append(*ZoomAdjustedPixelValueForLength(coordinate.X(), style)); |
| pair->Append(*ZoomAdjustedPixelValueForLength(coordinate.Y(), style)); |
| list->Append(*pair); |
| } |
| |
| return list; |
| } |
| |
| // Returns a suitable value for the page-break-(before|after) property, given |
| // the computed value of the more general break-(before|after) property. |
| static CSSValue* ValueForPageBreakBetween(EBreakBetween break_value) { |
| switch (break_value) { |
| case EBreakBetween::kAvoidColumn: |
| case EBreakBetween::kColumn: |
| case EBreakBetween::kRecto: |
| case EBreakBetween::kVerso: |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| case EBreakBetween::kPage: |
| return CSSIdentifierValue::Create(CSSValueAlways); |
| case EBreakBetween::kAvoidPage: |
| return CSSIdentifierValue::Create(CSSValueAvoid); |
| default: |
| return CSSIdentifierValue::Create(break_value); |
| } |
| } |
| |
| // Returns a suitable value for the -webkit-column-break-(before|after) |
| // property, given the computed value of the more general break-(before|after) |
| // property. |
| static CSSValue* ValueForWebkitColumnBreakBetween(EBreakBetween break_value) { |
| switch (break_value) { |
| case EBreakBetween::kAvoidPage: |
| case EBreakBetween::kLeft: |
| case EBreakBetween::kPage: |
| case EBreakBetween::kRecto: |
| case EBreakBetween::kRight: |
| case EBreakBetween::kVerso: |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| case EBreakBetween::kColumn: |
| return CSSIdentifierValue::Create(CSSValueAlways); |
| case EBreakBetween::kAvoidColumn: |
| return CSSIdentifierValue::Create(CSSValueAvoid); |
| default: |
| return CSSIdentifierValue::Create(break_value); |
| } |
| } |
| |
| // Returns a suitable value for the page-break-inside property, given the |
| // computed value of the more general break-inside property. |
| static CSSValue* ValueForPageBreakInside(EBreakInside break_value) { |
| switch (break_value) { |
| case EBreakInside::kAvoidColumn: |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| case EBreakInside::kAvoidPage: |
| return CSSIdentifierValue::Create(CSSValueAvoid); |
| default: |
| return CSSIdentifierValue::Create(break_value); |
| } |
| } |
| |
| // Returns a suitable value for the -webkit-column-break-inside property, given |
| // the computed value of the more general break-inside property. |
| static CSSValue* ValueForWebkitColumnBreakInside(EBreakInside break_value) { |
| switch (break_value) { |
| case EBreakInside::kAvoidPage: |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| case EBreakInside::kAvoidColumn: |
| return CSSIdentifierValue::Create(CSSValueAvoid); |
| default: |
| return CSSIdentifierValue::Create(break_value); |
| } |
| } |
| |
| const CSSValue* ComputedStyleCSSValueMapping::Get( |
| const AtomicString custom_property_name, |
| const ComputedStyle& style, |
| const PropertyRegistry* registry) { |
| if (registry) { |
| const PropertyRegistration* registration = |
| registry->Registration(custom_property_name); |
| if (registration) { |
| const CSSValue* result = style.GetRegisteredVariable( |
| custom_property_name, registration->Inherits()); |
| if (result) |
| return result; |
| return registration->Initial(); |
| } |
| } |
| |
| bool is_inherited_property = true; |
| CSSVariableData* data = |
| style.GetVariable(custom_property_name, is_inherited_property); |
| if (!data) |
| return nullptr; |
| |
| return CSSCustomPropertyDeclaration::Create(custom_property_name, data); |
| } |
| |
| std::unique_ptr<HashMap<AtomicString, RefPtr<CSSVariableData>>> |
| ComputedStyleCSSValueMapping::GetVariables(const ComputedStyle& style) { |
| // TODO(timloh): Also return non-inherited variables |
| StyleInheritedVariables* variables = style.InheritedVariables(); |
| if (variables) |
| return variables->GetVariables(); |
| return nullptr; |
| } |
| |
| static bool WidthOrHeightPropertyAppliesToObject(const LayoutObject& object) { |
| // According to |
| // http://www.w3.org/TR/CSS2/visudet.html#the-width-property and |
| // http://www.w3.org/TR/CSS2/visudet.html#the-height-property, the "width" or |
| // "height" property does not apply to non-atomic inline elements. |
| if (!object.IsAtomicInlineLevel() && object.IsInline()) |
| return false; |
| |
| // Non-root SVG should be treated as non-atomic inline no matter how we |
| // implement it internally (e.g. LayoutSVGBlock is based on LayoutBlockFlow). |
| return !object.IsSVGChild(); |
| } |
| |
| const CSSValue* ComputedStyleCSSValueMapping::Get( |
| CSSPropertyID property_id, |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| Node* styled_node, |
| bool allow_visited_style) { |
| const SVGComputedStyle& svg_style = style.SvgStyle(); |
| property_id = CSSProperty::ResolveDirectionAwareProperty( |
| property_id, style.Direction(), style.GetWritingMode()); |
| switch (property_id) { |
| case CSSPropertyInvalid: |
| return nullptr; |
| |
| case CSSPropertyBackgroundColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyBackgroundColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.BackgroundColor()); |
| case CSSPropertyBackgroundImage: |
| case CSSPropertyWebkitMaskImage: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = property_id == CSSPropertyWebkitMaskImage |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) { |
| if (curr_layer->GetImage()) |
| list->Append(*curr_layer->GetImage()->ComputedCSSValue()); |
| else |
| list->Append(*CSSIdentifierValue::Create(CSSValueNone)); |
| } |
| return list; |
| } |
| case CSSPropertyBackgroundSize: |
| case CSSPropertyWebkitMaskSize: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = property_id == CSSPropertyWebkitMaskSize |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) |
| list->Append(*ValueForFillSize(curr_layer->Size(), style)); |
| return list; |
| } |
| case CSSPropertyBackgroundRepeat: |
| case CSSPropertyWebkitMaskRepeat: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = property_id == CSSPropertyWebkitMaskRepeat |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) |
| list->Append( |
| *ValueForFillRepeat(curr_layer->RepeatX(), curr_layer->RepeatY())); |
| return list; |
| } |
| case CSSPropertyMaskSourceType: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const FillLayer* curr_layer = &style.MaskLayers(); curr_layer; |
| curr_layer = curr_layer->Next()) |
| list->Append(*ValueForFillSourceType(curr_layer->MaskSourceType())); |
| return list; |
| } |
| case CSSPropertyWebkitMaskComposite: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = |
| property_id == CSSPropertyWebkitMaskComposite |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) |
| list->Append(*CSSIdentifierValue::Create(curr_layer->Composite())); |
| return list; |
| } |
| case CSSPropertyBackgroundAttachment: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const FillLayer* curr_layer = &style.BackgroundLayers(); curr_layer; |
| curr_layer = curr_layer->Next()) |
| list->Append(*CSSIdentifierValue::Create(curr_layer->Attachment())); |
| return list; |
| } |
| case CSSPropertyBackgroundClip: |
| case CSSPropertyBackgroundOrigin: |
| case CSSPropertyWebkitBackgroundClip: |
| case CSSPropertyWebkitBackgroundOrigin: |
| case CSSPropertyWebkitMaskClip: |
| case CSSPropertyWebkitMaskOrigin: { |
| bool is_clip = property_id == CSSPropertyBackgroundClip || |
| property_id == CSSPropertyWebkitBackgroundClip || |
| property_id == CSSPropertyWebkitMaskClip; |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = (property_id == CSSPropertyWebkitMaskClip || |
| property_id == CSSPropertyWebkitMaskOrigin) |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) { |
| EFillBox box = is_clip ? curr_layer->Clip() : curr_layer->Origin(); |
| list->Append(*CSSIdentifierValue::Create(box)); |
| } |
| return list; |
| } |
| case CSSPropertyBackgroundPosition: |
| case CSSPropertyWebkitMaskPosition: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = property_id == CSSPropertyWebkitMaskPosition |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) |
| list->Append( |
| *CreatePositionListForLayer(property_id, *curr_layer, style)); |
| return list; |
| } |
| case CSSPropertyBackgroundPositionX: |
| case CSSPropertyWebkitMaskPositionX: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = |
| property_id == CSSPropertyWebkitMaskPositionX |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(curr_layer->XPosition(), style)); |
| return list; |
| } |
| case CSSPropertyBackgroundPositionY: |
| case CSSPropertyWebkitMaskPositionY: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = |
| property_id == CSSPropertyWebkitMaskPositionY |
| ? &style.MaskLayers() |
| : &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(curr_layer->YPosition(), style)); |
| return list; |
| } |
| case CSSPropertyBorderCollapse: |
| if (style.BorderCollapse() == EBorderCollapse::kCollapse) |
| return CSSIdentifierValue::Create(CSSValueCollapse); |
| return CSSIdentifierValue::Create(CSSValueSeparate); |
| case CSSPropertyBorderSpacing: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append( |
| *ZoomAdjustedPixelValue(style.HorizontalBorderSpacing(), style)); |
| list->Append( |
| *ZoomAdjustedPixelValue(style.VerticalBorderSpacing(), style)); |
| return list; |
| } |
| case CSSPropertyWebkitBorderHorizontalSpacing: |
| return ZoomAdjustedPixelValue(style.HorizontalBorderSpacing(), style); |
| case CSSPropertyWebkitBorderVerticalSpacing: |
| return ZoomAdjustedPixelValue(style.VerticalBorderSpacing(), style); |
| case CSSPropertyBorderImageSource: |
| if (style.BorderImageSource()) |
| return style.BorderImageSource()->ComputedCSSValue(); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyBorderTopColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyBorderTopColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.BorderTopColor()); |
| case CSSPropertyBorderRightColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyBorderRightColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.BorderRightColor()); |
| case CSSPropertyBorderBottomColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyBorderBottomColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.BorderBottomColor()); |
| case CSSPropertyBorderLeftColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyBorderLeftColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.BorderLeftColor()); |
| case CSSPropertyBorderTopStyle: |
| return CSSIdentifierValue::Create(style.BorderTopStyle()); |
| case CSSPropertyBorderRightStyle: |
| return CSSIdentifierValue::Create(style.BorderRightStyle()); |
| case CSSPropertyBorderBottomStyle: |
| return CSSIdentifierValue::Create(style.BorderBottomStyle()); |
| case CSSPropertyBorderLeftStyle: |
| return CSSIdentifierValue::Create(style.BorderLeftStyle()); |
| case CSSPropertyBorderTopWidth: |
| return ZoomAdjustedPixelValue(style.BorderTopWidth(), style); |
| case CSSPropertyBorderRightWidth: |
| return ZoomAdjustedPixelValue(style.BorderRightWidth(), style); |
| case CSSPropertyBorderBottomWidth: |
| return ZoomAdjustedPixelValue(style.BorderBottomWidth(), style); |
| case CSSPropertyBorderLeftWidth: |
| return ZoomAdjustedPixelValue(style.BorderLeftWidth(), style); |
| case CSSPropertyBottom: |
| return ValueForPositionOffset(style, CSSPropertyBottom, layout_object); |
| case CSSPropertyWebkitBoxAlign: |
| return CSSIdentifierValue::Create(style.BoxAlign()); |
| case CSSPropertyWebkitBoxDecorationBreak: |
| if (style.BoxDecorationBreak() == EBoxDecorationBreak::kSlice) |
| return CSSIdentifierValue::Create(CSSValueSlice); |
| return CSSIdentifierValue::Create(CSSValueClone); |
| case CSSPropertyWebkitBoxDirection: |
| return CSSIdentifierValue::Create(style.BoxDirection()); |
| case CSSPropertyWebkitBoxFlex: |
| return CSSPrimitiveValue::Create(style.BoxFlex(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyWebkitBoxFlexGroup: |
| return CSSPrimitiveValue::Create(style.BoxFlexGroup(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyWebkitBoxLines: |
| return CSSIdentifierValue::Create(style.BoxLines()); |
| case CSSPropertyWebkitBoxOrdinalGroup: |
| return CSSPrimitiveValue::Create(style.BoxOrdinalGroup(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyWebkitBoxOrient: |
| return CSSIdentifierValue::Create(style.BoxOrient()); |
| case CSSPropertyWebkitBoxPack: |
| return CSSIdentifierValue::Create(style.BoxPack()); |
| case CSSPropertyWebkitBoxReflect: |
| return ValueForReflection(style.BoxReflect(), style); |
| case CSSPropertyBoxShadow: |
| return ValueForShadowList(style.BoxShadow(), style, true); |
| case CSSPropertyCaptionSide: |
| return CSSIdentifierValue::Create(style.CaptionSide()); |
| case CSSPropertyCaretColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyCaretColor).Rgb()) |
| : CurrentColorOrValidColor( |
| style, style.CaretColor().IsAutoColor() |
| ? StyleColor::CurrentColor() |
| : style.CaretColor().ToStyleColor()); |
| case CSSPropertyClear: |
| return CSSIdentifierValue::Create(style.Clear()); |
| case CSSPropertyColor: |
| return CSSColorValue::Create( |
| allow_visited_style |
| ? style.VisitedDependentColor(CSSPropertyColor).Rgb() |
| : style.GetColor().Rgb()); |
| case CSSPropertyWebkitPrintColorAdjust: |
| return CSSIdentifierValue::Create(style.PrintColorAdjust()); |
| case CSSPropertyColumnCount: |
| if (style.HasAutoColumnCount()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return CSSPrimitiveValue::Create(style.ColumnCount(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyColumnFill: |
| return CSSIdentifierValue::Create(style.GetColumnFill()); |
| case CSSPropertyColumnGap: |
| if (style.HasNormalColumnGap()) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| return ZoomAdjustedPixelValue(style.ColumnGap(), style); |
| case CSSPropertyColumnRuleColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyOutlineColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.ColumnRuleColor()); |
| case CSSPropertyColumnRuleStyle: |
| return CSSIdentifierValue::Create(style.ColumnRuleStyle()); |
| case CSSPropertyColumnRuleWidth: |
| return ZoomAdjustedPixelValue(style.ColumnRuleWidth(), style); |
| case CSSPropertyColumnSpan: |
| return CSSIdentifierValue::Create(style.GetColumnSpan() ? CSSValueAll |
| : CSSValueNone); |
| case CSSPropertyWebkitColumnBreakAfter: |
| return ValueForWebkitColumnBreakBetween(style.BreakAfter()); |
| case CSSPropertyWebkitColumnBreakBefore: |
| return ValueForWebkitColumnBreakBetween(style.BreakBefore()); |
| case CSSPropertyWebkitColumnBreakInside: |
| return ValueForWebkitColumnBreakInside(style.BreakInside()); |
| case CSSPropertyColumnWidth: |
| if (style.HasAutoColumnWidth()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValue(style.ColumnWidth(), style); |
| case CSSPropertyTabSize: |
| return CSSPrimitiveValue::Create( |
| style.GetTabSize().GetPixelSize(1.0), |
| style.GetTabSize().IsSpaces() ? CSSPrimitiveValue::UnitType::kNumber |
| : CSSPrimitiveValue::UnitType::kPixels); |
| case CSSPropertyTextSizeAdjust: |
| if (style.GetTextSizeAdjust().IsAuto()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return CSSPrimitiveValue::Create( |
| style.GetTextSizeAdjust().Multiplier() * 100, |
| CSSPrimitiveValue::UnitType::kPercentage); |
| case CSSPropertyCursor: { |
| CSSValueList* list = nullptr; |
| CursorList* cursors = style.Cursors(); |
| if (cursors && cursors->size() > 0) { |
| list = CSSValueList::CreateCommaSeparated(); |
| for (const CursorData& cursor : *cursors) { |
| if (StyleImage* image = cursor.GetImage()) { |
| list->Append(*CSSCursorImageValue::Create( |
| *image->ComputedCSSValue(), cursor.HotSpotSpecified(), |
| cursor.HotSpot())); |
| } |
| } |
| } |
| CSSValue* value = CSSIdentifierValue::Create(style.Cursor()); |
| if (list) { |
| list->Append(*value); |
| return list; |
| } |
| return value; |
| } |
| case CSSPropertyDirection: |
| return CSSIdentifierValue::Create(style.Direction()); |
| case CSSPropertyDisplay: |
| return CSSIdentifierValue::Create(style.Display()); |
| case CSSPropertyEmptyCells: |
| return CSSIdentifierValue::Create(style.EmptyCells()); |
| case CSSPropertyPlaceContent: { |
| // TODO (jfernandez): The spec states that we should return the specified |
| // value. |
| return ValuesForShorthandProperty(placeContentShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| } |
| case CSSPropertyPlaceItems: { |
| // TODO (jfernandez): The spec states that we should return the specified |
| // value. |
| return ValuesForShorthandProperty(placeItemsShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| } |
| case CSSPropertyPlaceSelf: { |
| // TODO (jfernandez): The spec states that we should return the specified |
| // value. |
| return ValuesForShorthandProperty(placeSelfShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| } |
| case CSSPropertyAlignContent: |
| return ValueForContentPositionAndDistributionWithOverflowAlignment( |
| style.AlignContent(), CSSValueStretch); |
| case CSSPropertyAlignItems: |
| return ValueForItemPositionWithOverflowAlignment(style.AlignItems()); |
| case CSSPropertyAlignSelf: |
| return ValueForItemPositionWithOverflowAlignment(style.AlignSelf()); |
| case CSSPropertyFlex: |
| return ValuesForShorthandProperty(flexShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| case CSSPropertyFlexBasis: |
| return ZoomAdjustedPixelValueForLength(style.FlexBasis(), style); |
| case CSSPropertyFlexDirection: |
| return CSSIdentifierValue::Create(style.FlexDirection()); |
| case CSSPropertyFlexFlow: |
| return ValuesForShorthandProperty(flexFlowShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyFlexGrow: |
| return CSSPrimitiveValue::Create(style.FlexGrow(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyFlexShrink: |
| return CSSPrimitiveValue::Create(style.FlexShrink(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyFlexWrap: |
| return CSSIdentifierValue::Create(style.FlexWrap()); |
| case CSSPropertyJustifyContent: |
| return ValueForContentPositionAndDistributionWithOverflowAlignment( |
| style.JustifyContent(), CSSValueFlexStart); |
| case CSSPropertyOrder: |
| return CSSPrimitiveValue::Create(style.Order(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyFloat: |
| if (style.Display() != EDisplay::kNone && style.HasOutOfFlowPosition()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return CSSIdentifierValue::Create(style.Floating()); |
| case CSSPropertyFont: |
| return ValueForFont(style); |
| case CSSPropertyFontFamily: |
| return ValueForFontFamily(style); |
| case CSSPropertyFontSize: |
| return ValueForFontSize(style); |
| case CSSPropertyFontSizeAdjust: |
| if (style.HasFontSizeAdjust()) |
| return CSSPrimitiveValue::Create(style.FontSizeAdjust(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyFontStretch: |
| return ValueForFontStretch(style); |
| case CSSPropertyFontStyle: |
| return ValueForFontStyle(style); |
| case CSSPropertyFontVariant: |
| return ValuesForFontVariantProperty(style, layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyFontWeight: |
| return ValueForFontWeight(style); |
| case CSSPropertyFontFeatureSettings: { |
| const FontFeatureSettings* feature_settings = |
| style.GetFontDescription().FeatureSettings(); |
| if (!feature_settings || !feature_settings->size()) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (unsigned i = 0; i < feature_settings->size(); ++i) { |
| const FontFeature& feature = feature_settings->at(i); |
| CSSFontFeatureValue* feature_value = |
| CSSFontFeatureValue::Create(feature.Tag(), feature.Value()); |
| list->Append(*feature_value); |
| } |
| return list; |
| } |
| case CSSPropertyFontVariationSettings: { |
| DCHECK(RuntimeEnabledFeatures::cssVariableFontsEnabled()); |
| const FontVariationSettings* variation_settings = |
| style.GetFontDescription().VariationSettings(); |
| if (!variation_settings || !variation_settings->size()) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (unsigned i = 0; i < variation_settings->size(); ++i) { |
| const FontVariationAxis& variation_axis = variation_settings->at(i); |
| CSSFontVariationValue* variation_value = CSSFontVariationValue::Create( |
| variation_axis.Tag(), variation_axis.Value()); |
| list->Append(*variation_value); |
| } |
| return list; |
| } |
| case CSSPropertyGridAutoFlow: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| switch (style.GetGridAutoFlow()) { |
| case kAutoFlowRow: |
| case kAutoFlowRowDense: |
| list->Append(*CSSIdentifierValue::Create(CSSValueRow)); |
| break; |
| case kAutoFlowColumn: |
| case kAutoFlowColumnDense: |
| list->Append(*CSSIdentifierValue::Create(CSSValueColumn)); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| |
| switch (style.GetGridAutoFlow()) { |
| case kAutoFlowRowDense: |
| case kAutoFlowColumnDense: |
| list->Append(*CSSIdentifierValue::Create(CSSValueDense)); |
| break; |
| default: |
| // Do nothing. |
| break; |
| } |
| |
| return list; |
| } |
| // Specs mention that getComputedStyle() should return the used value of the |
| // property instead of the computed one for grid-template-{rows|columns} but |
| // not for the grid-auto-{rows|columns} as things like grid-auto-columns: |
| // 2fr; cannot be resolved to a value in pixels as the '2fr' means very |
| // different things depending on the size of the explicit grid or the number |
| // of implicit tracks added to the grid. See |
| // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html |
| case CSSPropertyGridAutoColumns: |
| return ValueForGridTrackSizeList(kForColumns, style); |
| case CSSPropertyGridAutoRows: |
| return ValueForGridTrackSizeList(kForRows, style); |
| |
| case CSSPropertyGridTemplateColumns: |
| return ValueForGridTrackList(kForColumns, layout_object, style); |
| case CSSPropertyGridTemplateRows: |
| return ValueForGridTrackList(kForRows, layout_object, style); |
| |
| case CSSPropertyGridColumnStart: |
| return ValueForGridPosition(style.GridColumnStart()); |
| case CSSPropertyGridColumnEnd: |
| return ValueForGridPosition(style.GridColumnEnd()); |
| case CSSPropertyGridRowStart: |
| return ValueForGridPosition(style.GridRowStart()); |
| case CSSPropertyGridRowEnd: |
| return ValueForGridPosition(style.GridRowEnd()); |
| case CSSPropertyGridColumn: |
| return ValuesForGridShorthand(gridColumnShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| case CSSPropertyGridRow: |
| return ValuesForGridShorthand(gridRowShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| case CSSPropertyGridArea: |
| return ValuesForGridShorthand(gridAreaShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| case CSSPropertyGridTemplate: |
| return ValuesForGridShorthand(gridTemplateShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyGrid: |
| return ValuesForGridShorthand(gridShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| case CSSPropertyGridTemplateAreas: |
| if (!style.NamedGridAreaRowCount()) { |
| DCHECK(!style.NamedGridAreaColumnCount()); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| } |
| |
| return CSSGridTemplateAreasValue::Create( |
| style.NamedGridArea(), style.NamedGridAreaRowCount(), |
| style.NamedGridAreaColumnCount()); |
| case CSSPropertyGridColumnGap: |
| return ZoomAdjustedPixelValueForLength(style.GridColumnGap(), style); |
| case CSSPropertyGridRowGap: |
| return ZoomAdjustedPixelValueForLength(style.GridRowGap(), style); |
| case CSSPropertyGridGap: |
| return ValuesForShorthandProperty(gridGapShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| |
| case CSSPropertyHeight: |
| if (layout_object) { |
| if (!WidthOrHeightPropertyAppliesToObject(*layout_object)) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValue(SizingBox(layout_object).Height(), style); |
| } |
| return ZoomAdjustedPixelValueForLength(style.Height(), style); |
| case CSSPropertyWebkitHighlight: |
| if (style.Highlight() == g_null_atom) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return CSSStringValue::Create(style.Highlight()); |
| case CSSPropertyHyphens: |
| return CSSIdentifierValue::Create(style.GetHyphens()); |
| case CSSPropertyWebkitHyphenateCharacter: |
| if (style.HyphenationString().IsNull()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return CSSStringValue::Create(style.HyphenationString()); |
| case CSSPropertyImageRendering: |
| return CSSIdentifierValue::Create(style.ImageRendering()); |
| case CSSPropertyImageOrientation: |
| if (style.RespectImageOrientation() == kRespectImageOrientation) |
| return CSSIdentifierValue::Create(CSSValueFromImage); |
| return CSSPrimitiveValue::Create(0, |
| CSSPrimitiveValue::UnitType::kDegrees); |
| case CSSPropertyIsolation: |
| return CSSIdentifierValue::Create(style.Isolation()); |
| case CSSPropertyJustifyItems: |
| return ValueForItemPositionWithOverflowAlignment(style.JustifyItems()); |
| case CSSPropertyJustifySelf: |
| return ValueForItemPositionWithOverflowAlignment(style.JustifySelf()); |
| case CSSPropertyLeft: |
| return ValueForPositionOffset(style, CSSPropertyLeft, layout_object); |
| case CSSPropertyLetterSpacing: |
| if (!style.LetterSpacing()) |
| return CSSIdentifierValue::Create(CSSValueNormal); |
| return ZoomAdjustedPixelValue(style.LetterSpacing(), style); |
| case CSSPropertyWebkitLineClamp: |
| if (style.LineClamp().IsNone()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return CSSPrimitiveValue::Create( |
| style.LineClamp().Value(), |
| style.LineClamp().IsPercentage() |
| ? CSSPrimitiveValue::UnitType::kPercentage |
| : CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyLineHeight: |
| return ValueForLineHeight(style); |
| case CSSPropertyLineHeightStep: |
| return ZoomAdjustedPixelValue(style.LineHeightStep(), style); |
| case CSSPropertyListStyleImage: |
| if (style.ListStyleImage()) |
| return style.ListStyleImage()->ComputedCSSValue(); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyListStylePosition: |
| return CSSIdentifierValue::Create(style.ListStylePosition()); |
| case CSSPropertyListStyleType: |
| return CSSIdentifierValue::Create(style.ListStyleType()); |
| case CSSPropertyWebkitLocale: |
| if (style.Locale().IsNull()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return CSSStringValue::Create(style.Locale()); |
| case CSSPropertyMarginTop: { |
| Length margin_top = style.MarginTop(); |
| if (margin_top.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(margin_top, style); |
| return ZoomAdjustedPixelValue(ToLayoutBox(layout_object)->MarginTop(), |
| style); |
| } |
| case CSSPropertyMarginRight: { |
| Length margin_right = style.MarginRight(); |
| if (margin_right.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(margin_right, style); |
| float value; |
| if (margin_right.IsPercentOrCalc()) { |
| // LayoutBox gives a marginRight() that is the distance between the |
| // right-edge of the child box and the right-edge of the containing box, |
| // when display == EDisplay::kBlock. Let's calculate the absolute value |
| // of the specified margin-right % instead of relying on LayoutBox's |
| // marginRight() value. |
| value = MinimumValueForLength( |
| margin_right, ToLayoutBox(layout_object) |
| ->ContainingBlockLogicalWidthForContent()) |
| .ToFloat(); |
| } else { |
| value = ToLayoutBox(layout_object)->MarginRight().ToFloat(); |
| } |
| return ZoomAdjustedPixelValue(value, style); |
| } |
| case CSSPropertyMarginBottom: { |
| Length margin_bottom = style.MarginBottom(); |
| if (margin_bottom.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(margin_bottom, style); |
| return ZoomAdjustedPixelValue(ToLayoutBox(layout_object)->MarginBottom(), |
| style); |
| } |
| case CSSPropertyMarginLeft: { |
| Length margin_left = style.MarginLeft(); |
| if (margin_left.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(margin_left, style); |
| return ZoomAdjustedPixelValue(ToLayoutBox(layout_object)->MarginLeft(), |
| style); |
| } |
| case CSSPropertyWebkitUserModify: |
| return CSSIdentifierValue::Create(style.UserModify()); |
| case CSSPropertyMaxHeight: { |
| const Length& max_height = style.MaxHeight(); |
| if (max_height.IsMaxSizeNone()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return ZoomAdjustedPixelValueForLength(max_height, style); |
| } |
| case CSSPropertyMaxWidth: { |
| const Length& max_width = style.MaxWidth(); |
| if (max_width.IsMaxSizeNone()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return ZoomAdjustedPixelValueForLength(max_width, style); |
| } |
| case CSSPropertyMinHeight: |
| if (style.MinHeight().IsAuto()) { |
| Node* parent = styled_node->parentNode(); |
| if (IsFlexOrGrid(parent ? parent->EnsureComputedStyle() : nullptr)) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValue(0, style); |
| } |
| return ZoomAdjustedPixelValueForLength(style.MinHeight(), style); |
| case CSSPropertyMinWidth: |
| if (style.MinWidth().IsAuto()) { |
| Node* parent = styled_node->parentNode(); |
| if (IsFlexOrGrid(parent ? parent->EnsureComputedStyle() : nullptr)) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValue(0, style); |
| } |
| return ZoomAdjustedPixelValueForLength(style.MinWidth(), style); |
| case CSSPropertyObjectFit: |
| return CSSIdentifierValue::Create(style.GetObjectFit()); |
| case CSSPropertyObjectPosition: |
| return CSSValuePair::Create( |
| ZoomAdjustedPixelValueForLength(style.ObjectPosition().X(), style), |
| ZoomAdjustedPixelValueForLength(style.ObjectPosition().Y(), style), |
| CSSValuePair::kKeepIdenticalValues); |
| case CSSPropertyOpacity: |
| return CSSPrimitiveValue::Create(style.Opacity(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyOrphans: |
| return CSSPrimitiveValue::Create(style.Orphans(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyOutlineColor: |
| return allow_visited_style |
| ? CSSColorValue::Create( |
| style.VisitedDependentColor(CSSPropertyOutlineColor) |
| .Rgb()) |
| : CurrentColorOrValidColor(style, style.OutlineColor()); |
| case CSSPropertyOutlineOffset: |
| return ZoomAdjustedPixelValue(style.OutlineOffset(), style); |
| case CSSPropertyOutlineStyle: |
| if (style.OutlineStyleIsAuto()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return CSSIdentifierValue::Create(style.OutlineStyle()); |
| case CSSPropertyOutlineWidth: |
| return ZoomAdjustedPixelValue(style.OutlineWidth(), style); |
| case CSSPropertyOverflow: |
| if (style.OverflowX() == style.OverflowY()) |
| return CSSIdentifierValue::Create(style.OverflowX()); |
| return nullptr; |
| case CSSPropertyOverflowAnchor: |
| return CSSIdentifierValue::Create(style.OverflowAnchor()); |
| case CSSPropertyOverflowWrap: |
| return CSSIdentifierValue::Create(style.OverflowWrap()); |
| case CSSPropertyOverflowX: |
| return CSSIdentifierValue::Create(style.OverflowX()); |
| case CSSPropertyOverflowY: |
| return CSSIdentifierValue::Create(style.OverflowY()); |
| case CSSPropertyPaddingTop: { |
| Length padding_top = style.PaddingTop(); |
| if (padding_top.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(padding_top, style); |
| return ZoomAdjustedPixelValue( |
| ToLayoutBox(layout_object)->ComputedCSSPaddingTop(), style); |
| } |
| case CSSPropertyPaddingRight: { |
| Length padding_right = style.PaddingRight(); |
| if (padding_right.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(padding_right, style); |
| return ZoomAdjustedPixelValue( |
| ToLayoutBox(layout_object)->ComputedCSSPaddingRight(), style); |
| } |
| case CSSPropertyPaddingBottom: { |
| Length padding_bottom = style.PaddingBottom(); |
| if (padding_bottom.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(padding_bottom, style); |
| return ZoomAdjustedPixelValue( |
| ToLayoutBox(layout_object)->ComputedCSSPaddingBottom(), style); |
| } |
| case CSSPropertyPaddingLeft: { |
| Length padding_left = style.PaddingLeft(); |
| if (padding_left.IsFixed() || !layout_object || !layout_object->IsBox()) |
| return ZoomAdjustedPixelValueForLength(padding_left, style); |
| return ZoomAdjustedPixelValue( |
| ToLayoutBox(layout_object)->ComputedCSSPaddingLeft(), style); |
| } |
| case CSSPropertyBreakAfter: |
| return CSSIdentifierValue::Create(style.BreakAfter()); |
| case CSSPropertyBreakBefore: |
| return CSSIdentifierValue::Create(style.BreakBefore()); |
| case CSSPropertyBreakInside: |
| return CSSIdentifierValue::Create(style.BreakInside()); |
| case CSSPropertyPageBreakAfter: |
| return ValueForPageBreakBetween(style.BreakAfter()); |
| case CSSPropertyPageBreakBefore: |
| return ValueForPageBreakBetween(style.BreakBefore()); |
| case CSSPropertyPageBreakInside: |
| return ValueForPageBreakInside(style.BreakInside()); |
| case CSSPropertyPosition: |
| return CSSIdentifierValue::Create(style.GetPosition()); |
| case CSSPropertyQuotes: |
| if (!style.Quotes()) { |
| // TODO(ramya.v): We should return the quote values that we're actually |
| // using. |
| return nullptr; |
| } |
| if (style.Quotes()->size()) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (int i = 0; i < style.Quotes()->size(); i++) { |
| list->Append( |
| *CSSStringValue::Create(style.Quotes()->GetOpenQuote(i))); |
| list->Append( |
| *CSSStringValue::Create(style.Quotes()->GetCloseQuote(i))); |
| } |
| return list; |
| } |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyRight: |
| return ValueForPositionOffset(style, CSSPropertyRight, layout_object); |
| case CSSPropertyWebkitRubyPosition: |
| return CSSIdentifierValue::Create(style.GetRubyPosition()); |
| case CSSPropertyScrollBehavior: |
| return CSSIdentifierValue::Create(style.GetScrollBehavior()); |
| case CSSPropertyTableLayout: |
| return CSSIdentifierValue::Create(style.TableLayout()); |
| case CSSPropertyTextAlign: |
| return CSSIdentifierValue::Create(style.GetTextAlign()); |
| case CSSPropertyTextAlignLast: |
| return CSSIdentifierValue::Create(style.TextAlignLast()); |
| case CSSPropertyTextDecoration: |
| if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) |
| return ValuesForShorthandProperty(textDecorationShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| // Fall through. |
| case CSSPropertyTextDecorationLine: |
| return RenderTextDecorationFlagsToCSSValue(style.GetTextDecoration()); |
| case CSSPropertyTextDecorationSkip: |
| return ValueForTextDecorationSkip(style.GetTextDecorationSkip()); |
| case CSSPropertyTextDecorationStyle: |
| return ValueForTextDecorationStyle(style.GetTextDecorationStyle()); |
| case CSSPropertyTextDecorationColor: |
| return CurrentColorOrValidColor(style, style.TextDecorationColor()); |
| case CSSPropertyTextJustify: |
| return CSSIdentifierValue::Create(style.GetTextJustify()); |
| case CSSPropertyTextUnderlinePosition: |
| return CSSIdentifierValue::Create(style.GetTextUnderlinePosition()); |
| case CSSPropertyWebkitTextDecorationsInEffect: |
| return RenderTextDecorationFlagsToCSSValue( |
| style.TextDecorationsInEffect()); |
| case CSSPropertyWebkitTextFillColor: |
| return CurrentColorOrValidColor(style, style.TextFillColor()); |
| case CSSPropertyWebkitTextEmphasisColor: |
| return CurrentColorOrValidColor(style, style.TextEmphasisColor()); |
| case CSSPropertyWebkitTextEmphasisPosition: |
| return CSSIdentifierValue::Create(style.GetTextEmphasisPosition()); |
| case CSSPropertyWebkitTextEmphasisStyle: |
| switch (style.GetTextEmphasisMark()) { |
| case TextEmphasisMark::kNone: |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case TextEmphasisMark::kCustom: |
| return CSSStringValue::Create(style.TextEmphasisCustomMark()); |
| case TextEmphasisMark::kAuto: |
| NOTREACHED(); |
| // Fall through |
| case TextEmphasisMark::kDot: |
| case TextEmphasisMark::kCircle: |
| case TextEmphasisMark::kDoubleCircle: |
| case TextEmphasisMark::kTriangle: |
| case TextEmphasisMark::kSesame: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append( |
| *CSSIdentifierValue::Create(style.GetTextEmphasisFill())); |
| list->Append( |
| *CSSIdentifierValue::Create(style.GetTextEmphasisMark())); |
| return list; |
| } |
| } |
| case CSSPropertyTextIndent: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*ZoomAdjustedPixelValueForLength(style.TextIndent(), style)); |
| if (RuntimeEnabledFeatures::css3TextEnabled() && |
| (style.GetTextIndentLine() == TextIndentLine::kEachLine || |
| style.GetTextIndentType() == TextIndentType::kHanging)) { |
| if (style.GetTextIndentLine() == TextIndentLine::kEachLine) |
| list->Append(*CSSIdentifierValue::Create(CSSValueEachLine)); |
| if (style.GetTextIndentType() == TextIndentType::kHanging) |
| list->Append(*CSSIdentifierValue::Create(CSSValueHanging)); |
| } |
| return list; |
| } |
| case CSSPropertyTextShadow: |
| return ValueForShadowList(style.TextShadow(), style, false); |
| case CSSPropertyTextRendering: |
| return CSSIdentifierValue::Create( |
| style.GetFontDescription().TextRendering()); |
| case CSSPropertyTextOverflow: |
| if (style.GetTextOverflow()) |
| return CSSIdentifierValue::Create(CSSValueEllipsis); |
| return CSSIdentifierValue::Create(CSSValueClip); |
| case CSSPropertyWebkitTextSecurity: |
| return CSSIdentifierValue::Create(style.TextSecurity()); |
| case CSSPropertyWebkitTextStrokeColor: |
| return CurrentColorOrValidColor(style, style.TextStrokeColor()); |
| case CSSPropertyWebkitTextStrokeWidth: |
| return ZoomAdjustedPixelValue(style.TextStrokeWidth(), style); |
| case CSSPropertyTextTransform: |
| return CSSIdentifierValue::Create(style.TextTransform()); |
| case CSSPropertyTop: |
| return ValueForPositionOffset(style, CSSPropertyTop, layout_object); |
| case CSSPropertyTouchAction: |
| return TouchActionFlagsToCSSValue(style.GetTouchAction()); |
| case CSSPropertyUnicodeBidi: |
| return CSSIdentifierValue::Create(style.GetUnicodeBidi()); |
| case CSSPropertyVerticalAlign: |
| switch (style.VerticalAlign()) { |
| case EVerticalAlign::kBaseline: |
| return CSSIdentifierValue::Create(CSSValueBaseline); |
| case EVerticalAlign::kMiddle: |
| return CSSIdentifierValue::Create(CSSValueMiddle); |
| case EVerticalAlign::kSub: |
| return CSSIdentifierValue::Create(CSSValueSub); |
| case EVerticalAlign::kSuper: |
| return CSSIdentifierValue::Create(CSSValueSuper); |
| case EVerticalAlign::kTextTop: |
| return CSSIdentifierValue::Create(CSSValueTextTop); |
| case EVerticalAlign::kTextBottom: |
| return CSSIdentifierValue::Create(CSSValueTextBottom); |
| case EVerticalAlign::kTop: |
| return CSSIdentifierValue::Create(CSSValueTop); |
| case EVerticalAlign::kBottom: |
| return CSSIdentifierValue::Create(CSSValueBottom); |
| case EVerticalAlign::kBaselineMiddle: |
| return CSSIdentifierValue::Create(CSSValueWebkitBaselineMiddle); |
| case EVerticalAlign::kLength: |
| return ZoomAdjustedPixelValueForLength(style.GetVerticalAlignLength(), |
| style); |
| } |
| NOTREACHED(); |
| return nullptr; |
| case CSSPropertyVisibility: |
| return CSSIdentifierValue::Create(style.Visibility()); |
| case CSSPropertyWhiteSpace: |
| return CSSIdentifierValue::Create(style.WhiteSpace()); |
| case CSSPropertyWidows: |
| return CSSPrimitiveValue::Create(style.Widows(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyWidth: |
| if (layout_object) { |
| if (!WidthOrHeightPropertyAppliesToObject(*layout_object)) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return ZoomAdjustedPixelValue(SizingBox(layout_object).Width(), style); |
| } |
| return ZoomAdjustedPixelValueForLength(style.Width(), style); |
| case CSSPropertyWillChange: |
| return ValueForWillChange(style.WillChangeProperties(), |
| style.WillChangeContents(), |
| style.WillChangeScrollPosition()); |
| case CSSPropertyWordBreak: |
| return CSSIdentifierValue::Create(style.WordBreak()); |
| case CSSPropertyWordSpacing: |
| return ZoomAdjustedPixelValue(style.WordSpacing(), style); |
| case CSSPropertyWordWrap: |
| return CSSIdentifierValue::Create(style.OverflowWrap()); |
| case CSSPropertyWebkitLineBreak: |
| return CSSIdentifierValue::Create(style.GetLineBreak()); |
| case CSSPropertyResize: |
| return CSSIdentifierValue::Create(style.Resize()); |
| case CSSPropertyFontKerning: |
| return CSSIdentifierValue::Create( |
| style.GetFontDescription().GetKerning()); |
| case CSSPropertyWebkitFontSmoothing: |
| return CSSIdentifierValue::Create( |
| style.GetFontDescription().FontSmoothing()); |
| case CSSPropertyFontVariantLigatures: |
| return ValueForFontVariantLigatures(style); |
| case CSSPropertyFontVariantCaps: |
| return ValueForFontVariantCaps(style); |
| case CSSPropertyFontVariantNumeric: |
| return ValueForFontVariantNumeric(style); |
| case CSSPropertyZIndex: |
| if (style.HasAutoZIndex() || !style.IsStackingContext()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| return CSSPrimitiveValue::Create(style.ZIndex(), |
| CSSPrimitiveValue::UnitType::kInteger); |
| case CSSPropertyZoom: |
| return CSSPrimitiveValue::Create(style.Zoom(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyBoxSizing: |
| if (style.BoxSizing() == EBoxSizing::kContentBox) |
| return CSSIdentifierValue::Create(CSSValueContentBox); |
| return CSSIdentifierValue::Create(CSSValueBorderBox); |
| case CSSPropertyWebkitAppRegion: |
| return CSSIdentifierValue::Create(style.GetDraggableRegionMode() == |
| kDraggableRegionDrag |
| ? CSSValueDrag |
| : CSSValueNoDrag); |
| case CSSPropertyAnimationDelay: |
| return ValueForAnimationDelay(style.Animations()); |
| case CSSPropertyAnimationDirection: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (size_t i = 0; i < animation_data->DirectionList().size(); ++i) |
| list->Append( |
| *ValueForAnimationDirection(animation_data->DirectionList()[i])); |
| } else { |
| list->Append(*CSSIdentifierValue::Create(CSSValueNormal)); |
| } |
| return list; |
| } |
| case CSSPropertyAnimationDuration: |
| return ValueForAnimationDuration(style.Animations()); |
| case CSSPropertyAnimationFillMode: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (size_t i = 0; i < animation_data->FillModeList().size(); ++i) |
| list->Append( |
| *ValueForAnimationFillMode(animation_data->FillModeList()[i])); |
| } else { |
| list->Append(*CSSIdentifierValue::Create(CSSValueNone)); |
| } |
| return list; |
| } |
| case CSSPropertyAnimationIterationCount: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (size_t i = 0; i < animation_data->IterationCountList().size(); ++i) |
| list->Append(*ValueForAnimationIterationCount( |
| animation_data->IterationCountList()[i])); |
| } else { |
| list->Append(*CSSPrimitiveValue::Create( |
| CSSAnimationData::InitialIterationCount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| } |
| return list; |
| } |
| case CSSPropertyAnimationName: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (size_t i = 0; i < animation_data->NameList().size(); ++i) |
| list->Append( |
| *CSSCustomIdentValue::Create(animation_data->NameList()[i])); |
| } else { |
| list->Append(*CSSIdentifierValue::Create(CSSValueNone)); |
| } |
| return list; |
| } |
| case CSSPropertyAnimationPlayState: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (size_t i = 0; i < animation_data->PlayStateList().size(); ++i) |
| list->Append( |
| *ValueForAnimationPlayState(animation_data->PlayStateList()[i])); |
| } else { |
| list->Append(*CSSIdentifierValue::Create(CSSValueRunning)); |
| } |
| return list; |
| } |
| case CSSPropertyAnimationTimingFunction: |
| return ValueForAnimationTimingFunction(style.Animations()); |
| case CSSPropertyAnimation: { |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| CSSValueList* animations_list = CSSValueList::CreateCommaSeparated(); |
| for (size_t i = 0; i < animation_data->NameList().size(); ++i) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append( |
| *CSSCustomIdentValue::Create(animation_data->NameList()[i])); |
| list->Append(*CSSPrimitiveValue::Create( |
| CSSTimingData::GetRepeated(animation_data->DurationList(), i), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| list->Append(*CreateTimingFunctionValue( |
| CSSTimingData::GetRepeated(animation_data->TimingFunctionList(), |
| i) |
| .Get())); |
| list->Append(*CSSPrimitiveValue::Create( |
| CSSTimingData::GetRepeated(animation_data->DelayList(), i), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| list->Append( |
| *ValueForAnimationIterationCount(CSSTimingData::GetRepeated( |
| animation_data->IterationCountList(), i))); |
| list->Append(*ValueForAnimationDirection( |
| CSSTimingData::GetRepeated(animation_data->DirectionList(), i))); |
| list->Append(*ValueForAnimationFillMode( |
| CSSTimingData::GetRepeated(animation_data->FillModeList(), i))); |
| list->Append(*ValueForAnimationPlayState( |
| CSSTimingData::GetRepeated(animation_data->PlayStateList(), i))); |
| animations_list->Append(*list); |
| } |
| return animations_list; |
| } |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| // animation-name default value. |
| list->Append(*CSSIdentifierValue::Create(CSSValueNone)); |
| list->Append( |
| *CSSPrimitiveValue::Create(CSSAnimationData::InitialDuration(), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| list->Append(*CreateTimingFunctionValue( |
| CSSAnimationData::InitialTimingFunction().Get())); |
| list->Append( |
| *CSSPrimitiveValue::Create(CSSAnimationData::InitialDelay(), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| list->Append( |
| *CSSPrimitiveValue::Create(CSSAnimationData::InitialIterationCount(), |
| CSSPrimitiveValue::UnitType::kNumber)); |
| list->Append( |
| *ValueForAnimationDirection(CSSAnimationData::InitialDirection())); |
| list->Append( |
| *ValueForAnimationFillMode(CSSAnimationData::InitialFillMode())); |
| // Initial animation-play-state. |
| list->Append(*CSSIdentifierValue::Create(CSSValueRunning)); |
| return list; |
| } |
| case CSSPropertyWebkitAppearance: |
| return CSSIdentifierValue::Create(style.Appearance()); |
| case CSSPropertyBackfaceVisibility: |
| return CSSIdentifierValue::Create( |
| (style.BackfaceVisibility() == kBackfaceVisibilityHidden) |
| ? CSSValueHidden |
| : CSSValueVisible); |
| case CSSPropertyWebkitBorderImage: |
| return ValueForNinePieceImage(style.BorderImage(), style); |
| case CSSPropertyBorderImageOutset: |
| return ValueForNinePieceImageQuad(style.BorderImage().Outset(), style); |
| case CSSPropertyBorderImageRepeat: |
| return ValueForNinePieceImageRepeat(style.BorderImage()); |
| case CSSPropertyBorderImageSlice: |
| return ValueForNinePieceImageSlice(style.BorderImage()); |
| case CSSPropertyBorderImageWidth: |
| return ValueForNinePieceImageQuad(style.BorderImage().BorderSlices(), |
| style); |
| case CSSPropertyWebkitMaskBoxImage: |
| return ValueForNinePieceImage(style.MaskBoxImage(), style); |
| case CSSPropertyWebkitMaskBoxImageOutset: |
| return ValueForNinePieceImageQuad(style.MaskBoxImage().Outset(), style); |
| case CSSPropertyWebkitMaskBoxImageRepeat: |
| return ValueForNinePieceImageRepeat(style.MaskBoxImage()); |
| case CSSPropertyWebkitMaskBoxImageSlice: |
| return ValueForNinePieceImageSlice(style.MaskBoxImage()); |
| case CSSPropertyWebkitMaskBoxImageWidth: |
| return ValueForNinePieceImageQuad(style.MaskBoxImage().BorderSlices(), |
| style); |
| case CSSPropertyWebkitMaskBoxImageSource: |
| if (style.MaskBoxImageSource()) |
| return style.MaskBoxImageSource()->ComputedCSSValue(); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyWebkitFontSizeDelta: |
| // Not a real style property -- used by the editing engine -- so has no |
| // computed value. |
| return nullptr; |
| case CSSPropertyWebkitMarginBottomCollapse: |
| case CSSPropertyWebkitMarginAfterCollapse: |
| return CSSIdentifierValue::Create(style.MarginAfterCollapse()); |
| case CSSPropertyWebkitMarginTopCollapse: |
| case CSSPropertyWebkitMarginBeforeCollapse: |
| return CSSIdentifierValue::Create(style.MarginBeforeCollapse()); |
| case CSSPropertyPerspective: |
| if (!style.HasPerspective()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| return ZoomAdjustedPixelValue(style.Perspective(), style); |
| case CSSPropertyPerspectiveOrigin: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (layout_object) { |
| LayoutRect box; |
| if (layout_object->IsBox()) |
| box = ToLayoutBox(layout_object)->BorderBoxRect(); |
| |
| list->Append(*ZoomAdjustedPixelValue( |
| MinimumValueForLength(style.PerspectiveOriginX(), box.Width()), |
| style)); |
| list->Append(*ZoomAdjustedPixelValue( |
| MinimumValueForLength(style.PerspectiveOriginY(), box.Height()), |
| style)); |
| } else { |
| list->Append(*ZoomAdjustedPixelValueForLength( |
| style.PerspectiveOriginX(), style)); |
| list->Append(*ZoomAdjustedPixelValueForLength( |
| style.PerspectiveOriginY(), style)); |
| } |
| return list; |
| } |
| case CSSPropertyWebkitRtlOrdering: |
| return CSSIdentifierValue::Create(style.RtlOrdering() == EOrder::kVisual |
| ? CSSValueVisual |
| : CSSValueLogical); |
| case CSSPropertyWebkitTapHighlightColor: |
| return CurrentColorOrValidColor(style, style.TapHighlightColor()); |
| case CSSPropertyWebkitUserDrag: |
| return CSSIdentifierValue::Create(style.UserDrag()); |
| case CSSPropertyUserSelect: |
| return CSSIdentifierValue::Create(style.UserSelect()); |
| case CSSPropertyBorderBottomLeftRadius: |
| return &ValueForBorderRadiusCorner(style.BorderBottomLeftRadius(), style); |
| case CSSPropertyBorderBottomRightRadius: |
| return &ValueForBorderRadiusCorner(style.BorderBottomRightRadius(), |
| style); |
| case CSSPropertyBorderTopLeftRadius: |
| return &ValueForBorderRadiusCorner(style.BorderTopLeftRadius(), style); |
| case CSSPropertyBorderTopRightRadius: |
| return &ValueForBorderRadiusCorner(style.BorderTopRightRadius(), style); |
| case CSSPropertyClip: { |
| if (style.HasAutoClip()) |
| return CSSIdentifierValue::Create(CSSValueAuto); |
| CSSValue* top = ZoomAdjustedPixelValueOrAuto(style.Clip().Top(), style); |
| CSSValue* right = |
| ZoomAdjustedPixelValueOrAuto(style.Clip().Right(), style); |
| CSSValue* bottom = |
| ZoomAdjustedPixelValueOrAuto(style.Clip().Bottom(), style); |
| CSSValue* left = ZoomAdjustedPixelValueOrAuto(style.Clip().Left(), style); |
| return CSSQuadValue::Create(top, right, bottom, left, |
| CSSQuadValue::kSerializeAsRect); |
| } |
| case CSSPropertySpeak: |
| return CSSIdentifierValue::Create(style.Speak()); |
| case CSSPropertyTransform: |
| return ComputedTransform(layout_object, style); |
| case CSSPropertyTransformBox: |
| return CSSIdentifierValue::Create(style.TransformBox()); |
| case CSSPropertyTransformOrigin: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (layout_object) { |
| LayoutRect box; |
| if (layout_object->IsBox()) |
| box = ToLayoutBox(layout_object)->BorderBoxRect(); |
| |
| list->Append(*ZoomAdjustedPixelValue( |
| MinimumValueForLength(style.TransformOriginX(), box.Width()), |
| style)); |
| list->Append(*ZoomAdjustedPixelValue( |
| MinimumValueForLength(style.TransformOriginY(), box.Height()), |
| style)); |
| if (style.TransformOriginZ() != 0) |
| list->Append( |
| *ZoomAdjustedPixelValue(style.TransformOriginZ(), style)); |
| } else { |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(style.TransformOriginX(), style)); |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(style.TransformOriginY(), style)); |
| if (style.TransformOriginZ() != 0) |
| list->Append( |
| *ZoomAdjustedPixelValue(style.TransformOriginZ(), style)); |
| } |
| return list; |
| } |
| case CSSPropertyTransformStyle: |
| return CSSIdentifierValue::Create( |
| (style.TransformStyle3D() == kTransformStyle3DPreserve3D) |
| ? CSSValuePreserve3d |
| : CSSValueFlat); |
| case CSSPropertyTransitionDelay: |
| return ValueForAnimationDelay(style.Transitions()); |
| case CSSPropertyTransitionDuration: |
| return ValueForAnimationDuration(style.Transitions()); |
| case CSSPropertyTransitionProperty: |
| return ValueForTransitionProperty(style.Transitions()); |
| case CSSPropertyTransitionTimingFunction: |
| return ValueForAnimationTimingFunction(style.Transitions()); |
| case CSSPropertyTransition: { |
| const CSSTransitionData* transition_data = style.Transitions(); |
| if (transition_data) { |
| CSSValueList* transitions_list = CSSValueList::CreateCommaSeparated(); |
| for (size_t i = 0; i < transition_data->PropertyList().size(); ++i) { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*CreateTransitionPropertyValue( |
| transition_data->PropertyList()[i])); |
| list->Append(*CSSPrimitiveValue::Create( |
| CSSTimingData::GetRepeated(transition_data->DurationList(), i), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| list->Append(*CreateTimingFunctionValue( |
| CSSTimingData::GetRepeated(transition_data->TimingFunctionList(), |
| i) |
| .Get())); |
| list->Append(*CSSPrimitiveValue::Create( |
| CSSTimingData::GetRepeated(transition_data->DelayList(), i), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| transitions_list->Append(*list); |
| } |
| return transitions_list; |
| } |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| // transition-property default value. |
| list->Append(*CSSIdentifierValue::Create(CSSValueAll)); |
| list->Append( |
| *CSSPrimitiveValue::Create(CSSTransitionData::InitialDuration(), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| list->Append(*CreateTimingFunctionValue( |
| CSSTransitionData::InitialTimingFunction().Get())); |
| list->Append( |
| *CSSPrimitiveValue::Create(CSSTransitionData::InitialDelay(), |
| CSSPrimitiveValue::UnitType::kSeconds)); |
| return list; |
| } |
| case CSSPropertyPointerEvents: |
| return CSSIdentifierValue::Create(style.PointerEvents()); |
| case CSSPropertyWritingMode: |
| case CSSPropertyWebkitWritingMode: |
| return CSSIdentifierValue::Create(style.GetWritingMode()); |
| case CSSPropertyWebkitTextCombine: |
| if (style.GetTextCombine() == kTextCombineAll) |
| return CSSIdentifierValue::Create(CSSValueHorizontal); |
| case CSSPropertyTextCombineUpright: |
| return CSSIdentifierValue::Create(style.GetTextCombine()); |
| case CSSPropertyWebkitTextOrientation: |
| if (style.GetTextOrientation() == TextOrientation::kMixed) |
| return CSSIdentifierValue::Create(CSSValueVerticalRight); |
| case CSSPropertyTextOrientation: |
| return CSSIdentifierValue::Create(style.GetTextOrientation()); |
| case CSSPropertyContent: |
| return ValueForContentData(style); |
| case CSSPropertyCounterIncrement: |
| return ValueForCounterDirectives(style, property_id); |
| case CSSPropertyCounterReset: |
| return ValueForCounterDirectives(style, property_id); |
| case CSSPropertyClipPath: |
| if (ClipPathOperation* operation = style.ClipPath()) { |
| if (operation->GetType() == ClipPathOperation::SHAPE) |
| return ValueForBasicShape( |
| style, ToShapeClipPathOperation(operation)->GetBasicShape()); |
| if (operation->GetType() == ClipPathOperation::REFERENCE) { |
| return CSSURIValue::Create( |
| AtomicString(ToReferenceClipPathOperation(operation)->Url())); |
| } |
| } |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyShapeMargin: |
| return CSSValue::Create(style.ShapeMargin(), style.EffectiveZoom()); |
| case CSSPropertyShapeImageThreshold: |
| return CSSPrimitiveValue::Create(style.ShapeImageThreshold(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyShapeOutside: |
| return ValueForShape(style, style.ShapeOutside()); |
| case CSSPropertyFilter: |
| return ValueForFilter(style, style.Filter()); |
| case CSSPropertyBackdropFilter: |
| return ValueForFilter(style, style.BackdropFilter()); |
| case CSSPropertyMixBlendMode: |
| return CSSIdentifierValue::Create(style.BlendMode()); |
| |
| case CSSPropertyBackgroundBlendMode: { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const FillLayer* curr_layer = &style.BackgroundLayers(); curr_layer; |
| curr_layer = curr_layer->Next()) |
| list->Append(*CSSIdentifierValue::Create(curr_layer->BlendMode())); |
| return list; |
| } |
| case CSSPropertyBackground: |
| return ValuesForBackgroundShorthand(style, layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorder: { |
| const CSSValue* value = Get(CSSPropertyBorderTop, style, layout_object, |
| styled_node, allow_visited_style); |
| const CSSPropertyID kProperties[] = {CSSPropertyBorderRight, |
| CSSPropertyBorderBottom, |
| CSSPropertyBorderLeft}; |
| for (size_t i = 0; i < WTF_ARRAY_LENGTH(kProperties); ++i) { |
| if (!DataEquivalent(value, Get(kProperties[i], style, layout_object, |
| styled_node, allow_visited_style))) |
| return nullptr; |
| } |
| return value; |
| } |
| case CSSPropertyBorderBottom: |
| return ValuesForShorthandProperty(borderBottomShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorderColor: |
| return ValuesForSidesShorthand(borderColorShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorderLeft: |
| return ValuesForShorthandProperty(borderLeftShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorderImage: |
| return ValueForNinePieceImage(style.BorderImage(), style); |
| case CSSPropertyBorderRadius: |
| return ValueForBorderRadiusShorthand(style); |
| case CSSPropertyBorderRight: |
| return ValuesForShorthandProperty(borderRightShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorderStyle: |
| return ValuesForSidesShorthand(borderStyleShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorderTop: |
| return ValuesForShorthandProperty(borderTopShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyBorderWidth: |
| return ValuesForSidesShorthand(borderWidthShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyColumnRule: |
| return ValuesForShorthandProperty(columnRuleShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyColumns: |
| return ValuesForShorthandProperty(columnsShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyListStyle: |
| return ValuesForShorthandProperty(listStyleShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyMargin: |
| return ValuesForSidesShorthand(marginShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| case CSSPropertyOutline: |
| return ValuesForShorthandProperty(outlineShorthand(), style, |
| layout_object, styled_node, |
| allow_visited_style); |
| case CSSPropertyPadding: |
| return ValuesForSidesShorthand(paddingShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| // Individual properties not part of the spec. |
| case CSSPropertyBackgroundRepeatX: |
| case CSSPropertyBackgroundRepeatY: |
| return nullptr; |
| |
| case CSSPropertyOffset: |
| return ValuesForShorthandProperty(offsetShorthand(), style, layout_object, |
| styled_node, allow_visited_style); |
| |
| case CSSPropertyOffsetAnchor: |
| return ValueForPosition(style.OffsetAnchor(), style); |
| |
| case CSSPropertyOffsetPosition: |
| return ValueForPosition(style.OffsetPosition(), style); |
| |
| case CSSPropertyOffsetPath: |
| if (const BasicShape* style_motion_path = style.OffsetPath()) |
| return ValueForBasicShape(style, style_motion_path); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| case CSSPropertyOffsetDistance: |
| return ZoomAdjustedPixelValueForLength(style.OffsetDistance(), style); |
| |
| case CSSPropertyOffsetRotate: { |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (style.OffsetRotate().type == kOffsetRotationAuto) |
| list->Append(*CSSIdentifierValue::Create(CSSValueAuto)); |
| list->Append(*CSSPrimitiveValue::Create( |
| style.OffsetRotate().angle, CSSPrimitiveValue::UnitType::kDegrees)); |
| return list; |
| } |
| |
| // Unimplemented CSS 3 properties (including CSS3 shorthand properties). |
| case CSSPropertyWebkitTextEmphasis: |
| return nullptr; |
| |
| // Directional properties are resolved by resolveDirectionAwareProperty() |
| // before the switch. |
| case CSSPropertyBlockSize: |
| case CSSPropertyInlineSize: |
| case CSSPropertyMaxBlockSize: |
| case CSSPropertyMaxInlineSize: |
| case CSSPropertyMinBlockSize: |
| case CSSPropertyMinInlineSize: |
| case CSSPropertyWebkitBorderEnd: |
| case CSSPropertyWebkitBorderEndColor: |
| case CSSPropertyWebkitBorderEndStyle: |
| case CSSPropertyWebkitBorderEndWidth: |
| case CSSPropertyWebkitBorderStart: |
| case CSSPropertyWebkitBorderStartColor: |
| case CSSPropertyWebkitBorderStartStyle: |
| case CSSPropertyWebkitBorderStartWidth: |
| case CSSPropertyWebkitBorderAfter: |
| case CSSPropertyWebkitBorderAfterColor: |
| case CSSPropertyWebkitBorderAfterStyle: |
| case CSSPropertyWebkitBorderAfterWidth: |
| case CSSPropertyWebkitBorderBefore: |
| case CSSPropertyWebkitBorderBeforeColor: |
| case CSSPropertyWebkitBorderBeforeStyle: |
| case CSSPropertyWebkitBorderBeforeWidth: |
| case CSSPropertyWebkitMarginEnd: |
| case CSSPropertyWebkitMarginStart: |
| case CSSPropertyWebkitMarginAfter: |
| case CSSPropertyWebkitMarginBefore: |
| case CSSPropertyWebkitPaddingEnd: |
| case CSSPropertyWebkitPaddingStart: |
| case CSSPropertyWebkitPaddingAfter: |
| case CSSPropertyWebkitPaddingBefore: |
| case CSSPropertyWebkitLogicalWidth: |
| case CSSPropertyWebkitLogicalHeight: |
| case CSSPropertyWebkitMinLogicalWidth: |
| case CSSPropertyWebkitMinLogicalHeight: |
| case CSSPropertyWebkitMaxLogicalWidth: |
| case CSSPropertyWebkitMaxLogicalHeight: |
| NOTREACHED(); |
| return nullptr; |
| |
| // Unimplemented @font-face properties. |
| case CSSPropertyFontDisplay: |
| case CSSPropertySrc: |
| case CSSPropertyUnicodeRange: |
| return nullptr; |
| |
| // Other unimplemented properties. |
| case CSSPropertyPage: // for @page |
| case CSSPropertySize: // for @page |
| return nullptr; |
| |
| // Unimplemented -webkit- properties. |
| case CSSPropertyWebkitMarginCollapse: |
| case CSSPropertyWebkitMask: |
| case CSSPropertyWebkitMaskRepeatX: |
| case CSSPropertyWebkitMaskRepeatY: |
| case CSSPropertyWebkitPerspectiveOriginX: |
| case CSSPropertyWebkitPerspectiveOriginY: |
| case CSSPropertyWebkitTextStroke: |
| case CSSPropertyWebkitTransformOriginX: |
| case CSSPropertyWebkitTransformOriginY: |
| case CSSPropertyWebkitTransformOriginZ: |
| return nullptr; |
| |
| // @viewport rule properties. |
| case CSSPropertyMaxZoom: |
| case CSSPropertyMinZoom: |
| case CSSPropertyOrientation: |
| case CSSPropertyUserZoom: |
| return nullptr; |
| |
| // SVG properties. |
| case CSSPropertyClipRule: |
| return CSSIdentifierValue::Create(svg_style.ClipRule()); |
| case CSSPropertyFloodOpacity: |
| return CSSPrimitiveValue::Create(svg_style.FloodOpacity(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyStopOpacity: |
| return CSSPrimitiveValue::Create(svg_style.StopOpacity(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyColorInterpolation: |
| return CSSIdentifierValue::Create(svg_style.ColorInterpolation()); |
| case CSSPropertyColorInterpolationFilters: |
| return CSSIdentifierValue::Create(svg_style.ColorInterpolationFilters()); |
| case CSSPropertyFillOpacity: |
| return CSSPrimitiveValue::Create(svg_style.FillOpacity(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyFillRule: |
| return CSSIdentifierValue::Create(svg_style.FillRule()); |
| case CSSPropertyColorRendering: |
| return CSSIdentifierValue::Create(svg_style.ColorRendering()); |
| case CSSPropertyShapeRendering: |
| return CSSIdentifierValue::Create(svg_style.ShapeRendering()); |
| case CSSPropertyStrokeLinecap: |
| return CSSIdentifierValue::Create(svg_style.CapStyle()); |
| case CSSPropertyStrokeLinejoin: |
| return CSSIdentifierValue::Create(svg_style.JoinStyle()); |
| case CSSPropertyStrokeMiterlimit: |
| return CSSPrimitiveValue::Create(svg_style.StrokeMiterLimit(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyStrokeOpacity: |
| return CSSPrimitiveValue::Create(svg_style.StrokeOpacity(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| case CSSPropertyAlignmentBaseline: |
| return CSSIdentifierValue::Create(svg_style.AlignmentBaseline()); |
| case CSSPropertyDominantBaseline: |
| return CSSIdentifierValue::Create(svg_style.DominantBaseline()); |
| case CSSPropertyTextAnchor: |
| return CSSIdentifierValue::Create(svg_style.TextAnchor()); |
| case CSSPropertyMask: |
| if (!svg_style.MaskerResource().IsEmpty()) |
| return CSSURIValue::Create( |
| SerializeAsFragmentIdentifier(svg_style.MaskerResource())); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyFloodColor: |
| return CurrentColorOrValidColor(style, svg_style.FloodColor()); |
| case CSSPropertyLightingColor: |
| return CurrentColorOrValidColor(style, svg_style.LightingColor()); |
| case CSSPropertyStopColor: |
| return CurrentColorOrValidColor(style, svg_style.StopColor()); |
| case CSSPropertyFill: |
| return AdjustSVGPaintForCurrentColor( |
| svg_style.FillPaintType(), svg_style.FillPaintUri(), |
| svg_style.FillPaintColor(), style.GetColor()); |
| case CSSPropertyMarkerEnd: |
| if (!svg_style.MarkerEndResource().IsEmpty()) |
| return CSSURIValue::Create( |
| SerializeAsFragmentIdentifier(svg_style.MarkerEndResource())); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyMarkerMid: |
| if (!svg_style.MarkerMidResource().IsEmpty()) |
| return CSSURIValue::Create( |
| SerializeAsFragmentIdentifier(svg_style.MarkerMidResource())); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyMarkerStart: |
| if (!svg_style.MarkerStartResource().IsEmpty()) |
| return CSSURIValue::Create( |
| SerializeAsFragmentIdentifier(svg_style.MarkerStartResource())); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyStroke: |
| return AdjustSVGPaintForCurrentColor( |
| svg_style.StrokePaintType(), svg_style.StrokePaintUri(), |
| svg_style.StrokePaintColor(), style.GetColor()); |
| case CSSPropertyStrokeDasharray: |
| return StrokeDashArrayToCSSValueList(*svg_style.StrokeDashArray(), style); |
| case CSSPropertyStrokeDashoffset: |
| return ZoomAdjustedPixelValueForLength(svg_style.StrokeDashOffset(), |
| style); |
| case CSSPropertyStrokeWidth: |
| return PixelValueForUnzoomedLength(svg_style.StrokeWidth(), style); |
| case CSSPropertyBaselineShift: { |
| switch (svg_style.BaselineShift()) { |
| case BS_SUPER: |
| return CSSIdentifierValue::Create(CSSValueSuper); |
| case BS_SUB: |
| return CSSIdentifierValue::Create(CSSValueSub); |
| case BS_LENGTH: |
| return ZoomAdjustedPixelValueForLength(svg_style.BaselineShiftValue(), |
| style); |
| } |
| NOTREACHED(); |
| return nullptr; |
| } |
| case CSSPropertyBufferedRendering: |
| return CSSIdentifierValue::Create(svg_style.BufferedRendering()); |
| case CSSPropertyPaintOrder: |
| return PaintOrderToCSSValueList(svg_style); |
| case CSSPropertyVectorEffect: |
| return CSSIdentifierValue::Create(svg_style.VectorEffect()); |
| case CSSPropertyMaskType: |
| return CSSIdentifierValue::Create(svg_style.MaskType()); |
| case CSSPropertyMarker: |
| // the above properties are not yet implemented in the engine |
| return nullptr; |
| case CSSPropertyD: |
| if (const StylePath* style_path = svg_style.D()) |
| return style_path->ComputedCSSValue(); |
| return CSSIdentifierValue::Create(CSSValueNone); |
| case CSSPropertyCx: |
| return ZoomAdjustedPixelValueForLength(svg_style.Cx(), style); |
| case CSSPropertyCy: |
| return ZoomAdjustedPixelValueForLength(svg_style.Cy(), style); |
| case CSSPropertyX: |
| return ZoomAdjustedPixelValueForLength(svg_style.X(), style); |
| case CSSPropertyY: |
| return ZoomAdjustedPixelValueForLength(svg_style.Y(), style); |
| case CSSPropertyR: |
| return ZoomAdjustedPixelValueForLength(svg_style.R(), style); |
| case CSSPropertyRx: |
| return ZoomAdjustedPixelValueForLength(svg_style.Rx(), style); |
| case CSSPropertyRy: |
| return ZoomAdjustedPixelValueForLength(svg_style.Ry(), style); |
| case CSSPropertyScrollSnapType: |
| return CSSIdentifierValue::Create(style.GetScrollSnapType()); |
| case CSSPropertyScrollSnapPointsX: |
| return ValueForScrollSnapPoints(style.ScrollSnapPointsX(), style); |
| case CSSPropertyScrollSnapPointsY: |
| return ValueForScrollSnapPoints(style.ScrollSnapPointsY(), style); |
| case CSSPropertyScrollSnapCoordinate: |
| return ValueForScrollSnapCoordinate(style.ScrollSnapCoordinate(), style); |
| case CSSPropertyScrollSnapDestination: |
| return ValueForScrollSnapDestination(style.ScrollSnapDestination(), |
| style); |
| case CSSPropertyTranslate: { |
| if (!style.Translate()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (layout_object && layout_object->IsBox()) { |
| LayoutRect box = ToLayoutBox(layout_object)->BorderBoxRect(); |
| list->Append(*ZoomAdjustedPixelValue( |
| FloatValueForLength(style.Translate()->X(), box.Width().ToFloat()), |
| style)); |
| |
| if (!style.Translate()->Y().IsZero() || style.Translate()->Z() != 0) |
| list->Append(*ZoomAdjustedPixelValue( |
| FloatValueForLength(style.Translate()->Y(), |
| box.Height().ToFloat()), |
| style)); |
| |
| } else { |
| // No box to resolve the percentage values |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(style.Translate()->X(), style)); |
| |
| if (!style.Translate()->Y().IsZero() || style.Translate()->Z() != 0) |
| list->Append( |
| *ZoomAdjustedPixelValueForLength(style.Translate()->Y(), style)); |
| } |
| |
| if (style.Translate()->Z() != 0) |
| list->Append(*ZoomAdjustedPixelValue(style.Translate()->Z(), style)); |
| |
| return list; |
| } |
| case CSSPropertyRotate: { |
| if (!style.Rotate()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (style.Rotate()->X() != 0 || style.Rotate()->Y() != 0 || |
| style.Rotate()->Z() != 1) { |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Rotate()->X(), CSSPrimitiveValue::UnitType::kNumber)); |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Rotate()->Y(), CSSPrimitiveValue::UnitType::kNumber)); |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Rotate()->Z(), CSSPrimitiveValue::UnitType::kNumber)); |
| } |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Rotate()->Angle(), CSSPrimitiveValue::UnitType::kDegrees)); |
| return list; |
| } |
| case CSSPropertyScale: { |
| if (!style.Scale()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Scale()->X(), CSSPrimitiveValue::UnitType::kNumber)); |
| if (style.Scale()->Y() == 1 && style.Scale()->Z() == 1) |
| return list; |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Scale()->Y(), CSSPrimitiveValue::UnitType::kNumber)); |
| if (style.Scale()->Z() != 1) |
| list->Append(*CSSPrimitiveValue::Create( |
| style.Scale()->Z(), CSSPrimitiveValue::UnitType::kNumber)); |
| return list; |
| } |
| case CSSPropertyContain: { |
| if (!style.Contain()) |
| return CSSIdentifierValue::Create(CSSValueNone); |
| if (style.Contain() == kContainsStrict) |
| return CSSIdentifierValue::Create(CSSValueStrict); |
| if (style.Contain() == kContainsContent) |
| return CSSIdentifierValue::Create(CSSValueContent); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (style.ContainsStyle()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueStyle)); |
| if (style.Contain() & kContainsLayout) |
| list->Append(*CSSIdentifierValue::Create(CSSValueLayout)); |
| if (style.ContainsPaint()) |
| list->Append(*CSSIdentifierValue::Create(CSSValuePaint)); |
| if (style.ContainsSize()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueSize)); |
| DCHECK(list->length()); |
| return list; |
| } |
| case CSSPropertyVariable: |
| // Variables are retrieved via get(AtomicString). |
| NOTREACHED(); |
| return nullptr; |
| case CSSPropertyAll: |
| return nullptr; |
| default: |
| break; |
| } |
| NOTREACHED(); |
| return nullptr; |
| } |
| |
| } // namespace blink |