Add :nth-child selector
Mon Nov 30 04:09:10 UTC 2009 pix@kepibu.org
* Add :nth-child selector
hunk ./notes 118
-*** positional selectors [2/12]
+*** positional selectors [3/12]
hunk ./notes 120
- * [ ] :nth-child(xn+y)
+ * [X] :nth-child(xn+y)
hunk ./selectors.lisp 37
+(defclass nth-last-child-selector (nth-child-selector) ())
hunk ./selectors.lisp 57
- (#T(regexp$ ":nth-child\\([ ]*([0-9]+)[ ]*\\)" (?n))
- (cons (make-instance 'nth-child-selector :arg (parse-integer n)) (parse-selector &rest)))
+ ;; FIXME: fix cl-unification so it can handle non-matching groups,
+ ;; so we can merge all these nth-child-selector variants
+ ;; into one or two
+ (#T(regexp$ ":nth-child\\([ ]*([+-]?[0-9]+)n[ ]*([+-]?[0-9]+)[ ]*\\)" (?a ?b))
+ (cons (make-instance 'nth-child-selector :arg (cons (parse-integer a) (parse-integer b))) (parse-selector &rest)))
+ (#T(regexp$ ":nth-child\\([ ]*([+-]?[0-9]+)n[ ]*\\)" (?a))
+ (cons (make-instance 'nth-child-selector :arg (cons (parse-integer a) 0)) (parse-selector &rest)))
+ (#T(regexp$ ":nth-child\\([ ]*n[ ]*([+-]?[0-9]+)[ ]*\\)" (?b))
+ (cons (make-instance 'nth-child-selector :arg (cons 1 (parse-integer b))) (parse-selector &rest)))
+ (#T(regexp$ ":nth-child\\([ ]*-n[ ]*([+-]?[0-9]+)[ ]*\\)" (?b))
+ (cons (make-instance 'nth-child-selector :arg (cons -1 (parse-integer b))) (parse-selector &rest)))
+ (#T(regexp$ ":nth-child\\([ ]*([+-]?[0-9]+)[ ]*\\)" (?b))
+ (cons (make-instance 'nth-child-selector :arg (cons 0 (parse-integer b))) (parse-selector &rest)))
+ (#T(regexp$ ":nth-child\\([ ]*odd[ ]*\\)" ())
+ (cons (make-instance 'nth-child-selector :arg (cons 2 1)) (parse-selector &rest)))
+ (#T(regexp$ ":nth-child\\([ ]*even[ ]*\\)" ())
+ (cons (make-instance 'nth-child-selector :arg (cons 2 0)) (parse-selector &rest)))
hunk ./selectors.lisp 75
- (cons (make-instance 'nth-child-selector :arg 1) (parse-selector &rest)))
+ (cons (make-instance 'nth-child-selector :arg (cons 0 1)) (parse-selector &rest)))
hunk ./selectors.lisp 107
- (pos (position element (element-children parent) :test #'eq)))
- (= (selector-arg selector) (1+ pos))))
+ (pos (position element (funcall (typecase selector
+ (nth-last-child-selector #'reverse)
+ (nth-child-selector #'identity))
+ (element-children parent)) :test #'eq)))
+ (let ((pos (1+ pos))
+ (a (car (selector-arg selector)))
+ (b (cdr (selector-arg selector))))
+ ;; pos = An + B
+ (cond
+ ;; pos = 0n + B
+ ((= 0 a) (= b pos))
+ ;; (pos - B)/A = n
+ (t (and (zerop (mod (- pos b) a))
+ (not (minusp (/ (- pos b) a)))))))))