@@ -224,8 +224,12 @@ static bool _matchLink(Gc::Ref<Dom::Element> el) {
224224
225225// 14.3.1. :nth-child() pseudo-class
226226// 14.3.2. :nth-last-child() pseudo-class
227+ // 14.3.3. :first-child pseudo-class
228+ // 14.3.4. :last-child pseudo-class
227229// https://www.w3.org/TR/selectors-4/#the-nth-child-pseudo
228230// https://www.w3.org/TR/selectors-4/#the-nth-last-child-pseudo
231+ // https://www.w3.org/TR/selectors-4/#the-first-child-pseudo
232+ // https://www.w3.org/TR/selectors-4/#the-last-child-pseudo
229233static bool _matchNthChild (Gc::Ref<Dom::Element> e, Pseudo::AnBofS const & anbOfS, bool isLast) {
230234 auto [anb, ofS] = anbOfS;
231235 if (ofS) {
@@ -247,36 +251,14 @@ static bool _matchNthChild(Gc::Ref<Dom::Element> e, Pseudo::AnBofS const& anbOfS
247251 }
248252}
249253
250- // 14.3.3. :first-child pseudo-class
251- // https://www.w3.org/TR/selectors-4/#the-first-child-pseudo
252- static bool _matchFirstChild (Gc::Ref<Dom::Element> e) {
253- Gc::Ptr<Dom::Node> curr = e;
254- while (curr->hasPreviousSibling ()) {
255- auto prev = curr->previousSibling ();
256- if (auto el = prev->is <Dom::Element>())
257- return false ;
258- curr = prev;
259- }
260- return true ;
261- }
262-
263- // 14.3.4. :last-child pseudo-class
264- // https://www.w3.org/TR/selectors-4/#the-last-child-pseudo
265- static bool _matchLastChild (Gc::Ref<Dom::Element> e) {
266- Gc::Ptr<Dom::Node> curr = e;
267- while (curr->hasNextSibling ()) {
268- auto next = curr->nextSibling ();
269- if (auto el = next->is <Dom::Element>())
270- return false ;
271- curr = next;
272- }
273- return true ;
274- }
275-
276254// 14.4.1. :nth-of-type pseudo-class
277255// 14.4.2. :nth-last-of-type pseudo-class
256+ // 14.4.3. :first-of-type pseudo-class
257+ // 14.4.4. :last-of-type pseudo-class
278258// https://www.w3.org/TR/selectors-4/#the-nth-of-type-pseudo
279259// https://www.w3.org/TR/selectors-4/#the-nth-last-of-type-pseudo
260+ // https://www.w3.org/TR/selectors-4/#the-first-of-type-pseudo
261+ // https://www.w3.org/TR/selectors-4/#the-last-of-type-pseudo
280262static bool _matchNthOfType (Gc::Ref<Dom::Element> e, AnB const & anb, bool isLast) {
281263 Gc::Ptr<Dom::Node> curr = e;
282264 auto name = e->qualifiedName ;
@@ -290,38 +272,6 @@ static bool _matchNthOfType(Gc::Ref<Dom::Element> e, AnB const& anb, bool isLast
290272 return anb.match (index + 1 );
291273}
292274
293- // 14.4.3. :first-of-type pseudo-class
294- // https://www.w3.org/TR/selectors-4/#the-first-of-type-pseudo
295- static bool _matchFirstOfType (Gc::Ref<Dom::Element> e) {
296- Gc::Ptr<Dom::Node> curr = e;
297- auto name = e->qualifiedName ;
298-
299- while (curr->hasPreviousSibling ()) {
300- auto prev = curr->previousSibling ();
301- if (auto el = prev->is <Dom::Element>())
302- if (e->qualifiedName == name)
303- return false ;
304- curr = prev;
305- }
306- return true ;
307- }
308-
309- // 14.4.4. :last-of-type pseudo-class
310- // https://www.w3.org/TR/selectors-4/#the-last-of-type-pseudo
311- static bool _matchLastOfType (Gc::Ref<Dom::Element> e) {
312- Gc::Ptr<Dom::Node> curr = e;
313- auto name = e->qualifiedName ;
314-
315- while (curr->hasNextSibling ()) {
316- auto prev = curr->nextSibling ();
317- if (auto el = prev->is <Dom::Element>())
318- if (e->qualifiedName == name)
319- return false ;
320- curr = prev;
321- }
322- return true ;
323- }
324-
325275static bool _match (Pseudo const & s, Gc::Ref<Dom::Element> el) {
326276 switch (s.type ) {
327277 case Pseudo::LINK:
@@ -331,16 +281,16 @@ static bool _match(Pseudo const& s, Gc::Ref<Dom::Element> el) {
331281 return el->qualifiedName == Html::HTML_TAG;
332282
333283 case Pseudo::FIRST_OF_TYPE:
334- return _matchFirstOfType (el);
284+ return _matchNthOfType (el, AnB{ 0 , 1 }, false );
335285
336286 case Pseudo::LAST_OF_TYPE:
337- return _matchLastOfType (el);
287+ return _matchNthOfType (el, AnB{ 0 , 1 }, true );
338288
339289 case Pseudo::FIRST_CHILD:
340- return _matchFirstChild (el);
290+ return _matchNthChild (el, Pseudo::AnBofS{AnB{ 0 , 1 }, NONE}, false );
341291
342292 case Pseudo::LAST_CHILD:
343- return _matchLastChild (el);
293+ return _matchNthChild (el, Pseudo::AnBofS{AnB{ 0 , 1 }, NONE}, true );
344294
345295 case Pseudo::NTH_CHILD:
346296 return _matchNthChild (el, s.extra .unwrap <Pseudo::AnBofS>(" unexpected missing AnB" ), false );
0 commit comments