diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 6b8b40552cc..67dc749fc8a 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -1440,6 +1440,12 @@ Optional ComputedProperties::user_select() const return keyword_to_user_select(value.to_keyword()); } +Optional ComputedProperties::isolation() const +{ + auto const& value = property(CSS::PropertyID::Isolation); + return keyword_to_isolation(value.to_keyword()); +} + Optional ComputedProperties::mask_type() const { auto const& value = property(CSS::PropertyID::MaskType); diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index 9e7d8bf6a5c..0c21276b265 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -160,6 +160,7 @@ public: Optional unicode_bidi() const; Optional writing_mode() const; Optional user_select() const; + Optional isolation() const; static Vector transformations_for_style_value(CSSStyleValue const& value); Vector transformations() const; diff --git a/Libraries/LibWeb/CSS/ComputedValues.h b/Libraries/LibWeb/CSS/ComputedValues.h index 38f0d67d29a..5f1494b10e0 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Libraries/LibWeb/CSS/ComputedValues.h @@ -171,6 +171,7 @@ public: static CSS::UnicodeBidi unicode_bidi() { return CSS::UnicodeBidi::Normal; } static CSS::WritingMode writing_mode() { return CSS::WritingMode::HorizontalTb; } static CSS::UserSelect user_select() { return CSS::UserSelect::Auto; } + static CSS::Isolation isolation() { return CSS::Isolation::Auto; } // https://www.w3.org/TR/SVG/geometry.html static LengthPercentage cx() { return CSS::Length::make_px(0); } @@ -426,6 +427,7 @@ public: CSS::UnicodeBidi unicode_bidi() const { return m_noninherited.unicode_bidi; } CSS::WritingMode writing_mode() const { return m_inherited.writing_mode; } CSS::UserSelect user_select() const { return m_noninherited.user_select; } + CSS::Isolation isolation() const { return m_noninherited.isolation; } CSS::LengthBox const& inset() const { return m_noninherited.inset; } const CSS::LengthBox& margin() const { return m_noninherited.margin; } @@ -678,6 +680,7 @@ protected: CSS::ObjectPosition object_position { InitialValues::object_position() }; CSS::UnicodeBidi unicode_bidi { InitialValues::unicode_bidi() }; CSS::UserSelect user_select { InitialValues::user_select() }; + CSS::Isolation isolation { InitialValues::isolation() }; Optional rotate; Optional translate; @@ -851,6 +854,7 @@ public: void set_unicode_bidi(CSS::UnicodeBidi value) { m_noninherited.unicode_bidi = value; } void set_writing_mode(CSS::WritingMode value) { m_inherited.writing_mode = value; } void set_user_select(CSS::UserSelect value) { m_noninherited.user_select = value; } + void set_isolation(CSS::Isolation value) { m_noninherited.isolation = value; } void set_fill(SVGPaint value) { m_inherited.fill = move(value); } void set_stroke(SVGPaint value) { m_inherited.stroke = move(value); } diff --git a/Libraries/LibWeb/CSS/Enums.json b/Libraries/LibWeb/CSS/Enums.json index b0c44b4658b..09fe23c2068 100644 --- a/Libraries/LibWeb/CSS/Enums.json +++ b/Libraries/LibWeb/CSS/Enums.json @@ -300,6 +300,10 @@ "optimizespeed=pixelated", "optimizequality=smooth" ], + "isolation": [ + "auto", + "isolate" + ], "justify-content": [ "normal", "start", diff --git a/Libraries/LibWeb/CSS/Properties.json b/Libraries/LibWeb/CSS/Properties.json index fe5de26f7ca..aa9bfe60252 100644 --- a/Libraries/LibWeb/CSS/Properties.json +++ b/Libraries/LibWeb/CSS/Properties.json @@ -1684,6 +1684,14 @@ ], "max-values": 1 }, + "isolation": { + "animation-type": "none", + "inherited": false, + "initial": "auto", + "valid-types": [ + "isolation" + ] + }, "justify-content": { "animation-type": "discrete", "inherited": false, diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 9b2c1398884..90c9ce75617 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -218,6 +218,11 @@ bool Node::establishes_stacking_context() const if (computed_values().mask().has_value() || computed_values().clip_path().has_value() || computed_values().mask_image()) return true; + // https://drafts.fxtf.org/compositing/#propdef-isolation + // For CSS, setting isolation to isolate will turn the element into a stacking context. + if (computed_values().isolation() == CSS::Isolation::Isolate) + return true; + return computed_values().opacity() < 1.0f; } @@ -1008,6 +1013,9 @@ void NodeWithStyle::apply_style(const CSS::ComputedProperties& computed_style) if (auto user_select = computed_style.user_select(); user_select.has_value()) computed_values.set_user_select(user_select.value()); + if (auto isolation = computed_style.isolation(); isolation.has_value()) + computed_values.set_isolation(isolation.value()); + propagate_style_to_anonymous_wrappers(); } diff --git a/Tests/LibWeb/Ref/expected/css-isolation.html b/Tests/LibWeb/Ref/expected/css-isolation.html new file mode 100644 index 00000000000..db87c6cc65a --- /dev/null +++ b/Tests/LibWeb/Ref/expected/css-isolation.html @@ -0,0 +1,9 @@ + + +
diff --git a/Tests/LibWeb/Ref/input/css-isolation.html b/Tests/LibWeb/Ref/input/css-isolation.html new file mode 100644 index 00000000000..81d5c693351 --- /dev/null +++ b/Tests/LibWeb/Ref/input/css-isolation.html @@ -0,0 +1,18 @@ + + + +
+
+
+
+
+
diff --git a/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-all-supported-properties-and-default-values.txt b/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-all-supported-properties-and-default-values.txt index 080eff7258e..b9a5888a54c 100644 --- a/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-all-supported-properties-and-default-values.txt +++ b/Tests/LibWeb/Text/expected/css/CSSStyleDeclaration-all-supported-properties-and-default-values.txt @@ -1,6 +1,6 @@ All supported properties and their default values exposed from CSSStyleDeclaration from getComputedStyle: 'cssText': '' -'length': '213' +'length': '214' 'parentRule': 'null' 'cssFloat': 'none' 'WebkitAlignContent': 'normal' @@ -384,6 +384,7 @@ All supported properties and their default values exposed from CSSStyleDeclarati 'inset-inline-end': 'auto' 'insetInlineStart': 'auto' 'inset-inline-start': 'auto' +'isolation': 'auto' 'justifyContent': 'normal' 'justify-content': 'normal' 'justifyItems': 'legacy' 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 096950a2e94..8c6069af5a2 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 @@ -141,78 +141,79 @@ All properties associated with getComputedStyle(document.body): "138": "inset-block-start", "139": "inset-inline-end", "140": "inset-inline-start", - "141": "justify-content", - "142": "justify-items", - "143": "justify-self", - "144": "left", - "145": "margin-block-end", - "146": "margin-block-start", - "147": "margin-bottom", - "148": "margin-inline-end", - "149": "margin-inline-start", - "150": "margin-left", - "151": "margin-right", - "152": "margin-top", - "153": "mask", - "154": "mask-image", - "155": "mask-type", - "156": "max-height", - "157": "max-inline-size", - "158": "max-width", - "159": "min-height", - "160": "min-inline-size", - "161": "min-width", - "162": "object-fit", - "163": "object-position", - "164": "opacity", - "165": "order", - "166": "outline-color", - "167": "outline-offset", - "168": "outline-style", - "169": "outline-width", - "170": "overflow-x", - "171": "overflow-y", - "172": "padding-block-end", - "173": "padding-block-start", - "174": "padding-bottom", - "175": "padding-inline-end", - "176": "padding-inline-start", - "177": "padding-left", - "178": "padding-right", - "179": "padding-top", - "180": "position", - "181": "r", - "182": "right", - "183": "rotate", - "184": "row-gap", - "185": "rx", - "186": "ry", - "187": "scale", - "188": "scrollbar-gutter", - "189": "scrollbar-width", - "190": "stop-color", - "191": "stop-opacity", - "192": "table-layout", - "193": "text-decoration-color", - "194": "text-decoration-style", - "195": "text-decoration-thickness", - "196": "text-overflow", - "197": "top", - "198": "transform", - "199": "transform-box", - "200": "transform-origin", - "201": "transition-delay", - "202": "transition-duration", - "203": "transition-property", - "204": "transition-timing-function", - "205": "translate", - "206": "unicode-bidi", - "207": "user-select", - "208": "vertical-align", - "209": "width", - "210": "x", - "211": "y", - "212": "z-index" + "141": "isolation", + "142": "justify-content", + "143": "justify-items", + "144": "justify-self", + "145": "left", + "146": "margin-block-end", + "147": "margin-block-start", + "148": "margin-bottom", + "149": "margin-inline-end", + "150": "margin-inline-start", + "151": "margin-left", + "152": "margin-right", + "153": "margin-top", + "154": "mask", + "155": "mask-image", + "156": "mask-type", + "157": "max-height", + "158": "max-inline-size", + "159": "max-width", + "160": "min-height", + "161": "min-inline-size", + "162": "min-width", + "163": "object-fit", + "164": "object-position", + "165": "opacity", + "166": "order", + "167": "outline-color", + "168": "outline-offset", + "169": "outline-style", + "170": "outline-width", + "171": "overflow-x", + "172": "overflow-y", + "173": "padding-block-end", + "174": "padding-block-start", + "175": "padding-bottom", + "176": "padding-inline-end", + "177": "padding-inline-start", + "178": "padding-left", + "179": "padding-right", + "180": "padding-top", + "181": "position", + "182": "r", + "183": "right", + "184": "rotate", + "185": "row-gap", + "186": "rx", + "187": "ry", + "188": "scale", + "189": "scrollbar-gutter", + "190": "scrollbar-width", + "191": "stop-color", + "192": "stop-opacity", + "193": "table-layout", + "194": "text-decoration-color", + "195": "text-decoration-style", + "196": "text-decoration-thickness", + "197": "text-overflow", + "198": "top", + "199": "transform", + "200": "transform-box", + "201": "transform-origin", + "202": "transition-delay", + "203": "transition-duration", + "204": "transition-property", + "205": "transition-timing-function", + "206": "translate", + "207": "unicode-bidi", + "208": "user-select", + "209": "vertical-align", + "210": "width", + "211": "x", + "212": "y", + "213": "z-index" } All properties associated with document.body.style by default: {} diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt index a6ef57b3e06..f14108f4fa8 100644 --- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt +++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt @@ -139,6 +139,7 @@ inset-block-end: auto inset-block-start: auto inset-inline-end: auto inset-inline-start: auto +isolation: auto justify-content: normal justify-items: legacy justify-self: auto