Add sibling and adjacent combinators
Thu Dec 3 00:12:02 UTC 2009 pix@kepibu.org
* Add sibling and adjacent combinators
diff -rN -u old-Oh, Ducks!/selectors.lisp new-Oh, Ducks!/selectors.lisp
--- old-Oh, Ducks!/selectors.lisp 2013-07-24 10:32:17.000000000 +0000
+++ new-Oh, Ducks!/selectors.lisp 2013-07-24 10:32:17.000000000 +0000
@@ -51,8 +51,10 @@
(defun parse-selector (selector)
(match-case (selector)
;; combinators
- #+TODO (#T(regexp$ "[ ]*[~][ ]*" ()) (list (make-instance 'sibling-combinator :matcher (parse-selector &rest))))
- #+TODO (#T(regexp$ "[ ]*[+][ ]*" ()) (list (make-instance 'adjacent-combinator :matcher (parse-selector &rest))))
+ (#T(regexp$ "[ ]*[~][ ]*" ())
+ (list (make-instance 'sibling-combinator :matcher (parse-selector &rest))))
+ (#T(regexp$ "[ ]*[+][ ]*" ())
+ (list (make-instance 'adjacent-combinator :matcher (parse-selector &rest))))
(#T(regexp$ "[ ]*[>][ ]*" ())
(list (make-instance 'child-combinator :matcher (parse-selector &rest))))
(#T(regexp$ "[ ]+" ())
@@ -143,10 +145,18 @@
(defmethod element-matches-p (element (selector descendant-combinator))
(some (rcurry #'element-matches-p (matcher selector)) (element-ancestors element)))
-#+TODO
(defmethod element-matches-p (element (selector adjacent-combinator))
- ...)
+ (let* ((parent (element-parent element))
+ (siblings (element-children parent))
+ (ourpos (position element siblings :test #'eq)))
+ (and ourpos
+ (> ourpos 0)
+ (element-matches-p (elt siblings (1- ourpos)) (matcher selector)))))
-#+TODO
(defmethod element-matches-p (element (selector sibling-combinator))
- ...)
+ (let* ((parent (element-parent element))
+ (siblings (element-children parent))
+ (ourpos (position element siblings :test #'eq)))
+ (and ourpos
+ (> ourpos 0)
+ (find-if (rcurry #'element-matches-p (matcher selector)) siblings :end ourpos))))
diff -rN -u old-Oh, Ducks!/tests.lisp new-Oh, Ducks!/tests.lisp
--- old-Oh, Ducks!/tests.lisp 2013-07-24 10:32:17.000000000 +0000
+++ new-Oh, Ducks!/tests.lisp 2013-07-24 10:32:17.000000000 +0000
@@ -59,6 +59,17 @@
"<div>I do <i>not</i> <i>like</i> cheese.</div><div><span>I like <i>cheese</i>.</span></div>")
(values div))
+(match (#T(html (:model dom)
+ ("b + i" . ?i))
+ "<div>I <b>really</b> <i>like</i> cheese. Do you not <i>dislike</i> cheese?</div>")
+ (values i))
+
+(match (#T(html (:model dom)
+ ("b ~ i" . ?i))
+ "<div>I <i>really</i> <b>like</b> cheese. Do you not <i>dislike</i> cheese?</div>")
+ (values i))
+
+
#+LATER?
(match (#t(html ("div::content" . #t(regexp+ "^f(o+)" (?o))))
"<div>barbaz</div><div>fooooooobar</div>")