diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index b1eb3b6dd85..d7a92043c56 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -960,6 +960,10 @@ RefPtr CSSStyleProperties::style_value_for_computed_propert auto border_top_width = layout_node.computed_values().border_top(); return LengthStyleValue::create(Length::make_px(border_top_width.width)); } + case PropertyID::OutlineWidth: { + auto outline_width = layout_node.computed_values().outline_width(); + return LengthStyleValue::create(outline_width); + } case PropertyID::WebkitTextFillColor: return CSSColorValue::create_from_color(layout_node.computed_values().webkit_text_fill_color(), ColorSyntax::Modern); case PropertyID::Invalid: diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index f2b4d72b818..5a9664f8e1e 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -728,6 +728,29 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) computed_values.set_transition_delay(transition_delay.resolve_time({ .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value()); } + auto resolve_border_width = [&](CSS::PropertyID width_property) -> CSSPixels { + auto const& value = computed_style.property(width_property); + if (value.is_calculated()) + return max(CSSPixels { 0 }, + value.as_calculated().resolve_length({ .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) })->to_px(*this)); + if (value.is_length()) + return value.as_length().length().to_px(*this); + if (value.is_keyword()) { + // https://www.w3.org/TR/css-backgrounds-3/#valdef-line-width-thin + switch (value.to_keyword()) { + case CSS::Keyword::Thin: + return 1; + case CSS::Keyword::Medium: + return 3; + case CSS::Keyword::Thick: + return 5; + default: + VERIFY_NOT_REACHED(); + } + } + VERIFY_NOT_REACHED(); + }; + auto do_border_style = [&](CSS::BorderData& border, CSS::PropertyID width_property, CSS::PropertyID color_property, CSS::PropertyID style_property) { // FIXME: The default border color value is `currentcolor`, but since we can't resolve that easily, // we just manually grab the value from `color`. This makes it dependent on `color` being @@ -743,30 +766,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) if (border.line_style == CSS::LineStyle::None || border.line_style == CSS::LineStyle::Hidden) { border.width = 0; } else { - auto resolve_border_width = [&]() -> CSSPixels { - auto const& value = computed_style.property(width_property); - if (value.is_calculated()) - return max(CSSPixels { 0 }, - value.as_calculated().resolve_length({ .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) })->to_px(*this)); - if (value.is_length()) - return value.as_length().length().to_px(*this); - if (value.is_keyword()) { - // https://www.w3.org/TR/css-backgrounds-3/#valdef-line-width-thin - switch (value.to_keyword()) { - case CSS::Keyword::Thin: - return 1; - case CSS::Keyword::Medium: - return 3; - case CSS::Keyword::Thick: - return 5; - default: - VERIFY_NOT_REACHED(); - } - } - VERIFY_NOT_REACHED(); - }; - - border.width = snap_a_length_as_a_border_width(document().page().client().device_pixels_per_css_pixel(), resolve_border_width()); + border.width = snap_a_length_as_a_border_width(document().page().client().device_pixels_per_css_pixel(), resolve_border_width(width_property)); } }; @@ -780,8 +780,13 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) if (auto const& outline_offset = computed_style.property(CSS::PropertyID::OutlineOffset); outline_offset.is_length()) computed_values.set_outline_offset(outline_offset.as_length().length()); computed_values.set_outline_style(computed_style.outline_style()); - if (auto const& outline_width = computed_style.property(CSS::PropertyID::OutlineWidth); outline_width.is_length()) - computed_values.set_outline_width(outline_width.as_length().length()); + + CSSPixels resolved_outline_width = 0; + if (computed_values.outline_style() != CSS::OutlineStyle::None) + resolved_outline_width = max(CSSPixels { 0 }, resolve_border_width(CSS::PropertyID::OutlineWidth)); + + auto snapped_outline_width = snap_a_length_as_a_border_width(document().page().client().device_pixels_per_css_pixel(), resolved_outline_width); + computed_values.set_outline_width(CSS::Length::make_px(snapped_outline_width)); computed_values.set_grid_auto_columns(computed_style.grid_auto_columns()); computed_values.set_grid_auto_rows(computed_style.grid_auto_rows()); diff --git a/Tests/LibWeb/Text/expected/css/CSSStyleProperties-all-supported-properties-and-default-values.txt b/Tests/LibWeb/Text/expected/css/CSSStyleProperties-all-supported-properties-and-default-values.txt index 470be656079..d45264ddd73 100644 --- a/Tests/LibWeb/Text/expected/css/CSSStyleProperties-all-supported-properties-and-default-values.txt +++ b/Tests/LibWeb/Text/expected/css/CSSStyleProperties-all-supported-properties-and-default-values.txt @@ -496,15 +496,15 @@ All supported properties and their default values exposed from CSSStylePropertie 'object-position': '50% 50%' 'opacity': '1' 'order': '0' -'outline': 'rgb(0, 0, 0) none medium' +'outline': 'rgb(0, 0, 0) none 0px' 'outlineColor': 'rgb(0, 0, 0)' 'outline-color': 'rgb(0, 0, 0)' 'outlineOffset': '0px' 'outline-offset': '0px' 'outlineStyle': 'none' 'outline-style': 'none' -'outlineWidth': 'medium' -'outline-width': 'medium' +'outlineWidth': '0px' +'outline-width': '0px' 'overflow': 'visible' 'overflowX': 'visible' 'overflow-x': 'visible' diff --git a/Tests/LibWeb/Text/expected/css/calc-coverage.txt b/Tests/LibWeb/Text/expected/css/calc-coverage.txt index c0f6b4b9f44..5c74168d9f9 100644 --- a/Tests/LibWeb/Text/expected/css/calc-coverage.txt +++ b/Tests/LibWeb/Text/expected/css/calc-coverage.txt @@ -116,8 +116,8 @@ order: 'calc(2)' -> '2' order: 'calc(2 * var(--n))' -> '4' outline-offset: 'calc(2px)' -> '2px' outline-offset: 'calc(2px * var(--n))' -> '4px' -outline-width: 'calc(2px)' -> '2px' -outline-width: 'calc(2px * var(--n))' -> '4px' +outline-width: 'calc(2px)' -> '0px' +outline-width: 'calc(2px * var(--n))' -> '0px' padding-bottom: 'calc(2px)' -> '2px' padding-bottom: 'calc(2px * var(--n))' -> '4px' padding-left: 'calc(2%)' -> '15.6875px' diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt index 16969d9bae5..7ccc821b2a2 100644 --- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt +++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt @@ -186,7 +186,7 @@ order: 0 outline-color: rgb(0, 0, 0) outline-offset: 0px outline-style: none -outline-width: medium +outline-width: 0px overflow-x: visible overflow-y: visible padding-block-end: 0px diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-ui/parsing/outline-width-computed.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-ui/parsing/outline-width-computed.txt new file mode 100644 index 00000000000..e77ca5f847a --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-ui/parsing/outline-width-computed.txt @@ -0,0 +1,14 @@ +Harness status: OK + +Found 9 tests + +9 Pass +Pass Property outline-width value '2.5px' +Pass Property outline-width value '10px' +Pass Property outline-width value '0.5em' +Pass Property outline-width value 'calc(10px + 0.5em)' +Pass Property outline-width value 'calc(10px - 0.5em)' +Pass Property outline-width value 'thin' +Pass Property outline-width value 'medium' +Pass Property outline-width value 'thick' +Pass outline-width is 0 when outline-style is none \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-ui/parsing/outline-width-computed.html b/Tests/LibWeb/Text/input/wpt-import/css/css-ui/parsing/outline-width-computed.html new file mode 100644 index 00000000000..2ac81cc94e5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-ui/parsing/outline-width-computed.html @@ -0,0 +1,45 @@ + + + + +CSS UI Level 3: getComputedStyle().outlineWidth + + + + + + + + +
+ + +