| // Copyright 2014 The Cobalt Authors. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "cobalt/cssom/computed_style.h" | |
| #include <memory> | |
| #include <utility> | |
| #include <vector> | |
| #include "cobalt/base/polymorphic_downcast.h" | |
| #include "cobalt/cssom/absolute_url_value.h" | |
| #include "cobalt/cssom/calc_value.h" | |
| #include "cobalt/cssom/cobalt_ui_nav_focus_transform_function.h" | |
| #include "cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.h" | |
| #include "cobalt/cssom/css_computed_style_data.h" | |
| #include "cobalt/cssom/css_computed_style_declaration.h" | |
| #include "cobalt/cssom/font_weight_value.h" | |
| #include "cobalt/cssom/keyword_value.h" | |
| #include "cobalt/cssom/length_value.h" | |
| #include "cobalt/cssom/linear_gradient_value.h" | |
| #include "cobalt/cssom/matrix_function.h" | |
| #include "cobalt/cssom/number_value.h" | |
| #include "cobalt/cssom/percentage_value.h" | |
| #include "cobalt/cssom/property_list_value.h" | |
| #include "cobalt/cssom/property_value_visitor.h" | |
| #include "cobalt/cssom/radial_gradient_value.h" | |
| #include "cobalt/cssom/rotate_function.h" | |
| #include "cobalt/cssom/scale_function.h" | |
| #include "cobalt/cssom/shadow_value.h" | |
| #include "cobalt/cssom/transform_function.h" | |
| #include "cobalt/cssom/transform_function_list_value.h" | |
| #include "cobalt/cssom/transform_function_visitor.h" | |
| #include "cobalt/cssom/translate_function.h" | |
| #include "cobalt/cssom/url_value.h" | |
| namespace cobalt { | |
| namespace cssom { | |
| namespace { | |
| scoped_refptr<LengthValue> ProvideAbsoluteLength( | |
| const scoped_refptr<LengthValue>& specified_length, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) { | |
| switch (specified_length->unit()) { | |
| // "px" is an absolute unit. | |
| // https://www.w3.org/TR/css3-values/#absolute-lengths | |
| case kPixelsUnit: | |
| return scoped_refptr<LengthValue>(specified_length); | |
| // "em" equals to the computed value of the "font-size" property of | |
| // the element on which it is used. | |
| // https://www.w3.org/TR/css3-values/#font-relative-lengths | |
| case kFontSizesAkaEmUnit: { | |
| DCHECK_EQ(kPixelsUnit, computed_font_size->unit()); | |
| return new LengthValue( | |
| computed_font_size->value() * specified_length->value(), kPixelsUnit); | |
| } | |
| // "rem" equals to the computed value of font-size on the root element. | |
| // https://www.w3.org/TR/css3-values/#font-relative-lengths | |
| case kRootElementFontSizesAkaRemUnit: { | |
| DCHECK_EQ(kPixelsUnit, root_computed_font_size->unit()); | |
| return new LengthValue( | |
| root_computed_font_size->value() * specified_length->value(), | |
| kPixelsUnit); | |
| } | |
| // "vw" equal to 1% of the width of the initial containing block. | |
| // https://www.w3.org/TR/css3-values/#viewport-relative-lengths | |
| case kViewportWidthPercentsAkaVwUnit: { | |
| return new LengthValue( | |
| viewport_size.width() * specified_length->value() / 100.0f, | |
| kPixelsUnit); | |
| } | |
| // "vh" equal to 1% of the height of the initial containing block. | |
| // https://www.w3.org/TR/css3-values/#viewport-relative-lengths | |
| case kViewportHeightPercentsAkaVhUnit: { | |
| return new LengthValue( | |
| viewport_size.height() * specified_length->value() / 100.0f, | |
| kPixelsUnit); | |
| } | |
| } | |
| NOTREACHED(); | |
| return NULL; | |
| } | |
| // For values that can be either lengths or percentages, this function will | |
| // return a value that, if the original value was a length, is now | |
| // absolutized. | |
| scoped_refptr<PropertyValue> ProvideAbsoluteLengthIfNonNullLength( | |
| const scoped_refptr<PropertyValue>& specified_value, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) { | |
| if (!specified_value) { | |
| return specified_value; | |
| } | |
| if (specified_value->GetTypeId() == base::GetTypeId<LengthValue>()) { | |
| LengthValue* value_as_length = | |
| base::polymorphic_downcast<LengthValue*>(specified_value.get()); | |
| return ProvideAbsoluteLength(value_as_length, computed_font_size, | |
| root_computed_font_size, viewport_size); | |
| } else { | |
| return specified_value; | |
| } | |
| } | |
| // Applices ProvideAbsoluteLengthIfNonNullLength() for every item in a | |
| // PropertyValueList. | |
| scoped_refptr<PropertyListValue> ProvideAbsoluteLengthsForNonNullLengthsInList( | |
| const scoped_refptr<PropertyListValue>& specified_value, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) { | |
| std::unique_ptr<PropertyListValue::Builder> builder( | |
| new PropertyListValue::Builder()); | |
| builder->reserve(specified_value->value().size()); | |
| for (PropertyListValue::Builder::const_iterator iter = | |
| specified_value->value().begin(); | |
| iter != specified_value->value().end(); ++iter) { | |
| builder->push_back(ProvideAbsoluteLengthIfNonNullLength( | |
| *iter, computed_font_size, root_computed_font_size, viewport_size)); | |
| } | |
| return new PropertyListValue(std::move(builder)); | |
| } | |
| // Computed value: absolute length; | |
| // '0' if the border style is 'none' or 'hidden'. | |
| // https://www.w3.org/TR/css3-background/#border-width | |
| class ComputedBorderWidthProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBorderWidthProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size, | |
| const PropertyValue* border_style); | |
| void VisitLength(LengthValue* length) override; | |
| const scoped_refptr<PropertyValue>& computed_border_width() const { | |
| return computed_border_width_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| const PropertyValue* border_style_; | |
| scoped_refptr<PropertyValue> computed_border_width_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedBorderWidthProvider); | |
| }; | |
| ComputedBorderWidthProvider::ComputedBorderWidthProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size, | |
| const PropertyValue* border_style) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size), | |
| border_style_(border_style) {} | |
| void ComputedBorderWidthProvider::VisitLength(LengthValue* specified_length) { | |
| if (border_style_ == KeywordValue::GetNone().get() || | |
| border_style_ == KeywordValue::GetHidden().get()) { | |
| computed_border_width_ = new LengthValue(0, kPixelsUnit); | |
| } else { | |
| DCHECK_EQ(border_style_, KeywordValue::GetSolid().get()); | |
| computed_border_width_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| } | |
| // Computed value: numeric weight value. | |
| // https://www.w3.org/TR/css3-fonts/#font-weight-prop | |
| class ComputedFontWeightProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedFontWeightProvider() {} | |
| void VisitFontWeight(FontWeightValue* weight) override; | |
| const scoped_refptr<FontWeightValue>& computed_font_weight() const { | |
| return computed_font_weight_; | |
| } | |
| private: | |
| scoped_refptr<FontWeightValue> computed_font_weight_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedFontWeightProvider); | |
| }; | |
| // TODO: Support bolder and lighter. Match the weight with font face. | |
| // Quite often there are only a few weights available for a particular font | |
| // family. When a weight is specified for which no face exists, a face with a | |
| // nearby weight is used. | |
| // https://www.w3.org/TR/css3-fonts/#font-matching-algorithm | |
| void ComputedFontWeightProvider::VisitFontWeight( | |
| FontWeightValue* specified_weight) { | |
| computed_font_weight_ = specified_weight; | |
| } | |
| // Computed value: absolute length. | |
| // https://www.w3.org/TR/css3-fonts/#font-size-prop | |
| class ComputedFontSizeProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedFontSizeProvider(const LengthValue* parent_computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<LengthValue>& computed_font_size() const { | |
| return computed_font_size_; | |
| } | |
| private: | |
| const LengthValue* parent_computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<LengthValue> computed_font_size_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedFontSizeProvider); | |
| }; | |
| ComputedFontSizeProvider::ComputedFontSizeProvider( | |
| const LengthValue* parent_computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : parent_computed_font_size_(parent_computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedFontSizeProvider::VisitLength(LengthValue* specified_length) { | |
| // "em" on "font-size" is calculated relatively to the inherited value | |
| // of "font-size". | |
| // https://www.w3.org/TR/css3-values/#font-relative-lengths | |
| computed_font_size_ = | |
| ProvideAbsoluteLength(specified_length, parent_computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedFontSizeProvider::VisitPercentage( | |
| PercentageValue* specified_percentage) { | |
| // A percentage value specifies an absolute font size relative to the parent | |
| // element's fonts size. | |
| // https://www.w3.org/TR/css3-fonts/#percentage-size-value | |
| computed_font_size_ = new LengthValue( | |
| parent_computed_font_size_->value() * specified_percentage->value(), | |
| kPixelsUnit); | |
| } | |
| // Computed value: for length and percentage the absolute value; | |
| // otherwise as specified. | |
| // https://www.w3.org/TR/CSS21/visudet.html#line-height | |
| class ComputedLineHeightProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedLineHeightProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitNumber(NumberValue* number) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_line_height() const { | |
| return computed_line_height_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_line_height_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedLineHeightProvider); | |
| }; | |
| ComputedLineHeightProvider::ComputedLineHeightProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedLineHeightProvider::VisitLength(LengthValue* specified_length) { | |
| computed_line_height_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedLineHeightProvider::VisitNumber(NumberValue* specified_number) { | |
| // The computed value is the same as the specified value. | |
| // https://www.w3.org/TR/CSS2/visudet.html#line-height | |
| computed_line_height_ = specified_number; | |
| } | |
| void ComputedLineHeightProvider::VisitPercentage(PercentageValue* percentage) { | |
| // The computed value of the property is this percentage multiplied by the | |
| // element's computed font size. Negative values are illegal. | |
| // https://www.w3.org/TR/CSS21/visudet.html#line-height | |
| computed_line_height_ = new LengthValue( | |
| computed_font_size_->value() * percentage->value(), kPixelsUnit); | |
| } | |
| void ComputedLineHeightProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kNormal: | |
| computed_line_height_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| // Computed value: the percentage as specified or the absolute length. | |
| // https://www.w3.org/TR/CSS21/box.html#margin-properties | |
| // https://www.w3.org/TR/CSS21/box.html#padding-properties | |
| class ComputedMarginOrPaddingEdgeProvider | |
| : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedMarginOrPaddingEdgeProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_margin_or_padding_edge() const { | |
| return computed_margin_or_padding_edge_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_margin_or_padding_edge_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedMarginOrPaddingEdgeProvider); | |
| }; | |
| ComputedMarginOrPaddingEdgeProvider::ComputedMarginOrPaddingEdgeProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedMarginOrPaddingEdgeProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| computed_margin_or_padding_edge_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| void ComputedMarginOrPaddingEdgeProvider::VisitLength( | |
| LengthValue* specified_length) { | |
| computed_margin_or_padding_edge_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedMarginOrPaddingEdgeProvider::VisitPercentage( | |
| PercentageValue* percentage) { | |
| computed_margin_or_padding_edge_ = percentage; | |
| } | |
| class ComputedPositionOffsetProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedPositionOffsetProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_position_offset() const { | |
| return computed_position_offset_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_position_offset_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedPositionOffsetProvider); | |
| }; | |
| void ComputedPositionOffsetProvider::VisitLength( | |
| LengthValue* specified_length) { | |
| computed_position_offset_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedPositionOffsetProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| computed_position_offset_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| void ComputedPositionOffsetProvider::VisitPercentage( | |
| PercentageValue* percentage) { | |
| computed_position_offset_ = percentage; | |
| } | |
| ComputedPositionOffsetProvider::ComputedPositionOffsetProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| // Computed value: the percentage or "auto" or the absolute length. | |
| // https://www.w3.org/TR/CSS21/visudet.html#the-height-property | |
| class ComputedHeightProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedHeightProvider(const PropertyValue* parent_computed_height, | |
| const PropertyValue* parent_computed_top, | |
| const PropertyValue* parent_computed_bottom, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size, bool out_of_flow); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_height() const { | |
| return computed_height_; | |
| } | |
| private: | |
| const PropertyValue* parent_computed_height_; | |
| const PropertyValue* parent_computed_top_; | |
| const PropertyValue* parent_computed_bottom_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| bool out_of_flow_; | |
| scoped_refptr<PropertyValue> computed_height_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedHeightProvider); | |
| }; | |
| ComputedHeightProvider::ComputedHeightProvider( | |
| const PropertyValue* parent_computed_height, | |
| const PropertyValue* parent_computed_top, | |
| const PropertyValue* parent_computed_bottom, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size, | |
| bool out_of_flow) | |
| : parent_computed_height_(parent_computed_height), | |
| parent_computed_top_(parent_computed_top), | |
| parent_computed_bottom_(parent_computed_bottom), | |
| computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size), | |
| out_of_flow_(out_of_flow) {} | |
| void ComputedHeightProvider::VisitLength(LengthValue* specified_length) { | |
| computed_height_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedHeightProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| computed_height_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| void ComputedHeightProvider::VisitPercentage(PercentageValue* percentage) { | |
| const scoped_refptr<PropertyValue>& auto_value = KeywordValue::GetAuto(); | |
| // If the height of the containing block is not specified explicitly | |
| // (i.e., it depends on content height), and this element is not absolutely | |
| // positioned, the value computes to "auto". | |
| // https://www.w3.org/TR/CSS21/visudet.html#the-height-property | |
| computed_height_ = (parent_computed_height_ == auto_value && | |
| (parent_computed_top_ == auto_value || | |
| parent_computed_bottom_ == auto_value) && | |
| !out_of_flow_) | |
| ? auto_value | |
| : percentage; | |
| } | |
| // Computed value: the percentage or "auto" or the absolute length. | |
| // https://www.w3.org/TR/CSS2/visudet.html#propdef-max-height | |
| class ComputedMaxHeightProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedMaxHeightProvider(const PropertyValue* parent_computed_max_height, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size, bool out_of_flow); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_max_height() const { | |
| return computed_max_height_; | |
| } | |
| private: | |
| const PropertyValue* parent_computed_max_height_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| bool out_of_flow_; | |
| scoped_refptr<PropertyValue> computed_max_height_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedMaxHeightProvider); | |
| }; | |
| ComputedMaxHeightProvider::ComputedMaxHeightProvider( | |
| const PropertyValue* parent_computed_max_height, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size, | |
| bool out_of_flow) | |
| : parent_computed_max_height_(parent_computed_max_height), | |
| computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size), | |
| out_of_flow_(out_of_flow) {} | |
| void ComputedMaxHeightProvider::VisitLength(LengthValue* specified_length) { | |
| computed_max_height_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedMaxHeightProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kNone: | |
| computed_max_height_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| void ComputedMaxHeightProvider::VisitPercentage(PercentageValue* percentage) { | |
| const scoped_refptr<PropertyValue>& auto_value = KeywordValue::GetAuto(); | |
| const scoped_refptr<PropertyValue>& none_value = KeywordValue::GetNone(); | |
| // If the max_height of the containing block is not specified explicitly | |
| // (i.e., it depends on content max_height), and this element is not | |
| // absolutely positioned, the percentage value is treated as 'none'. | |
| // https://www.w3.org/TR/CSS2/visudet.html#propdef-max-height | |
| computed_max_height_ = | |
| (parent_computed_max_height_ == auto_value && !out_of_flow_) ? none_value | |
| : percentage; | |
| } | |
| // Computed value: the percentage or "auto" or the absolute length. | |
| // https://www.w3.org/TR/CSS2/visudet.html#propdef-min-height | |
| class ComputedMinHeightProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedMinHeightProvider(const PropertyValue* parent_computed_height, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size, bool out_of_flow); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_min_height() const { | |
| return computed_min_height_; | |
| } | |
| private: | |
| const PropertyValue* parent_computed_height_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| bool out_of_flow_; | |
| scoped_refptr<PropertyValue> computed_min_height_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedMinHeightProvider); | |
| }; | |
| ComputedMinHeightProvider::ComputedMinHeightProvider( | |
| const PropertyValue* parent_computed_height, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size, | |
| bool out_of_flow) | |
| : parent_computed_height_(parent_computed_height), | |
| computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size), | |
| out_of_flow_(out_of_flow) {} | |
| void ComputedMinHeightProvider::VisitLength(LengthValue* specified_length) { | |
| computed_min_height_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedMinHeightProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| computed_min_height_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| void ComputedMinHeightProvider::VisitPercentage(PercentageValue* percentage) { | |
| const scoped_refptr<PropertyValue>& auto_value = KeywordValue::GetAuto(); | |
| // If the height of the containing block is not specified explicitly | |
| // (i.e., it depends on content height), and this element is not | |
| // absolutely positioned, the percentage value is treated as '0'. | |
| // https://www.w3.org/TR/CSS2/visudet.html#propdef-min-height | |
| if (parent_computed_height_ == auto_value && !out_of_flow_) { | |
| computed_min_height_ = new LengthValue(0, kPixelsUnit); | |
| } else { | |
| computed_min_height_ = percentage; | |
| } | |
| } | |
| // Computed value: the percentage or "auto" as specified or the absolute length. | |
| // https://www.w3.org/TR/CSS21/visudet.html#the-width-property | |
| class ComputedWidthValueProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedWidthValueProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_value() const { | |
| return computed_value_; | |
| } | |
| protected: | |
| scoped_refptr<PropertyValue> computed_value_; | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedWidthValueProvider); | |
| }; | |
| ComputedWidthValueProvider::ComputedWidthValueProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedWidthValueProvider::VisitLength(LengthValue* specified_length) { | |
| computed_value_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedWidthValueProvider::VisitPercentage(PercentageValue* percentage) { | |
| computed_value_ = percentage; | |
| } | |
| // Computed value: For auto the width depends on the values of other properties. | |
| // https://www.w3.org/TR/CSS21/visudet.html#the-width-property | |
| class ComputedWidthProvider : public ComputedWidthValueProvider { | |
| public: | |
| ComputedWidthProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) | |
| : ComputedWidthValueProvider(computed_font_size, root_computed_font_size, | |
| viewport_size) {} | |
| void VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| computed_value_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| private: | |
| DISALLOW_COPY_AND_ASSIGN(ComputedWidthProvider); | |
| }; | |
| // Computed value: For all values other than auto and content, flex-basis is | |
| // resolved the same way as width. | |
| // https://www.w3.org/TR/css-flexbox-1/#flex-basis-property | |
| class ComputedFlexBasisProvider : public ComputedWidthValueProvider { | |
| public: | |
| ComputedFlexBasisProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) | |
| : ComputedWidthValueProvider(computed_font_size, root_computed_font_size, | |
| viewport_size) {} | |
| void VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kContent: | |
| computed_value_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| private: | |
| DISALLOW_COPY_AND_ASSIGN(ComputedFlexBasisProvider); | |
| }; | |
| // Computed value: the percentage or "auto" as specified or the absolute length. | |
| // https://www.w3.org/TR/CSS2/visudet.html#min-max-widths | |
| class ComputedMinMaxWidthProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedMinMaxWidthProvider(PropertyValue* parent_computed_width, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| const scoped_refptr<PropertyValue>& computed_min_max_width() const { | |
| return computed_min_max_width_; | |
| } | |
| private: | |
| PropertyValue* parent_computed_width_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_min_max_width_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedMinMaxWidthProvider); | |
| }; | |
| ComputedMinMaxWidthProvider::ComputedMinMaxWidthProvider( | |
| PropertyValue* parent_computed_width, const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : parent_computed_width_(parent_computed_width), | |
| computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedMinMaxWidthProvider::VisitLength(LengthValue* specified_length) { | |
| computed_min_max_width_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedMinMaxWidthProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kNone: | |
| computed_min_max_width_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| class ComputedLengthIsNegativeProvider : public DefaultingPropertyValueVisitor { | |
| public: | |
| ComputedLengthIsNegativeProvider() : computed_length_is_negative_(false) {} | |
| void VisitLength(LengthValue* length_value) override { | |
| switch (length_value->unit()) { | |
| case kPixelsUnit: | |
| case kFontSizesAkaEmUnit: | |
| case kRootElementFontSizesAkaRemUnit: | |
| case kViewportWidthPercentsAkaVwUnit: | |
| case kViewportHeightPercentsAkaVhUnit: | |
| computed_length_is_negative_ = length_value->value() < 0; | |
| break; | |
| } | |
| } | |
| void VisitDefault(PropertyValue* property_value) override {} | |
| bool computed_length_is_negative() { return computed_length_is_negative_; } | |
| private: | |
| bool computed_length_is_negative_; | |
| }; | |
| void ComputedMinMaxWidthProvider::VisitPercentage(PercentageValue* percentage) { | |
| ComputedLengthIsNegativeProvider computed_length_is_negative_provider; | |
| parent_computed_width_->Accept(&computed_length_is_negative_provider); | |
| // If the containing block's width is negative, the used value is zero. | |
| // https://www.w3.org/TR/CSS2/visudet.html#min-max-widths | |
| if (computed_length_is_negative_provider.computed_length_is_negative()) { | |
| computed_min_max_width_ = new LengthValue(0, kPixelsUnit); | |
| } else { | |
| computed_min_max_width_ = percentage; | |
| } | |
| } | |
| namespace { | |
| // Helper class for |ComputedBackgroundPositionProvider| and | |
| // |ComputedTransformOriginProvider| to resolve the computed value of position | |
| // part. | |
| // https://www.w3.org/TR/css3-background/#the-background-position | |
| // https://www.w3.org/TR/css3-transforms/#propdef-transform-origin | |
| class ComputedPositionHelper { | |
| public: | |
| ComputedPositionHelper(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| // Forwards the call on to the appropriate method depending on the number | |
| // of parameters in |input_position_builder|. | |
| void ComputePosition(const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder); | |
| // Only resolve the first value of |input_position_builder|, other than the | |
| // first value would be ignored. | |
| void ComputeOneValuePosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder); | |
| // Only resolve the first two values of |input_position_builder|, other than | |
| // the first two values would be ignored. | |
| void ComputeTwoValuesPosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder); | |
| // Only resolve three or four values of |input_position_builder|. | |
| void ComputeThreeOrFourValuesPosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder); | |
| private: | |
| enum Direction { | |
| kHorizontal, | |
| kVertical, | |
| kCenter, | |
| kNone, | |
| }; | |
| struct OriginInfo { | |
| OriginInfo(float origin_as_percentage, int offset_multiplier, | |
| Direction direction) | |
| : origin_as_percentage(origin_as_percentage), | |
| offset_multiplier(offset_multiplier), | |
| direction(direction) {} | |
| float origin_as_percentage; | |
| int offset_multiplier; | |
| Direction direction; | |
| }; | |
| const OriginInfo ConvertToOriginInfo( | |
| const scoped_refptr<PropertyValue>& keyword) const; | |
| scoped_refptr<CalcValue> ProvideCalcValueFromOriginAndOffset( | |
| OriginInfo* origin_info, const scoped_refptr<PropertyValue>& offset); | |
| void FillPositionBuilderFromOriginAndOffset( | |
| const scoped_refptr<PropertyValue>& origin, | |
| const scoped_refptr<PropertyValue>& offset, | |
| PropertyListValue::Builder* position_builder); | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedPositionHelper); | |
| }; | |
| ComputedPositionHelper::ComputedPositionHelper( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedPositionHelper::ComputePosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder) { | |
| switch (input_position_builder.size()) { | |
| case 1: | |
| ComputeOneValuePosition(input_position_builder, output_position_builder); | |
| break; | |
| case 2: | |
| ComputeTwoValuesPosition(input_position_builder, output_position_builder); | |
| break; | |
| case 3: // fall-through | |
| case 4: | |
| ComputeThreeOrFourValuesPosition(input_position_builder, | |
| output_position_builder); | |
| break; | |
| } | |
| } | |
| // If only one value is specified, the second value is assumed to be center. | |
| void ComputedPositionHelper::ComputeOneValuePosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder) { | |
| DCHECK_GE(input_position_builder.size(), 1u); | |
| PropertyListValue::Builder position_builder; | |
| position_builder.push_back(input_position_builder[0]); | |
| position_builder.push_back(KeywordValue::GetCenter()); | |
| ComputeTwoValuesPosition(position_builder, output_position_builder); | |
| } | |
| // If two position values are given, a length or percentage as the | |
| // first value represents the horizontal position (or offset) and a length or | |
| // percentage as the second value represents the vertical position (or offset). | |
| void ComputedPositionHelper::ComputeTwoValuesPosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder) { | |
| DCHECK_GE(input_position_builder.size(), 2u); | |
| for (size_t i = 0; i < 2; ++i) { | |
| scoped_refptr<PropertyValue> current_value = input_position_builder[i]; | |
| if (current_value->GetTypeId() == base::GetTypeId<CalcValue>()) { | |
| // If it is already a CalcValue, nothing needs to be done. | |
| (*output_position_builder)[i] = current_value; | |
| } else if (current_value->GetTypeId() == base::GetTypeId<KeywordValue>()) { | |
| FillPositionBuilderFromOriginAndOffset(current_value, NULL, | |
| output_position_builder); | |
| } else { | |
| OriginInfo default_origin = OriginInfo(0.0f, 1, kNone); | |
| (*output_position_builder)[i] = | |
| ProvideCalcValueFromOriginAndOffset(&default_origin, current_value); | |
| } | |
| } | |
| } | |
| // If three values are given, then there are two cases: | |
| // 1. <KeywordValue Length/Percentage KeywordValue> | |
| // 2. <KeywordValue KeywordValue Length/Percentage> | |
| // If four values are given, then each <percentage> or <length> represents | |
| // an offset and must be preceded by a keyword, which specifies from which | |
| // edge the offset is given. Keyword cannot be 'center'. The pattern is | |
| // <KeywordValue Length/Percentage KeywordValue Length/Percentage> | |
| void ComputedPositionHelper::ComputeThreeOrFourValuesPosition( | |
| const PropertyListValue::Builder& input_position_builder, | |
| PropertyListValue::Builder* output_position_builder) { | |
| DCHECK_GT(input_position_builder.size(), 2u); | |
| DCHECK_LE(input_position_builder.size(), 4u); | |
| for (size_t i = 0; i < input_position_builder.size(); ++i) { | |
| scoped_refptr<PropertyValue> previous_value = | |
| (i == 0) ? NULL : input_position_builder[i - 1]; | |
| scoped_refptr<PropertyValue> current_value = input_position_builder[i]; | |
| if (current_value->GetTypeId() == base::GetTypeId<KeywordValue>()) { | |
| FillPositionBuilderFromOriginAndOffset(current_value, NULL, | |
| output_position_builder); | |
| } else { | |
| DCHECK(previous_value); | |
| DCHECK(previous_value->GetTypeId() == base::GetTypeId<KeywordValue>()); | |
| FillPositionBuilderFromOriginAndOffset(previous_value, current_value, | |
| output_position_builder); | |
| } | |
| } | |
| } | |
| // 1) 'top' computes to '0%' for the vertical position if one or two values are | |
| // given, otherwise specifies the top edge as the origin for the next | |
| // offset. | |
| // 2) 'right' computes to '100%' for the horizontal position if one or two | |
| // values are given, otherwise specifies the right edge as the origin for | |
| // the next offset. | |
| // 3) 'bottom' computes to '100%' for the vertical position if one or two values | |
| // are given, otherwise specifies the bottom edge as the origin for the | |
| // the next offset. | |
| // 4) 'left' computes to '0%' for the horizontal position if one or two values | |
| // are given, otherwise specifies the left edge as the origin for the next | |
| // offset. | |
| // 5) 'center' computes to '50%' (left 50%) for the horizontal position if | |
| // horizontal position is not specified, or '50%' (right 50%) for the | |
| // vertical position is not specified. | |
| const ComputedPositionHelper::OriginInfo | |
| ComputedPositionHelper::ConvertToOriginInfo( | |
| const scoped_refptr<PropertyValue>& keyword) const { | |
| DCHECK(keyword->GetTypeId() == base::GetTypeId<KeywordValue>()); | |
| if (keyword == KeywordValue::GetLeft()) { | |
| return OriginInfo(0.0f, 1, kHorizontal); | |
| } else if (keyword == KeywordValue::GetRight()) { | |
| return OriginInfo(1.0f, -1, kHorizontal); | |
| } else if (keyword == KeywordValue::GetTop()) { | |
| return OriginInfo(0.0f, 1, kVertical); | |
| } else if (keyword == KeywordValue::GetBottom()) { | |
| return OriginInfo(1.0f, -1, kVertical); | |
| } else { | |
| return OriginInfo(0.5f, 1, kCenter); | |
| } | |
| } | |
| // If the |offset| is specified, the |origin| specifies from which edge | |
| // the offset is given. Otherwise, the |origin| indicates the corresponding | |
| // percentage value to the upper left corner for the horizontal/vertical | |
| // position. The horizontal and vertical values are stored as CalcValue in | |
| // computed style. eg: (background-position: bottom 20px left 40%;) would be | |
| // computed as Calc(0px, 40%), Calc(-20px, 100%) | |
| scoped_refptr<CalcValue> | |
| ComputedPositionHelper::ProvideCalcValueFromOriginAndOffset( | |
| OriginInfo* origin_info, const scoped_refptr<PropertyValue>& offset) { | |
| DCHECK(origin_info); | |
| if (!offset) { | |
| return new CalcValue( | |
| new PercentageValue(origin_info->origin_as_percentage)); | |
| } | |
| scoped_refptr<LengthValue> length_value; | |
| scoped_refptr<PercentageValue> percentage_value; | |
| if (offset->GetTypeId() == base::GetTypeId<LengthValue>()) { | |
| scoped_refptr<LengthValue> length_provider = ProvideAbsoluteLength( | |
| base::polymorphic_downcast<LengthValue*>(offset.get()), | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| length_value = new LengthValue( | |
| origin_info->offset_multiplier * length_provider->value(), | |
| length_provider->unit()); | |
| percentage_value = new PercentageValue(origin_info->origin_as_percentage); | |
| return new CalcValue(length_value, percentage_value); | |
| } else { | |
| DCHECK(offset->GetTypeId() == base::GetTypeId<PercentageValue>()); | |
| PercentageValue* percentage = | |
| base::polymorphic_downcast<PercentageValue*>(offset.get()); | |
| percentage_value = new PercentageValue(origin_info->origin_as_percentage + | |
| origin_info->offset_multiplier * | |
| percentage->value()); | |
| return new CalcValue(percentage_value); | |
| } | |
| } | |
| void ComputedPositionHelper::FillPositionBuilderFromOriginAndOffset( | |
| const scoped_refptr<PropertyValue>& origin, | |
| const scoped_refptr<PropertyValue>& offset, | |
| PropertyListValue::Builder* output_position_builder) { | |
| DCHECK(origin->GetTypeId() == base::GetTypeId<KeywordValue>()); | |
| OriginInfo origin_info = ConvertToOriginInfo(origin); | |
| switch (origin_info.direction) { | |
| case kHorizontal: { | |
| (*output_position_builder)[0] = | |
| ProvideCalcValueFromOriginAndOffset(&origin_info, offset); | |
| break; | |
| } | |
| case kVertical: { | |
| (*output_position_builder)[1] = | |
| ProvideCalcValueFromOriginAndOffset(&origin_info, offset); | |
| break; | |
| } | |
| case kCenter: { | |
| if (!(*output_position_builder)[0]) { | |
| (*output_position_builder)[0] = | |
| ProvideCalcValueFromOriginAndOffset(&origin_info, offset); | |
| } | |
| if (!(*output_position_builder)[1]) { | |
| (*output_position_builder)[1] = | |
| ProvideCalcValueFromOriginAndOffset(&origin_info, offset); | |
| } | |
| break; | |
| } | |
| case kNone: // fall-through | |
| NOTREACHED(); | |
| break; | |
| } | |
| } | |
| } // namespace | |
| // Absolutizes the value of "background-image" property. | |
| // Computed value: as specified, but with URIs made absolute. | |
| // https://www.w3.org/TR/css3-background/#the-background-image | |
| class ComputedBackgroundImageSingleLayerProvider | |
| : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBackgroundImageSingleLayerProvider( | |
| const GURL& base_url, const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) | |
| : base_url_(base_url), | |
| computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitLinearGradient(LinearGradientValue* linear_gradient_value) override; | |
| void VisitRadialGradient(RadialGradientValue* radial_gradient_value) override; | |
| void VisitURL(URLValue* url_value) override; | |
| const scoped_refptr<PropertyValue>& computed_background_image() const { | |
| return computed_background_image_; | |
| } | |
| private: | |
| const GURL base_url_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_background_image_; | |
| }; | |
| void ComputedBackgroundImageSingleLayerProvider::VisitKeyword( | |
| KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kNone: | |
| computed_background_image_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| break; | |
| } | |
| } | |
| namespace { | |
| ColorStopList ComputeColorStopList(const ColorStopList& color_stops, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) { | |
| ColorStopList computed_color_stops; | |
| computed_color_stops.reserve(color_stops.size()); | |
| for (ColorStopList::const_iterator iter = color_stops.begin(); | |
| iter != color_stops.end(); ++iter) { | |
| const ColorStop& color_stop = **iter; | |
| computed_color_stops.emplace_back(new ColorStop( | |
| color_stop.rgba(), ProvideAbsoluteLengthIfNonNullLength( | |
| color_stop.position(), computed_font_size, | |
| root_computed_font_size, viewport_size))); | |
| } | |
| return computed_color_stops; | |
| } | |
| } // namespace | |
| void ComputedBackgroundImageSingleLayerProvider::VisitLinearGradient( | |
| LinearGradientValue* linear_gradient_value) { | |
| // We must walk through the list of color stop positions and absolutize the | |
| // any length values. | |
| ColorStopList computed_color_stops = ComputeColorStopList( | |
| linear_gradient_value->color_stop_list(), computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| if (linear_gradient_value->angle_in_radians()) { | |
| computed_background_image_ = | |
| new LinearGradientValue(*linear_gradient_value->angle_in_radians(), | |
| std::move(computed_color_stops)); | |
| } else { | |
| computed_background_image_ = | |
| new LinearGradientValue(*linear_gradient_value->side_or_corner(), | |
| std::move(computed_color_stops)); | |
| } | |
| } | |
| namespace { | |
| scoped_refptr<PropertyListValue> CalculateComputedRadialGradientPosition( | |
| const scoped_refptr<PropertyListValue>& specified_position, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) { | |
| if (!specified_position) { | |
| // If no position is specified, we default to 'center'. | |
| std::unique_ptr<PropertyListValue::Builder> builder( | |
| new PropertyListValue::Builder(2, new PercentageValue(0.5f))); | |
| return new PropertyListValue(std::move(builder)); | |
| } | |
| size_t size = specified_position->value().size(); | |
| DCHECK_GE(size, 1u); | |
| DCHECK_LE(size, 4u); | |
| ComputedPositionHelper position_helper( | |
| computed_font_size, root_computed_font_size, viewport_size); | |
| std::unique_ptr<PropertyListValue::Builder> computed_position_builder( | |
| new PropertyListValue::Builder(2, scoped_refptr<PropertyValue>())); | |
| position_helper.ComputePosition(specified_position->value(), | |
| computed_position_builder.get()); | |
| return new PropertyListValue(std::move(computed_position_builder)); | |
| } | |
| } // namespace | |
| void ComputedBackgroundImageSingleLayerProvider::VisitRadialGradient( | |
| RadialGradientValue* radial_gradient_value) { | |
| // We must walk through the list of color stop positions and absolutize the | |
| // any length values. | |
| ColorStopList computed_color_stops = ComputeColorStopList( | |
| radial_gradient_value->color_stop_list(), computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| // The center of the gradient must be absolutized if it is a length. | |
| scoped_refptr<PropertyListValue> computed_position = | |
| CalculateComputedRadialGradientPosition( | |
| radial_gradient_value->position(), computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| // If the radial gradient specifies size values, they must also be absolutized | |
| // if they are lengths. | |
| if (radial_gradient_value->size_value()) { | |
| computed_background_image_ = new RadialGradientValue( | |
| radial_gradient_value->shape(), | |
| ProvideAbsoluteLengthsForNonNullLengthsInList( | |
| radial_gradient_value->size_value(), computed_font_size_, | |
| root_computed_font_size_, viewport_size_), | |
| computed_position, std::move(computed_color_stops)); | |
| } else { | |
| computed_background_image_ = new RadialGradientValue( | |
| radial_gradient_value->shape(), *radial_gradient_value->size_keyword(), | |
| computed_position, std::move(computed_color_stops)); | |
| } | |
| } | |
| void ComputedBackgroundImageSingleLayerProvider::VisitURL(URLValue* url_value) { | |
| if (url_value->value().empty()) { | |
| // No need to convert URLValue into AbsoluteURLValue. | |
| computed_background_image_ = KeywordValue::GetNone(); | |
| return; | |
| } | |
| GURL absolute_url; | |
| if (url_value->is_absolute()) { | |
| absolute_url = GURL(url_value->value()); | |
| } else { | |
| absolute_url = url_value->Resolve(base_url_); | |
| } | |
| if (!absolute_url.is_valid()) { | |
| DLOG(WARNING) << "Invalid url: " << absolute_url.spec(); | |
| // No further process is needed if the url is invalid. | |
| computed_background_image_ = KeywordValue::GetNone(); | |
| return; | |
| } | |
| computed_background_image_ = new AbsoluteURLValue(absolute_url); | |
| } | |
| class ComputedBackgroundImageProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBackgroundImageProvider(const GURL& base_url, | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) | |
| : base_url_(base_url), | |
| computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void VisitPropertyList(PropertyListValue* property_list_value) override; | |
| const scoped_refptr<PropertyValue>& computed_background_image() const { | |
| return computed_background_image_; | |
| } | |
| private: | |
| const GURL base_url_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_background_image_; | |
| }; | |
| void ComputedBackgroundImageProvider::VisitPropertyList( | |
| PropertyListValue* property_list_value) { | |
| std::unique_ptr<PropertyListValue::Builder> builder( | |
| new PropertyListValue::Builder()); | |
| builder->reserve(property_list_value->value().size()); | |
| ComputedBackgroundImageSingleLayerProvider single_layer_provider( | |
| base_url_, computed_font_size_, root_computed_font_size_, viewport_size_); | |
| for (size_t i = 0; i < property_list_value->value().size(); ++i) { | |
| property_list_value->value()[i]->Accept(&single_layer_provider); | |
| scoped_refptr<PropertyValue> computed_background_image = | |
| single_layer_provider.computed_background_image(); | |
| builder->push_back(computed_background_image); | |
| } | |
| computed_background_image_ = new PropertyListValue(std::move(builder)); | |
| } | |
| class ComputedBackgroundSizeSingleValueProvider | |
| : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBackgroundSizeSingleValueProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitLength(LengthValue* length) override; | |
| void VisitPercentage(PercentageValue* percentage) override; | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| const scoped_refptr<PropertyValue>& computed_background_size() const { | |
| return computed_background_size_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_background_size_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedBackgroundSizeSingleValueProvider); | |
| }; | |
| ComputedBackgroundSizeSingleValueProvider:: | |
| ComputedBackgroundSizeSingleValueProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedBackgroundSizeSingleValueProvider::VisitLength( | |
| LengthValue* length) { | |
| computed_background_size_ = ProvideAbsoluteLength( | |
| length, computed_font_size_, root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedBackgroundSizeSingleValueProvider::VisitPercentage( | |
| PercentageValue* percentage) { | |
| computed_background_size_ = percentage; | |
| } | |
| void ComputedBackgroundSizeSingleValueProvider::VisitKeyword( | |
| KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kCover: | |
| computed_background_size_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNone: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| // ComputedBackgroundPositionProvider provides a property list which has two | |
| // CalcValue. Each of CalcValue has two parts <percentage> and <length>. | |
| // <percentage> and <length> values here represent an offset of the top left | |
| // corner of the background image from the top left corner of the background | |
| // positioning area. | |
| // https://www.w3.org/TR/css3-background/#the-background-position | |
| class ComputedBackgroundPositionProvider | |
| : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBackgroundPositionProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitPropertyList(PropertyListValue* property_list_value) override; | |
| const scoped_refptr<PropertyValue>& computed_background_position() const { | |
| return computed_background_position_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_background_position_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedBackgroundPositionProvider); | |
| }; | |
| ComputedBackgroundPositionProvider::ComputedBackgroundPositionProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedBackgroundPositionProvider::VisitPropertyList( | |
| PropertyListValue* property_list_value) { | |
| size_t size = property_list_value->value().size(); | |
| DCHECK_GE(size, 1u); | |
| DCHECK_LE(size, 4u); | |
| ComputedPositionHelper position_helper( | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| std::unique_ptr<PropertyListValue::Builder> background_position_builder( | |
| new PropertyListValue::Builder(2, scoped_refptr<PropertyValue>())); | |
| position_helper.ComputePosition(property_list_value->value(), | |
| background_position_builder.get()); | |
| computed_background_position_ = | |
| new PropertyListValue(std::move(background_position_builder)); | |
| } | |
| class ComputedBackgroundSizeProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBackgroundSizeProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitPropertyList(PropertyListValue* property_list_value) override; | |
| const scoped_refptr<PropertyValue>& computed_background_size() const { | |
| return computed_background_size_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_background_size_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedBackgroundSizeProvider); | |
| }; | |
| ComputedBackgroundSizeProvider::ComputedBackgroundSizeProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedBackgroundSizeProvider::VisitKeyword(KeywordValue* keyword) { | |
| computed_background_size_ = keyword; | |
| } | |
| void ComputedBackgroundSizeProvider::VisitPropertyList( | |
| PropertyListValue* property_list_value) { | |
| ComputedBackgroundSizeSingleValueProvider left_value_provider( | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| property_list_value->value()[0]->Accept(&left_value_provider); | |
| ComputedBackgroundSizeSingleValueProvider right_value_provider( | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| property_list_value->value()[1]->Accept(&right_value_provider); | |
| std::unique_ptr<PropertyListValue::Builder> builder( | |
| new PropertyListValue::Builder()); | |
| builder->reserve(2); | |
| builder->push_back(left_value_provider.computed_background_size()); | |
| builder->push_back(right_value_provider.computed_background_size()); | |
| computed_background_size_ = new PropertyListValue(std::move(builder)); | |
| } | |
| // https://www.w3.org/TR/css3-background/#border-radius | |
| class ComputedBorderRadiusProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedBorderRadiusProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitLength(LengthValue* specified_length); | |
| void VisitPercentage(PercentageValue* percentage); | |
| const scoped_refptr<PropertyValue>& computed_border_radius() const { | |
| return computed_border_radius_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_border_radius_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedBorderRadiusProvider); | |
| }; | |
| ComputedBorderRadiusProvider::ComputedBorderRadiusProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedBorderRadiusProvider::VisitLength(LengthValue* specified_length) { | |
| computed_border_radius_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| void ComputedBorderRadiusProvider::VisitPercentage( | |
| PercentageValue* percentage) { | |
| computed_border_radius_ = percentage; | |
| } | |
| // Computed value: any <length> made absolute; any specified color computed; | |
| // otherwise as specified. | |
| // https://www.w3.org/TR/css3-background/#box-shadow | |
| // https://www.w3.org/TR/css-text-decor-3/#text-shadow-property | |
| class ComputedShadowProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedShadowProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size, | |
| const RGBAColorValue* computed_color); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitPropertyList(PropertyListValue* property_list_value) override; | |
| const scoped_refptr<PropertyValue>& computed_shadow() const { | |
| return computed_shadow_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| const RGBAColorValue* computed_color_; | |
| scoped_refptr<PropertyValue> computed_shadow_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedShadowProvider); | |
| }; | |
| ComputedShadowProvider::ComputedShadowProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size, | |
| const RGBAColorValue* computed_color) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size), | |
| computed_color_(computed_color) {} | |
| void ComputedShadowProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kNone: | |
| computed_shadow_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| void ComputedShadowProvider::VisitPropertyList( | |
| PropertyListValue* property_list_value) { | |
| std::unique_ptr<PropertyListValue::Builder> builder( | |
| new PropertyListValue::Builder()); | |
| builder->reserve(property_list_value->value().size()); | |
| for (size_t i = 0; i < property_list_value->value().size(); ++i) { | |
| ShadowValue* shadow_value = base::polymorphic_downcast<ShadowValue*>( | |
| property_list_value->value()[i].get()); | |
| scoped_refptr<LengthValue> computed_lengths[ShadowValue::kMaxLengths]; | |
| for (int j = 0; j < ShadowValue::kMaxLengths; ++j) { | |
| LengthValue* specified_length = shadow_value->lengths()[j].get(); | |
| if (specified_length) { | |
| computed_lengths[j] = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| } | |
| scoped_refptr<RGBAColorValue> color = shadow_value->color(); | |
| if (!color) { | |
| color = new RGBAColorValue(computed_color_->value()); | |
| } | |
| builder->push_back( | |
| new ShadowValue(computed_lengths, color, shadow_value->has_inset())); | |
| } | |
| computed_shadow_ = new PropertyListValue(std::move(builder)); | |
| } | |
| // Computed value: for length of translation transforms. | |
| // https://www.w3.org/TR/css3-transforms/#propdef-transform | |
| class ComputedTransformFunctionProvider : public TransformFunctionVisitor { | |
| public: | |
| ComputedTransformFunctionProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitMatrix(const MatrixFunction* matrix_function) override; | |
| void VisitRotate(const RotateFunction* rotate_function) override; | |
| void VisitScale(const ScaleFunction* scale_function) override; | |
| void VisitTranslate(const TranslateFunction* translate_function) override; | |
| void VisitCobaltUiNavFocusTransform( | |
| const CobaltUiNavFocusTransformFunction* focus_function) override; | |
| void VisitCobaltUiNavSpotlightTransform( | |
| const CobaltUiNavSpotlightTransformFunction* spotlight_function) override; | |
| std::unique_ptr<TransformFunction> PassComputedTransformFunction() { | |
| return std::move(computed_transform_function_); | |
| } | |
| private: | |
| std::unique_ptr<TransformFunction> computed_transform_function_; | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| }; | |
| ComputedTransformFunctionProvider::ComputedTransformFunctionProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedTransformFunctionProvider::VisitMatrix( | |
| const MatrixFunction* matrix_function) { | |
| computed_transform_function_.reset(new MatrixFunction(*matrix_function)); | |
| } | |
| void ComputedTransformFunctionProvider::VisitRotate( | |
| const RotateFunction* rotate_function) { | |
| computed_transform_function_.reset(new RotateFunction(*rotate_function)); | |
| } | |
| void ComputedTransformFunctionProvider::VisitScale( | |
| const ScaleFunction* scale_function) { | |
| computed_transform_function_.reset(new ScaleFunction(*scale_function)); | |
| } | |
| void ComputedTransformFunctionProvider::VisitTranslate( | |
| const TranslateFunction* translate_function) { | |
| switch (translate_function->offset_type()) { | |
| case TranslateFunction::kLength: { | |
| computed_transform_function_.reset(new TranslateFunction( | |
| translate_function->axis(), | |
| ProvideAbsoluteLength(translate_function->offset_as_length(), | |
| computed_font_size_, root_computed_font_size_, | |
| viewport_size_))); | |
| } break; | |
| case TranslateFunction::kPercentage: { | |
| computed_transform_function_.reset( | |
| new TranslateFunction(*translate_function)); | |
| } break; | |
| case TranslateFunction::kCalc: { | |
| scoped_refptr<CalcValue> calc_value = | |
| translate_function->offset_as_calc(); | |
| computed_transform_function_.reset(new TranslateFunction( | |
| translate_function->axis(), | |
| new CalcValue(ProvideAbsoluteLength( | |
| calc_value->length_value(), computed_font_size_, | |
| root_computed_font_size_, viewport_size_), | |
| calc_value->percentage_value()))); | |
| } break; | |
| } | |
| } | |
| void ComputedTransformFunctionProvider::VisitCobaltUiNavFocusTransform( | |
| const CobaltUiNavFocusTransformFunction* focus_function) { | |
| computed_transform_function_.reset( | |
| new CobaltUiNavFocusTransformFunction(*focus_function)); | |
| } | |
| void ComputedTransformFunctionProvider::VisitCobaltUiNavSpotlightTransform( | |
| const CobaltUiNavSpotlightTransformFunction* spotlight_function) { | |
| computed_transform_function_.reset( | |
| new CobaltUiNavSpotlightTransformFunction(*spotlight_function)); | |
| } | |
| // Absolutizes the value of "text-indent" property. | |
| class ComputedTextIndentProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedTextIndentProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitLength(LengthValue* length) override; | |
| const scoped_refptr<LengthValue>& computed_text_indent() const { | |
| return computed_text_indent_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<LengthValue> computed_text_indent_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedTextIndentProvider); | |
| }; | |
| ComputedTextIndentProvider::ComputedTextIndentProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedTextIndentProvider::VisitLength(LengthValue* specified_length) { | |
| computed_text_indent_ = | |
| ProvideAbsoluteLength(specified_length, computed_font_size_, | |
| root_computed_font_size_, viewport_size_); | |
| } | |
| // ComputedTransformOriginProvider provides a property list which has three | |
| // PropertyValues. The first two PropertyValues are CalcValue to represent | |
| // the horizontal position (or offset) and the vertical position (or offset). | |
| // The third value always represents the Z position (or offset) and must be a | |
| // LengthValue. | |
| // https://www.w3.org/TR/css3-transforms/#propdef-transform-origin | |
| class ComputedTransformOriginProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedTransformOriginProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitPropertyList(PropertyListValue* property_list_value) override; | |
| const scoped_refptr<PropertyValue>& computed_transform_origin() const { | |
| return computed_transform_origin_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_transform_origin_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedTransformOriginProvider); | |
| }; | |
| ComputedTransformOriginProvider::ComputedTransformOriginProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedTransformOriginProvider::VisitPropertyList( | |
| PropertyListValue* property_list_value) { | |
| size_t size = property_list_value->value().size(); | |
| DCHECK_GE(size, 1u); | |
| DCHECK_LE(size, 3u); | |
| ComputedPositionHelper position_helper( | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| std::unique_ptr<PropertyListValue::Builder> transform_origin_builder( | |
| new PropertyListValue::Builder(3, scoped_refptr<PropertyValue>())); | |
| // If one or two values are specified, the third value is assumed to be 0px. | |
| switch (size) { | |
| case 1: | |
| case 2: | |
| position_helper.ComputePosition(property_list_value->value(), | |
| transform_origin_builder.get()); | |
| (*transform_origin_builder)[2] = new LengthValue(0.0f, kPixelsUnit); | |
| break; | |
| case 3: | |
| position_helper.ComputeTwoValuesPosition(property_list_value->value(), | |
| transform_origin_builder.get()); | |
| // The third value must be LengthValue type. | |
| (*transform_origin_builder)[2] = ProvideAbsoluteLength( | |
| base::polymorphic_downcast<LengthValue*>( | |
| property_list_value->value()[2].get()), | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| break; | |
| } | |
| computed_transform_origin_ = | |
| new PropertyListValue(std::move(transform_origin_builder)); | |
| } | |
| class ComputedTransformProvider : public NotReachedPropertyValueVisitor { | |
| public: | |
| ComputedTransformProvider(const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, | |
| const math::Size& viewport_size); | |
| void VisitKeyword(KeywordValue* keyword) override; | |
| void VisitTransformPropertyValue( | |
| TransformPropertyValue* transform_property_value) override; | |
| const scoped_refptr<PropertyValue>& computed_transform_list() const { | |
| return computed_transform_list_; | |
| } | |
| private: | |
| const LengthValue* computed_font_size_; | |
| const LengthValue* root_computed_font_size_; | |
| const math::Size& viewport_size_; | |
| scoped_refptr<PropertyValue> computed_transform_list_; | |
| DISALLOW_COPY_AND_ASSIGN(ComputedTransformProvider); | |
| }; | |
| ComputedTransformProvider::ComputedTransformProvider( | |
| const LengthValue* computed_font_size, | |
| const LengthValue* root_computed_font_size, const math::Size& viewport_size) | |
| : computed_font_size_(computed_font_size), | |
| root_computed_font_size_(root_computed_font_size), | |
| viewport_size_(viewport_size) {} | |
| void ComputedTransformProvider::VisitTransformPropertyValue( | |
| TransformPropertyValue* transform_property_value) { | |
| // This should only ever be a TransformFunctionListValue at this point. | |
| TransformFunctionListValue* transform_function_list = | |
| base::polymorphic_downcast<TransformFunctionListValue*>( | |
| transform_property_value); | |
| if (!transform_function_list->value().HasTrait( | |
| TransformFunction::kTraitUsesRelativeUnits)) { | |
| // If the transform list contains no transforms that use relative units, | |
| // then we do not need to do anything and we can pass through the existing | |
| // transform. | |
| computed_transform_list_ = transform_function_list; | |
| } else { | |
| // The transform list contains at least one transform with relative units. | |
| // In this case, rebuild the transform list with computed length values. | |
| TransformFunctionListValue::Builder computed_list_builder; | |
| for (TransformFunctionListValue::Builder::const_iterator iter = | |
| transform_function_list->value().begin(); | |
| iter != transform_function_list->value().end(); ++iter) { | |
| TransformFunction* transform_function = iter->get(); | |
| ComputedTransformFunctionProvider computed_transform_function_provider( | |
| computed_font_size_, root_computed_font_size_, viewport_size_); | |
| transform_function->Accept(&computed_transform_function_provider); | |
| computed_list_builder.push_back( | |
| computed_transform_function_provider.PassComputedTransformFunction()); | |
| } | |
| computed_transform_list_ = | |
| new TransformFunctionListValue(std::move(computed_list_builder)); | |
| } | |
| } | |
| void ComputedTransformProvider::VisitKeyword(KeywordValue* keyword) { | |
| switch (keyword->value()) { | |
| case KeywordValue::kNone: | |
| computed_transform_list_ = keyword; | |
| break; | |
| case KeywordValue::kAbsolute: | |
| case KeywordValue::kAlternate: | |
| case KeywordValue::kAlternateReverse: | |
| case KeywordValue::kAuto: | |
| case KeywordValue::kBackwards: | |
| case KeywordValue::kBaseline: | |
| case KeywordValue::kBlock: | |
| case KeywordValue::kBoth: | |
| case KeywordValue::kBottom: | |
| case KeywordValue::kBreakWord: | |
| case KeywordValue::kCenter: | |
| case KeywordValue::kClip: | |
| case KeywordValue::kCollapse: | |
| case KeywordValue::kColumn: | |
| case KeywordValue::kColumnReverse: | |
| case KeywordValue::kContain: | |
| case KeywordValue::kContent: | |
| case KeywordValue::kCover: | |
| case KeywordValue::kCurrentColor: | |
| case KeywordValue::kCursive: | |
| case KeywordValue::kEllipsis: | |
| case KeywordValue::kEnd: | |
| case KeywordValue::kEquirectangular: | |
| case KeywordValue::kFantasy: | |
| case KeywordValue::kFixed: | |
| case KeywordValue::kFlex: | |
| case KeywordValue::kFlexEnd: | |
| case KeywordValue::kFlexStart: | |
| case KeywordValue::kForwards: | |
| case KeywordValue::kHidden: | |
| case KeywordValue::kInfinite: | |
| case KeywordValue::kInherit: | |
| case KeywordValue::kInitial: | |
| case KeywordValue::kInline: | |
| case KeywordValue::kInlineBlock: | |
| case KeywordValue::kInlineFlex: | |
| case KeywordValue::kLeft: | |
| case KeywordValue::kLineThrough: | |
| case KeywordValue::kMiddle: | |
| case KeywordValue::kMonoscopic: | |
| case KeywordValue::kMonospace: | |
| case KeywordValue::kNoRepeat: | |
| case KeywordValue::kNormal: | |
| case KeywordValue::kNowrap: | |
| case KeywordValue::kPre: | |
| case KeywordValue::kPreLine: | |
| case KeywordValue::kPreWrap: | |
| case KeywordValue::kRelative: | |
| case KeywordValue::kRepeat: | |
| case KeywordValue::kReverse: | |
| case KeywordValue::kRight: | |
| case KeywordValue::kRow: | |
| case KeywordValue::kRowReverse: | |
| case KeywordValue::kSansSerif: | |
| case KeywordValue::kScroll: | |
| case KeywordValue::kSerif: | |
| case KeywordValue::kSolid: | |
| case KeywordValue::kSpaceAround: | |
| case KeywordValue::kSpaceBetween: | |
| case KeywordValue::kStart: | |
| case KeywordValue::kStatic: | |
| case KeywordValue::kStereoscopicLeftRight: | |
| case KeywordValue::kStereoscopicTopBottom: | |
| case KeywordValue::kStretch: | |
| case KeywordValue::kTop: | |
| case KeywordValue::kUppercase: | |
| case KeywordValue::kVisible: | |
| case KeywordValue::kWrap: | |
| case KeywordValue::kWrapReverse: | |
| NOTREACHED(); | |
| } | |
| } | |
| // This helper class creates a context within which cascaded style properties | |
| // can be efficiently promoted to computed properties. | |
| // In particular, some computed style calculations depend on other computed | |
| // styles, and this class manages the caching of those dependent values so that | |
| // if they are depended upon more than once, they are quickly recalled, and if | |
| // they are never depended upon, no extra time is spend resolving them. For | |
| // example, many properties depend on font size, and so they can simply call | |
| // CalculateComputedStyleContext::GetFontSize() to obtain that value, and all | |
| // computations will be handled internally. | |
| class CalculateComputedStyleContext { | |
| public: | |
| CalculateComputedStyleContext( | |
| MutableCSSComputedStyleData* cascaded_style, | |
| const scoped_refptr<CSSComputedStyleDeclaration>& | |
| parent_computed_style_declaration, | |
| const scoped_refptr<const CSSComputedStyleData>& root_computed_style, | |
| const math::Size& viewport_size, | |
| GURLMap* const property_key_to_base_url_map) | |
| : cascaded_style_(cascaded_style), | |
| parent_computed_style_(*parent_computed_style_declaration->data()), | |
| root_computed_style_(*root_computed_style), | |
| viewport_size_(viewport_size), | |
| property_key_to_base_url_map_(property_key_to_base_url_map) { | |
| cascaded_style_->SetParentComputedStyleDeclaration( | |
| parent_computed_style_declaration); | |
| } | |
| // Updates the property specified by the iterator to its computed value. | |
| void SetComputedStyleForProperty(PropertyKey key, | |
| scoped_refptr<PropertyValue>* value); | |
| // For certain elements, the computed value of display becomes 'block'. | |
| // https://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo | |
| // This is amended by flexbox for 'inline-flex' and 'flex'. | |
| // https://www.w3.org/TR/css-flexbox-1/#flex-containers | |
| // Flex items are also modified in this way. | |
| // https://www.w3.org/TR/css-flexbox-1/#flex-items | |
| // In CSS Display 3 (which Cobalt does not yet implement), this process is | |
| // called 'blockification'/'blockify'. | |
| // https://www.w3.org/TR/css-display-3/#blockify | |
| void BlockifyIfNeeded(); | |
| private: | |
| // Immediately promote the specified property key to computed value (if | |
| // necessary). | |
| void ComputeValue(PropertyKey key); | |
| // Check if the property value is set to inherit or initial, and assign it | |
| // an appropriate computed value in this case. | |
| bool HandleInheritOrInitial(PropertyKey key, | |
| scoped_refptr<PropertyValue>* value); | |
| // Check what property property we are dealing with, and promote it to | |
| // a computed value accordingly (e.g. by invoking one of the many different | |
| // computed style computations defined above.) | |
| void HandleSpecifiedValue(PropertyKey key, | |
| scoped_refptr<PropertyValue>* value); | |
| // If the modified value was a (potentially) dependent property value, cache | |
| // its computed value so that we know it has been computed. | |
| void OnComputedStyleCalculated(PropertyKey key, | |
| const scoped_refptr<PropertyValue>& value); | |
| // Helper function to determine if the computed style implies absolute | |
| // positioning. | |
| bool IsAbsolutelyPositioned(); | |
| // Helper function to return the computed font size. | |
| LengthValue* GetFontSize(); | |
| // Helper function to return the computed font size of root element. | |
| LengthValue* GetRootFontSize(); | |
| // Helper function to return one percent of the viewport size . | |
| const math::Size& GetViewportSizeOnePercent(); | |
| // Helper function to return the computed border style for an edge based on | |
| // border width properties. | |
| PropertyValue* GetBorderOrOutlineStyleBasedOnWidth(PropertyKey key); | |
| PropertyValue* GetBorderBottomStyle(); | |
| PropertyValue* GetBorderLeftStyle(); | |
| PropertyValue* GetBorderRightStyle(); | |
| PropertyValue* GetBorderTopStyle(); | |
| PropertyValue* GetOutlineStyle(); | |
| // Helper function to return the computed color. | |
| RGBAColorValue* GetColor(); | |
| // The style that, during the scope of CalculateComputedStyleContext, is | |
| // promoted from being a cascaded style to a computed style. | |
| MutableCSSComputedStyleData* cascaded_style_; | |
| // The parent computed style. | |
| const CSSComputedStyleData& parent_computed_style_; | |
| // The root computed style. | |
| const CSSComputedStyleData& root_computed_style_; | |
| // One percent of width and height of viewport size. | |
| const math::Size& viewport_size_; | |
| // Provides a base URL for each property key. This is used by properties | |
| // that deal with URLs, such as background-image, to resolve relative URLs | |
| // based on which style sheet they were specified from. | |
| GURLMap* const property_key_to_base_url_map_; | |
| // Cached computed values for a small specific set of properties that other | |
| // properties computed style calculations depend upon. These are lazily | |
| // computed. | |
| scoped_refptr<PropertyValue> computed_border_bottom_style_; | |
| scoped_refptr<PropertyValue> computed_border_left_style_; | |
| scoped_refptr<PropertyValue> computed_border_right_style_; | |
| scoped_refptr<PropertyValue> computed_border_top_style_; | |
| scoped_refptr<PropertyValue> computed_color_; | |
| scoped_refptr<PropertyValue> computed_font_size_; | |
| scoped_refptr<PropertyValue> computed_outline_style_; | |
| scoped_refptr<PropertyValue> computed_position_; | |
| }; | |
| void CalculateComputedStyleContext::SetComputedStyleForProperty( | |
| PropertyKey key, scoped_refptr<PropertyValue>* value) { | |
| // If a property has keyword value 'inherit' or 'initial', it must be | |
| // set to the corresponding inherited or initial value. In this case, | |
| // the parent's value is already computed so we can skip the computation | |
| // step. | |
| if (!HandleInheritOrInitial(key, value)) { | |
| HandleSpecifiedValue(key, value); | |
| } | |
| OnComputedStyleCalculated(key, *value); | |
| } | |
| void CalculateComputedStyleContext::BlockifyIfNeeded() { | |
| auto display = cascaded_style_->display(); | |
| bool is_inline_flex = display == KeywordValue::GetInlineFlex(); | |
| bool is_inline = display == KeywordValue::GetInline() || | |
| display == KeywordValue::GetInlineBlock() || is_inline_flex; | |
| auto parent_display = parent_computed_style_.display(); | |
| bool parent_is_flex_container = | |
| parent_display == KeywordValue::GetFlex() || | |
| parent_display == KeywordValue::GetInlineFlex(); | |
| // Blockification is applied for elements with in inline outer display type | |
| // inline when they are either absolutely positioned, | |
| // https://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo | |
| // or when they are flex items. | |
| // https://www.w3.org/TR/css-flexbox-1/#flex-items | |
| // Since children of flex containers are either flex items or absolutely | |
| // positioned, we apply blockification for all flex children. | |
| if (is_inline && (IsAbsolutelyPositioned() || parent_is_flex_container)) { | |
| if (is_inline_flex) { | |
| cascaded_style_->set_display(KeywordValue::GetFlex()); | |
| } else { | |
| cascaded_style_->set_display(KeywordValue::GetBlock()); | |
| } | |
| } | |
| cascaded_style_->set_is_inline_before_blockification(is_inline); | |
| } | |
| bool CalculateComputedStyleContext::IsAbsolutelyPositioned() { | |
| // An absolutely positioned element (or its box) implies that the element's | |
| // 'position' property has the value 'absolute' or 'fixed'. | |
| // https://www.w3.org/TR/CSS21/visuren.html#absolutely-positioned | |
| if (!computed_position_) { | |
| ComputeValue(kPositionProperty); | |
| } | |
| DCHECK(computed_position_); | |
| return computed_position_ == KeywordValue::GetAbsolute() || | |
| computed_position_ == KeywordValue::GetFixed(); | |
| } | |
| LengthValue* CalculateComputedStyleContext::GetFontSize() { | |
| if (!computed_font_size_) { | |
| ComputeValue(kFontSizeProperty); | |
| } | |
| DCHECK(computed_font_size_); | |
| return base::polymorphic_downcast<LengthValue*>(computed_font_size_.get()); | |
| } | |
| LengthValue* CalculateComputedStyleContext::GetRootFontSize() { | |
| return base::polymorphic_downcast<LengthValue*>( | |
| root_computed_style_.font_size().get()); | |
| } | |
| const math::Size& CalculateComputedStyleContext::GetViewportSizeOnePercent() { | |
| return viewport_size_; | |
| } | |
| PropertyValue* | |
| CalculateComputedStyleContext::GetBorderOrOutlineStyleBasedOnWidth( | |
| PropertyKey key) { | |
| if (key == kBorderBottomWidthProperty) { | |
| return GetBorderBottomStyle(); | |
| } else if (key == kBorderLeftWidthProperty) { | |
| return GetBorderLeftStyle(); | |
| } else if (key == kBorderRightWidthProperty) { | |
| return GetBorderRightStyle(); | |
| } else if (key == kBorderTopWidthProperty) { | |
| return GetBorderTopStyle(); | |
| } else { | |
| DCHECK_EQ(key, kOutlineWidthProperty); | |
| return GetOutlineStyle(); | |
| } | |
| } | |
| PropertyValue* CalculateComputedStyleContext::GetBorderBottomStyle() { | |
| if (!computed_border_bottom_style_) { | |
| ComputeValue(kBorderBottomStyleProperty); | |
| } | |
| DCHECK(computed_border_bottom_style_); | |
| return computed_border_bottom_style_.get(); | |
| } | |
| PropertyValue* CalculateComputedStyleContext::GetBorderLeftStyle() { | |
| if (!computed_border_left_style_) { | |
| ComputeValue(kBorderLeftStyleProperty); | |
| } | |
| DCHECK(computed_border_left_style_); | |
| return computed_border_left_style_.get(); | |
| } | |
| PropertyValue* CalculateComputedStyleContext::GetBorderRightStyle() { | |
| if (!computed_border_right_style_) { | |
| ComputeValue(kBorderRightStyleProperty); | |
| } | |
| DCHECK(computed_border_right_style_); | |
| return computed_border_right_style_.get(); | |
| } | |
| PropertyValue* CalculateComputedStyleContext::GetBorderTopStyle() { | |
| if (!computed_border_top_style_) { | |
| ComputeValue(kBorderTopStyleProperty); | |
| } | |
| DCHECK(computed_border_top_style_); | |
| return computed_border_top_style_.get(); | |
| } | |
| RGBAColorValue* CalculateComputedStyleContext::GetColor() { | |
| if (!computed_color_) { | |
| ComputeValue(kColorProperty); | |
| } | |
| DCHECK(computed_color_); | |
| return base::polymorphic_downcast<RGBAColorValue*>(computed_color_.get()); | |
| } | |
| PropertyValue* CalculateComputedStyleContext::GetOutlineStyle() { | |
| if (!computed_outline_style_) { | |
| ComputeValue(kOutlineStyleProperty); | |
| } | |
| DCHECK(computed_outline_style_); | |
| return computed_outline_style_.get(); | |
| } | |
| void CalculateComputedStyleContext::ComputeValue(PropertyKey key) { | |
| if (cascaded_style_->IsDeclared(key)) { | |
| scoped_refptr<PropertyValue>& cascaded_value = | |
| cascaded_style_->GetDeclaredPropertyValueReference(key); | |
| SetComputedStyleForProperty(key, &cascaded_value); | |
| } else { | |
| const scoped_refptr<PropertyValue>& computed_value = | |
| cascaded_style_->GetPropertyValueReference(key); | |
| OnComputedStyleCalculated(key, computed_value); | |
| } | |
| } | |
| bool CalculateComputedStyleContext::HandleInheritOrInitial( | |
| PropertyKey key, scoped_refptr<PropertyValue>* value) { | |
| if (*value == KeywordValue::GetInherit()) { | |
| // Add this property to the list of those that inherited their declared | |
| // value from the parent. This allows the computed style to later determine | |
| // if a value that was explicitly inherited from the parent is no longer | |
| // valid. | |
| cascaded_style_->AddDeclaredPropertyInheritedFromParent(key); | |
| *value = parent_computed_style_.GetPropertyValue(key); | |
| return true; | |
| } else if (*value == KeywordValue::GetInitial()) { | |
| *value = GetPropertyInitialValue(key); | |
| // If the initial value is current color, it still requires to do further | |
| // processing. | |
| return *value == KeywordValue::GetCurrentColor() ? false : true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| void CalculateComputedStyleContext::HandleSpecifiedValue( | |
| PropertyKey key, scoped_refptr<PropertyValue>* value) { | |
| switch (key) { | |
| case kBackgroundPositionProperty: { | |
| ComputedBackgroundPositionProvider background_position_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&background_position_provider); | |
| const scoped_refptr<PropertyValue>& computed_background_position = | |
| background_position_provider.computed_background_position(); | |
| if (computed_background_position) { | |
| *value = computed_background_position; | |
| } | |
| } break; | |
| case kBorderBottomColorProperty: | |
| case kBorderLeftColorProperty: | |
| case kBorderRightColorProperty: | |
| case kBorderTopColorProperty: | |
| case kOutlineColorProperty: | |
| case kTextDecorationColorProperty: { | |
| if (*value == KeywordValue::GetCurrentColor()) { | |
| // The computed value of the 'currentColor' keyword is the computed | |
| // value of the 'color' property. | |
| *value = GetColor(); | |
| } | |
| } break; | |
| case kBorderBottomWidthProperty: | |
| case kBorderLeftWidthProperty: | |
| case kBorderRightWidthProperty: | |
| case kBorderTopWidthProperty: | |
| case kOutlineWidthProperty: { | |
| ComputedBorderWidthProvider border_width_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent(), | |
| GetBorderOrOutlineStyleBasedOnWidth(key)); | |
| (*value)->Accept(&border_width_provider); | |
| *value = border_width_provider.computed_border_width(); | |
| } break; | |
| case kBoxShadowProperty: | |
| case kTextShadowProperty: { | |
| ComputedShadowProvider shadow_provider(GetFontSize(), GetRootFontSize(), | |
| GetViewportSizeOnePercent(), | |
| GetColor()); | |
| (*value)->Accept(&shadow_provider); | |
| *value = shadow_provider.computed_shadow(); | |
| } break; | |
| case kFlexBasisProperty: { | |
| ComputedFlexBasisProvider flex_basis_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&flex_basis_provider); | |
| *value = flex_basis_provider.computed_value(); | |
| } break; | |
| case kFontSizeProperty: { | |
| // Only compute this if computed_font_size_ isn't set, otherwise that | |
| // is an indication that it was previously computed as a dependency for | |
| // another property value computation. | |
| if (!computed_font_size_) { | |
| ComputedFontSizeProvider font_size_provider( | |
| base::polymorphic_downcast<LengthValue*>( | |
| parent_computed_style_.font_size().get()), | |
| GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&font_size_provider); | |
| if (font_size_provider.computed_font_size()) { | |
| *value = font_size_provider.computed_font_size(); | |
| } | |
| } | |
| } break; | |
| case kFontWeightProperty: { | |
| ComputedFontWeightProvider font_weight_provider; | |
| (*value)->Accept(&font_weight_provider); | |
| *value = font_weight_provider.computed_font_weight(); | |
| } break; | |
| case kHeightProperty: { | |
| ComputedHeightProvider height_provider( | |
| parent_computed_style_.height().get(), | |
| parent_computed_style_.top().get(), | |
| parent_computed_style_.bottom().get(), GetFontSize(), | |
| GetRootFontSize(), GetViewportSizeOnePercent(), | |
| IsAbsolutelyPositioned()); | |
| (*value)->Accept(&height_provider); | |
| *value = height_provider.computed_height(); | |
| } break; | |
| case kLineHeightProperty: { | |
| ComputedLineHeightProvider line_height_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&line_height_provider); | |
| *value = line_height_provider.computed_line_height(); | |
| } break; | |
| case kMarginBottomProperty: | |
| case kMarginLeftProperty: | |
| case kMarginRightProperty: | |
| case kMarginTopProperty: { | |
| ComputedMarginOrPaddingEdgeProvider margin_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&margin_provider); | |
| *value = margin_provider.computed_margin_or_padding_edge(); | |
| } break; | |
| case kPaddingBottomProperty: | |
| case kPaddingLeftProperty: | |
| case kPaddingRightProperty: | |
| case kPaddingTopProperty: { | |
| ComputedMarginOrPaddingEdgeProvider padding_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&padding_provider); | |
| *value = padding_provider.computed_margin_or_padding_edge(); | |
| } break; | |
| case kMaxHeightProperty: { | |
| ComputedMaxHeightProvider max_height_provider( | |
| parent_computed_style_.height().get(), GetFontSize(), | |
| GetRootFontSize(), GetViewportSizeOnePercent(), | |
| IsAbsolutelyPositioned()); | |
| (*value)->Accept(&max_height_provider); | |
| *value = max_height_provider.computed_max_height(); | |
| } break; | |
| case kMinHeightProperty: { | |
| ComputedMinHeightProvider min_height_provider( | |
| parent_computed_style_.height().get(), GetFontSize(), | |
| GetRootFontSize(), GetViewportSizeOnePercent(), | |
| IsAbsolutelyPositioned()); | |
| (*value)->Accept(&min_height_provider); | |
| *value = min_height_provider.computed_min_height(); | |
| } break; | |
| case kMaxWidthProperty: | |
| case kMinWidthProperty: { | |
| ComputedMinMaxWidthProvider min_max_width_provider( | |
| parent_computed_style_.width().get(), GetFontSize(), | |
| GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&min_max_width_provider); | |
| *value = min_max_width_provider.computed_min_max_width(); | |
| } break; | |
| case kWidthProperty: { | |
| ComputedWidthProvider width_provider(GetFontSize(), GetRootFontSize(), | |
| GetViewportSizeOnePercent()); | |
| (*value)->Accept(&width_provider); | |
| *value = width_provider.computed_value(); | |
| } break; | |
| case kBackgroundImageProperty: { | |
| if (property_key_to_base_url_map_) { | |
| ComputedBackgroundImageProvider background_image_provider( | |
| (*property_key_to_base_url_map_)[kBackgroundImageProperty], | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&background_image_provider); | |
| *value = background_image_provider.computed_background_image(); | |
| } | |
| } break; | |
| case kBackgroundSizeProperty: { | |
| ComputedBackgroundSizeProvider background_size_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&background_size_provider); | |
| *value = background_size_provider.computed_background_size(); | |
| } break; | |
| case kBorderBottomLeftRadiusProperty: | |
| case kBorderBottomRightRadiusProperty: | |
| case kBorderTopLeftRadiusProperty: | |
| case kBorderTopRightRadiusProperty: { | |
| ComputedBorderRadiusProvider border_radius_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&border_radius_provider); | |
| *value = border_radius_provider.computed_border_radius(); | |
| } break; | |
| case kTextIndentProperty: { | |
| ComputedTextIndentProvider text_indent_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&text_indent_provider); | |
| *value = text_indent_provider.computed_text_indent(); | |
| } break; | |
| case kTransformOriginProperty: { | |
| ComputedTransformOriginProvider transform_origin_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&transform_origin_provider); | |
| *value = transform_origin_provider.computed_transform_origin(); | |
| } break; | |
| case kTransformProperty: { | |
| ComputedTransformProvider transform_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&transform_provider); | |
| *value = transform_provider.computed_transform_list(); | |
| } break; | |
| case kBottomProperty: | |
| case kLeftProperty: | |
| case kRightProperty: | |
| case kTopProperty: { | |
| ComputedPositionOffsetProvider position_offset_provider( | |
| GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent()); | |
| (*value)->Accept(&position_offset_provider); | |
| *value = position_offset_provider.computed_position_offset(); | |
| } break; | |
| // The specified value resolves directly to the computed value for these | |
| // properties. | |
| case kAlignContentProperty: | |
| case kAlignItemsProperty: | |
| case kAlignSelfProperty: | |
| case kAnimationDelayProperty: | |
| case kAnimationDirectionProperty: | |
| case kAnimationDurationProperty: | |
| case kAnimationFillModeProperty: | |
| case kAnimationIterationCountProperty: | |
| case kAnimationNameProperty: | |
| case kAnimationTimingFunctionProperty: | |
| case kBackgroundColorProperty: | |
| case kBackgroundRepeatProperty: | |
| case kBorderBottomStyleProperty: | |
| case kBorderLeftStyleProperty: | |
| case kBorderRightStyleProperty: | |
| case kBorderTopStyleProperty: | |
| case kColorProperty: | |
| case kContentProperty: | |
| case kDisplayProperty: | |
| case kFilterProperty: | |
| case kFlexDirectionProperty: | |
| case kFlexGrowProperty: | |
| case kFlexShrinkProperty: | |
| case kFlexWrapProperty: | |
| case kFontFamilyProperty: | |
| case kFontStyleProperty: | |
| case kIntersectionObserverRootMarginProperty: | |
| case kJustifyContentProperty: | |
| case kOpacityProperty: | |
| case kOrderProperty: | |
| case kOutlineStyleProperty: | |
| case kOverflowProperty: | |
| case kOverflowWrapProperty: | |
| case kPointerEventsProperty: | |
| case kPositionProperty: | |
| case kTextAlignProperty: | |
| case kTextDecorationLineProperty: | |
| case kTextOverflowProperty: | |
| case kTextTransformProperty: | |
| case kTransitionDelayProperty: | |
| case kTransitionDurationProperty: | |
| case kTransitionPropertyProperty: | |
| case kTransitionTimingFunctionProperty: | |
| case kVerticalAlignProperty: | |
| case kVisibilityProperty: | |
| case kWhiteSpaceProperty: | |
| case kWordWrapProperty: | |
| case kZIndexProperty: | |
| // Nothing. | |
| break; | |
| // Shorthand properties and at-rule properties should not occur here because | |
| // they do not have computed values themselves. | |
| case kAllProperty: | |
| case kAnimationProperty: | |
| case kBackgroundProperty: | |
| case kBorderBottomProperty: | |
| case kBorderColorProperty: | |
| case kBorderLeftProperty: | |
| case kBorderProperty: | |
| case kBorderRadiusProperty: | |
| case kBorderRightProperty: | |
| case kBorderStyleProperty: | |
| case kBorderTopProperty: | |
| case kBorderWidthProperty: | |
| case kFlexProperty: | |
| case kFlexFlowProperty: | |
| case kFontProperty: | |
| case kMarginProperty: | |
| case kNoneProperty: | |
| case kOutlineProperty: | |
| case kPaddingProperty: | |
| case kSrcProperty: | |
| case kTextDecorationProperty: | |
| case kTransitionProperty: | |
| case kUnicodeRangeProperty: | |
| NOTREACHED(); | |
| break; | |
| } | |
| } // NOLINT(readability/fn_size) | |
| void CalculateComputedStyleContext::OnComputedStyleCalculated( | |
| PropertyKey key, const scoped_refptr<PropertyValue>& value) { | |
| switch (key) { | |
| case kFontSizeProperty: | |
| computed_font_size_ = value; | |
| break; | |
| case kPositionProperty: | |
| computed_position_ = value; | |
| break; | |
| case kBorderBottomStyleProperty: | |
| computed_border_bottom_style_ = value; | |
| break; | |
| case kBorderLeftStyleProperty: | |
| computed_border_left_style_ = value; | |
| break; | |
| case kBorderRightStyleProperty: | |
| computed_border_right_style_ = value; | |
| break; | |
| case kBorderTopStyleProperty: | |
| computed_border_top_style_ = value; | |
| break; | |
| case kColorProperty: | |
| computed_color_ = value; | |
| break; | |
| case kOutlineStyleProperty: | |
| computed_outline_style_ = value; | |
| break; | |
| case kAllProperty: | |
| case kAlignContentProperty: | |
| case kAlignItemsProperty: | |
| case kAlignSelfProperty: | |
| case kAnimationDelayProperty: | |
| case kAnimationDirectionProperty: | |
| case kAnimationDurationProperty: | |
| case kAnimationFillModeProperty: | |
| case kAnimationIterationCountProperty: | |
| case kAnimationNameProperty: | |
| case kAnimationProperty: | |
| case kAnimationTimingFunctionProperty: | |
| case kBackgroundColorProperty: | |
| case kBackgroundImageProperty: | |
| case kBackgroundPositionProperty: | |
| case kBackgroundProperty: | |
| case kBackgroundRepeatProperty: | |
| case kBackgroundSizeProperty: | |
| case kBorderBottomProperty: | |
| case kBorderBottomColorProperty: | |
| case kBorderBottomLeftRadiusProperty: | |
| case kBorderBottomRightRadiusProperty: | |
| case kBorderBottomWidthProperty: | |
| case kBorderColorProperty: | |
| case kBorderLeftProperty: | |
| case kBorderLeftColorProperty: | |
| case kBorderLeftWidthProperty: | |
| case kBorderRadiusProperty: | |
| case kBorderRightProperty: | |
| case kBorderRightColorProperty: | |
| case kBorderRightWidthProperty: | |
| case kBorderStyleProperty: | |
| case kBorderTopProperty: | |
| case kBorderTopColorProperty: | |
| case kBorderTopLeftRadiusProperty: | |
| case kBorderTopRightRadiusProperty: | |
| case kBorderTopWidthProperty: | |
| case kBorderProperty: | |
| case kBorderWidthProperty: | |
| case kBottomProperty: | |
| case kBoxShadowProperty: | |
| case kContentProperty: | |
| case kDisplayProperty: | |
| case kFilterProperty: | |
| case kFlexProperty: | |
| case kFlexBasisProperty: | |
| case kFlexDirectionProperty: | |
| case kFlexFlowProperty: | |
| case kFlexGrowProperty: | |
| case kFlexShrinkProperty: | |
| case kFlexWrapProperty: | |
| case kFontFamilyProperty: | |
| case kFontProperty: | |
| case kFontStyleProperty: | |
| case kFontWeightProperty: | |
| case kHeightProperty: | |
| case kIntersectionObserverRootMarginProperty: | |
| case kJustifyContentProperty: | |
| case kLeftProperty: | |
| case kLineHeightProperty: | |
| case kMarginBottomProperty: | |
| case kMarginLeftProperty: | |
| case kMarginProperty: | |
| case kMarginRightProperty: | |
| case kMarginTopProperty: | |
| case kMaxHeightProperty: | |
| case kMaxWidthProperty: | |
| case kMinHeightProperty: | |
| case kMinWidthProperty: | |
| case kNoneProperty: | |
| case kOpacityProperty: | |
| case kOrderProperty: | |
| case kOutlineProperty: | |
| case kOutlineColorProperty: | |
| case kOutlineWidthProperty: | |
| case kOverflowProperty: | |
| case kOverflowWrapProperty: | |
| case kPaddingBottomProperty: | |
| case kPaddingLeftProperty: | |
| case kPaddingProperty: | |
| case kPaddingRightProperty: | |
| case kPaddingTopProperty: | |
| case kPointerEventsProperty: | |
| case kRightProperty: | |
| case kSrcProperty: | |
| case kTextAlignProperty: | |
| case kTextDecorationColorProperty: | |
| case kTextDecorationLineProperty: | |
| case kTextDecorationProperty: | |
| case kTextIndentProperty: | |
| case kTextOverflowProperty: | |
| case kTextShadowProperty: | |
| case kTextTransformProperty: | |
| case kTopProperty: | |
| case kTransformOriginProperty: | |
| case kTransformProperty: | |
| case kTransitionDelayProperty: | |
| case kTransitionDurationProperty: | |
| case kTransitionProperty: | |
| case kTransitionPropertyProperty: | |
| case kTransitionTimingFunctionProperty: | |
| case kUnicodeRangeProperty: | |
| case kVerticalAlignProperty: | |
| case kVisibilityProperty: | |
| case kWhiteSpaceProperty: | |
| case kWidthProperty: | |
| case kWordWrapProperty: | |
| case kZIndexProperty: | |
| break; | |
| } | |
| } | |
| } // namespace | |
| void PromoteToComputedStyle( | |
| const scoped_refptr<MutableCSSComputedStyleData>& cascaded_style, | |
| const scoped_refptr<CSSComputedStyleDeclaration>& | |
| parent_computed_style_declaration, | |
| const scoped_refptr<const CSSComputedStyleData>& root_computed_style, | |
| const math::Size& viewport_size, | |
| GURLMap* const property_key_to_base_url_map) { | |
| DCHECK(cascaded_style); | |
| DCHECK(parent_computed_style_declaration); | |
| DCHECK(root_computed_style); | |
| if (!cascaded_style || !root_computed_style || | |
| !parent_computed_style_declaration) { | |
| return; | |
| } | |
| // Create a context for calculating the computed style. This object is | |
| // useful because it can cache computed style values that are depended upon | |
| // by other properties' computed style calculations. | |
| CalculateComputedStyleContext calculate_computed_style_context( | |
| cascaded_style.get(), parent_computed_style_declaration, | |
| root_computed_style, viewport_size, property_key_to_base_url_map); | |
| // For each inherited, animatable property, set the property value to | |
| // inherited if it is not already declared. This causes the value to be | |
| // explicitly set within the CSSComputedStyleData and ensures that the | |
| // original value will be available for transitions (which need to know the | |
| // before and after state of the property) even when the property is inherited | |
| // from a parent that has changed. | |
| const PropertyKeyVector& inherited_animatable_properties = | |
| GetInheritedAnimatableProperties(); | |
| for (PropertyKeyVector::const_iterator iter = | |
| inherited_animatable_properties.begin(); | |
| iter != inherited_animatable_properties.end(); ++iter) { | |
| if (!cascaded_style->IsDeclared(*iter)) { | |
| cascaded_style->SetPropertyValue(*iter, KeywordValue::GetInherit()); | |
| } | |
| } | |
| // Go through all declared values and calculate their computed values. | |
| CSSComputedStyleData::PropertyValues* declared_property_values = | |
| cascaded_style->declared_property_values(); | |
| for (CSSComputedStyleData::PropertyValues::iterator property_value_iterator = | |
| declared_property_values->begin(); | |
| property_value_iterator != declared_property_values->end(); | |
| ++property_value_iterator) { | |
| calculate_computed_style_context.SetComputedStyleForProperty( | |
| property_value_iterator->first, &property_value_iterator->second); | |
| } | |
| calculate_computed_style_context.BlockifyIfNeeded(); | |
| } | |
| scoped_refptr<CSSComputedStyleData> GetComputedStyleOfAnonymousBox( | |
| const scoped_refptr<CSSComputedStyleDeclaration>& | |
| parent_computed_style_declaration) { | |
| scoped_refptr<MutableCSSComputedStyleData> computed_style = | |
| new MutableCSSComputedStyleData(); | |
| PromoteToComputedStyle(computed_style, parent_computed_style_declaration, | |
| parent_computed_style_declaration->data(), | |
| math::Size(), NULL); | |
| return computed_style; | |
| } | |
| } // namespace cssom | |
| } // namespace cobalt |