implicit-element is a better name than root
Sat Dec 5 07:18:05 UTC 2009 pix@kepibu.org
* implicit-element is a better name than root
Also add a bit of support for sibling combinators when dealing with the
implicit element, and note a problem that crops up when dealing with
selections on a non-root element (should a simple-selector select the
element, or is there an implicit descendant combinator?).
hunk ./selectors.lisp 3
-(defvar *effective-root* nil
- "The element to be considered as the root element during unification. Is the implicit element to be matched by combinators without a leading qualifier. E.g., \"> a\" will match <a> tags directly under *effective-root*.")
+(defvar *implicit-element* nil
+ "The element to be considered as an implicit element to be matched by combinators without a leading qualifier. E.g., \"> a\" will match <a> tags directly under *implicit-element*, and \"+ a\" will match <a> tags directly following *implicit-element*.")
hunk ./selectors.lisp 55
-(defclass %root-selector (simple-selector) ())
-(defparameter %root-selector (make-instance '%root-selector))
+(defclass %implicit-element-selector (selector) ())
+(defparameter %implicit-element-selector (make-instance '%implicit-element-selector))
hunk ./selectors.lisp 58
-(defmethod print-object ((selector %root-selector) stream)
+(defmethod print-object ((selector %implicit-element-selector) stream)
hunk ./selectors.lisp 65
- (list (make-instance 'sibling-combinator :matcher (or (parse-selector &rest) %root-selector))))
+ (list (make-instance 'sibling-combinator :matcher (or (parse-selector &rest) %implicit-element-selector))))
hunk ./selectors.lisp 67
- (list (make-instance 'adjacent-combinator :matcher (or (parse-selector &rest) %root-selector))))
+ (list (make-instance 'adjacent-combinator :matcher (or (parse-selector &rest) %implicit-element-selector))))
hunk ./selectors.lisp 69
- (list (make-instance 'child-combinator :matcher (or (parse-selector &rest) %root-selector))))
+ (list (make-instance 'child-combinator :matcher (or (parse-selector &rest) %implicit-element-selector))))
hunk ./selectors.lisp 71
- (list (make-instance 'descendant-combinator :matcher (or (parse-selector &rest) %root-selector))))
+ (list (make-instance 'descendant-combinator :matcher (or (parse-selector &rest) %implicit-element-selector))))
hunk ./selectors.lisp 106
+(defun find-matching-elements-in-list (selector element-list)
+ (reduce #'nconc
+ (mapcar (curry #'find-matching-elements selector)
+ element-list)))
+
hunk ./selectors.lisp 155
-(defmethod element-matches-p (element (selector %root-selector))
- (eq element *effective-root*))
+(defmethod element-matches-p (element (selector %implicit-element-selector))
+ (eq element *implicit-element*))
hunk ./selectors.lisp 182
+
+;; Hello excessively long name
+(defun terminating-implicit-sibling-combinator-p (selector)
+ (typecase selector
+ ((or sibling-combinator adjacent-combinator)
+ (typecase (matcher selector)
+ (%implicit-element-selector t)
+ (list (terminating-implicit-sibling-combinator-p (car (last (matcher selector)))))))
+ (combinator (terminating-implicit-sibling-combinator-p (matcher selector)))
+ (selector nil)
+ (null nil)
+ (list (terminating-implicit-sibling-combinator-p (car (last selector))))
+ (t nil)))
hunk ./tests.lisp 82
-;; Note, however, that searches are strictly recursive. So a sibling
-;; combinator won't match.
-;; FIXME: should it?
+;; siblings will also match, thanks to a bit of ugly code
hunk ./tests.lisp 85
- "<div><i>ham</i> foo <q>bar <i>baz</i></q> quuz <i>spam</i></div>")
+ "<div><i>ham</i> foo <q>bar <i>baz</i></q> quuz <i>spam</i><q></q><i>not match</i></div>")
hunk ./tests.lisp 90
+(match (#T(html (:model dom)
+ ("q" . ?q))
+ "<div> foo <q>outer q <i>baz <q>inner q</q></i></q> quuz</div>")
+ (match (#t(html ("q" . ?i))
+ (first q))
+ i))
+
hunk ./unify.lisp 21
- (let* ((*effective-root* document)
- (val (find-matching-elements css-specifier document)))
+ (let* ((*implicit-element* document)
+ ;; FIXME: this is UGLY!
+ (val (cond
+ ((terminating-implicit-sibling-combinator-p css-specifier)
+ ;; search remaining siblings
+ (find-matching-elements-in-list
+ css-specifier
+ (rest
+ (member document
+ (when-let* ((parent (element-parent document)))
+ (element-children parent))
+ :test #'eq))))
+ ;; search subelements
+;;; FIXME: this assumes if someone passes us a node they want to find
+;;; subelements of that node. In the case of nested matches, that's probably
+;;; true, but it hardly seems fair to assume it. Really we want some sort of
+;;; descendant combinator to be sure, but the general one (#\Space) doesn't
+;;; exactly show up all that well. Somebody might assume " b" was the same as
+;;; "b" and get confused.
+ ((element-parent document)
+ (find-matching-elements-in-list css-specifier (element-children document)))
+ ;; root element includes itself
+ (t (find-matching-elements css-specifier document)))))