diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index d2b465598e4..1afdcd5b724 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -1951,6 +1951,47 @@ ShapeRendering ComputedProperties::shape_rendering() const return keyword_to_shape_rendering(value.to_keyword()).release_value(); } +PaintOrderList ComputedProperties::paint_order() const +{ + auto const& value = property(PropertyID::PaintOrder); + if (value.is_keyword()) { + auto keyword = value.as_keyword().keyword(); + if (keyword == Keyword::Normal) + return InitialValues::paint_order(); + auto paint_order_keyword = keyword_to_paint_order(keyword); + VERIFY(paint_order_keyword.has_value()); + switch (*paint_order_keyword) { + case PaintOrder::Fill: + return InitialValues::paint_order(); + case PaintOrder::Stroke: + return PaintOrderList { PaintOrder::Stroke, PaintOrder::Fill, PaintOrder::Markers }; + case PaintOrder::Markers: + return PaintOrderList { PaintOrder::Markers, PaintOrder::Fill, PaintOrder::Stroke }; + } + } + + VERIFY(value.is_value_list()); + auto const& value_list = value.as_value_list(); + // The list must contain 2 values at this point, since the third value is omitted during parsing due to the + // shortest-serialization principle. + VERIFY(value_list.size() == 2); + PaintOrderList paint_order_list {}; + + // We use the sum of the keyword values to infer what the missing keyword is. Since each keyword can only appear in + // the list once, the sum of their values will always be 3. + auto sum = 0; + for (auto i = 0; i < 2; i++) { + auto keyword = value_list.value_at(i, false)->as_keyword().keyword(); + auto paint_order_keyword = keyword_to_paint_order(keyword); + VERIFY(paint_order_keyword.has_value()); + sum += to_underlying(*paint_order_keyword); + paint_order_list[i] = *paint_order_keyword; + } + VERIFY(sum <= 3); + paint_order_list[2] = static_cast(3 - sum); + return paint_order_list; +} + WillChange ComputedProperties::will_change() const { auto const& value = property(PropertyID::WillChange); diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index 0799b09dd62..99e7d77bd63 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -199,6 +199,7 @@ public: ClipRule clip_rule() const; float flood_opacity() const; CSS::ShapeRendering shape_rendering() const; + PaintOrderList paint_order() const; WillChange will_change() const; diff --git a/Libraries/LibWeb/CSS/ComputedValues.h b/Libraries/LibWeb/CSS/ComputedValues.h index 6d5eb7a9fc0..159a970014e 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Libraries/LibWeb/CSS/ComputedValues.h @@ -118,6 +118,8 @@ using CursorData = Variant, CursorPredefin using ListStyleType = Variant; +using PaintOrderList = Array; + class InitialValues { public: static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; } @@ -259,6 +261,7 @@ public: } static CSS::ScrollbarWidth scrollbar_width() { return CSS::ScrollbarWidth::Auto; } static CSS::ShapeRendering shape_rendering() { return CSS::ShapeRendering::Auto; } + static PaintOrderList paint_order() { return { PaintOrder::Fill, PaintOrder::Stroke, PaintOrder::Markers }; } static WillChange will_change() { return WillChange::make_auto(); } }; @@ -590,6 +593,7 @@ public: CSS::ClipRule clip_rule() const { return m_inherited.clip_rule; } Color flood_color() const { return m_noninherited.flood_color; } float flood_opacity() const { return m_noninherited.flood_opacity; } + PaintOrderList paint_order() const { return m_inherited.paint_order; } LengthPercentage const& cx() const { return m_noninherited.cx; } LengthPercentage const& cy() const { return m_noninherited.cy; } @@ -702,6 +706,7 @@ protected: CSS::FillRule fill_rule { InitialValues::fill_rule() }; Optional stroke; float fill_opacity { InitialValues::fill_opacity() }; + PaintOrderList paint_order { InitialValues::paint_order() }; Vector> stroke_dasharray; LengthPercentage stroke_dashoffset { InitialValues::stroke_dashoffset() }; CSS::StrokeLinecap stroke_linecap { InitialValues::stroke_linecap() }; @@ -1032,6 +1037,7 @@ public: void set_flood_color(Color value) { m_noninherited.flood_color = value; } void set_flood_opacity(float value) { m_noninherited.flood_opacity = value; } void set_shape_rendering(CSS::ShapeRendering value) { m_noninherited.shape_rendering = value; } + void set_paint_order(PaintOrderList value) { m_inherited.paint_order = value; } void set_cx(LengthPercentage cx) { m_noninherited.cx = move(cx); } void set_cy(LengthPercentage cy) { m_noninherited.cy = move(cy); } diff --git a/Libraries/LibWeb/CSS/Enums.json b/Libraries/LibWeb/CSS/Enums.json index 21e0d614342..8340038dc41 100644 --- a/Libraries/LibWeb/CSS/Enums.json +++ b/Libraries/LibWeb/CSS/Enums.json @@ -575,6 +575,11 @@ "legal", "ledger" ], + "paint-order": [ + "fill", + "stroke", + "markers" + ], "pointer-events": [ "auto", "all", diff --git a/Libraries/LibWeb/CSS/Keywords.json b/Libraries/LibWeb/CSS/Keywords.json index 42a5fd79d1b..0a099294698 100644 --- a/Libraries/LibWeb/CSS/Keywords.json +++ b/Libraries/LibWeb/CSS/Keywords.json @@ -319,6 +319,7 @@ "luminosity", "manipulation", "mark", + "markers", "marktext", "match-parent", "match-source", @@ -498,6 +499,7 @@ "strict", "strict-origin", "strict-origin-when-cross-origin", + "stroke", "stroke-box", "style", "sub", diff --git a/Libraries/LibWeb/CSS/Parser/Parser.h b/Libraries/LibWeb/CSS/Parser/Parser.h index ec8bb1cfbc6..f8a96fa3627 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Libraries/LibWeb/CSS/Parser/Parser.h @@ -454,6 +454,7 @@ private: RefPtr parse_math_depth_value(TokenStream&); RefPtr parse_opacity_value(PropertyID property_id, TokenStream&); RefPtr parse_overflow_value(TokenStream&); + RefPtr parse_paint_order_value(TokenStream&); RefPtr parse_place_content_value(TokenStream&); RefPtr parse_place_items_value(TokenStream&); RefPtr parse_place_self_value(TokenStream&); diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index 612b6257997..cc16d62007d 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -701,6 +701,10 @@ Parser::ParseErrorOr> Parser::parse_css_value(Pr if (auto parsed_value = parse_overflow_value(tokens); parsed_value && !tokens.has_next_token()) return parsed_value.release_nonnull(); return ParseError::SyntaxError; + case PropertyID::PaintOrder: + if (auto parsed_value = parse_paint_order_value(tokens); parsed_value && !tokens.has_next_token()) + return parsed_value.release_nonnull(); + return ParseError::SyntaxError; case PropertyID::PlaceContent: if (auto parsed_value = parse_place_content_value(tokens); parsed_value && !tokens.has_next_token()) return parsed_value.release_nonnull(); @@ -3856,6 +3860,84 @@ RefPtr Parser::parse_overflow_value(TokenStream Parser::parse_paint_order_value(TokenStream& tokens) +{ + if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) + return normal; + + bool has_fill = false; + bool has_stroke = false; + bool has_markers = false; + + auto parse_paint_order_keyword = [&](auto& inner_tokens) -> RefPtr { + auto maybe_value = parse_keyword_value(inner_tokens); + if (!maybe_value) + return nullptr; + + switch (maybe_value->to_keyword()) { + case Keyword::Fill: + if (has_fill) + return nullptr; + has_fill = true; + break; + case Keyword::Markers: + if (has_markers) + return nullptr; + has_markers = true; + break; + case Keyword::Stroke: + if (has_stroke) + return nullptr; + has_stroke = true; + break; + default: + return nullptr; + } + + return maybe_value.release_nonnull(); + }; + + tokens.discard_whitespace(); + if (tokens.is_empty()) + return nullptr; + + auto transaction = tokens.begin_transaction(); + auto first_keyword_value = parse_paint_order_keyword(tokens); + if (!first_keyword_value) + return nullptr; + + tokens.discard_whitespace(); + if (!tokens.has_next_token()) { + transaction.commit(); + return first_keyword_value; + } + + auto second_keyword_value = parse_paint_order_keyword(tokens); + if (!second_keyword_value) + return nullptr; + + tokens.discard_whitespace(); + if (tokens.has_next_token()) { + // The third keyword is parsed to ensure it is valid, but it doesn't get added to the list. This follows the + // shortest-serialization principle, as the value can always be inferred. + if (auto third_keyword_value = parse_paint_order_keyword(tokens); !third_keyword_value) + return nullptr; + tokens.discard_whitespace(); + if (tokens.has_next_token()) + return nullptr; + } + + transaction.commit(); + auto expected_second_keyword = Keyword::Fill; + if (first_keyword_value->to_keyword() == Keyword::Fill) + expected_second_keyword = Keyword::Stroke; + + if (expected_second_keyword == second_keyword_value->to_keyword()) + return first_keyword_value; + + return StyleValueList::create({ first_keyword_value.release_nonnull(), second_keyword_value.release_nonnull() }, StyleValueList::Separator::Space); +} + RefPtr Parser::parse_place_content_value(TokenStream& tokens) { auto transaction = tokens.begin_transaction(); diff --git a/Libraries/LibWeb/CSS/Properties.json b/Libraries/LibWeb/CSS/Properties.json index 3757bc2ab7a..de2130f6875 100644 --- a/Libraries/LibWeb/CSS/Properties.json +++ b/Libraries/LibWeb/CSS/Properties.json @@ -2889,6 +2889,17 @@ "unitless-length" ] }, + "paint-order": { + "animation-type": "discrete", + "inherited": true, + "initial": "normal", + "valid-identifiers": [ + "normal" + ], + "valid-types": [ + "paint-order" + ] + }, "place-content": { "inherited": false, "initial": "normal", diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index c84c40b6aee..768e8536ed2 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -854,6 +854,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) else if (stroke_width.is_percentage()) computed_values.set_stroke_width(CSS::LengthPercentage { stroke_width.as_percentage().percentage() }); computed_values.set_shape_rendering(computed_style.shape_rendering()); + computed_values.set_paint_order(computed_style.paint_order()); auto const& mask_image = computed_style.property(CSS::PropertyID::MaskImage); if (mask_image.is_url()) { diff --git a/Libraries/LibWeb/SVG/SVGElement.cpp b/Libraries/LibWeb/SVG/SVGElement.cpp index daf7317989a..9d75f159299 100644 --- a/Libraries/LibWeb/SVG/SVGElement.cpp +++ b/Libraries/LibWeb/SVG/SVGElement.cpp @@ -77,6 +77,7 @@ static ReadonlySpan attribute_style_properties() NamedPropertyID(CSS::PropertyID::MaskType), NamedPropertyID(CSS::PropertyID::Opacity), NamedPropertyID(CSS::PropertyID::Overflow), + NamedPropertyID(CSS::PropertyID::PaintOrder), NamedPropertyID(CSS::PropertyID::PointerEvents), NamedPropertyID(CSS::PropertyID::R, { SVG::TagNames::circle }), NamedPropertyID(CSS::PropertyID::Rx, { SVG::TagNames::ellipse, SVG::TagNames::rect }), diff --git a/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-has-indexed-property-getter.txt b/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-has-indexed-property-getter.txt index ae4ce63f441..dcc88ff8d67 100644 --- a/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-has-indexed-property-getter.txt +++ b/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-has-indexed-property-getter.txt @@ -41,6 +41,7 @@ All properties associated with getComputedStyle(document.body): "math-depth", "math-shift", "math-style", + "paint-order", "pointer-events", "quotes", "shape-rendering", 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 e8ee95f5fd7..60a00502020 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 @@ -610,6 +610,8 @@ All supported properties and their default values exposed from CSSStylePropertie 'padding-right': '0px' 'paddingTop': '0px' 'padding-top': '0px' +'paintOrder': 'normal' +'paint-order': 'normal' 'placeContent': 'normal' 'place-content': 'normal' 'placeItems': 'normal legacy' diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt index 9cc6db61751..ad3ac7124cd 100644 --- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt +++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt @@ -39,6 +39,7 @@ list-style-type: disc math-depth: 0 math-shift: normal math-style: normal +paint-order: normal pointer-events: auto quotes: auto shape-rendering: auto @@ -91,7 +92,7 @@ background-position-x: 0% background-position-y: 0% background-repeat: repeat background-size: auto -block-size: 1395px +block-size: 1410px border-block-end-color: rgb(0, 0, 0) border-block-end-style: none border-block-end-width: 0px @@ -167,7 +168,7 @@ grid-row-start: auto grid-template-areas: none grid-template-columns: none grid-template-rows: none -height: 2535px +height: 2550px inline-size: 784px inset-block-end: auto inset-block-start: auto diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-cascade/all-prop-revert-layer.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-cascade/all-prop-revert-layer.txt index 805a803af23..e8b191f7b52 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-cascade/all-prop-revert-layer.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-cascade/all-prop-revert-layer.txt @@ -1,8 +1,8 @@ Harness status: OK -Found 257 tests +Found 258 tests -250 Pass +251 Pass 7 Fail Pass accent-color Pass border-collapse @@ -43,6 +43,7 @@ Pass list-style-type Pass math-depth Pass math-shift Pass math-style +Pass paint-order Pass pointer-events Pass quotes Pass shape-rendering diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/cssom/shorthand-values.txt b/Tests/LibWeb/Text/expected/wpt-import/css/cssom/shorthand-values.txt index 1f0465c77f7..0ccfa5c34a2 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/cssom/shorthand-values.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/cssom/shorthand-values.txt @@ -2,15 +2,15 @@ Harness status: OK Found 20 tests -15 Pass -5 Fail +14 Pass +6 Fail Pass The serialization of border: 1px; border-top: 1px; should be canonical. Pass The serialization of border: 1px solid red; should be canonical. Pass The serialization of border: 1px red; should be canonical. Pass The serialization of border: red; should be canonical. Fail The serialization of border-top: 1px; border-right: 1px; border-bottom: 1px; border-left: 1px; border-image: none; should be canonical. Fail The serialization of border-top: 1px; border-right: 1px; border-bottom: 1px; border-left: 1px; should be canonical. -Pass The serialization of border-top: 1px; border-right: 2px; border-bottom: 3px; border-left: 4px; should be canonical. +Fail The serialization of border-top: 1px; border-right: 2px; border-bottom: 3px; border-left: 4px; should be canonical. Fail The serialization of border: 1px; border-top: 2px; should be canonical. Fail The serialization of border: 1px; border-top: 1px !important; should be canonical. Fail The serialization of border: 1px; border-top-color: red; should be canonical. diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/painting/inheritance.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/inheritance.txt index 2e51ace4cd5..168adcbd289 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/svg/painting/inheritance.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/inheritance.txt @@ -2,8 +2,8 @@ Harness status: OK Found 38 tests -30 Pass -8 Fail +32 Pass +6 Fail Pass Property fill has initial value rgb(0, 0, 0) Pass Property fill inherits Pass Property fill-rule has initial value nonzero @@ -32,8 +32,8 @@ Fail Property marker-mid has initial value none Fail Property marker-mid inherits Fail Property marker-end has initial value none Fail Property marker-end inherits -Fail Property paint-order has initial value normal -Fail Property paint-order inherits +Pass Property paint-order has initial value normal +Pass Property paint-order inherits Pass Property color-interpolation has initial value srgb Pass Property color-interpolation inherits Pass Property shape-rendering has initial value auto diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/painting/parsing/paint-order-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/parsing/paint-order-invalid.txt new file mode 100644 index 00000000000..d79fb201a1c --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/parsing/paint-order-invalid.txt @@ -0,0 +1,8 @@ +Harness status: OK + +Found 3 tests + +3 Pass +Pass e.style['paint-order'] = "normal stroke" should not set the property value +Pass e.style['paint-order'] = "fill fill" should not set the property value +Pass e.style['paint-order'] = "markers normal" should not set the property value \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/painting/parsing/paint-order-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/parsing/paint-order-valid.txt new file mode 100644 index 00000000000..98ff1d7ff11 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/parsing/paint-order-valid.txt @@ -0,0 +1,21 @@ +Harness status: OK + +Found 16 tests + +16 Pass +Pass e.style['paint-order'] = "normal" should set the property value +Pass e.style['paint-order'] = "fill" should set the property value +Pass e.style['paint-order'] = "stroke" should set the property value +Pass e.style['paint-order'] = "markers" should set the property value +Pass e.style['paint-order'] = "fill stroke" should set the property value +Pass e.style['paint-order'] = "fill markers" should set the property value +Pass e.style['paint-order'] = "stroke fill" should set the property value +Pass e.style['paint-order'] = "stroke markers" should set the property value +Pass e.style['paint-order'] = "markers fill" should set the property value +Pass e.style['paint-order'] = "markers stroke" should set the property value +Pass e.style['paint-order'] = "fill stroke markers" should set the property value +Pass e.style['paint-order'] = "fill markers stroke" should set the property value +Pass e.style['paint-order'] = "stroke fill markers" should set the property value +Pass e.style['paint-order'] = "stroke markers fill" should set the property value +Pass e.style['paint-order'] = "markers fill stroke" should set the property value +Pass e.style['paint-order'] = "markers stroke fill" should set the property value \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/painting/scripted/paint-order-computed-value-01.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/scripted/paint-order-computed-value-01.txt new file mode 100644 index 00000000000..beb8d79ab75 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/painting/scripted/paint-order-computed-value-01.txt @@ -0,0 +1,49 @@ +Harness status: OK + +Found 44 tests + +44 Pass +Pass 'paint-order' computed style serialization, "normal" => "normal" (property) +Pass 'paint-order' computed style serialization, "fill" => "fill" (property) +Pass 'paint-order' computed style serialization, "stroke" => "stroke" (property) +Pass 'paint-order' computed style serialization, "markers" => "markers" (property) +Pass 'paint-order' computed style serialization, "fill stroke" => "fill" (property) +Pass 'paint-order' computed style serialization, "fill markers" => "fill markers" (property) +Pass 'paint-order' computed style serialization, "stroke fill" => "stroke" (property) +Pass 'paint-order' computed style serialization, "stroke markers" => "stroke markers" (property) +Pass 'paint-order' computed style serialization, "markers fill" => "markers" (property) +Pass 'paint-order' computed style serialization, "markers stroke" => "markers stroke" (property) +Pass 'paint-order' computed style serialization, "fill stroke markers" => "fill" (property) +Pass 'paint-order' computed style serialization, "fill markers stroke" => "fill markers" (property) +Pass 'paint-order' computed style serialization, "stroke fill markers" => "stroke" (property) +Pass 'paint-order' computed style serialization, "stroke markers fill" => "stroke markers" (property) +Pass 'paint-order' computed style serialization, "markers fill stroke" => "markers" (property) +Pass 'paint-order' computed style serialization, "markers stroke fill" => "markers stroke" (property) +Pass 'paint-order' computed style serialization, "foo" => "normal" (property) +Pass 'paint-order' computed style serialization, "fill foo" => "normal" (property) +Pass 'paint-order' computed style serialization, "stroke foo" => "normal" (property) +Pass 'paint-order' computed style serialization, "markers foo" => "normal" (property) +Pass 'paint-order' computed style serialization, "normal foo" => "normal" (property) +Pass 'paint-order' computed style serialization, "fill markers stroke foo" => "normal" (property) +Pass 'paint-order' computed style serialization, "normal" => "normal" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill" => "fill" (presentation attribute) +Pass 'paint-order' computed style serialization, "stroke" => "stroke" (presentation attribute) +Pass 'paint-order' computed style serialization, "markers" => "markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill stroke" => "fill" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill markers" => "fill markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "stroke fill" => "stroke" (presentation attribute) +Pass 'paint-order' computed style serialization, "stroke markers" => "stroke markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "markers fill" => "markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "markers stroke" => "markers stroke" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill stroke markers" => "fill" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill markers stroke" => "fill markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "stroke fill markers" => "stroke" (presentation attribute) +Pass 'paint-order' computed style serialization, "stroke markers fill" => "stroke markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "markers fill stroke" => "markers" (presentation attribute) +Pass 'paint-order' computed style serialization, "markers stroke fill" => "markers stroke" (presentation attribute) +Pass 'paint-order' computed style serialization, "foo" => "normal" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill foo" => "normal" (presentation attribute) +Pass 'paint-order' computed style serialization, "stroke foo" => "normal" (presentation attribute) +Pass 'paint-order' computed style serialization, "markers foo" => "normal" (presentation attribute) +Pass 'paint-order' computed style serialization, "normal foo" => "normal" (presentation attribute) +Pass 'paint-order' computed style serialization, "fill markers stroke foo" => "normal" (presentation attribute) \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-irrelevant.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-irrelevant.txt index c5f5cc3ba5a..addf2f101cb 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-irrelevant.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-irrelevant.txt @@ -1,8 +1,8 @@ Harness status: OK -Found 47 tests +Found 48 tests -44 Pass +45 Pass 3 Fail Pass clip-path presentation attribute supported on an irrelevant element Pass clip-rule presentation attribute supported on an irrelevant element @@ -29,6 +29,7 @@ Pass mask-type presentation attribute supported on an irrelevant element Pass mask presentation attribute supported on an irrelevant element Pass opacity presentation attribute supported on an irrelevant element Pass overflow presentation attribute supported on an irrelevant element +Pass paint-order presentation attribute supported on an irrelevant element Pass pointer-events presentation attribute supported on an irrelevant element Pass shape-rendering presentation attribute supported on an irrelevant element Pass stop-color presentation attribute supported on an irrelevant element diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-relevant.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-relevant.txt index 01c2c276dc8..683eea049a1 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-relevant.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-relevant.txt @@ -1,8 +1,8 @@ Harness status: OK -Found 57 tests +Found 58 tests -53 Pass +54 Pass 4 Fail Pass clip-path presentation attribute supported on a relevant element Pass clip-rule presentation attribute supported on a relevant element @@ -32,6 +32,7 @@ Pass mask-type presentation attribute supported on a relevant element Pass mask presentation attribute supported on a relevant element Pass opacity presentation attribute supported on a relevant element Pass overflow presentation attribute supported on a relevant element +Pass paint-order presentation attribute supported on a relevant element Pass pointer-events presentation attribute supported on a relevant element Pass r presentation attribute supported on a relevant element Pass rx presentation attribute supported on a relevant element diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-unknown.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-unknown.txt index 3bf0c173c4c..b5a6fa599e6 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-unknown.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/styling/presentation-attributes-unknown.txt @@ -1,8 +1,8 @@ Harness status: OK -Found 47 tests +Found 48 tests -44 Pass +45 Pass 3 Fail Pass clip-path presentation attribute supported on an unknown SVG element Pass clip-rule presentation attribute supported on an unknown SVG element @@ -29,6 +29,7 @@ Pass mask-type presentation attribute supported on an unknown SVG element Pass mask presentation attribute supported on an unknown SVG element Pass opacity presentation attribute supported on an unknown SVG element Pass overflow presentation attribute supported on an unknown SVG element +Pass paint-order presentation attribute supported on an unknown SVG element Pass pointer-events presentation attribute supported on an unknown SVG element Pass shape-rendering presentation attribute supported on an unknown SVG element Pass stop-color presentation attribute supported on an unknown SVG element diff --git a/Tests/LibWeb/Text/input/wpt-import/svg/painting/parsing/paint-order-invalid.svg b/Tests/LibWeb/Text/input/wpt-import/svg/painting/parsing/paint-order-invalid.svg new file mode 100644 index 00000000000..f39142ac490 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/svg/painting/parsing/paint-order-invalid.svg @@ -0,0 +1,22 @@ + + + SVG Painting: parsing paint-order with invalid values + + + + + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/svg/painting/parsing/paint-order-valid.svg b/Tests/LibWeb/Text/input/wpt-import/svg/painting/parsing/paint-order-valid.svg new file mode 100644 index 00000000000..7e7c09ccaac --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/svg/painting/parsing/paint-order-valid.svg @@ -0,0 +1,38 @@ + + + SVG Painting: parsing paint-order with valid values + + + + + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/svg/painting/scripted/paint-order-computed-value-01.svg b/Tests/LibWeb/Text/input/wpt-import/svg/painting/scripted/paint-order-computed-value-01.svg new file mode 100644 index 00000000000..bf574e6a583 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/svg/painting/scripted/paint-order-computed-value-01.svg @@ -0,0 +1,62 @@ + + 'paint-order' computed style serialization + + + + +