Mon Jan 4 06:32:07 UTC 2010 pix@kepibu.org * Add *of-type selectors diff -rN -u old-Oh, Ducks!/notes new-Oh, Ducks!/notes --- old-Oh, Ducks!/notes 2013-11-17 08:43:14.000000000 +0000 +++ new-Oh, Ducks!/notes 2013-11-17 08:43:14.000000000 +0000 @@ -134,7 +134,7 @@ * [ ] selectors involving descendants ** write documentation ** improve selector support -*** positional selectors [9/19] +*** positional selectors [18/19] * [X] :nth-child(an+b) * [X] :nth-child(b) * [X] :nth-child(odd|even) @@ -143,16 +143,16 @@ * [X] :nth-last-child(odd|even) * [X] :first-child * [X] :last-child - * [ ] :nth-of-type(an+b) - * [ ] :nth-of-type(b) - * [ ] :nth-of-type(odd|even) - * [ ] :nth-last-of-type(an+b) - * [ ] :nth-last-of-type(b) - * [ ] :nth-last-of-type(odd|even) - * [ ] :first-of-type - * [ ] :last-of-type + * [X] :nth-of-type(an+b) + * [X] :nth-of-type(b) + * [X] :nth-of-type(odd|even) + * [X] :nth-last-of-type(an+b) + * [X] :nth-last-of-type(b) + * [X] :nth-last-of-type(odd|even) + * [X] :first-of-type + * [X] :last-of-type * [X] :only-child - * [ ] :only-of-type + * [X] :only-of-type * [ ] :empty *** attribute selectors [0/7] * [ ] attribute-present [att] diff -rN -u old-Oh, Ducks!/selectors.lisp new-Oh, Ducks!/selectors.lisp --- old-Oh, Ducks!/selectors.lisp 2013-11-17 08:43:14.000000000 +0000 +++ new-Oh, Ducks!/selectors.lisp 2013-11-17 08:43:14.000000000 +0000 @@ -38,6 +38,8 @@ (defclass class-selector (simple-selector) ()) (defclass nth-child-selector (simple-selector) ()) (defclass nth-last-child-selector (nth-child-selector) ()) +(defclass nth-of-type-selector (nth-child-selector) ()) +(defclass nth-last-of-type-selector (nth-of-type-selector) ()) (defmethod initialize-instance :after ((selector nth-child-selector) &key (asign "+") a @@ -113,6 +115,18 @@ :asign asign :a a :bsign bsign :b b) (parse-selector &rest))) + (#T(regexp$ (":nth-of-type(" \s* an+b \s* ")") + (?asign ?a ?bsign ?b)) + (cons (make-instance 'nth-of-type-selector + :asign asign :a a + :bsign bsign :b b) + (parse-selector &rest))) + (#T(regexp$ (":nth-last-of-type(" \s* an+b \s* ")") + (?asign ?a ?bsign ?b)) + (cons (make-instance 'nth-last-of-type-selector + :asign asign :a a + :bsign bsign :b b) + (parse-selector &rest))) ;; absolute (B) (#T(regexp$ (":nth-child(" \s* b \s* ")") (?b)) @@ -122,6 +136,14 @@ (?b)) (cons (make-instance 'nth-last-child-selector :a 0 :b b) (parse-selector &rest))) + (#T(regexp$ (":nth-of-type(" \s* b \s* ")") + (?b)) + (cons (make-instance 'nth-of-type-selector :a 0 :b b) + (parse-selector &rest))) + (#T(regexp$ (":nth-last-of-type(" \s* b \s* ")") + (?b)) + (cons (make-instance 'nth-last-of-type-selector :a 0 :b b) + (parse-selector &rest))) ;; named (odd, even) (#T(regexp$ (":nth-child(" \s* odd/even \s* ")") (?which)) @@ -131,6 +153,14 @@ (?which)) (cons (make-instance 'nth-last-child-selector :namedp t :b which) (parse-selector &rest))) + (#T(regexp$ (":nth-of-type(" \s* odd/even \s* ")") + (?which)) + (cons (make-instance 'nth-of-type-selector :namedp t :b which) + (parse-selector &rest))) + (#T(regexp$ (":nth-last-of-type(" \s* odd/even \s* ")") + (?which)) + (cons (make-instance 'nth-last-of-type-selector :namedp t :b which) + (parse-selector &rest))) ;; Everybody else (#T(regexp$ (":first-child") ()) (cons (make-instance 'nth-child-selector :a 0 :b 1) @@ -142,6 +172,16 @@ (list* (make-instance 'nth-child-selector :a 0 :b 1) (make-instance 'nth-last-child-selector :a 0 :b 1) (parse-selector &rest))) + (#T(regexp$ (":first-of-type") ()) + (cons (make-instance 'nth-of-type-selector :a 0 :b 1) + (parse-selector &rest))) + (#T(regexp$ (":last-of-type") ()) + (cons (make-instance 'nth-last-of-type-selector :a 0 :b 1) + (parse-selector &rest))) + (#T(regexp$ (":only-of-type") ()) + (list* (make-instance 'nth-of-type-selector :a 0 :b 1) + (make-instance 'nth-last-of-type-selector :a 0 :b 1) + (parse-selector &rest))) (#T(regexp$ (#\# $name) (?id)) (cons (make-instance 'id-selector :arg id) (parse-selector &rest))) (#T(regexp$ (#\. $name) (?class)) @@ -191,6 +231,21 @@ (parent (element-parent element))) (an+b? (car arg) (cdr arg) element (reverse (element-children parent))))) +(defmethod subject-p ((selector nth-of-type-selector) element) + (when-let* ((arg (selector-arg selector)) + (parent (element-parent element))) + (an+b? (car arg) (cdr arg) element + (remove-if-not (rcurry #'element-type-equal (element-type element)) + (element-children parent))))) + +(defmethod subject-p ((selector nth-last-of-type-selector) element) + (when-let* ((arg (selector-arg selector)) + (parent (element-parent element))) + (an+b? (car arg) (cdr arg) element + (reverse + (remove-if-not (rcurry #'element-type-equal (element-type element)) + (element-children parent)))))) + (defmethod subject-p ((selector class-selector) element) (member (selector-arg selector) (element-classes element) diff -rN -u old-Oh, Ducks!/tests.lisp new-Oh, Ducks!/tests.lisp --- old-Oh, Ducks!/tests.lisp 2013-11-17 08:43:14.000000000 +0000 +++ new-Oh, Ducks!/tests.lisp 2013-11-17 08:43:14.000000000 +0000 @@ -59,10 +59,17 @@ "
I do not like cheese.
I like cheese.
") (values div d2)) +(match (#t(html (:model dom) + (":nth-last-of-type(2)" . ?first) + (":nth-of-type(2)" . ?last)) + "
1i2i
") + (values first last)) + (match (#T(html (:model dom) - ("i:only-child" . ?i)) + ("i:only-child" . ?i) + ("i:only-of-type" . ?i-type)) "
I do not like cheese.
I like cheese.
") - (values i)) + (values i i-type)) ;; throws 'unification-failure (match (#T(html (:model dom)