From 85b5be0a202ebd5d699789aa20adc917dfee5786 Mon Sep 17 00:00:00 2001 From: Luke Warlow Date: Tue, 2 Jul 2024 00:36:36 +0100 Subject: [PATCH] LibWeb: Implement :modal pseudo class Adds the :modal pseudo class which matches dialogs opened with showModal(). (cherry picked from commit 63a5ff70e5f3bee10839415885a158e304719fec) --- .../Layout/expected/dialog-open-modal.txt | 20 +++++++++++++++++++ .../Layout/expected/dialog-open-non-modal.txt | 18 +++++++++++++++++ Tests/LibWeb/Layout/expected/top-layer.txt | 10 +++++----- .../Layout/input/dialog-open-modal.html | 16 +++++++++++++++ .../Layout/input/dialog-open-non-modal.html | 9 +++++++++ .../Libraries/LibWeb/CSS/PseudoClasses.json | 3 +++ .../Libraries/LibWeb/CSS/SelectorEngine.cpp | 9 +++++++++ .../Libraries/LibWeb/HTML/HTMLDialogElement.h | 2 ++ 8 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/dialog-open-modal.txt create mode 100644 Tests/LibWeb/Layout/expected/dialog-open-non-modal.txt create mode 100644 Tests/LibWeb/Layout/input/dialog-open-modal.html create mode 100644 Tests/LibWeb/Layout/input/dialog-open-non-modal.html diff --git a/Tests/LibWeb/Layout/expected/dialog-open-modal.txt b/Tests/LibWeb/Layout/expected/dialog-open-modal.txt new file mode 100644 index 00000000000000..df1052f8fda718 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/dialog-open-modal.txt @@ -0,0 +1,20 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x0 children: inline + TextNode <#text> + Box at (358.84375,19) content-size 82.3125x562 positioned flex-container(row) [FFC] children: not-inline + BlockContainer <(anonymous)> (not painted) [BFC] children: inline + TextNode <#text> + BlockContainer at (358.84375,19) content-size 82.3125x562 flex-item [BFC] children: inline + frag 0 from TextNode start: 0, length: 10, rect: [358.84375,19 82.3125x17] baseline: 13.296875 + "I'm a node" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) [BFC] children: inline + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x600] + PaintableWithLines (BlockContainer) [8,8 784x0] + PaintableBox (Box#modal) [339.84375,0 120.3125x600] + PaintableWithLines (BlockContainer) [358.84375,19 82.3125x562] + TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/expected/dialog-open-non-modal.txt b/Tests/LibWeb/Layout/expected/dialog-open-non-modal.txt new file mode 100644 index 00000000000000..6442d09562743b --- /dev/null +++ b/Tests/LibWeb/Layout/expected/dialog-open-non-modal.txt @@ -0,0 +1,18 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x0 children: inline + BlockContainer at (358.84375,27) content-size 82.3125x17 positioned [BFC] children: inline + TextNode <#text> + InlineNode + frag 0 from TextNode start: 0, length: 10, rect: [358.84375,27 82.3125x17] baseline: 13.296875 + "I'm a node" + TextNode <#text> + TextNode <#text> + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x600] + PaintableWithLines (BlockContainer) [8,8 784x0] + PaintableWithLines (BlockContainer) [339.84375,8 120.3125x55] + InlinePaintable (InlineNode) + TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/expected/top-layer.txt b/Tests/LibWeb/Layout/expected/top-layer.txt index 4fdd081bcda4de..3954286e715a19 100644 --- a/Tests/LibWeb/Layout/expected/top-layer.txt +++ b/Tests/LibWeb/Layout/expected/top-layer.txt @@ -2,15 +2,15 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x16 [BFC] children: not-inline BlockContainer at (8,8) content-size 784x0 children: inline TextNode <#text> - BlockContainer at (196.671875,35) content-size 406.65625x49 positioned [BFC] children: not-inline - BlockContainer

at (196.671875,51) content-size 406.65625x17 children: inline - frag 0 from TextNode start: 0, length: 50, rect: [196.671875,51 406.65625x17] baseline: 13.296875 + BlockContainer at (196.671875,19) content-size 406.65625x562 positioned [BFC] children: not-inline + BlockContainer

at (196.671875,35) content-size 406.65625x17 children: inline + frag 0 from TextNode start: 0, length: 50, rect: [196.671875,35 406.65625x17] baseline: 13.296875 "Dialog's layout node should be a child of viewport" TextNode <#text> ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x16] PaintableWithLines (BlockContainer) [8,8 784x0] - PaintableWithLines (BlockContainer

#dialog) [177.671875,16 444.65625x87] - PaintableWithLines (BlockContainer

) [196.671875,51 406.65625x17] + PaintableWithLines (BlockContainer

#dialog) [177.671875,0 444.65625x600] + PaintableWithLines (BlockContainer

) [196.671875,35 406.65625x17] TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/input/dialog-open-modal.html b/Tests/LibWeb/Layout/input/dialog-open-modal.html new file mode 100644 index 00000000000000..492f2e89961513 --- /dev/null +++ b/Tests/LibWeb/Layout/input/dialog-open-modal.html @@ -0,0 +1,16 @@ + + +

+ I'm a node + + + \ No newline at end of file diff --git a/Tests/LibWeb/Layout/input/dialog-open-non-modal.html b/Tests/LibWeb/Layout/input/dialog-open-non-modal.html new file mode 100644 index 00000000000000..36dce619484492 --- /dev/null +++ b/Tests/LibWeb/Layout/input/dialog-open-non-modal.html @@ -0,0 +1,9 @@ + + + + I'm a node + diff --git a/Userland/Libraries/LibWeb/CSS/PseudoClasses.json b/Userland/Libraries/LibWeb/CSS/PseudoClasses.json index 1523d1ad9b776d..22b5400875683a 100644 --- a/Userland/Libraries/LibWeb/CSS/PseudoClasses.json +++ b/Userland/Libraries/LibWeb/CSS/PseudoClasses.json @@ -71,6 +71,9 @@ "local-link": { "argument": "" }, + "modal": { + "argument": "" + }, "muted": { "argument": "" }, diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp index 1b7ed4eef084e1..535dd5366920fc 100644 --- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -542,6 +542,15 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla case CSS::PseudoClass::Open: case CSS::PseudoClass::Closed: return matches_open_state_pseudo_class(element, pseudo_class.type == CSS::PseudoClass::Open); + case CSS::PseudoClass::Modal: { + // https://drafts.csswg.org/selectors/#modal-state + if (is(element)) { + auto const& dialog_element = static_cast(element); + return dialog_element.is_modal(); + } + // FIXME: fullscreen elements are also modal. + return false; + } } return false; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.h b/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.h index 8055c7128436a1..63836cef0b6bcf 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.h @@ -30,6 +30,8 @@ class HTMLDialogElement final : public HTMLElement { // https://www.w3.org/TR/html-aria/#el-dialog virtual Optional default_role() const override { return ARIA::Role::dialog; } + bool is_modal() const { return m_is_modal; } + private: HTMLDialogElement(DOM::Document&, DOM::QualifiedName);