| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/blink/renderer/core/css/basic_shape_functions.h" |
| #include "third_party/blink/renderer/core/css/css_axis_value.h" |
| #include "third_party/blink/renderer/core/css/css_color_value.h" |
| #include "third_party/blink/renderer/core/css/css_counter_value.h" |
| #include "third_party/blink/renderer/core/css/css_cursor_image_value.h" |
| #include "third_party/blink/renderer/core/css/css_custom_ident_value.h" |
| #include "third_party/blink/renderer/core/css/css_font_feature_value.h" |
| #include "third_party/blink/renderer/core/css/css_font_selector.h" |
| #include "third_party/blink/renderer/core/css/css_font_variation_value.h" |
| #include "third_party/blink/renderer/core/css/css_function_value.h" |
| #include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h" |
| #include "third_party/blink/renderer/core/css/css_identifier_value.h" |
| #include "third_party/blink/renderer/core/css/css_initial_color_value.h" |
| #include "third_party/blink/renderer/core/css/css_layout_function_value.h" |
| #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" |
| #include "third_party/blink/renderer/core/css/css_primitive_value.h" |
| #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" |
| #include "third_party/blink/renderer/core/css/css_quad_value.h" |
| #include "third_party/blink/renderer/core/css/css_reflect_value.h" |
| #include "third_party/blink/renderer/core/css/css_resolution_units.h" |
| #include "third_party/blink/renderer/core/css/css_string_value.h" |
| #include "third_party/blink/renderer/core/css/css_uri_value.h" |
| #include "third_party/blink/renderer/core/css/css_value_list.h" |
| #include "third_party/blink/renderer/core/css/css_value_pair.h" |
| #include "third_party/blink/renderer/core/css/parser/css_parser_context.h" |
| #include "third_party/blink/renderer/core/css/parser/css_parser_fast_paths.h" |
| #include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h" |
| #include "third_party/blink/renderer/core/css/parser/css_parser_mode.h" |
| #include "third_party/blink/renderer/core/css/parser/css_parser_token.h" |
| #include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h" |
| #include "third_party/blink/renderer/core/css/parser/css_property_parser.h" |
| #include "third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h" |
| #include "third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h" |
| #include "third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h" |
| #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" |
| #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" |
| #include "third_party/blink/renderer/core/css/properties/longhands.h" |
| #include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h" |
| #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" |
| #include "third_party/blink/renderer/core/css/scoped_css_value.h" |
| #include "third_party/blink/renderer/core/css/style_engine.h" |
| #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" |
| #include "third_party/blink/renderer/core/css_value_keywords.h" |
| #include "third_party/blink/renderer/core/frame/settings.h" |
| #include "third_party/blink/renderer/core/frame/web_feature.h" |
| #include "third_party/blink/renderer/core/layout/counter_node.h" |
| #include "third_party/blink/renderer/core/layout/layout_box.h" |
| #include "third_party/blink/renderer/core/layout/layout_object.h" |
| #include "third_party/blink/renderer/core/style/computed_style.h" |
| #include "third_party/blink/renderer/core/style/grid_area.h" |
| #include "third_party/blink/renderer/core/style/reference_clip_path_operation.h" |
| #include "third_party/blink/renderer/core/style/shape_clip_path_operation.h" |
| #include "third_party/blink/renderer/core/style_property_shorthand.h" |
| #include "third_party/blink/renderer/platform/geometry/length.h" |
| #include "third_party/blink/renderer/platform/heap/heap.h" |
| #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" |
| #include "third_party/blink/renderer/platform/runtime_enabled_features.h" |
| |
| // Implementations of methods in Longhand subclasses that aren't generated. |
| |
| namespace blink { |
| namespace css_longhand { |
| |
| const CSSValue* AlignContent::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeContentDistributionOverflowPosition( |
| range, css_parsing_utils::IsContentPositionKeyword); |
| } |
| |
| const CSSValue* AlignContent::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils:: |
| ValueForContentPositionAndDistributionWithOverflowAlignment( |
| style.AlignContent()); |
| } |
| |
| const CSSValue* AlignItems::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| // align-items property does not allow the 'auto' value. |
| if (css_parsing_utils::IdentMatches<CSSValueID::kAuto>(range.Peek().Id())) |
| return nullptr; |
| return css_parsing_utils::ConsumeSelfPositionOverflowPosition( |
| range, css_parsing_utils::IsSelfPositionKeyword); |
| } |
| |
| const CSSValue* AlignItems::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForItemPositionWithOverflowAlignment( |
| style.AlignItems()); |
| } |
| |
| const CSSValue* AlignSelf::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeSelfPositionOverflowPosition( |
| range, css_parsing_utils::IsSelfPositionKeyword); |
| } |
| |
| const CSSValue* AlignSelf::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForItemPositionWithOverflowAlignment( |
| style.AlignSelf()); |
| } |
| const CSSValue* AlignmentBaseline::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.AlignmentBaseline()); |
| } |
| |
| const CSSValue* AnimationDelay::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeTime, range, context, kValueRangeAll); |
| } |
| |
| const CSSValue* AnimationDelay::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForAnimationDelay(style.Animations()); |
| } |
| |
| const CSSValue* AnimationDelay::InitialValue() const { |
| DEFINE_STATIC_LOCAL( |
| const Persistent<CSSValue>, value, |
| (CSSNumericLiteralValue::Create(CSSTimingData::InitialDelay(), |
| CSSPrimitiveValue::UnitType::kSeconds))); |
| return value; |
| } |
| |
| const CSSValue* AnimationDirection::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeIdent< |
| CSSValueID::kNormal, CSSValueID::kAlternate, CSSValueID::kReverse, |
| CSSValueID::kAlternateReverse>, |
| range); |
| } |
| |
| const CSSValue* AnimationDirection::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (wtf_size_t i = 0; i < animation_data->DirectionList().size(); ++i) { |
| list->Append(*ComputedStyleUtils::ValueForAnimationDirection( |
| animation_data->DirectionList()[i])); |
| } |
| } else { |
| list->Append(*InitialValue()); |
| } |
| return list; |
| } |
| |
| const CSSValue* AnimationDirection::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kNormal))); |
| return value; |
| } |
| |
| const CSSValue* AnimationDuration::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeTime, range, context, kValueRangeNonNegative); |
| } |
| |
| const CSSValue* AnimationDuration::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForAnimationDuration(style.Animations()); |
| } |
| |
| const CSSValue* AnimationDuration::InitialValue() const { |
| DEFINE_STATIC_LOCAL( |
| const Persistent<CSSValue>, value, |
| (CSSNumericLiteralValue::Create(CSSTimingData::InitialDuration(), |
| CSSPrimitiveValue::UnitType::kSeconds))); |
| return value; |
| } |
| |
| const CSSValue* AnimationFillMode::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeIdent<CSSValueID::kNone, CSSValueID::kForwards, |
| CSSValueID::kBackwards, |
| CSSValueID::kBoth>, |
| range); |
| } |
| |
| const CSSValue* AnimationFillMode::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (wtf_size_t i = 0; i < animation_data->FillModeList().size(); ++i) { |
| list->Append(*ComputedStyleUtils::ValueForAnimationFillMode( |
| animation_data->FillModeList()[i])); |
| } |
| } else { |
| list->Append(*InitialValue()); |
| } |
| return list; |
| } |
| |
| const CSSValue* AnimationFillMode::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kNone))); |
| return value; |
| } |
| |
| const CSSValue* AnimationIterationCount::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeAnimationIterationCount, range, context); |
| } |
| |
| const CSSValue* AnimationIterationCount::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (wtf_size_t i = 0; i < animation_data->IterationCountList().size(); |
| ++i) { |
| list->Append(*ComputedStyleUtils::ValueForAnimationIterationCount( |
| animation_data->IterationCountList()[i])); |
| } |
| } else { |
| list->Append(*InitialValue()); |
| } |
| return list; |
| } |
| |
| const CSSValue* AnimationIterationCount::InitialValue() const { |
| DEFINE_STATIC_LOCAL( |
| const Persistent<CSSValue>, value, |
| (CSSNumericLiteralValue::Create(CSSAnimationData::InitialIterationCount(), |
| CSSPrimitiveValue::UnitType::kNumber))); |
| return value; |
| } |
| |
| const CSSValue* AnimationName::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| // Allow quoted name if this is an alias property. |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeAnimationName, range, context, |
| local_context.UseAliasParsing()); |
| } |
| |
| const CSSValue* AnimationName::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (wtf_size_t i = 0; i < animation_data->NameList().size(); ++i) { |
| list->Append(*MakeGarbageCollected<CSSCustomIdentValue>( |
| animation_data->NameList()[i])); |
| } |
| } else { |
| list->Append(*InitialValue()); |
| } |
| return list; |
| } |
| |
| const CSSValue* AnimationName::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kNone))); |
| return value; |
| } |
| |
| void AnimationName::ApplyValue(StyleResolverState& state, |
| const ScopedCSSValue& scoped_value) const { |
| // TODO(futhark): Set the TreeScope on CSSAnimationData. |
| ApplyValue(state, scoped_value.GetCSSValue()); |
| } |
| |
| const CSSValue* AnimationPlayState::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeIdent<CSSValueID::kRunning, |
| CSSValueID::kPaused>, |
| range); |
| } |
| |
| const CSSValue* AnimationPlayState::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (wtf_size_t i = 0; i < animation_data->PlayStateList().size(); ++i) { |
| list->Append(*ComputedStyleUtils::ValueForAnimationPlayState( |
| animation_data->PlayStateList()[i])); |
| } |
| } else { |
| list->Append(*InitialValue()); |
| } |
| return list; |
| } |
| |
| const CSSValue* AnimationPlayState::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kRunning))); |
| return value; |
| } |
| |
| const CSSValue* AnimationTimeline::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeAnimationTimeline, range, context); |
| } |
| |
| const CSSValue* AnimationTimeline::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const CSSAnimationData* animation_data = style.Animations(); |
| if (animation_data) { |
| for (const auto& timeline : animation_data->TimelineList()) |
| list->Append(*ComputedStyleUtils::ValueForStyleNameOrKeyword(timeline)); |
| } else { |
| list->Append(*InitialValue()); |
| } |
| return list; |
| } |
| |
| const CSSValue* AnimationTimeline::InitialValue() const { |
| return CSSIdentifierValue::Create(CSSValueID::kAuto); |
| } |
| |
| const CSSValue* AnimationTimingFunction::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeAnimationTimingFunction, range, context); |
| } |
| |
| const CSSValue* AnimationTimingFunction::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForAnimationTimingFunction( |
| style.Animations()); |
| } |
| |
| const CSSValue* AnimationTimingFunction::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kEase))); |
| return value; |
| } |
| |
| const CSSValue* AspectRatio::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| // Syntax: auto | auto 1/2 | 1/2 auto |
| CSSValue* auto_value = nullptr; |
| if (range.Peek().Id() == CSSValueID::kAuto) |
| auto_value = css_parsing_utils::ConsumeIdent(range); |
| |
| if (range.AtEnd()) |
| return auto_value; |
| |
| CSSValue* width = |
| css_parsing_utils::ConsumeNumber(range, context, kValueRangeNonNegative); |
| if (!width) |
| return nullptr; |
| CSSValue* height = nullptr; |
| if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) { |
| height = css_parsing_utils::ConsumeNumber(range, context, |
| kValueRangeNonNegative); |
| if (!height) |
| return nullptr; |
| } else { |
| // A missing height is treated as 1. |
| height = CSSNumericLiteralValue::Create( |
| 1.0f, CSSPrimitiveValue::UnitType::kNumber); |
| } |
| |
| CSSValueList* ratio_list = CSSValueList::CreateSlashSeparated(); |
| ratio_list->Append(*width); |
| if (height) |
| ratio_list->Append(*height); |
| if (!range.AtEnd()) { |
| if (auto_value) |
| return nullptr; |
| if (range.Peek().Id() != CSSValueID::kAuto) |
| return nullptr; |
| auto_value = css_parsing_utils::ConsumeIdent(range); |
| } |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (auto_value) |
| list->Append(*auto_value); |
| list->Append(*ratio_list); |
| return list; |
| } |
| |
| const CSSValue* AspectRatio::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| bool allow_visited_style) const { |
| auto& ratio = style.AspectRatio(); |
| if (ratio.GetTypeForComputedStyle() == EAspectRatioType::kAuto) |
| return CSSIdentifierValue::Create(CSSValueID::kAuto); |
| |
| CSSValueList* ratio_list = CSSValueList::CreateSlashSeparated(); |
| ratio_list->Append(*CSSNumericLiteralValue::Create( |
| ratio.GetRatio().Width(), CSSPrimitiveValue::UnitType::kNumber)); |
| ratio_list->Append(*CSSNumericLiteralValue::Create( |
| ratio.GetRatio().Height(), CSSPrimitiveValue::UnitType::kNumber)); |
| if (ratio.GetTypeForComputedStyle() == EAspectRatioType::kRatio) |
| return ratio_list; |
| |
| DCHECK_EQ(ratio.GetTypeForComputedStyle(), EAspectRatioType::kAutoAndRatio); |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kAuto)); |
| list->Append(*ratio_list); |
| return list; |
| } |
| |
| const CSSValue* BackdropFilter::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeFilterFunctionList(range, context); |
| } |
| |
| const CSSValue* BackdropFilter::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForFilter(style, style.BackdropFilter()); |
| } |
| |
| void BackdropFilter::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| state.Style()->SetBackdropFilter( |
| StyleBuilderConverter::ConvertFilterOperations(state, value, |
| PropertyID())); |
| } |
| |
| const CSSValue* BackfaceVisibility::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create( |
| (style.BackfaceVisibility() == EBackfaceVisibility::kHidden) |
| ? CSSValueID::kHidden |
| : CSSValueID::kVisible); |
| } |
| |
| const CSSValue* BackgroundAttachment::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeBackgroundAttachment, range); |
| } |
| |
| const CSSValue* BackgroundAttachment::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const FillLayer* curr_layer = &style.BackgroundLayers(); curr_layer; |
| curr_layer = curr_layer->Next()) |
| list->Append(*CSSIdentifierValue::Create(curr_layer->Attachment())); |
| return list; |
| } |
| |
| const CSSValue* BackgroundBlendMode::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeBackgroundBlendMode, range); |
| } |
| |
| const CSSValue* BackgroundBlendMode::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| for (const FillLayer* curr_layer = &style.BackgroundLayers(); curr_layer; |
| curr_layer = curr_layer->Next()) |
| list->Append(*CSSIdentifierValue::Create(curr_layer->GetBlendMode())); |
| return list; |
| } |
| |
| const CSSValue* BackgroundClip::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBackgroundBox( |
| range, local_context, css_parsing_utils::AllowTextValue::kAllow); |
| } |
| |
| const CSSValue* BackgroundClip::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) { |
| EFillBox box = curr_layer->Clip(); |
| list->Append(*CSSIdentifierValue::Create(box)); |
| } |
| return list; |
| } |
| |
| const CSSValue* BackgroundColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context, |
| IsQuirksModeBehavior(context.Mode())); |
| } |
| |
| const blink::Color BackgroundColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleColor background_color = style.BackgroundColor(); |
| if (style.ShouldForceColor(background_color)) { |
| return To<Longhand>(GetCSSPropertyInternalForcedBackgroundColor()) |
| .ColorIncludingFallback(false, style); |
| } |
| return background_color.Resolve(style.GetCurrentColor(), |
| style.UsedColorScheme()); |
| } |
| |
| const CSSValue* BackgroundColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (allow_visited_style) { |
| return cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()); |
| } |
| |
| StyleColor background_color = style.BackgroundColor(); |
| if (style.ShouldForceColor(background_color)) { |
| return GetCSSPropertyInternalForcedBackgroundColor() |
| .CSSValueFromComputedStyle(style, nullptr, allow_visited_style); |
| } |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return ComputedStyleUtils::CurrentColorOrValidColor( |
| style, background_color, CSSValuePhase::kUsedValue); |
| } |
| |
| const CSSValue* BackgroundImage::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumeImageOrNone, range, context); |
| } |
| |
| const CSSValue* BackgroundImage::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| const FillLayer& fill_layer = style.BackgroundLayers(); |
| return ComputedStyleUtils::BackgroundImageOrWebkitMaskImage( |
| style, allow_visited_style, fill_layer); |
| } |
| |
| const CSSValue* BackgroundOrigin::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBackgroundBox( |
| range, local_context, css_parsing_utils::AllowTextValue::kForbid); |
| } |
| |
| const CSSValue* BackgroundOrigin::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = CSSValueList::CreateCommaSeparated(); |
| const FillLayer* curr_layer = &style.BackgroundLayers(); |
| for (; curr_layer; curr_layer = curr_layer->Next()) { |
| EFillBox box = curr_layer->Origin(); |
| list->Append(*CSSIdentifierValue::Create(box)); |
| } |
| return list; |
| } |
| |
| const CSSValue* BackgroundPositionX::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft, |
| CSSValueID::kRight>, |
| range, context); |
| } |
| |
| const CSSValue* BackgroundPositionX::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| const FillLayer* curr_layer = &style.BackgroundLayers(); |
| return ComputedStyleUtils::BackgroundPositionXOrWebkitMaskPositionX( |
| style, curr_layer); |
| } |
| |
| const CSSValue* BackgroundPositionY::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCommaSeparatedList( |
| css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop, |
| CSSValueID::kBottom>, |
| range, context); |
| } |
| |
| const CSSValue* BackgroundPositionY::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| const FillLayer* curr_layer = &style.BackgroundLayers(); |
| return ComputedStyleUtils::BackgroundPositionYOrWebkitMaskPositionY( |
| style, curr_layer); |
| } |
| |
| const CSSValue* BackgroundSize::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBackgroundOrMaskSize( |
| range, context, local_context, WebFeature::kNegativeBackgroundSize); |
| } |
| |
| const CSSValue* BackgroundSize::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| const FillLayer& fill_layer = style.BackgroundLayers(); |
| return ComputedStyleUtils::BackgroundImageOrWebkitMaskSize(style, fill_layer); |
| } |
| |
| const CSSValue* BaselineShift::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| CSSValueID id = range.Peek().Id(); |
| if (id == CSSValueID::kBaseline || id == CSSValueID::kSub || |
| id == CSSValueID::kSuper) |
| return css_parsing_utils::ConsumeIdent(range); |
| CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode); |
| return css_parsing_utils::ConsumeLengthOrPercent(range, context, |
| kValueRangeAll); |
| } |
| |
| const CSSValue* BaselineShift::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| switch (style.BaselineShiftType()) { |
| case EBaselineShiftType::kSuper: |
| return CSSIdentifierValue::Create(CSSValueID::kSuper); |
| case EBaselineShiftType::kSub: |
| return CSSIdentifierValue::Create(CSSValueID::kSub); |
| case EBaselineShiftType::kLength: |
| return ComputedStyleUtils::ZoomAdjustedPixelValueForLength( |
| style.BaselineShift(), style); |
| } |
| NOTREACHED(); |
| return nullptr; |
| } |
| |
| void BaselineShift::ApplyInherit(StyleResolverState& state) const { |
| state.Style()->SetBaselineShiftType(state.ParentStyle()->BaselineShiftType()); |
| state.Style()->SetBaselineShift(state.ParentStyle()->BaselineShift()); |
| } |
| |
| void BaselineShift::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { |
| EBaselineShiftType baseline_shift_type = EBaselineShiftType::kLength; |
| switch (identifier_value->GetValueID()) { |
| case CSSValueID::kBaseline: |
| baseline_shift_type = EBaselineShiftType::kLength; |
| break; |
| case CSSValueID::kSub: |
| baseline_shift_type = EBaselineShiftType::kSub; |
| break; |
| case CSSValueID::kSuper: |
| baseline_shift_type = EBaselineShiftType::kSuper; |
| break; |
| default: |
| NOTREACHED(); |
| } |
| state.Style()->SetBaselineShiftType(baseline_shift_type); |
| state.Style()->SetBaselineShift(Length::Fixed()); |
| } else { |
| state.Style()->SetBaselineShiftType(EBaselineShiftType::kLength); |
| state.Style()->SetBaselineShift(StyleBuilderConverter::ConvertLength( |
| state, To<CSSPrimitiveValue>(value))); |
| } |
| } |
| |
| const CSSValue* BlockSize::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeWidthOrHeight(range, context); |
| } |
| |
| bool BlockSize::IsLayoutDependent(const ComputedStyle* style, |
| LayoutObject* layout_object) const { |
| return layout_object && (layout_object->IsBox() || layout_object->IsSVG()); |
| } |
| |
| const CSSValue* BorderBlockEndColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context); |
| } |
| |
| const CSSValue* BorderBlockEndWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderWidth( |
| range, context, css_parsing_utils::UnitlessQuirk::kForbid); |
| } |
| |
| const CSSValue* BorderBlockStartColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context); |
| } |
| |
| const CSSValue* BorderBlockStartWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderWidth( |
| range, context, css_parsing_utils::UnitlessQuirk::kForbid); |
| } |
| |
| const CSSValue* BorderBottomColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ConsumeBorderColorSide(range, context, |
| local_context); |
| } |
| |
| const blink::Color BorderBottomColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleColor border_bottom_color = style.BorderBottomColor(); |
| if (style.ShouldForceColor(border_bottom_color)) { |
| return To<Longhand>(GetCSSPropertyInternalForcedBorderColor()) |
| .ColorIncludingFallback(false, style); |
| } |
| return ComputedStyleUtils::BorderSideColor( |
| style, border_bottom_color, style.BorderBottomStyle(), visited_link); |
| } |
| |
| const CSSValue* BorderBottomColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| StyleColor border_bottom_color = style.BorderBottomColor(); |
| if (style.ShouldForceColor(border_bottom_color)) { |
| return GetCSSPropertyInternalForcedBorderColor().CSSValueFromComputedStyle( |
| style, nullptr, allow_visited_style); |
| } |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return allow_visited_style |
| ? cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()) |
| : ComputedStyleUtils::CurrentColorOrValidColor( |
| style, border_bottom_color, CSSValuePhase::kUsedValue); |
| } |
| |
| const CSSValue* BorderBottomLeftRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderBottomLeftRadius::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForBorderRadiusCorner( |
| style.BorderBottomLeftRadius(), style); |
| } |
| |
| const CSSValue* BorderBottomRightRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderBottomRightRadius::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForBorderRadiusCorner( |
| style.BorderBottomRightRadius(), style); |
| } |
| const CSSValue* BorderBottomStyle::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BorderBottomStyle()); |
| } |
| |
| const CSSValue* BorderBottomWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBorderWidthSide(range, context, local_context); |
| } |
| |
| const CSSValue* BorderBottomWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ZoomAdjustedPixelValue(style.BorderBottomWidth(), style); |
| } |
| |
| const CSSValue* BorderCollapse::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.BorderCollapse() == EBorderCollapse::kCollapse) |
| return CSSIdentifierValue::Create(CSSValueID::kCollapse); |
| return CSSIdentifierValue::Create(CSSValueID::kSeparate); |
| } |
| |
| const CSSValue* BorderEndEndRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderEndStartRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderImageOutset::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderImageOutset(range, context); |
| } |
| |
| const CSSValue* BorderImageOutset::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForNinePieceImageQuad( |
| style.BorderImage().Outset(), style); |
| } |
| |
| const CSSValue* BorderImageOutset::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSQuadValue>, value, |
| (MakeGarbageCollected<CSSQuadValue>( |
| CSSNumericLiteralValue::Create( |
| 0, CSSPrimitiveValue::UnitType::kInteger), |
| CSSQuadValue::kSerializeAsQuad))); |
| return value; |
| } |
| |
| const CSSValue* BorderImageRepeat::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderImageRepeat(range); |
| } |
| |
| const CSSValue* BorderImageRepeat::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForNinePieceImageRepeat(style.BorderImage()); |
| } |
| |
| const CSSValue* BorderImageRepeat::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kStretch))); |
| return value; |
| } |
| |
| const CSSValue* BorderImageSlice::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderImageSlice( |
| range, context, css_parsing_utils::DefaultFill::kNoFill); |
| } |
| |
| const CSSValue* BorderImageSlice::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForNinePieceImageSlice(style.BorderImage()); |
| } |
| |
| const CSSValue* BorderImageSlice::InitialValue() const { |
| DEFINE_STATIC_LOCAL( |
| const Persistent<cssvalue::CSSBorderImageSliceValue>, value, |
| (MakeGarbageCollected<cssvalue::CSSBorderImageSliceValue>( |
| MakeGarbageCollected<CSSQuadValue>( |
| CSSNumericLiteralValue::Create( |
| 100, CSSPrimitiveValue::UnitType::kPercentage), |
| CSSQuadValue::kSerializeAsQuad), |
| /* fill */ false))); |
| return value; |
| } |
| |
| const CSSValue* BorderImageSource::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeImageOrNone(range, context); |
| } |
| |
| const CSSValue* BorderImageSource::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.BorderImageSource()) { |
| return style.BorderImageSource()->ComputedCSSValue(style, |
| allow_visited_style); |
| } |
| return CSSIdentifierValue::Create(CSSValueID::kNone); |
| } |
| |
| const CSSValue* BorderImageSource::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSValue>, value, |
| (CSSIdentifierValue::Create(CSSValueID::kNone))); |
| return value; |
| } |
| |
| void BorderImageSource::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| state.Style()->SetBorderImageSource( |
| state.GetStyleImage(CSSPropertyID::kBorderImageSource, value)); |
| } |
| |
| const CSSValue* BorderImageWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderImageWidth(range, context); |
| } |
| |
| const CSSValue* BorderImageWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForNinePieceImageQuad( |
| style.BorderImage().BorderSlices(), style); |
| } |
| |
| const CSSValue* BorderImageWidth::InitialValue() const { |
| DEFINE_STATIC_LOCAL(const Persistent<CSSQuadValue>, value, |
| (MakeGarbageCollected<CSSQuadValue>( |
| CSSNumericLiteralValue::Create( |
| 1, CSSPrimitiveValue::UnitType::kInteger), |
| CSSQuadValue::kSerializeAsQuad))); |
| return value; |
| } |
| |
| const CSSValue* BorderInlineEndColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context); |
| } |
| |
| const CSSValue* BorderInlineEndWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderWidth( |
| range, context, css_parsing_utils::UnitlessQuirk::kForbid); |
| } |
| |
| const CSSValue* BorderInlineStartColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context); |
| } |
| |
| const CSSValue* BorderInlineStartWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeBorderWidth( |
| range, context, css_parsing_utils::UnitlessQuirk::kForbid); |
| } |
| |
| const CSSValue* BorderLeftColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ConsumeBorderColorSide(range, context, |
| local_context); |
| } |
| |
| const blink::Color BorderLeftColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleColor border_left_color = style.BorderLeftColor(); |
| if (style.ShouldForceColor(border_left_color)) { |
| return To<Longhand>(GetCSSPropertyInternalForcedBorderColor()) |
| .ColorIncludingFallback(false, style); |
| } |
| return ComputedStyleUtils::BorderSideColor( |
| style, border_left_color, style.BorderLeftStyle(), visited_link); |
| } |
| |
| const CSSValue* BorderLeftColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| StyleColor border_left_color = style.BorderLeftColor(); |
| if (style.ShouldForceColor(border_left_color)) { |
| return GetCSSPropertyInternalForcedBorderColor().CSSValueFromComputedStyle( |
| style, nullptr, allow_visited_style); |
| } |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return allow_visited_style |
| ? cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()) |
| : ComputedStyleUtils::CurrentColorOrValidColor( |
| style, border_left_color, CSSValuePhase::kUsedValue); |
| } |
| |
| const CSSValue* BorderLeftStyle::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BorderLeftStyle()); |
| } |
| |
| const CSSValue* BorderLeftWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBorderWidthSide(range, context, local_context); |
| } |
| |
| const CSSValue* BorderLeftWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ZoomAdjustedPixelValue(style.BorderLeftWidth(), style); |
| } |
| |
| const CSSValue* BorderRightColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ConsumeBorderColorSide(range, context, |
| local_context); |
| } |
| |
| const blink::Color BorderRightColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleColor border_right_color = style.BorderRightColor(); |
| if (style.ShouldForceColor(border_right_color)) { |
| return To<Longhand>(GetCSSPropertyInternalForcedBorderColor()) |
| .ColorIncludingFallback(false, style); |
| } |
| return ComputedStyleUtils::BorderSideColor(style, border_right_color, |
| style.BorderRightStyle(), false); |
| } |
| |
| const CSSValue* BorderRightColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| StyleColor border_right_color = style.BorderRightColor(); |
| if (style.ShouldForceColor(border_right_color)) { |
| return GetCSSPropertyInternalForcedBorderColor().CSSValueFromComputedStyle( |
| style, nullptr, allow_visited_style); |
| } |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return allow_visited_style |
| ? cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()) |
| : ComputedStyleUtils::CurrentColorOrValidColor( |
| style, border_right_color, CSSValuePhase::kUsedValue); |
| } |
| |
| const CSSValue* BorderRightStyle::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BorderRightStyle()); |
| } |
| |
| const CSSValue* BorderRightWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBorderWidthSide(range, context, local_context); |
| } |
| |
| const CSSValue* BorderRightWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ZoomAdjustedPixelValue(style.BorderRightWidth(), style); |
| } |
| |
| const CSSValue* BorderStartStartRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderStartEndRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderTopColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ConsumeBorderColorSide(range, context, |
| local_context); |
| } |
| |
| const blink::Color BorderTopColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleColor border_top_color = style.BorderTopColor(); |
| if (style.ShouldForceColor(border_top_color)) { |
| return To<Longhand>(GetCSSPropertyInternalForcedBorderColor()) |
| .ColorIncludingFallback(false, style); |
| } |
| return ComputedStyleUtils::BorderSideColor( |
| style, border_top_color, style.BorderTopStyle(), visited_link); |
| } |
| |
| const CSSValue* BorderTopColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| StyleColor border_top_color = style.BorderTopColor(); |
| if (style.ShouldForceColor(border_top_color)) { |
| return GetCSSPropertyInternalForcedBorderColor().CSSValueFromComputedStyle( |
| style, nullptr, allow_visited_style); |
| } |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return allow_visited_style |
| ? cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()) |
| : ComputedStyleUtils::ComputedStyleUtils::CurrentColorOrValidColor( |
| style, border_top_color, CSSValuePhase::kUsedValue); |
| } |
| |
| const CSSValue* BorderTopLeftRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderTopLeftRadius::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForBorderRadiusCorner( |
| style.BorderTopLeftRadius(), style); |
| } |
| |
| const CSSValue* BorderTopRightRadius::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ParseBorderRadiusCorner(range, context); |
| } |
| |
| const CSSValue* BorderTopRightRadius::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForBorderRadiusCorner( |
| style.BorderTopRightRadius(), style); |
| } |
| |
| const CSSValue* BorderTopStyle::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BorderTopStyle()); |
| } |
| |
| const CSSValue* BorderTopWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ParseBorderWidthSide(range, context, local_context); |
| } |
| |
| const CSSValue* BorderTopWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ZoomAdjustedPixelValue(style.BorderTopWidth(), style); |
| } |
| |
| const CSSValue* Bottom::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext& local_context) const { |
| return css_parsing_utils::ConsumeMarginOrOffset( |
| range, context, |
| css_parsing_utils::UnitlessUnlessShorthand(local_context)); |
| } |
| |
| bool Bottom::IsLayoutDependent(const ComputedStyle* style, |
| LayoutObject* layout_object) const { |
| return layout_object && layout_object->IsBox(); |
| } |
| |
| const CSSValue* Bottom::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForPositionOffset(style, *this, |
| layout_object); |
| } |
| |
| const CSSValue* BoxShadow::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeShadow( |
| range, context, css_parsing_utils::AllowInsetAndSpread::kAllow); |
| } |
| |
| const CSSValue* BoxShadow::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return ComputedStyleUtils::ValueForShadowList(style.BoxShadow(), style, true, |
| CSSValuePhase::kUsedValue); |
| } |
| |
| const CSSValue* BoxSizing::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.BoxSizing() == EBoxSizing::kContentBox) |
| return CSSIdentifierValue::Create(CSSValueID::kContentBox); |
| return CSSIdentifierValue::Create(CSSValueID::kBorderBox); |
| } |
| |
| const CSSValue* BreakAfter::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BreakAfter()); |
| } |
| |
| const CSSValue* BreakBefore::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BreakBefore()); |
| } |
| |
| const CSSValue* BreakInside::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BreakInside()); |
| } |
| |
| const CSSValue* BufferedRendering::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.BufferedRendering()); |
| } |
| |
| const CSSValue* CaptionSide::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.CaptionSide()); |
| } |
| |
| const CSSValue* CaretColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| if (range.Peek().Id() == CSSValueID::kAuto) |
| return css_parsing_utils::ConsumeIdent(range); |
| return css_parsing_utils::ConsumeColor(range, context); |
| } |
| |
| const blink::Color CaretColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleAutoColor auto_color = style.CaretColor(); |
| // TODO(rego): We may want to adjust the caret color if it's the same as |
| // the background to ensure good visibility and contrast. |
| StyleColor result = auto_color.IsAutoColor() ? StyleColor::CurrentColor() |
| : auto_color.ToStyleColor(); |
| if (style.ShouldForceColor(result)) |
| return style.GetInternalForcedCurrentColor(); |
| return result.Resolve(style.GetCurrentColor(), style.UsedColorScheme()); |
| } |
| |
| const CSSValue* CaretColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (allow_visited_style) { |
| return cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()); |
| } |
| |
| StyleAutoColor auto_color = style.CaretColor(); |
| // TODO(rego): We may want to adjust the caret color if it's the same as |
| // the background to ensure good visibility and contrast. |
| StyleColor result = auto_color.IsAutoColor() ? StyleColor::CurrentColor() |
| : auto_color.ToStyleColor(); |
| if (style.ShouldForceColor(result)) { |
| return cssvalue::CSSColorValue::Create( |
| style.GetInternalForcedCurrentColor().Rgb()); |
| } |
| |
| // https://drafts.csswg.org/cssom/#resolved-values |
| // For this property, the resolved value is the used value. |
| return ComputedStyleUtils::ValueForStyleAutoColor(style, style.CaretColor(), |
| CSSValuePhase::kUsedValue); |
| } |
| |
| void CaretColor::ApplyInitial(StyleResolverState& state) const { |
| state.Style()->SetCaretColor(StyleAutoColor::AutoColor()); |
| } |
| |
| void CaretColor::ApplyInherit(StyleResolverState& state) const { |
| state.Style()->SetCaretColor(state.ParentStyle()->CaretColor()); |
| } |
| |
| void CaretColor::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| state.Style()->SetCaretColor( |
| StyleBuilderConverter::ConvertStyleAutoColor(state, value)); |
| } |
| |
| const CSSValue* Clear::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.Clear()); |
| } |
| |
| namespace { |
| |
| CSSValue* ConsumeClipComponent(CSSParserTokenRange& range, |
| const CSSParserContext& context) { |
| if (range.Peek().Id() == CSSValueID::kAuto) |
| return css_parsing_utils::ConsumeIdent(range); |
| return css_parsing_utils::ConsumeLength( |
| range, context, kValueRangeAll, css_parsing_utils::UnitlessQuirk::kAllow); |
| } |
| |
| } // namespace |
| |
| const CSSValue* Clip::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| if (range.Peek().Id() == CSSValueID::kAuto) |
| return css_parsing_utils::ConsumeIdent(range); |
| |
| if (range.Peek().FunctionId() != CSSValueID::kRect) |
| return nullptr; |
| |
| CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range); |
| // rect(t, r, b, l) || rect(t r b l) |
| CSSValue* top = ConsumeClipComponent(args, context); |
| if (!top) |
| return nullptr; |
| bool needs_comma = css_parsing_utils::ConsumeCommaIncludingWhitespace(args); |
| CSSValue* right = ConsumeClipComponent(args, context); |
| if (!right || (needs_comma && |
| !css_parsing_utils::ConsumeCommaIncludingWhitespace(args))) |
| return nullptr; |
| CSSValue* bottom = ConsumeClipComponent(args, context); |
| if (!bottom || (needs_comma && |
| !css_parsing_utils::ConsumeCommaIncludingWhitespace(args))) |
| return nullptr; |
| CSSValue* left = ConsumeClipComponent(args, context); |
| if (!left || !args.AtEnd()) |
| return nullptr; |
| return MakeGarbageCollected<CSSQuadValue>(top, right, bottom, left, |
| CSSQuadValue::kSerializeAsRect); |
| } |
| |
| const CSSValue* Clip::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.HasAutoClip()) |
| return CSSIdentifierValue::Create(CSSValueID::kAuto); |
| CSSValue* top = ComputedStyleUtils::ZoomAdjustedPixelValueOrAuto( |
| style.Clip().Top(), style); |
| CSSValue* right = ComputedStyleUtils::ZoomAdjustedPixelValueOrAuto( |
| style.Clip().Right(), style); |
| CSSValue* bottom = ComputedStyleUtils::ZoomAdjustedPixelValueOrAuto( |
| style.Clip().Bottom(), style); |
| CSSValue* left = ComputedStyleUtils::ZoomAdjustedPixelValueOrAuto( |
| style.Clip().Left(), style); |
| return MakeGarbageCollected<CSSQuadValue>(top, right, bottom, left, |
| CSSQuadValue::kSerializeAsRect); |
| } |
| |
| const CSSValue* ClipPath::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| if (range.Peek().Id() == CSSValueID::kNone) |
| return css_parsing_utils::ConsumeIdent(range); |
| if (cssvalue::CSSURIValue* url = |
| css_parsing_utils::ConsumeUrl(range, context)) |
| return url; |
| return css_parsing_utils::ConsumeBasicShape( |
| range, context, css_parsing_utils::AllowPathValue::kAllow); |
| } |
| |
| const CSSValue* ClipPath::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (ClipPathOperation* operation = style.ClipPath()) { |
| if (operation->GetType() == ClipPathOperation::SHAPE) { |
| return ValueForBasicShape( |
| style, To<ShapeClipPathOperation>(operation)->GetBasicShape()); |
| } |
| if (operation->GetType() == ClipPathOperation::REFERENCE) { |
| AtomicString url = To<ReferenceClipPathOperation>(operation)->Url(); |
| return MakeGarbageCollected<cssvalue::CSSURIValue>(url); |
| } |
| } |
| return CSSIdentifierValue::Create(CSSValueID::kNone); |
| } |
| |
| const CSSValue* ClipRule::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.ClipRule()); |
| } |
| |
| const CSSValue* Color::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context, |
| IsQuirksModeBehavior(context.Mode())); |
| } |
| |
| const blink::Color Color::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| if (style.ShouldForceColor(style.GetColor())) { |
| return To<Longhand>(GetCSSPropertyInternalForcedColor()) |
| .ColorIncludingFallback(false, style); |
| } |
| return style.GetCurrentColor(); |
| } |
| |
| const CSSValue* Color::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.ShouldForceColor(style.GetColor())) { |
| return GetCSSPropertyInternalForcedColor().CSSValueFromComputedStyle( |
| style, nullptr, allow_visited_style); |
| } |
| return cssvalue::CSSColorValue::Create( |
| allow_visited_style ? style.VisitedDependentColor(*this).Rgb() |
| : style.GetCurrentColor().Rgb()); |
| } |
| |
| void Color::ApplyInitial(StyleResolverState& state) const { |
| state.Style()->SetColor(state.Style()->InitialColorForColorScheme()); |
| } |
| |
| void Color::ApplyInherit(StyleResolverState& state) const { |
| state.Style()->SetColor(state.ParentStyle()->GetColor()); |
| } |
| |
| void Color::ApplyValue(StyleResolverState& state, const CSSValue& value) const { |
| // As per the spec, 'color: currentColor' is treated as 'color: inherit' |
| auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); |
| if (identifier_value && |
| identifier_value->GetValueID() == CSSValueID::kCurrentcolor) { |
| ApplyInherit(state); |
| return; |
| } |
| if (auto* initial_color_value = DynamicTo<CSSInitialColorValue>(value)) { |
| DCHECK_EQ(state.GetElement(), state.GetDocument().documentElement()); |
| state.Style()->SetColor(state.Style()->InitialColorForColorScheme()); |
| return; |
| } |
| state.Style()->SetColor( |
| StyleBuilderConverter::ConvertStyleColor(state, value)); |
| } |
| |
| const CSSValue* ColorInterpolation::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.ColorInterpolation()); |
| } |
| |
| const CSSValue* ColorInterpolationFilters::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.ColorInterpolationFilters()); |
| } |
| |
| const CSSValue* ColorRendering::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.ColorRendering()); |
| } |
| |
| const CSSValue* ColorScheme::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| if (range.Peek().Id() == CSSValueID::kNormal) |
| return css_parsing_utils::ConsumeIdent(range); |
| |
| CSSValueList* values = CSSValueList::CreateSpaceSeparated(); |
| do { |
| CSSValueID id = range.Peek().Id(); |
| // 'normal' is handled above, and 'default' is reserved for future use. |
| // 'revert' is not yet implemented as a keyword, but still skip it for |
| // compat and interop. |
| if (id == CSSValueID::kNormal || id == CSSValueID::kRevert || |
| id == CSSValueID::kDefault) { |
| return nullptr; |
| } |
| CSSValue* value = |
| css_parsing_utils::ConsumeIdent<CSSValueID::kDark, CSSValueID::kLight>( |
| range); |
| if (!value) |
| value = css_parsing_utils::ConsumeCustomIdent(range, context); |
| if (!value) |
| return nullptr; |
| values->Append(*value); |
| } while (!range.AtEnd()); |
| return values; |
| } |
| |
| const CSSValue* ColorScheme::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.ColorScheme().IsEmpty()) |
| return CSSIdentifierValue::Create(CSSValueID::kNormal); |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| for (auto ident : style.ColorScheme()) { |
| list->Append(*MakeGarbageCollected<CSSCustomIdentValue>(ident)); |
| } |
| return list; |
| } |
| |
| const CSSValue* ColorScheme::InitialValue() const { |
| return CSSIdentifierValue::Create(CSSValueID::kNormal); |
| } |
| |
| void ColorScheme::ApplyInitial(StyleResolverState& state) const { |
| state.Style()->SetColorScheme(Vector<AtomicString>()); |
| state.Style()->SetDarkColorScheme(false); |
| } |
| |
| void ColorScheme::ApplyInherit(StyleResolverState& state) const { |
| state.Style()->SetColorScheme(state.ParentStyle()->ColorScheme()); |
| state.Style()->SetDarkColorScheme(state.ParentStyle()->DarkColorScheme()); |
| } |
| |
| void ColorScheme::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { |
| DCHECK(identifier_value->GetValueID() == CSSValueID::kNormal); |
| state.Style()->SetColorScheme(Vector<AtomicString>()); |
| state.Style()->SetDarkColorScheme(false); |
| } else if (const auto* scheme_list = DynamicTo<CSSValueList>(value)) { |
| bool prefers_dark = |
| state.GetDocument().GetStyleEngine().GetPreferredColorScheme() == |
| mojom::blink::PreferredColorScheme::kDark; |
| bool has_dark = false; |
| bool has_light = false; |
| Vector<AtomicString> color_schemes; |
| for (auto& item : *scheme_list) { |
| if (const auto* custom_ident = DynamicTo<CSSCustomIdentValue>(*item)) { |
| color_schemes.push_back(custom_ident->Value()); |
| } else if (const auto* ident = DynamicTo<CSSIdentifierValue>(*item)) { |
| color_schemes.push_back(ident->CssText()); |
| if (ident->GetValueID() == CSSValueID::kDark) |
| has_dark = true; |
| else if (ident->GetValueID() == CSSValueID::kLight) |
| has_light = true; |
| } else { |
| NOTREACHED(); |
| } |
| } |
| state.Style()->SetColorScheme(color_schemes); |
| state.Style()->SetDarkColorScheme(has_dark && (!has_light || prefers_dark)); |
| |
| if (has_dark) { |
| // Record kColorSchemeDarkSupportedOnRoot if dark is present (though dark |
| // may not be used). This metric is also recorded in |
| // StyleEngine::UpdateColorSchemeMetrics if a meta tag supports dark. |
| auto& doc = state.GetDocument(); |
| if (doc.documentElement() == state.ElementContext().GetElement()) |
| UseCounter::Count(doc, WebFeature::kColorSchemeDarkSupportedOnRoot); |
| } |
| } else { |
| NOTREACHED(); |
| } |
| } |
| |
| const CSSValue* ColumnCount::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColumnCount(range, context); |
| } |
| |
| const CSSValue* ColumnCount::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.HasAutoColumnCount()) |
| return CSSIdentifierValue::Create(CSSValueID::kAuto); |
| return CSSNumericLiteralValue::Create(style.ColumnCount(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| } |
| |
| const CSSValue* ColumnFill::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.GetColumnFill()); |
| } |
| |
| const CSSValue* ColumnGap::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeGapLength(range, context); |
| } |
| |
| const CSSValue* ColumnGap::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool) const { |
| return ComputedStyleUtils::ValueForGapLength(style.ColumnGap(), style); |
| } |
| |
| const CSSValue* ColumnRuleColor::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColor(range, context); |
| } |
| |
| const blink::Color ColumnRuleColor::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| StyleColor column_rule_color = style.ColumnRuleColor(); |
| if (style.ShouldForceColor(column_rule_color)) |
| return style.GetInternalForcedCurrentColor(); |
| return column_rule_color.Resolve(style.GetCurrentColor(), |
| style.UsedColorScheme()); |
| } |
| |
| const CSSValue* ColumnRuleColor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return allow_visited_style ? cssvalue::CSSColorValue::Create( |
| style.VisitedDependentColor(*this).Rgb()) |
| : ComputedStyleUtils::CurrentColorOrValidColor( |
| style, style.ColumnRuleColor(), |
| CSSValuePhase::kComputedValue); |
| } |
| |
| const CSSValue* ColumnRuleStyle::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.ColumnRuleStyle()); |
| } |
| |
| const CSSValue* ColumnRuleWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeLineWidth( |
| range, context, css_parsing_utils::UnitlessQuirk::kForbid); |
| } |
| |
| const CSSValue* ColumnRuleWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ZoomAdjustedPixelValue(style.ColumnRuleWidth(), style); |
| } |
| |
| const CSSValue* ColumnSpan::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeIdent<CSSValueID::kAll, CSSValueID::kNone>( |
| range); |
| } |
| |
| const CSSValue* ColumnSpan::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(static_cast<unsigned>(style.GetColumnSpan()) |
| ? CSSValueID::kAll |
| : CSSValueID::kNone); |
| } |
| |
| const CSSValue* ColumnWidth::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeColumnWidth(range, context); |
| } |
| |
| const CSSValue* ColumnWidth::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.HasAutoColumnWidth()) |
| return CSSIdentifierValue::Create(CSSValueID::kAuto); |
| return ZoomAdjustedPixelValue(style.ColumnWidth(), style); |
| } |
| |
| // none | strict | content | [ size || layout || style || paint ] |
| const CSSValue* Contain::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| CSSValueID id = range.Peek().Id(); |
| if (id == CSSValueID::kNone) |
| return css_parsing_utils::ConsumeIdent(range); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (id == CSSValueID::kStrict || id == CSSValueID::kContent) { |
| list->Append(*css_parsing_utils::ConsumeIdent(range)); |
| return list; |
| } |
| |
| CSSIdentifierValue* size = nullptr; |
| CSSIdentifierValue* layout = nullptr; |
| CSSIdentifierValue* style = nullptr; |
| CSSIdentifierValue* paint = nullptr; |
| while (true) { |
| id = range.Peek().Id(); |
| if ((id == CSSValueID::kSize || |
| (RuntimeEnabledFeatures::CSSContainSize1DEnabled() && |
| (id == CSSValueID::kBlockSize || id == CSSValueID::kInlineSize))) && |
| !size) { |
| size = css_parsing_utils::ConsumeIdent(range); |
| } else if (id == CSSValueID::kLayout && !layout) { |
| layout = css_parsing_utils::ConsumeIdent(range); |
| } else if (id == CSSValueID::kStyle && !style) { |
| style = css_parsing_utils::ConsumeIdent(range); |
| } else if (id == CSSValueID::kPaint && !paint) { |
| paint = css_parsing_utils::ConsumeIdent(range); |
| } else { |
| break; |
| } |
| } |
| if (size) |
| list->Append(*size); |
| if (layout) |
| list->Append(*layout); |
| if (style) { |
| context.Count(WebFeature::kCSSValueContainStyle); |
| list->Append(*style); |
| } |
| if (paint) |
| list->Append(*paint); |
| if (!list->length()) |
| return nullptr; |
| return list; |
| } |
| |
| const CSSValue* Contain::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (!style.Contain()) |
| return CSSIdentifierValue::Create(CSSValueID::kNone); |
| if (style.Contain() == kContainsStrict) |
| return CSSIdentifierValue::Create(CSSValueID::kStrict); |
| if (style.Contain() == kContainsContent) |
| return CSSIdentifierValue::Create(CSSValueID::kContent); |
| |
| CSSValueList* list = CSSValueList::CreateSpaceSeparated(); |
| if (style.ContainsSize()) { |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kSize)); |
| } else { |
| if (style.ContainsInlineSize()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kInlineSize)); |
| else if (style.ContainsBlockSize()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kBlockSize)); |
| } |
| if (style.ContainsLayout()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kLayout)); |
| if (style.ContainsStyle()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kStyle)); |
| if (style.ContainsPaint()) |
| list->Append(*CSSIdentifierValue::Create(CSSValueID::kPaint)); |
| DCHECK(list->length()); |
| return list; |
| } |
| |
| const CSSValue* ContainIntrinsicSize::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| if (range.Peek().Id() == CSSValueID::kAuto) |
| return css_parsing_utils::ConsumeIdent(range); |
| CSSValue* width = |
| css_parsing_utils::ConsumeLength(range, context, kValueRangeNonNegative); |
| if (!width) |
| return nullptr; |
| CSSValue* height = |
| css_parsing_utils::ConsumeLength(range, context, kValueRangeNonNegative); |
| if (!height) |
| height = width; |
| return MakeGarbageCollected<CSSValuePair>(width, height, |
| CSSValuePair::kDropIdenticalValues); |
| } |
| |
| const CSSValue* ContainIntrinsicSize::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject* layout_object, |
| bool allow_visited_style) const { |
| auto& size = style.ContainIntrinsicSize(); |
| if (size.Width().IsAuto()) { |
| DCHECK(size.Height().IsAuto()); |
| return CSSIdentifierValue::Create(CSSValueID::kAuto); |
| } |
| return MakeGarbageCollected<CSSValuePair>( |
| ComputedStyleUtils::ZoomAdjustedPixelValueForLength( |
| style.ContainIntrinsicSize().Width(), style), |
| ComputedStyleUtils::ZoomAdjustedPixelValueForLength( |
| style.ContainIntrinsicSize().Height(), style), |
| CSSValuePair::kDropIdenticalValues); |
| } |
| |
| namespace { |
| |
| CSSValue* ConsumeAttr(CSSParserTokenRange args, |
| const CSSParserContext& context) { |
| if (args.Peek().GetType() != kIdentToken) |
| return nullptr; |
| |
| AtomicString attr_name = |
| args.ConsumeIncludingWhitespace().Value().ToAtomicString(); |
| if (!args.AtEnd()) |
| return nullptr; |
| |
| if (context.IsHTMLDocument()) |
| attr_name = attr_name.LowerASCII(); |
| |
| CSSFunctionValue* attr_value = |
| MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kAttr); |
| attr_value->Append(*MakeGarbageCollected<CSSCustomIdentValue>(attr_name)); |
| return attr_value; |
| } |
| |
| CSSValue* ConsumeCounterContent(CSSParserTokenRange args, |
| const CSSParserContext& context, |
| bool counters) { |
| CSSCustomIdentValue* identifier = |
| css_parsing_utils::ConsumeCustomIdent(args, context); |
| if (!identifier) |
| return nullptr; |
| |
| CSSStringValue* separator = nullptr; |
| if (!counters) { |
| separator = MakeGarbageCollected<CSSStringValue>(String()); |
| } else { |
| if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(args) || |
| args.Peek().GetType() != kStringToken) |
| return nullptr; |
| separator = MakeGarbageCollected<CSSStringValue>( |
| args.ConsumeIncludingWhitespace().Value().ToString()); |
| } |
| |
| CSSCustomIdentValue* list_style = nullptr; |
| if (css_parsing_utils::ConsumeCommaIncludingWhitespace(args)) { |
| if (!RuntimeEnabledFeatures::CSSAtRuleCounterStyleEnabled()) { |
| CSSValueID id = args.Peek().Id(); |
| if ((id != CSSValueID::kNone && |
| (id < CSSValueID::kDisc || id > CSSValueID::kKatakanaIroha))) |
| return nullptr; |
| list_style = MakeGarbageCollected<CSSCustomIdentValue>( |
| AtomicString(getValueName(id))); |
| args.ConsumeIncludingWhitespace(); |
| } else { |
| // Note: CSS3 spec doesn't allow 'none' but CSS2.1 allows it. We currently |
| // allow it for backward compatibility. |
| // See https://github.com/w3c/csswg-drafts/issues/5795 for details. |
| if (args.Peek().Id() == CSSValueID::kNone) { |
| list_style = MakeGarbageCollected<CSSCustomIdentValue>("none"); |
| args.ConsumeIncludingWhitespace(); |
| } else { |
| list_style = css_parsing_utils::ConsumeCounterStyleName(args, context); |
| } |
| } |
| } else { |
| list_style = MakeGarbageCollected<CSSCustomIdentValue>("decimal"); |
| } |
| |
| if (!list_style || !args.AtEnd()) |
| return nullptr; |
| return MakeGarbageCollected<cssvalue::CSSCounterValue>(identifier, list_style, |
| separator); |
| } |
| |
| } // namespace |
| |
| const CSSValue* Content::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| if (css_parsing_utils::IdentMatches<CSSValueID::kNone, CSSValueID::kNormal>( |
| range.Peek().Id())) |
| return css_parsing_utils::ConsumeIdent(range); |
| |
| CSSValueList* values = CSSValueList::CreateSpaceSeparated(); |
| CSSValueList* outer_list = CSSValueList::CreateSlashSeparated(); |
| bool alt_text_present = false; |
| do { |
| CSSValue* parsed_value = css_parsing_utils::ConsumeImage(range, context); |
| if (!parsed_value) { |
| parsed_value = css_parsing_utils::ConsumeIdent< |
| CSSValueID::kOpenQuote, CSSValueID::kCloseQuote, |
| CSSValueID::kNoOpenQuote, CSSValueID::kNoCloseQuote>(range); |
| } |
| if (!parsed_value) |
| parsed_value = css_parsing_utils::ConsumeString(range); |
| if (!parsed_value) { |
| if (range.Peek().FunctionId() == CSSValueID::kAttr) { |
| parsed_value = |
| ConsumeAttr(css_parsing_utils::ConsumeFunction(range), context); |
| } else if (range.Peek().FunctionId() == CSSValueID::kCounter) { |
| parsed_value = ConsumeCounterContent( |
| css_parsing_utils::ConsumeFunction(range), context, false); |
| } else if (range.Peek().FunctionId() == CSSValueID::kCounters) { |
| parsed_value = ConsumeCounterContent( |
| css_parsing_utils::ConsumeFunction(range), context, true); |
| } |
| } |
| if (!parsed_value) { |
| if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) { |
| // No values were parsed before the slash, so nothing to apply the |
| // alternative text to. |
| if (!values->length()) |
| return nullptr; |
| alt_text_present = true; |
| } else { |
| return nullptr; |
| } |
| } else { |
| values->Append(*parsed_value); |
| } |
| } while (!range.AtEnd() && !alt_text_present); |
| outer_list->Append(*values); |
| if (alt_text_present) { |
| CSSStringValue* alt_text = css_parsing_utils::ConsumeString(range); |
| if (!alt_text) |
| return nullptr; |
| outer_list->Append(*alt_text); |
| } |
| return outer_list; |
| } |
| |
| const CSSValue* Content::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForContentData(style, allow_visited_style); |
| } |
| |
| void Content::ApplyInitial(StyleResolverState& state) const { |
| state.Style()->SetContent(nullptr); |
| } |
| |
| void Content::ApplyInherit(StyleResolverState& state) const { |
| // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. |
| // This note is a reminder that eventually "inherit" needs to be supported. |
| } |
| |
| void Content::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| NOTREACHED(); |
| } |
| |
| void Content::ApplyValue(StyleResolverState& state, |
| const ScopedCSSValue& scoped_value) const { |
| const CSSValue& value = scoped_value.GetCSSValue(); |
| if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { |
| DCHECK(identifier_value->GetValueID() == CSSValueID::kNormal || |
| identifier_value->GetValueID() == CSSValueID::kNone); |
| if (identifier_value->GetValueID() == CSSValueID::kNone) |
| state.Style()->SetContent(MakeGarbageCollected<NoneContentData>()); |
| else |
| state.Style()->SetContent(nullptr); |
| return; |
| } |
| const CSSValueList& outer_list = To<CSSValueList>(value); |
| ContentData* first_content = nullptr; |
| ContentData* prev_content = nullptr; |
| for (auto& item : To<CSSValueList>(outer_list.Item(0))) { |
| ContentData* next_content = nullptr; |
| if (item->IsImageGeneratorValue() || item->IsImageSetValue() || |
| item->IsImageValue()) { |
| next_content = MakeGarbageCollected<ImageContentData>( |
| state.GetStyleImage(CSSPropertyID::kContent, *item)); |
| } else if (const auto* counter_value = |
| DynamicTo<cssvalue::CSSCounterValue>(item.Get())) { |
| next_content = MakeGarbageCollected<CounterContentData>( |
| AtomicString(counter_value->Identifier()), counter_value->ListStyle(), |
| AtomicString(counter_value->Separator()), |
| scoped_value.GetTreeScope()); |
| } else if (auto* item_identifier_value = |
| DynamicTo<CSSIdentifierValue>(item.Get())) { |
| QuoteType quote_type; |
| switch (item_identifier_value->GetValueID()) { |
| default: |
| NOTREACHED(); |
| FALLTHROUGH; |
| case CSSValueID::kOpenQuote: |
| quote_type = QuoteType::kOpen; |
| break; |
| case CSSValueID::kCloseQuote: |
| quote_type = QuoteType::kClose; |
| break; |
| case CSSValueID::kNoOpenQuote: |
| quote_type = QuoteType::kNoOpen; |
| break; |
| case CSSValueID::kNoCloseQuote: |
| quote_type = QuoteType::kNoClose; |
| break; |
| } |
| next_content = MakeGarbageCollected<QuoteContentData>(quote_type); |
| } else { |
| String string; |
| if (const auto* function_value = |
| DynamicTo<CSSFunctionValue>(item.Get())) { |
| DCHECK_EQ(function_value->FunctionType(), CSSValueID::kAttr); |
| state.Style()->SetHasAttrContent(); |
| // TODO: Can a namespace be specified for an attr(foo)? |
| QualifiedName attr( |
| g_null_atom, |
| To<CSSCustomIdentValue>(function_value->Item(0)).Value(), |
| g_null_atom); |
| const AtomicString& attr_value = state.GetElement().getAttribute(attr); |
| string = attr_value.IsNull() ? g_empty_string : attr_value.GetString(); |
| } else { |
| string = To<CSSStringValue>(*item).Value(); |
| } |
| if (prev_content && prev_content->IsText()) { |
| TextContentData* text_content = To<TextContentData>(prev_content); |
| text_content->SetText(text_content->GetText() + string); |
| continue; |
| } |
| next_content = MakeGarbageCollected<TextContentData>(string); |
| } |
| |
| if (!first_content) |
| first_content = next_content; |
| else |
| prev_content->SetNext(next_content); |
| |
| prev_content = next_content; |
| } |
| // If alt text was provided, it will be present as the final element of the |
| // outer list. |
| if (outer_list.length() > 1) { |
| String string = To<CSSStringValue>(outer_list.Item(1)).Value(); |
| auto* alt_content = MakeGarbageCollected<AltTextContentData>(string); |
| prev_content->SetNext(alt_content); |
| } |
| DCHECK(first_content); |
| state.Style()->SetContent(first_content); |
| } |
| |
| const int kCounterIncrementDefaultValue = 1; |
| |
| const CSSValue* CounterIncrement::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCounter(range, context, |
| kCounterIncrementDefaultValue); |
| } |
| |
| const CSSValue* CounterIncrement::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForCounterDirectives( |
| style, CounterNode::kIncrementType); |
| } |
| |
| const int kCounterResetDefaultValue = 0; |
| |
| const CSSValue* CounterReset::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCounter(range, context, |
| kCounterResetDefaultValue); |
| } |
| |
| const CSSValue* CounterReset::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForCounterDirectives(style, |
| CounterNode::kResetType); |
| } |
| |
| const int kCounterSetDefaultValue = 0; |
| |
| const CSSValue* CounterSet::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeCounter(range, context, |
| kCounterSetDefaultValue); |
| } |
| |
| const CSSValue* CounterSet::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForCounterDirectives(style, |
| CounterNode::kSetType); |
| } |
| |
| const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| bool in_quirks_mode = IsQuirksModeBehavior(context.Mode()); |
| CSSValueList* list = nullptr; |
| while (CSSValue* image = css_parsing_utils::ConsumeImage( |
| range, context, |
| css_parsing_utils::ConsumeGeneratedImagePolicy::kForbid)) { |
| double num; |
| IntPoint hot_spot(-1, -1); |
| bool hot_spot_specified = false; |
| if (css_parsing_utils::ConsumeNumberRaw(range, context, num)) { |
| hot_spot.SetX(clampTo<int>(num)); |
| if (!css_parsing_utils::ConsumeNumberRaw(range, context, num)) |
| return nullptr; |
| hot_spot.SetY(clampTo<int>(num)); |
| hot_spot_specified = true; |
| } |
| |
| if (!list) |
| list = CSSValueList::CreateCommaSeparated(); |
| |
| list->Append(*MakeGarbageCollected<cssvalue::CSSCursorImageValue>( |
| *image, hot_spot_specified, hot_spot)); |
| if (!css_parsing_utils::ConsumeCommaIncludingWhitespace(range)) |
| return nullptr; |
| } |
| |
| CSSValueID id = range.Peek().Id(); |
| if (!range.AtEnd()) { |
| if (id == CSSValueID::kWebkitZoomIn) |
| context.Count(WebFeature::kPrefixedCursorZoomIn); |
| else if (id == CSSValueID::kWebkitZoomOut) |
| context.Count(WebFeature::kPrefixedCursorZoomOut); |
| else if (id == CSSValueID::kWebkitGrab) |
| context.Count(WebFeature::kPrefixedCursorGrab); |
| else if (id == CSSValueID::kWebkitGrabbing) |
| context.Count(WebFeature::kPrefixedCursorGrabbing); |
| } |
| CSSValue* cursor_type = nullptr; |
| if (id == CSSValueID::kHand) { |
| if (!in_quirks_mode) // Non-standard behavior |
| return nullptr; |
| cursor_type = CSSIdentifierValue::Create(CSSValueID::kPointer); |
| range.ConsumeIncludingWhitespace(); |
| } else if ((id >= CSSValueID::kAuto && id <= CSSValueID::kWebkitZoomOut) || |
| id == CSSValueID::kCopy || id == CSSValueID::kNone) { |
| cursor_type = css_parsing_utils::ConsumeIdent(range); |
| } else { |
| return nullptr; |
| } |
| |
| if (!list) |
| return cursor_type; |
| list->Append(*cursor_type); |
| return list; |
| } |
| |
| const CSSValue* Cursor::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| CSSValueList* list = nullptr; |
| CursorList* cursors = style.Cursors(); |
| if (cursors && cursors->size() > 0) { |
| list = CSSValueList::CreateCommaSeparated(); |
| for (const CursorData& cursor : *cursors) { |
| if (StyleImage* image = cursor.GetImage()) { |
| list->Append(*MakeGarbageCollected<cssvalue::CSSCursorImageValue>( |
| *image->ComputedCSSValue(style, allow_visited_style), |
| cursor.HotSpotSpecified(), cursor.HotSpot())); |
| } |
| } |
| } |
| CSSValue* value = CSSIdentifierValue::Create(style.Cursor()); |
| if (list) { |
| list->Append(*value); |
| return list; |
| } |
| return value; |
| } |
| |
| void Cursor::ApplyInitial(StyleResolverState& state) const { |
| state.Style()->ClearCursorList(); |
| state.Style()->SetCursor(ComputedStyleInitialValues::InitialCursor()); |
| } |
| |
| void Cursor::ApplyInherit(StyleResolverState& state) const { |
| state.Style()->SetCursor(state.ParentStyle()->Cursor()); |
| state.Style()->SetCursorList(state.ParentStyle()->Cursors()); |
| } |
| |
| void Cursor::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| state.Style()->ClearCursorList(); |
| if (auto* value_list = DynamicTo<CSSValueList>(value)) { |
| state.Style()->SetCursor(ECursor::kAuto); |
| for (const auto& item : *value_list) { |
| if (const auto* cursor = |
| DynamicTo<cssvalue::CSSCursorImageValue>(*item)) { |
| const CSSValue& image = cursor->ImageValue(); |
| state.Style()->AddCursor( |
| state.GetStyleImage(CSSPropertyID::kCursor, image), |
| cursor->HotSpotSpecified(), cursor->HotSpot()); |
| } else { |
| state.Style()->SetCursor( |
| To<CSSIdentifierValue>(*item).ConvertTo<ECursor>()); |
| } |
| } |
| } else { |
| state.Style()->SetCursor( |
| To<CSSIdentifierValue>(value).ConvertTo<ECursor>()); |
| } |
| } |
| |
| const CSSValue* Cx::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeSVGGeometryPropertyLength(range, context, |
| kValueRangeAll); |
| } |
| |
| const CSSValue* Cx::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(style.Cx(), style); |
| } |
| |
| const CSSValue* Cy::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeSVGGeometryPropertyLength(range, context, |
| kValueRangeAll); |
| } |
| |
| const CSSValue* Cy::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(style.Cy(), style); |
| } |
| |
| const CSSValue* D::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext&, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumePathOrNone(range); |
| } |
| |
| const CSSValue* D::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (const StylePath* style_path = style.D()) |
| return style_path->ComputedCSSValue(); |
| return CSSIdentifierValue::Create(CSSValueID::kNone); |
| } |
| |
| const CSSValue* Direction::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.Direction()); |
| } |
| |
| void Direction::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| state.Style()->SetDirection( |
| To<CSSIdentifierValue>(value).ConvertTo<TextDirection>()); |
| } |
| |
| namespace { |
| |
| static bool IsDisplayOutside(CSSValueID id) { |
| return id >= CSSValueID::kInline && id <= CSSValueID::kBlock; |
| } |
| |
| static bool IsDisplayInside(CSSValueID id) { |
| if (id >= CSSValueID::kFlowRoot && id <= CSSValueID::kGrid) |
| return true; |
| if (id == CSSValueID::kMath) |
| return RuntimeEnabledFeatures::MathMLCoreEnabled(); |
| return false; |
| } |
| |
| static bool IsDisplayBox(CSSValueID id) { |
| return css_parsing_utils::IdentMatches<CSSValueID::kNone, |
| CSSValueID::kContents>(id); |
| } |
| |
| static bool IsDisplayInternal(CSSValueID id) { |
| return id >= CSSValueID::kTableRowGroup && id <= CSSValueID::kTableCaption; |
| } |
| |
| static bool IsDisplayLegacy(CSSValueID id) { |
| return id >= CSSValueID::kInlineBlock && id <= CSSValueID::kWebkitInlineFlex; |
| } |
| |
| } // namespace |
| |
| const CSSValue* Display::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| CSSValueID id = range.Peek().Id(); |
| CSSIdentifierValue* display_outside = nullptr; |
| CSSIdentifierValue* display_inside = nullptr; |
| if (IsDisplayOutside(id)) { |
| display_outside = css_parsing_utils::ConsumeIdent(range); |
| if (range.AtEnd()) |
| return display_outside; |
| id = range.Peek().Id(); |
| if (!IsDisplayInside(id)) |
| return nullptr; |
| display_inside = css_parsing_utils::ConsumeIdent(range); |
| } else if (IsDisplayInside(id)) { |
| display_inside = css_parsing_utils::ConsumeIdent(range); |
| if (range.AtEnd()) |
| return display_inside; |
| id = range.Peek().Id(); |
| if (!IsDisplayOutside(id)) |
| return nullptr; |
| display_outside = css_parsing_utils::ConsumeIdent(range); |
| } |
| if (display_outside && display_inside) { |
| // TODO(crbug.com/995106): should apply to more than just math. |
| if (display_inside->GetValueID() == CSSValueID::kMath) { |
| CSSValueList* parsed_values = CSSValueList::CreateSpaceSeparated(); |
| parsed_values->Append(*display_outside); |
| parsed_values->Append(*display_inside); |
| return parsed_values; |
| } |
| return nullptr; |
| } |
| if (id == CSSValueID::kListItem || IsDisplayBox(id) || |
| IsDisplayInternal(id) || IsDisplayLegacy(id)) |
| return css_parsing_utils::ConsumeIdent(range); |
| |
| if (!RuntimeEnabledFeatures::CSSLayoutAPIEnabled()) |
| return nullptr; |
| |
| if (!context.IsSecureContext()) |
| return nullptr; |
| |
| CSSValueID function = range.Peek().FunctionId(); |
| if (function != CSSValueID::kLayout && function != CSSValueID::kInlineLayout) |
| return nullptr; |
| |
| CSSParserTokenRange range_copy = range; |
| CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range_copy); |
| CSSCustomIdentValue* name = |
| css_parsing_utils::ConsumeCustomIdent(args, context); |
| |
| // If we didn't get a custom-ident or didn't exhaust the function arguments |
| // return nothing. |
| if (!name || !args.AtEnd()) |
| return nullptr; |
| |
| range = range_copy; |
| return MakeGarbageCollected<cssvalue::CSSLayoutFunctionValue>( |
| name, /* is_inline */ function == CSSValueID::kInlineLayout); |
| } |
| |
| const CSSValue* Display::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if (style.IsDisplayLayoutCustomBox()) { |
| return MakeGarbageCollected<cssvalue::CSSLayoutFunctionValue>( |
| MakeGarbageCollected<CSSCustomIdentValue>( |
| style.DisplayLayoutCustomName()), |
| style.IsDisplayInlineType()); |
| } |
| |
| if (style.Display() == EDisplay::kBlockMath) { |
| CSSValueList* values = CSSValueList::CreateSpaceSeparated(); |
| values->Append(*CSSIdentifierValue::Create(CSSValueID::kBlock)); |
| values->Append(*CSSIdentifierValue::Create(CSSValueID::kMath)); |
| return values; |
| } |
| |
| return CSSIdentifierValue::Create(style.Display()); |
| } |
| |
| void Display::ApplyInitial(StyleResolverState& state) const { |
| state.Style()->SetDisplay(ComputedStyleInitialValues::InitialDisplay()); |
| state.Style()->SetDisplayLayoutCustomName( |
| ComputedStyleInitialValues::InitialDisplayLayoutCustomName()); |
| } |
| |
| void Display::ApplyInherit(StyleResolverState& state) const { |
| state.Style()->SetDisplay(state.ParentStyle()->Display()); |
| state.Style()->SetDisplayLayoutCustomName( |
| state.ParentStyle()->DisplayLayoutCustomName()); |
| } |
| |
| void Display::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { |
| state.Style()->SetDisplay(identifier_value->ConvertTo<EDisplay>()); |
| state.Style()->SetDisplayLayoutCustomName( |
| ComputedStyleInitialValues::InitialDisplayLayoutCustomName()); |
| return; |
| } |
| |
| if (value.IsValueList()) { |
| state.Style()->SetDisplayLayoutCustomName( |
| ComputedStyleInitialValues::InitialDisplayLayoutCustomName()); |
| const CSSValueList& display_pair = To<CSSValueList>(value); |
| DCHECK_EQ(display_pair.length(), 2u); |
| DCHECK(display_pair.Item(0).IsIdentifierValue()); |
| DCHECK(display_pair.Item(1).IsIdentifierValue()); |
| const auto& outside = To<CSSIdentifierValue>(display_pair.Item(0)); |
| const auto& inside = To<CSSIdentifierValue>(display_pair.Item(1)); |
| // TODO(crbug.com/995106): should apply to more than just math. |
| DCHECK(inside.GetValueID() == CSSValueID::kMath); |
| if (outside.GetValueID() == CSSValueID::kBlock) |
| state.Style()->SetDisplay(EDisplay::kBlockMath); |
| else |
| state.Style()->SetDisplay(EDisplay::kMath); |
| return; |
| } |
| |
| const auto& layout_function_value = |
| To<cssvalue::CSSLayoutFunctionValue>(value); |
| |
| EDisplay display = layout_function_value.IsInline() |
| ? EDisplay::kInlineLayoutCustom |
| : EDisplay::kLayoutCustom; |
| state.Style()->SetDisplay(display); |
| state.Style()->SetDisplayLayoutCustomName(layout_function_value.GetName()); |
| } |
| |
| const CSSValue* DominantBaseline::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.DominantBaseline()); |
| } |
| |
| const CSSValue* EmptyCells::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.EmptyCells()); |
| } |
| |
| const CSSValue* Fill::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeSVGPaint(range, context); |
| } |
| |
| const CSSValue* Fill::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForSVGPaint(style.FillPaint(), style); |
| } |
| |
| const blink::Color Fill::ColorIncludingFallback( |
| bool visited_link, |
| const ComputedStyle& style) const { |
| DCHECK(!visited_link); |
| DCHECK(style.FillPaint().HasColor()); |
| const StyleColor& fill_color = style.FillPaint().GetColor(); |
| if (style.ShouldForceColor(fill_color)) |
| return style.GetInternalForcedCurrentColor(); |
| return fill_color.Resolve(style.GetCurrentColor(), style.UsedColorScheme()); |
| } |
| |
| const CSSValue* FillOpacity::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeAlphaValue(range, context); |
| } |
| |
| const CSSValue* FillOpacity::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSNumericLiteralValue::Create(style.FillOpacity(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| } |
| |
| const CSSValue* FillRule::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.FillRule()); |
| } |
| |
| const CSSValue* Filter::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeFilterFunctionList(range, context); |
| } |
| |
| const CSSValue* Filter::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ValueForFilter(style, style.Filter()); |
| } |
| |
| void Filter::ApplyValue(StyleResolverState& state, |
| const CSSValue& value) const { |
| state.Style()->SetFilter(StyleBuilderConverter::ConvertFilterOperations( |
| state, value, PropertyID())); |
| } |
| |
| const CSSValue* FlexBasis::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| // FIXME: Support intrinsic dimensions too. |
| if (range.Peek().Id() == CSSValueID::kAuto) |
| return css_parsing_utils::ConsumeIdent(range); |
| return css_parsing_utils::ConsumeLengthOrPercent(range, context, |
| kValueRangeNonNegative); |
| } |
| |
| const CSSValue* FlexBasis::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(style.FlexBasis(), |
| style); |
| } |
| |
| const CSSValue* FlexDirection::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.FlexDirection()); |
| } |
| |
| const CSSValue* FlexGrow::ParseSingleValue(CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeNumber(range, context, |
| kValueRangeNonNegative); |
| } |
| |
| const CSSValue* FlexGrow::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSNumericLiteralValue::Create(style.FlexGrow(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| } |
| |
| const CSSValue* FlexShrink::ParseSingleValue( |
| CSSParserTokenRange& range, |
| const CSSParserContext& context, |
| const CSSParserLocalContext&) const { |
| return css_parsing_utils::ConsumeNumber(range, context, |
| kValueRangeNonNegative); |
| } |
| |
| const CSSValue* FlexShrink::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSNumericLiteralValue::Create(style.FlexShrink(), |
| CSSPrimitiveValue::UnitType::kNumber); |
| } |
| |
| const CSSValue* FlexWrap::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| return CSSIdentifierValue::Create(style.FlexWrap()); |
| } |
| |
| const CSSValue* Float::CSSValueFromComputedStyleInternal( |
| const ComputedStyle& style, |
| const LayoutObject*, |
| bool allow_visited_style) const { |
| if |