9 ((parent :initarg
:parent
:initform nil
)
10 (children :initarg
:children
:initform nil
)
11 (owner :initarg
:owner
:initform nil
)))
13 (defclass document
(node)
14 ((doc-type :initarg
:doc-type
:reader dom
:doctype
)))
16 (defclass document-fragment
(node)
19 (defclass character-data
(node)
20 ((data :initarg
:data
:reader dom
:data
)))
22 (defclass attribute
(node)
23 ((name :initarg
:name
:reader dom
:name
)
24 (value :initarg
:value
:reader dom
:value
)
25 (specified-p :initarg
:specified-p
:reader dom
:specified
)))
27 (defclass element
(node)
28 ((tag-name :initarg
:tag-name
:reader dom
:tag-name
)
29 (attributes :initarg
:attributes
:reader dom
:attributes
30 :initform
(make-instance 'named-node-map
))))
32 (defclass text
(character-data)
35 (defclass comment
(character-data)
38 (defclass cdata-section
(text)
41 (defclass document-type
(node)
42 ((name :initarg
:name
:reader dom
:name
)
43 (entities :initarg
:entities
:reader dom
:entities
)
44 (notations :initarg
:notations
:reader dom
:notations
)))
46 (defclass notation
(node)
47 ((name :initarg
:name
:reader dom
:name
)
48 (public-id :initarg
:public-id
:reader dom
:public-id
)
49 (system-id :initarg
:system-id
:reader dom
:system-id
)))
51 (defclass entity
(node)
52 ((name :initarg
:name
:reader dom
:name
)
53 (public-id :initarg
:public-id
:reader dom
:public-id
)
54 (system-id :initarg
:system-id
:reader dom
:system-id
)
55 (notation-name :initarg
:notation-name
:reader dom
:notation-name
)))
57 (defclass entity-reference
(node)
58 ((name :initarg
:name
:reader dom
:name
)))
60 (defclass processing-instruction
(node)
61 ((target :initarg
:target
:reader dom
:target
)
62 (data :initarg
:data
:reader dom
:data
)))
64 (defclass named-node-map
()
65 ((items :initarg
:items
:reader dom
:items
71 ;; document-fragment protocol
74 (defmethod dom:implementation
((document document
))
77 (defmethod dom:document-element
((document document
))
78 (dolist (k (dom:child-nodes document
))
79 (cond ((typep k
'element
)
82 (defmethod dom:create-element
((document document
) tag-name
)
83 (setf tag-name
(rod tag-name
))
84 (make-instance 'element
88 (defmethod dom:create-document-fragment
((document document
))
89 (make-instance 'document-fragment
92 (defmethod dom:create-text-node
((document document
) data
)
93 (setf data
(rod data
))
98 (defmethod dom:create-comment
((document document
) data
)
99 (setf data
(rod data
))
100 (make-instance 'comment
104 (defmethod dom:create-cdata-section
((document document
) data
)
105 (setf data
(rod data
))
106 (make-instance 'cdata-section
110 (defmethod dom:create-processing-instruction
((document document
) target data
)
111 (setf target
(rod target
))
112 (setf data
(rod data
))
113 (make-instance 'processing-instruction
118 (defmethod dom:create-attribute
((document document
) name
)
119 (setf name
(rod name
))
120 (make-instance 'attribute
122 :specified-p nil
;???
125 (defmethod dom:create-entity-reference
((document document
) name
)
126 (setf name
(rod name
))
127 (make-instance 'entity-reference
131 (defmethod dom:get-elements-by-tag-name
((document document
) tag-name
)
132 (setf tag-name
(rod tag-name
))
134 (setf tag-name
(rod tag-name
))
135 (let ((wild-p (rod= tag-name
'#.
(string-rod "*"))))
137 (when (and (dom:element-p n
)
138 (or wild-p
(tag-name-eq tag-name
(dom:node-name n
))))
140 (mapc #'walk
(dom:child-nodes n
))))
146 (defmethod dom:parent-node
((node node
))
147 (slot-value node
'parent
))
149 (defmethod dom:child-nodes
((node node
))
150 (slot-value node
'children
))
152 (defmethod dom:first-child
((node node
))
153 (car (slot-value node
'children
)))
155 (defmethod dom:last-child
((node node
))
156 (car (last (slot-value node
'children
))))
158 (defmethod dom:previous-sibling
((node node
))
159 (with-slots (parent) node
161 (with-slots (children) parent
162 (do ((q children
(cdr q
)))
164 (cond ((eq (cadr q
) node
)
165 (return (car q
)))))))))
167 (defmethod dom:next-sibling
((node node
))
168 (with-slots (parent) node
170 (with-slots (children) parent
171 (do ((q children
(cdr q
)))
173 (cond ((eq (car q
) node
)
174 (return (cadr q
)))))))))
176 (defmethod dom:owner-document
((node node
))
177 (slot-value node
'owner
))
179 (defun ensure-valid-insertion-request (node new-child
)
180 (unless (can-adopt-p node new-child
)
181 ;; HIERARCHY_REQUEST_ERR
182 (error "~S cannot adopt ~S." node new-child
))
183 (unless (eq (dom:owner-document node
)
184 (dom:owner-document new-child
))
185 ;; WRONG_DOCUMENT_ERR
186 (error "~S cannot adopt ~S, since it was created by a different document."
188 (with-slots (children) node
189 (unless (null (slot-value new-child
'parent
))
190 (cond ((eq (slot-value new-child
'parent
)
193 (setf children
(delete new-child children
)))
195 ;; otherwise it is an error.
197 (error "~S is already adopted." new-child
)))) ))
199 (defmethod dom:insert-before
((node node
) (new-child node
) (ref-child t
))
200 (ensure-valid-insertion-request node new-child
)
201 (with-slots (children) node
202 (cond ((eq (car children
) ref-child
)
203 (setf (slot-value new-child
'parent
) node
)
204 (setf children
(cons new-child children
)))
206 (do ((q children
(cdr q
)))
208 (cond ((null ref-child
)
209 (setf (slot-value new-child
'parent
) node
)
210 (setf (cdr q
) (cons new-child nil
)))
213 (error "~S is no child of ~S." ref-child node
))))
214 (cond ((eq (cadr q
) ref-child
)
215 (setf (slot-value new-child
'parent
) node
)
216 (setf (cdr q
) (cons new-child
(cdr q
)))
220 (defmethod dom:insert-before
((node node
) (fragment document-fragment
) ref-child
)
221 (dolist (child (dom:child-nodes fragment
))
222 (dom:insert-before node child ref-child
))
225 (defmethod dom:replace-child
((node node
) (new-child node
) (old-child node
))
226 (ensure-valid-insertion-request node new-child
)
227 (with-slots (children) node
228 (do ((q children
(cdr q
)))
231 (error "~S is no child of ~S." old-child node
))
232 (cond ((eq (car q
) old-child
)
233 (setf (car q
) new-child
)
234 (setf (slot-value new-child
'parent
) node
)
235 (setf (slot-value old-child
'parent
) nil
)
239 (defmethod dom:append-child
((node node
) (new-child node
))
240 (ensure-valid-insertion-request node new-child
)
241 (with-slots (children) node
242 (setf children
(nconc children
(list new-child
)))
243 (setf (slot-value new-child
'parent
) node
)
246 (defmethod dom:has-child-nodes
((node node
))
247 (not (null (slot-value node
'children
))))
249 (defmethod dom:append-child
((node node
) (new-child document-fragment
))
250 (dolist (child (dom:child-nodes new-child
))
251 (dom:append-child node child
))
254 ;; was auf node noch implemetiert werden muss:
263 (defmethod dom:node-name
((self document
))
264 '#.
(string-rod "#document"))
266 (defmethod dom:node-name
((self document-fragment
))
267 '#.
(string-rod "#document-fragment"))
269 (defmethod dom:node-name
((self text
))
270 '#.
(string-rod "#text"))
272 (defmethod dom:node-name
((self cdata-section
))
273 '#.
(string-rod "#cdata-section"))
275 (defmethod dom:node-name
((self comment
))
276 '#.
(string-rod "#comment"))
278 (defmethod dom:node-name
((self attribute
))
281 (defmethod dom:node-name
((self element
))
284 (defmethod dom:node-name
((self document-type
))
287 (defmethod dom:node-name
((self notation
))
290 (defmethod dom:node-name
((self entity
))
293 (defmethod dom:node-name
((self entity-reference
))
296 (defmethod dom:node-name
((self processing-instruction
))
301 (defmethod dom:node-type
((self document
)) :document
)
302 (defmethod dom:node-type
((self document-fragment
)) :document-fragment
)
303 (defmethod dom:node-type
((self text
)) :text
)
304 (defmethod dom:node-type
((self comment
)) :comment
)
305 (defmethod dom:node-type
((self cdata-section
)) :cdata-section
)
306 (defmethod dom:node-type
((self attribute
)) :attribute
)
307 (defmethod dom:node-type
((self element
)) :element
)
308 (defmethod dom:node-type
((self document-type
)) :document-type
)
309 (defmethod dom:node-type
((self notation
)) :notation
)
310 (defmethod dom:node-type
((self entity
)) :entity
)
311 (defmethod dom:node-type
((self entity-reference
)) :entity-reference
)
312 (defmethod dom:node-type
((self processing-instruction
)) :processing-instruction
)
316 (defmethod dom:node-value
((self document
)) nil
)
317 (defmethod dom:node-value
((self document-fragment
)) nil
)
318 (defmethod dom:node-value
((self character-data
)) (dom:data self
))
319 (defmethod dom:node-value
((self attribute
)) (dom:name self
))
320 (defmethod dom:node-value
((self element
)) nil
)
321 (defmethod dom:node-value
((self document-type
)) nil
)
322 (defmethod dom:node-value
((self notation
)) nil
)
323 (defmethod dom:node-value
((self entity
)) nil
)
324 (defmethod dom:node-value
((self entity-reference
)) nil
)
325 (defmethod dom:node-value
((self processing-instruction
)) (dom:data self
))
329 ;; (gibt es nur auf element)
331 (defmethod dom:attributes
((self node
))
334 ;; dann fehlt noch can-adopt und attribute conventions fuer adoption
338 (defmethod dom:get-named-item
((self named-node-map
) name
)
339 (setf name
(rod name
))
340 (with-slots (items) self
341 (dolist (k items nil
)
342 (cond ((rod= name
(dom:node-name k
))
345 (defmethod dom:set-named-item
((self named-node-map
) arg
)
346 (let ((name (dom:node-name arg
)))
347 (with-slots (items) self
348 (dolist (k items
(progn (setf items
(cons arg items
))nil
))
349 (cond ((rod= name
(dom:node-name k
))
350 (setf items
(cons arg
(delete k items
)))
353 (defmethod dom:remove-named-item
((self named-node-map
) name
)
354 (setf name
(rod name
))
355 (with-slots (items) self
356 (dolist (k items nil
)
357 (cond ((rod= name
(dom:node-name k
))
358 (setf items
(delete k items
))
361 (defmethod dom:length
((self named-node-map
))
362 (with-slots (items) self
365 (defmethod dom:item
((self named-node-map
) index
)
366 (with-slots (items) self
371 (defmethod dom:length
((node character-data
))
372 (length (slot-value node
'value
)))
374 (defmethod dom:substring-data
((node character-data
) offset count
)
375 (subseq (slot-value node
'value
) offset
(+ offset count
)))
377 (defmethod dom:append-data
((node character-data
) arg
)
379 (with-slots (value) node
380 (setf value
(concatenate (type-of value
) value arg
)))
383 (defmethod dom:delete-data
((node character-data
) offset count
)
384 (with-slots (value) node
385 (let ((new (make-array (- (length value
) count
) :element-type
(type-of value
))))
387 :start1
0 :end1 offset
388 :start2
0 :end2 offset
)
390 :start1 offset
:end1
(length new
)
391 :start2
(+ offset count
) :end2
(length value
))
395 (defmethod dom:replace-data
((node character-data
) offset count arg
)
397 (with-slots (value) node
399 :start1 offset
:end1
(+ offset count
)
400 :start2
0 :end2 count
))
405 ;; hmm... value muss noch entities lesen und text-nodes in die hierarchie hängen.
407 (defmethod (setf dom
:value
) (new-value (node attribute
))
408 (setf (slot-value node
'value
) (rod new-value
)))
412 (defmethod dom:get-attribute-node
((element element
) name
)
413 (dom:get-named-item
(dom:attributes element
) name
))
415 (defmethod dom:set-attribute-node
((element element
) (new-attr attribute
))
416 (dom:set-named-item
(dom:attributes element
) new-attr
))
418 (defmethod dom:get-attribute
((element element
) name
)
419 (let ((a (dom:get-attribute-node element name
)))
424 (defmethod dom:set-attribute
((element element
) name value
)
425 (with-slots (owner) element
426 (dom:set-attribute-node
427 element
(make-instance 'attribute
434 (defmethod dom:remove-attribute-node
((element element
) (old-attr attribute
))
435 (let ((res (dom:remove-named-item element
(dom:name old-attr
))))
439 (error "Attribute not found."))))
441 (defmethod dom:get-elements-by-tag-name
((element element
) name
)
443 (error "Not implemented."))
445 (defmethod dom:normalize
((element element
))
446 (error "Not implemented.") )
450 (defmethod dom:split-text
((text text
) offset
)
452 (error "Not implemented."))
455 ;;; CDATA-SECTION -- nix
457 ;;; DOCUMENT-TYPE -- missing
460 ;;; ENTITY-REFERENCE -- nix
461 ;;; PROCESSING-INSTRUCTION -- nix
464 (defun can-adopt-p (x y
) x y t
)
469 (defmethod dom:node-p
((object node
)) t
)
470 (defmethod dom:node-p
((object t
)) nil
)
472 (defmethod dom:document-p
((object document
)) t
)
473 (defmethod dom:document-p
((object t
)) nil
)
475 (defmethod dom:document-fragment-p
((object document-fragment
)) t
)
476 (defmethod dom:document-fragment-p
((object t
)) nil
)
478 (defmethod dom:character-data-p
((object character-data
)) t
)
479 (defmethod dom:character-data-p
((object t
)) nil
)
481 (defmethod dom:attribute-p
((object attribute
)) t
)
482 (defmethod dom:attribute-p
((object t
)) nil
)
484 (defmethod dom:element-p
((object element
)) t
)
485 (defmethod dom:element-p
((object t
)) nil
)
487 (defmethod dom:text-node-p
((object text
)) t
)
488 (defmethod dom:text-node-p
((object t
)) nil
)
490 (defmethod dom:comment-p
((object comment
)) t
)
491 (defmethod dom:comment-p
((object t
)) nil
)
493 (defmethod dom:cdata-section-p
((object cdata-section
)) t
)
494 (defmethod dom:cdata-section-p
((object t
)) nil
)
496 (defmethod dom:document-type-p
((object document-type
)) t
)
497 (defmethod dom:document-type-p
((object t
)) nil
)
499 (defmethod dom:notation-p
((object notation
)) t
)
500 (defmethod dom:notation-p
((object t
)) nil
)
502 (defmethod dom:entity-p
((object entity
)) t
)
503 (defmethod dom:entity-p
((object t
)) nil
)
505 (defmethod dom:entity-reference-p
((object entity-reference
)) t
)
506 (defmethod dom:entity-reference-p
((object t
)) nil
)
508 (defmethod dom:processing-instruction-p
((object processing-instruction
)) t
)
509 (defmethod dom:processing-instruction-p
((object t
)) nil
)
511 (defmethod dom:named-node-map-p
((object named-node-map
)) t
)
512 (defmethod dom:named-node-map-p
((object t
)) nil
)