at (301,519) content-size 100x100 children: inline
+ line 0 width: 86.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ frag 0 from TextNode start: 0, length: 26, rect: [301,519 86.125x17.46875]
+ "حسنًا ، مرحباً"
+ line 1 width: 78.125, height: 17.9375, bottom: 35.40625, baseline: 13.53125
+ frag 0 from TextNode start: 27, length: 25, rect: [301,536 78.125x17.46875]
+ "أيها الأصدقاء"
+ TextNode <#text>
+ BlockContainer <(anonymous)> at (200,620) content-size 592x0 children: inline
+ TextNode <#text>
+ BlockContainer
at (401,621) content-size 100x100 children: inline
+ line 0 width: 86.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ frag 0 from TextNode start: 0, length: 26, rect: [401,621 86.125x17.46875]
+ "حسنًا ، مرحباً"
+ line 1 width: 78.125, height: 17.9375, bottom: 35.40625, baseline: 13.53125
+ frag 0 from TextNode start: 27, length: 25, rect: [401,638 78.125x17.46875]
+ "أيها الأصدقاء"
+ TextNode <#text>
+ BlockContainer <(anonymous)> at (200,722) content-size 592x0 children: inline
+ TextNode <#text>
+ BlockContainer
at (401,723) content-size 100x100 children: inline
+ line 0 width: 86.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ frag 0 from TextNode start: 0, length: 26, rect: [401,723 86.125x17.46875]
+ "حسنًا ، مرحباً"
+ line 1 width: 78.125, height: 17.9375, bottom: 35.40625, baseline: 13.53125
+ frag 0 from TextNode start: 27, length: 25, rect: [401,740 78.125x17.46875]
+ "أيها الأصدقاء"
+ TextNode <#text>
+ BlockContainer <(anonymous)> at (200,824) content-size 592x0 children: inline
+ TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x832]
+ PaintableWithLines (BlockContainer) [100,0 700x832]
+ PaintableWithLines (BlockContainer) [200,8 592x816]
+ PaintableWithLines (BlockContainer
) [300,8 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,110 592x0]
+ PaintableWithLines (BlockContainer
) [300,110 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,212 592x0]
+ PaintableWithLines (BlockContainer
) [400,212 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,314 592x0]
+ PaintableWithLines (BlockContainer
) [300,314 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,416 592x0]
+ PaintableWithLines (BlockContainer
) [300,416 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,518 592x0]
+ PaintableWithLines (BlockContainer
) [300,518 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,620 592x0]
+ PaintableWithLines (BlockContainer
) [400,620 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,722 592x0]
+ PaintableWithLines (BlockContainer
) [400,722 102x102]
+ TextPaintable (TextNode<#text>)
+ PaintableWithLines (BlockContainer(anonymous)) [200,824 592x0]
diff --git a/Tests/LibWeb/Layout/input/css-dir-selector.html b/Tests/LibWeb/Layout/input/css-dir-selector.html
new file mode 100644
index 0000000000..a6acd4f4f8
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/css-dir-selector.html
@@ -0,0 +1,24 @@
+
+
Well, hello friends!
+
Well, hello friends!
+
Well, hello friends!
+
Well, hello friends!
+
حسنًا ، مرحباً أيها الأصدقاء
+
حسنًا ، مرحباً أيها الأصدقاء
+
حسنًا ، مرحباً أيها الأصدقاء
+
حسنًا ، مرحباً أيها الأصدقاء
diff --git a/Userland/Libraries/LibWeb/CSS/PseudoClasses.json b/Userland/Libraries/LibWeb/CSS/PseudoClasses.json
index 41eb2b7a5b..5d2826acc6 100644
--- a/Userland/Libraries/LibWeb/CSS/PseudoClasses.json
+++ b/Userland/Libraries/LibWeb/CSS/PseudoClasses.json
@@ -11,6 +11,9 @@
"defined": {
"argument": ""
},
+ "dir": {
+ "argument": "
"
+ },
"disabled": {
"argument": ""
},
diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
index a18b3fe362..2d16da1ccf 100644
--- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
+++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
@@ -7,6 +7,7 @@
#include
#include
+#include
#include
#include
#include
@@ -428,6 +429,19 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
}
case CSS::PseudoClass::Target:
return element.is_target();
+ case CSS::PseudoClass::Dir: {
+ // "Values other than ltr and rtl are not invalid, but do not match anything."
+ // - https://www.w3.org/TR/selectors-4/#the-dir-pseudo
+ if (!first_is_one_of(pseudo_class.identifier, CSS::ValueID::Ltr, CSS::ValueID::Rtl))
+ return false;
+ switch (element.directionality()) {
+ case DOM::Element::Directionality::Ltr:
+ return pseudo_class.identifier == CSS::ValueID::Ltr;
+ case DOM::Element::Directionality::Rtl:
+ return pseudo_class.identifier == CSS::ValueID::Rtl;
+ }
+ VERIFY_NOT_REACHED();
+ }
}
return false;