Skip to content

Commit

Permalink
LibWeb: Implement :modal pseudo class
Browse files Browse the repository at this point in the history
Adds the :modal pseudo class which matches dialogs opened with
showModal().

(cherry picked from commit 63a5ff70e5f3bee10839415885a158e304719fec)
  • Loading branch information
lukewarlow authored and nico committed Jul 14, 2024
1 parent 0979766 commit 85b5be0
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 5 deletions.
20 changes: 20 additions & 0 deletions Tests/LibWeb/Layout/expected/dialog-open-modal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x0 children: inline
TextNode <#text>
Box <dialog#modal> 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 <span> 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<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x0]
PaintableBox (Box<DIALOG>#modal) [339.84375,0 120.3125x600]
PaintableWithLines (BlockContainer<SPAN>) [358.84375,19 82.3125x562]
TextPaintable (TextNode<#text>)
18 changes: 18 additions & 0 deletions Tests/LibWeb/Layout/expected/dialog-open-non-modal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x0 children: inline
BlockContainer <dialog> at (358.84375,27) content-size 82.3125x17 positioned [BFC] children: inline
TextNode <#text>
InlineNode <span>
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<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x0]
PaintableWithLines (BlockContainer<DIALOG>) [339.84375,8 120.3125x55]
InlinePaintable (InlineNode<SPAN>)
TextPaintable (TextNode<#text>)
10 changes: 5 additions & 5 deletions Tests/LibWeb/Layout/expected/top-layer.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x16 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x0 children: inline
TextNode <#text>
BlockContainer <dialog#dialog> at (196.671875,35) content-size 406.65625x49 positioned [BFC] children: not-inline
BlockContainer <p> 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 <dialog#dialog> at (196.671875,19) content-size 406.65625x562 positioned [BFC] children: not-inline
BlockContainer <p> 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<HTML>) [0,0 800x16]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x0]
PaintableWithLines (BlockContainer<DIALOG>#dialog) [177.671875,16 444.65625x87]
PaintableWithLines (BlockContainer<P>) [196.671875,51 406.65625x17]
PaintableWithLines (BlockContainer<DIALOG>#dialog) [177.671875,0 444.65625x600]
PaintableWithLines (BlockContainer<P>) [196.671875,35 406.65625x17]
TextPaintable (TextNode<#text>)
16 changes: 16 additions & 0 deletions Tests/LibWeb/Layout/input/dialog-open-modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<style>
:modal {
display: flex;
}
</style>

<dialog id="modal">
<span>I'm a node</span>
</dialog>

<script>
document.addEventListener("DOMContentLoaded", () => {
let modal = document.getElementById('modal');
modal.showModal();
});
</script>
9 changes: 9 additions & 0 deletions Tests/LibWeb/Layout/input/dialog-open-non-modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<style>
:modal {
display: flex;
}
</style>

<dialog open>
<span>I'm a node</span>
</dialog>
3 changes: 3 additions & 0 deletions Userland/Libraries/LibWeb/CSS/PseudoClasses.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
"local-link": {
"argument": ""
},
"modal": {
"argument": ""
},
"muted": {
"argument": ""
},
Expand Down
9 changes: 9 additions & 0 deletions Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTML::HTMLDialogElement>(element)) {
auto const& dialog_element = static_cast<HTML::HTMLDialogElement const&>(element);
return dialog_element.is_modal();
}
// FIXME: fullscreen elements are also modal.
return false;
}
}

return false;
Expand Down
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLDialogElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class HTMLDialogElement final : public HTMLElement {
// https://www.w3.org/TR/html-aria/#el-dialog
virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::dialog; }

bool is_modal() const { return m_is_modal; }

private:
HTMLDialogElement(DOM::Document&, DOM::QualifiedName);

Expand Down

0 comments on commit 85b5be0

Please sign in to comment.