From 9973b0184888b8abc2c386ab6ab80d453f4c26fe Mon Sep 17 00:00:00 2001 From: Glenn Skrzypczak Date: Sat, 29 Mar 2025 23:44:25 +0100 Subject: [PATCH] LibWeb/CSS: Improved implementation of `background-blend-mode` This is a improved version of a73cd88f0c8b76e8413c1b35e6bc667e03eba5b4 The old commit was reverted in 552dd18696b1009d84d2a605491d9339c3e1da12 The new version only paints an element into a new layer if background blend modes other than normal are used. The rasterization performance of most websites should therefore not suffer. Co-Authored-By: Alexander Kalenik --- Libraries/LibWeb/CSS/ComputedValues.h | 1 + .../LibWeb/CSS/Parser/PropertyParsing.cpp | 1 + Libraries/LibWeb/CSS/Properties.json | 8 + Libraries/LibWeb/Layout/Node.cpp | 3 + .../LibWeb/Painting/BackgroundPainting.cpp | 29 +- .../LibWeb/Painting/BackgroundPainting.h | 1 + Libraries/LibWeb/Painting/Blending.h | 48 +++ Libraries/LibWeb/Painting/SVGSVGPaintable.cpp | 12 +- Libraries/LibWeb/Painting/StackingContext.cpp | 12 +- Libraries/LibWeb/Painting/StackingContext.h | 20 -- ...kground-blend-mode-gradient-image-ref.html | 23 ++ .../background-blend-mode-gradient-image.html | 33 ++ .../background-blending/support/red.png | Bin 0 -> 2702 bytes ...eclaration-has-indexed-property-getter.txt | 311 +++++++++--------- ...upported-properties-and-default-values.txt | 2 + .../css/getComputedStyle-print-all.txt | 5 +- 16 files changed, 311 insertions(+), 198 deletions(-) create mode 100644 Libraries/LibWeb/Painting/Blending.h create mode 100644 Tests/LibWeb/Ref/expected/wpt-import/css/compositing/background-blending/reference/background-blend-mode-gradient-image-ref.html create mode 100644 Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/background-blend-mode-gradient-image.html create mode 100644 Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/support/red.png diff --git a/Libraries/LibWeb/CSS/ComputedValues.h b/Libraries/LibWeb/CSS/ComputedValues.h index c6c70dd53aa..1498ee729df 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Libraries/LibWeb/CSS/ComputedValues.h @@ -296,6 +296,7 @@ struct BackgroundLayerData { CSS::LengthPercentage size_y { CSS::Length::make_auto() }; CSS::Repeat repeat_x { CSS::Repeat::Repeat }; CSS::Repeat repeat_y { CSS::Repeat::Repeat }; + CSS::MixBlendMode blend_mode { CSS::MixBlendMode::Normal }; }; struct BorderData { diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index c62da16b21a..fc3e06b7a6f 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -443,6 +443,7 @@ Parser::ParseErrorOr> Parser::parse_css_value(Prope return parsed_value.release_nonnull(); return ParseError::SyntaxError; case PropertyID::BackgroundAttachment: + case PropertyID::BackgroundBlendMode: case PropertyID::BackgroundClip: case PropertyID::BackgroundImage: case PropertyID::BackgroundOrigin: diff --git a/Libraries/LibWeb/CSS/Properties.json b/Libraries/LibWeb/CSS/Properties.json index b01b3a8ed98..6cafcb1f2a9 100644 --- a/Libraries/LibWeb/CSS/Properties.json +++ b/Libraries/LibWeb/CSS/Properties.json @@ -327,6 +327,14 @@ "background-attachment" ] }, + "background-blend-mode": { + "animation-type": "none", + "inherited": false, + "initial": "normal", + "valid-types": [ + "mix-blend-mode" + ] + }, "background-clip": { "affects-layout": false, "animation-type": "repeatable-list", diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index d9f98d80853..f2b4d72b818 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -397,6 +397,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) auto const& y_positions = computed_style.property(CSS::PropertyID::BackgroundPositionY); auto const& repeats = computed_style.property(CSS::PropertyID::BackgroundRepeat); auto const& sizes = computed_style.property(CSS::PropertyID::BackgroundSize); + auto const& background_blend_modes = computed_style.property(CSS::PropertyID::BackgroundBlendMode); auto count_layers = [](auto const& maybe_style_value) -> size_t { if (maybe_style_value.is_value_list()) @@ -510,6 +511,8 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) layer.repeat_y = repeat_value->as_background_repeat().repeat_y(); } + layer.blend_mode = CSS::keyword_to_mix_blend_mode(value_for_layer(background_blend_modes, layer_index)->to_keyword()).value_or(CSS::MixBlendMode::Normal); + layers.append(move(layer)); } diff --git a/Libraries/LibWeb/Painting/BackgroundPainting.cpp b/Libraries/LibWeb/Painting/BackgroundPainting.cpp index 1857ec69b8a..1d676c3c901 100644 --- a/Libraries/LibWeb/Painting/BackgroundPainting.cpp +++ b/Libraries/LibWeb/Painting/BackgroundPainting.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,18 @@ void paint_background(PaintContext& context, PaintableBox const& paintable_box, { auto& display_list_recorder = context.display_list_recorder(); + // https://drafts.fxtf.org/compositing/#background-blend-mode + // Background layers must not blend with the content that is behind the element, + // instead they must act as if they are rendered into an isolated group. + // OPTIMIZATION: It is only required to render the element into an isolated group, + // if a background blend mode other than normal are used. + auto paint_into_isolated_group = any_of(resolved_background.layers, [](auto const& layer) { + return layer.blend_mode != CSS::MixBlendMode::Normal; + }); + if (paint_into_isolated_group) { + display_list_recorder.save_layer(); + } + DisplayListRecorderStateSaver state { display_list_recorder }; if (resolved_background.needs_text_clip) { auto display_list = compute_text_clip_paths(context, paintable_box, resolved_background.background_rect.location()); @@ -267,6 +280,11 @@ void paint_background(PaintContext& context, PaintableBox const& paintable_box, } }; + Gfx::CompositingAndBlendingOperator compositing_and_blending_operator = mix_blend_mode_to_compositing_and_blending_operator(layer.blend_mode); + if (compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal) { + display_list_recorder.apply_compositing_and_blending_operator(compositing_and_blending_operator); + } + if (auto color = image.color_if_single_pixel_bitmap(); color.has_value()) { // OPTIMIZATION: If the image is a single pixel, we can just fill the whole area with it. // However, we must first figure out the real coverage area, taking repeat etc into account. @@ -289,6 +307,14 @@ void paint_background(PaintContext& context, PaintableBox const& paintable_box, image.paint(context, image_device_rect, image_rendering); }); } + + if (compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal) { + display_list_recorder.restore(); + } + } + + if (paint_into_isolated_group) { + display_list_recorder.restore(); } } @@ -404,7 +430,8 @@ ResolvedBackground resolve_background_layers(Vector co .background_positioning_area = background_positioning_area, .image_rect = image_rect, .repeat_x = layer.repeat_x, - .repeat_y = layer.repeat_y }); + .repeat_y = layer.repeat_y, + .blend_mode = layer.blend_mode }); } return ResolvedBackground { diff --git a/Libraries/LibWeb/Painting/BackgroundPainting.h b/Libraries/LibWeb/Painting/BackgroundPainting.h index 63e583205ce..2f03aece225 100644 --- a/Libraries/LibWeb/Painting/BackgroundPainting.h +++ b/Libraries/LibWeb/Painting/BackgroundPainting.h @@ -24,6 +24,7 @@ struct ResolvedBackgroundLayerData { CSSPixelRect image_rect; CSS::Repeat repeat_x; CSS::Repeat repeat_y; + CSS::MixBlendMode blend_mode; }; struct BackgroundBox { diff --git a/Libraries/LibWeb/Painting/Blending.h b/Libraries/LibWeb/Painting/Blending.h new file mode 100644 index 00000000000..6d64183c4ab --- /dev/null +++ b/Libraries/LibWeb/Painting/Blending.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025, Glenn Skrzypczak + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::Painting { + +#define ENUMERATE_MIX_BLEND_MODES(E) \ + E(Normal) \ + E(Multiply) \ + E(Screen) \ + E(Overlay) \ + E(Darken) \ + E(Lighten) \ + E(ColorDodge) \ + E(ColorBurn) \ + E(HardLight) \ + E(SoftLight) \ + E(Difference) \ + E(Exclusion) \ + E(Hue) \ + E(Saturation) \ + E(Color) \ + E(Luminosity) \ + E(PlusDarker) \ + E(PlusLighter) + +static Gfx::CompositingAndBlendingOperator mix_blend_mode_to_compositing_and_blending_operator(CSS::MixBlendMode blend_mode) +{ + switch (blend_mode) { +#undef __ENUMERATE +#define __ENUMERATE(blend_mode) \ + case CSS::MixBlendMode::blend_mode: \ + return Gfx::CompositingAndBlendingOperator::blend_mode; + ENUMERATE_MIX_BLEND_MODES(__ENUMERATE) +#undef __ENUMERATE + default: + VERIFY_NOT_REACHED(); + } +} + +} diff --git a/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp b/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp index de2e92c2554..250bf5d3af4 100644 --- a/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp +++ b/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -60,16 +61,7 @@ void SVGSVGPaintable::paint_svg_box(PaintContext& context, PaintableBox const& s auto const& filter = computed_values.filter(); auto masking_area = svg_box.get_masking_area(); - Gfx::CompositingAndBlendingOperator compositing_and_blending_operator; - switch (computed_values.mix_blend_mode()) { -#undef __ENUMERATE -#define __ENUMERATE(mix_blend_mode) \ - case CSS::MixBlendMode::mix_blend_mode: \ - compositing_and_blending_operator = Gfx::CompositingAndBlendingOperator::mix_blend_mode; \ - break; - ENUMERATE_MIX_BLEND_MODES(__ENUMERATE) -#undef __ENUMERATE - } + Gfx::CompositingAndBlendingOperator compositing_and_blending_operator = mix_blend_mode_to_compositing_and_blending_operator(computed_values.mix_blend_mode()); auto needs_to_save_state = computed_values.isolation() == CSS::Isolation::Isolate || compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal || svg_box.has_css_transform() || svg_box.get_masking_area().has_value(); diff --git a/Libraries/LibWeb/Painting/StackingContext.cpp b/Libraries/LibWeb/Painting/StackingContext.cpp index 14a3e838560..30ce2dd7909 100644 --- a/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Libraries/LibWeb/Painting/StackingContext.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -313,16 +314,7 @@ void StackingContext::paint(PaintContext& context) const auto transform_matrix = paintable_box().transform(); auto transform_origin = paintable_box().transform_origin().to_type(); - Gfx::CompositingAndBlendingOperator compositing_and_blending_operator; - switch (paintable_box().computed_values().mix_blend_mode()) { -#undef __ENUMERATE -#define __ENUMERATE(mix_blend_mode) \ - case CSS::MixBlendMode::mix_blend_mode: \ - compositing_and_blending_operator = Gfx::CompositingAndBlendingOperator::mix_blend_mode; \ - break; - ENUMERATE_MIX_BLEND_MODES(__ENUMERATE) -#undef __ENUMERATE - } + Gfx::CompositingAndBlendingOperator compositing_and_blending_operator = mix_blend_mode_to_compositing_and_blending_operator(paintable_box().computed_values().mix_blend_mode()); DisplayListRecorder::PushStackingContextParams push_stacking_context_params { .opacity = opacity, diff --git a/Libraries/LibWeb/Painting/StackingContext.h b/Libraries/LibWeb/Painting/StackingContext.h index 900298c144d..03e995e2c69 100644 --- a/Libraries/LibWeb/Painting/StackingContext.h +++ b/Libraries/LibWeb/Painting/StackingContext.h @@ -12,26 +12,6 @@ namespace Web::Painting { -#define ENUMERATE_MIX_BLEND_MODES(E) \ - E(Normal) \ - E(Multiply) \ - E(Screen) \ - E(Overlay) \ - E(Darken) \ - E(Lighten) \ - E(ColorDodge) \ - E(ColorBurn) \ - E(HardLight) \ - E(SoftLight) \ - E(Difference) \ - E(Exclusion) \ - E(Hue) \ - E(Saturation) \ - E(Color) \ - E(Luminosity) \ - E(PlusDarker) \ - E(PlusLighter) - class StackingContext { friend class ViewportPaintable; diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/compositing/background-blending/reference/background-blend-mode-gradient-image-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/css/compositing/background-blending/reference/background-blend-mode-gradient-image-ref.html new file mode 100644 index 00000000000..4389960d783 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/compositing/background-blending/reference/background-blend-mode-gradient-image-ref.html @@ -0,0 +1,23 @@ + + + + + CSS Reftest Reference + + + + +

Test passes if there is no red square on the screen.
+ You should see a black square.

+
+ + diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/background-blend-mode-gradient-image.html b/Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/background-blend-mode-gradient-image.html new file mode 100644 index 00000000000..90cd4ee5485 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/background-blend-mode-gradient-image.html @@ -0,0 +1,33 @@ + + + + + CSS Test: blending between multiple backgrounds (gradient and image) using background-blend-mode + + + + + + + + + +

Test passes if there is no red square on the screen.
+ You should see a black square.

+
+ + + + diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/support/red.png b/Tests/LibWeb/Ref/input/wpt-import/css/compositing/background-blending/support/red.png new file mode 100644 index 0000000000000000000000000000000000000000..acc86d477054ba431d2de1671085569b4575d898 GIT binary patch literal 2702 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>iVqjnp6%kcuU|`@Z@Q5sCVBi)8VMc~o zb0ioT7|k-BodW_g@=NlIGx7@*Je{2t3X1a6GILTH7%Fb9?c3;eI6%bVeD|V90op8u z1r?JuG`77;IJQLBRbb6k#go^TEcD70ii^8i*RnX8UA%n%fs=s+0e_hOI~2ZpAfVXX z%rWofox@Ly4z9RSx;$}8qCoc5JgZAzYb<{s;R$BAz`6NK-c~+_M=E_k4nEgrdQf?J zoi*>jV>L6hczqh)=1pl;&~o_iv|Q?lgh6xND#tsF%d9f5JJ>KRjeDo>pn2jiuZHIJ z&yF<=Y3IMz7(8PzK2ghRP+GE*G0W2`D1C3R?&@i&p1WtWOtg_pwUSCHvgZ??swu5*QgIbQl<#S;1U`2nGf=ZZMY=MIb!{O+r=#wH?zs z9EzY$gu01JilDZ`9FF8BB0#prhd7c+q$+~hj@Kk4 zMWC3)ZXI?-$YF~!QIM<%DQr=b7qUr6ijcyVM+}@KVc~>b5mMNKv{FYAQm}!{2N^t| zQF$Q2b2RT_#sDZ@2u3)q;}T>(D3K7GEkVf{qzCG75EtYRoH-7ZSqUma&P+H>B3TjC ziBR7ml_$t1At{3T1L`}%il7F=e23j6QWZgM2L&5QE0UW)T)eRa(n?Sf%wW7Gp(q;7 ryRf8#6u6*x!5!iCVhjxb|1&eB|75LkJ68p22{CxO`njxgN@xNA-c~X! literal 0 HcmV?d00001 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 491d83a5460..6241b24af37 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 @@ -77,161 +77,162 @@ All properties associated with getComputedStyle(document.body): "74": "aspect-ratio", "75": "backdrop-filter", "76": "background-attachment", - "77": "background-clip", - "78": "background-color", - "79": "background-image", - "80": "background-origin", - "81": "background-position-x", - "82": "background-position-y", - "83": "background-repeat", - "84": "background-size", - "85": "block-size", - "86": "border-block-end-color", - "87": "border-block-end-style", - "88": "border-block-end-width", - "89": "border-block-start-color", - "90": "border-block-start-style", - "91": "border-block-start-width", - "92": "border-bottom-color", - "93": "border-bottom-left-radius", - "94": "border-bottom-right-radius", - "95": "border-bottom-style", - "96": "border-bottom-width", - "97": "border-inline-end-color", - "98": "border-inline-end-style", - "99": "border-inline-end-width", - "100": "border-inline-start-color", - "101": "border-inline-start-style", - "102": "border-inline-start-width", - "103": "border-left-color", - "104": "border-left-style", - "105": "border-left-width", - "106": "border-right-color", - "107": "border-right-style", - "108": "border-right-width", - "109": "border-top-color", - "110": "border-top-left-radius", - "111": "border-top-right-radius", - "112": "border-top-style", - "113": "border-top-width", - "114": "bottom", - "115": "box-shadow", - "116": "box-sizing", - "117": "clear", - "118": "clip", - "119": "clip-path", - "120": "column-count", - "121": "column-gap", - "122": "column-span", - "123": "column-width", - "124": "contain", - "125": "content", - "126": "content-visibility", - "127": "counter-increment", - "128": "counter-reset", - "129": "counter-set", - "130": "cx", - "131": "cy", - "132": "display", - "133": "filter", - "134": "flex-basis", - "135": "flex-direction", - "136": "flex-grow", - "137": "flex-shrink", - "138": "flex-wrap", - "139": "float", - "140": "grid-auto-columns", - "141": "grid-auto-flow", - "142": "grid-auto-rows", - "143": "grid-column-end", - "144": "grid-column-start", - "145": "grid-row-end", - "146": "grid-row-start", - "147": "grid-template-areas", - "148": "grid-template-columns", - "149": "grid-template-rows", - "150": "height", - "151": "inline-size", - "152": "inset-block-end", - "153": "inset-block-start", - "154": "inset-inline-end", - "155": "inset-inline-start", - "156": "isolation", - "157": "justify-content", - "158": "justify-items", - "159": "justify-self", - "160": "left", - "161": "margin-block-end", - "162": "margin-block-start", - "163": "margin-bottom", - "164": "margin-inline-end", - "165": "margin-inline-start", - "166": "margin-left", - "167": "margin-right", - "168": "margin-top", - "169": "mask-image", - "170": "mask-type", - "171": "max-block-size", - "172": "max-height", - "173": "max-inline-size", - "174": "max-width", - "175": "min-block-size", - "176": "min-height", - "177": "min-inline-size", - "178": "min-width", - "179": "mix-blend-mode", - "180": "object-fit", - "181": "object-position", - "182": "opacity", - "183": "order", - "184": "outline-color", - "185": "outline-offset", - "186": "outline-style", - "187": "outline-width", - "188": "overflow-x", - "189": "overflow-y", - "190": "padding-block-end", - "191": "padding-block-start", - "192": "padding-bottom", - "193": "padding-inline-end", - "194": "padding-inline-start", - "195": "padding-left", - "196": "padding-right", - "197": "padding-top", - "198": "position", - "199": "r", - "200": "right", - "201": "rotate", - "202": "row-gap", - "203": "rx", - "204": "ry", - "205": "scale", - "206": "scrollbar-gutter", - "207": "scrollbar-width", - "208": "stop-color", - "209": "stop-opacity", - "210": "table-layout", - "211": "text-decoration-color", - "212": "text-decoration-style", - "213": "text-decoration-thickness", - "214": "text-overflow", - "215": "top", - "216": "transform", - "217": "transform-box", - "218": "transform-origin", - "219": "transition-delay", - "220": "transition-duration", - "221": "transition-property", - "222": "transition-timing-function", - "223": "translate", - "224": "unicode-bidi", - "225": "user-select", - "226": "vertical-align", - "227": "view-transition-name", - "228": "width", - "229": "x", - "230": "y", - "231": "z-index" + "77": "background-blend-mode", + "78": "background-clip", + "79": "background-color", + "80": "background-image", + "81": "background-origin", + "82": "background-position-x", + "83": "background-position-y", + "84": "background-repeat", + "85": "background-size", + "86": "block-size", + "87": "border-block-end-color", + "88": "border-block-end-style", + "89": "border-block-end-width", + "90": "border-block-start-color", + "91": "border-block-start-style", + "92": "border-block-start-width", + "93": "border-bottom-color", + "94": "border-bottom-left-radius", + "95": "border-bottom-right-radius", + "96": "border-bottom-style", + "97": "border-bottom-width", + "98": "border-inline-end-color", + "99": "border-inline-end-style", + "100": "border-inline-end-width", + "101": "border-inline-start-color", + "102": "border-inline-start-style", + "103": "border-inline-start-width", + "104": "border-left-color", + "105": "border-left-style", + "106": "border-left-width", + "107": "border-right-color", + "108": "border-right-style", + "109": "border-right-width", + "110": "border-top-color", + "111": "border-top-left-radius", + "112": "border-top-right-radius", + "113": "border-top-style", + "114": "border-top-width", + "115": "bottom", + "116": "box-shadow", + "117": "box-sizing", + "118": "clear", + "119": "clip", + "120": "clip-path", + "121": "column-count", + "122": "column-gap", + "123": "column-span", + "124": "column-width", + "125": "contain", + "126": "content", + "127": "content-visibility", + "128": "counter-increment", + "129": "counter-reset", + "130": "counter-set", + "131": "cx", + "132": "cy", + "133": "display", + "134": "filter", + "135": "flex-basis", + "136": "flex-direction", + "137": "flex-grow", + "138": "flex-shrink", + "139": "flex-wrap", + "140": "float", + "141": "grid-auto-columns", + "142": "grid-auto-flow", + "143": "grid-auto-rows", + "144": "grid-column-end", + "145": "grid-column-start", + "146": "grid-row-end", + "147": "grid-row-start", + "148": "grid-template-areas", + "149": "grid-template-columns", + "150": "grid-template-rows", + "151": "height", + "152": "inline-size", + "153": "inset-block-end", + "154": "inset-block-start", + "155": "inset-inline-end", + "156": "inset-inline-start", + "157": "isolation", + "158": "justify-content", + "159": "justify-items", + "160": "justify-self", + "161": "left", + "162": "margin-block-end", + "163": "margin-block-start", + "164": "margin-bottom", + "165": "margin-inline-end", + "166": "margin-inline-start", + "167": "margin-left", + "168": "margin-right", + "169": "margin-top", + "170": "mask-image", + "171": "mask-type", + "172": "max-block-size", + "173": "max-height", + "174": "max-inline-size", + "175": "max-width", + "176": "min-block-size", + "177": "min-height", + "178": "min-inline-size", + "179": "min-width", + "180": "mix-blend-mode", + "181": "object-fit", + "182": "object-position", + "183": "opacity", + "184": "order", + "185": "outline-color", + "186": "outline-offset", + "187": "outline-style", + "188": "outline-width", + "189": "overflow-x", + "190": "overflow-y", + "191": "padding-block-end", + "192": "padding-block-start", + "193": "padding-bottom", + "194": "padding-inline-end", + "195": "padding-inline-start", + "196": "padding-left", + "197": "padding-right", + "198": "padding-top", + "199": "position", + "200": "r", + "201": "right", + "202": "rotate", + "203": "row-gap", + "204": "rx", + "205": "ry", + "206": "scale", + "207": "scrollbar-gutter", + "208": "scrollbar-width", + "209": "stop-color", + "210": "stop-opacity", + "211": "table-layout", + "212": "text-decoration-color", + "213": "text-decoration-style", + "214": "text-decoration-thickness", + "215": "text-overflow", + "216": "top", + "217": "transform", + "218": "transform-box", + "219": "transform-origin", + "220": "transition-delay", + "221": "transition-duration", + "222": "transition-property", + "223": "transition-timing-function", + "224": "translate", + "225": "unicode-bidi", + "226": "user-select", + "227": "vertical-align", + "228": "view-transition-name", + "229": "width", + "230": "x", + "231": "y", + "232": "z-index" } All properties associated with document.body.style by default: {} 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 ce05f2e1957..505d77dc028 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 @@ -162,6 +162,8 @@ All supported properties and their default values exposed from CSSStylePropertie 'background': 'rgba(0, 0, 0, 0) none 0% 0% auto auto repeat scroll padding-box border-box' 'backgroundAttachment': 'scroll' 'background-attachment': 'scroll' +'backgroundBlendMode': 'normal' +'background-blend-mode': 'normal' 'backgroundClip': 'border-box' 'background-clip': 'border-box' 'backgroundColor': 'rgba(0, 0, 0, 0)' diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt index 8d0ee4ec9d2..b68dc9fe891 100644 --- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt +++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt @@ -75,6 +75,7 @@ appearance: none aspect-ratio: auto backdrop-filter: none background-attachment: scroll +background-blend-mode: normal background-clip: border-box background-color: rgba(0, 0, 0, 0) background-image: none @@ -83,7 +84,7 @@ background-position-x: 0% background-position-y: 0% background-repeat: repeat background-size: auto auto -block-size: 1190px +block-size: 1204px border-block-end-color: rgb(0, 0, 0) border-block-end-style: none border-block-end-width: medium @@ -148,7 +149,7 @@ grid-row-start: auto grid-template-areas: none grid-template-columns: none grid-template-rows: none -height: 2100px +height: 2114px inline-size: 784px inset-block-end: auto inset-block-start: auto