|
1 | | -(ns clojure.data.xml.node |
| 1 | +(ns clojure.data.xml.js.dom |
2 | 2 | (:require |
3 | | - [clojure.data.xml.name :refer [qname-uri qname-local canonical-name]])) |
| 3 | + [clojure.data.xml.name :refer [qname-uri qname-local canonical-name xmlns-uri]] |
| 4 | + [clojure.data.xml.node :as node])) |
4 | 5 |
|
5 | 6 | (def doc |
6 | 7 | (.. (js/DOMParser.) |
|
77 | 78 | (def Element (type (element :e))) |
78 | 79 | (def NamedNodeMap (type (.-attributes (element :e)))) |
79 | 80 | (def NodeList (type (node-list []))) |
| 81 | +(def Attr (type (aget (.-attributes (element :e {:a "1"})) 0))) |
80 | 82 |
|
81 | 83 | ;; ## Coercions |
82 | 84 |
|
|
104 | 106 | (.-localName el) |
105 | 107 | "")) |
106 | 108 |
|
| 109 | +(defn- xmlns-attr? [a] |
| 110 | + (identical? xmlns-uri (.-namespaceURI a))) |
| 111 | +(def remove-xmlns-attrs-xf (remove xmlns-attr?)) |
| 112 | +(def remove-xmlns-attrs (partial into {} remove-xmlns-attrs-xf)) |
| 113 | +(def filter-xmlns-attrs (partial into {} (filter xmlns-attr?))) |
| 114 | + |
107 | 115 | (defn dom-element-attrs [el] |
108 | | - (persistent! |
109 | | - (reduce (fn [ta attr-node] |
110 | | - (assoc! ta |
111 | | - (dom-element-tag attr-node) |
112 | | - (.-value attr-node))) |
113 | | - (transient {}) |
114 | | - (array-seq el)))) |
| 116 | + (transduce |
| 117 | + remove-xmlns-attrs-xf |
| 118 | + (completing |
| 119 | + (fn [ta attr-node] |
| 120 | + (assoc! ta |
| 121 | + (dom-element-tag attr-node) |
| 122 | + (.-value attr-node))) |
| 123 | + persistent!) |
| 124 | + (transient {}) |
| 125 | + (array-seq el))) |
115 | 126 |
|
116 | 127 | (declare element-data) |
117 | 128 |
|
|
130 | 141 | (instance? Text el) |
131 | 142 | (.-nodeValue el) |
132 | 143 | (instance? Element el) |
133 | | - {:tag (dom-element-tag el) |
134 | | - :attrs (dom-element-attrs (.-attributes el)) |
135 | | - :content (node-list-vec (.-childNodes el))} |
| 144 | + (node/element* (dom-element-tag el) |
| 145 | + (dom-element-attrs (.-attributes el)) |
| 146 | + (node-list-vec (.-childNodes el)) |
| 147 | + (do |
| 148 | + (prn "META" {:clojure.data.xml/nss (filter-xmlns-attrs |
| 149 | + (.-attributes el))}) |
| 150 | + {:clojure.data.xml/nss (filter-xmlns-attrs |
| 151 | + (.-attributes el))})) |
136 | 152 | ;;(instance? NamedNodeMap el) |
137 | 153 | (.-getNamedItemNS el) |
138 | 154 | (dom-element-attrs el) |
|
144 | 160 |
|
145 | 161 | (defn extend-dom-as-data! [] |
146 | 162 | (extend-type Element |
| 163 | + IMap |
| 164 | + IMeta |
| 165 | + (-meta [el] |
| 166 | + {:clojure.data.xml/nss (filter-xmlns-attrs |
| 167 | + (.-attributes el))}) |
147 | 168 | ILookup |
148 | | - (-lookup [el k] |
149 | | - (case k |
150 | | - :tag (dom-element-tag el) |
151 | | - :attrs (.-attributes el) |
152 | | - :content (.-childNodes el) |
153 | | - (throw "XML tag has no key" {:key k :el el}))) |
| 169 | + (-lookup |
| 170 | + ([el k] |
| 171 | + (case k |
| 172 | + :tag (dom-element-tag el) |
| 173 | + :attrs (.-attributes el) |
| 174 | + :content (.-childNodes el) |
| 175 | + (throw "XML tag has no key" {:key k :el el}))) |
| 176 | + ([el k nf] |
| 177 | + (println "Element" k "=>" (case k |
| 178 | + :tag (dom-element-tag el) |
| 179 | + :attrs (.-attributes el) |
| 180 | + :content (.-childNodes el) |
| 181 | + nf)) |
| 182 | + (case k |
| 183 | + :tag (dom-element-tag el) |
| 184 | + :attrs (remove-xmlns-attrs (.-attributes el)) |
| 185 | + :content (.-childNodes el) |
| 186 | + nf))) |
| 187 | + ICounted |
| 188 | + (-count [nm] 3) |
154 | 189 | IEquiv |
155 | 190 | (-equiv [el0 el1] |
156 | | - (.isEqualNode el0 el1))) |
| 191 | + (if false #_(instance? Element el1) |
| 192 | + (do |
| 193 | + ;; we can't use .isEqualNode, since that has bugs with namespaces |
| 194 | + (.log js/console el0 el1) |
| 195 | + (println 'isEqualNode (.isEqualNode el0 el1)) |
| 196 | + (.isEqualNode el0 el1)) |
| 197 | + (and (= (:tag el0) (:tag el1)) |
| 198 | + (= (:attrs el0) (:attrs el1)) |
| 199 | + (= (:content el0) (:content el1)))))) |
157 | 200 | (extend-type NamedNodeMap |
| 201 | + IMap |
| 202 | + ISeqable |
| 203 | + (-seq [nm] (array-seq nm)) |
158 | 204 | ILookup |
159 | 205 | (-lookup |
160 | 206 | ([attrs attr] |
161 | 207 | (if-let [i (.getNamedItemNS attrs (qname-uri attr) (qname-local attr))] |
162 | 208 | (.-value i) |
163 | 209 | nil)) |
164 | 210 | ([attrs attr not-found] |
| 211 | + (println "Attrs" attr "=>" (if-let [i (.getNamedItemNS attrs (qname-uri attr) (qname-local attr))] |
| 212 | + (.-value i) |
| 213 | + not-found)) |
165 | 214 | (if-let [i (.getNamedItemNS attrs (qname-uri attr) (qname-local attr))] |
166 | 215 | (.-value i) |
167 | 216 | not-found))) |
168 | 217 | ICounted |
169 | | - (-count [nm] (alength nm)) |
| 218 | + (-count [nm] (reduce (fn [acc attr] |
| 219 | + (if (xmlns-attr? attr) |
| 220 | + acc |
| 221 | + (inc acc))) |
| 222 | + 0 nm)) |
170 | 223 | IKVReduce |
171 | 224 | (-kv-reduce [nm f init] |
172 | 225 | (reduce (fn [acc attr] |
173 | | - (f acc (dom-element-tag attr) (.-value attr))) |
| 226 | + (if (xmlns-attr? attr) |
| 227 | + acc |
| 228 | + (f acc (dom-element-tag attr) (.-value attr)))) |
174 | 229 | init nm)) |
175 | | - IIndexed |
176 | | - (-nth |
177 | | - ([nm n] (.-value (aget nm n))) |
178 | | - ([nm n nf] (if (and (<= 0 n) (< n (alength nm))) |
179 | | - (.-value (aget nm n)) |
180 | | - nf))) |
181 | 230 | IEquiv |
182 | 231 | (-equiv [nm0 nm1] |
183 | | - (and (identical? (count nm0) (count nm1)) |
184 | | - (reduce-kv (fn [_ qn v] |
185 | | - (or (identical? v (get nm1 qn "")) |
186 | | - (reduced false))) |
187 | | - true nm0)))) |
| 232 | + (println "NamedNodeMap.-equiv" (identical? nm0 nm1) (count nm0) (count nm1)) |
| 233 | + (or (identical? nm0 nm1) |
| 234 | + (and (identical? (count nm0) (count nm1)) |
| 235 | + (reduce-kv (fn [_ qn v] |
| 236 | + (println "=" v 'qn qn '(get nm1 qn "") (get nm1 qn "")) |
| 237 | + (or (identical? v (get nm1 qn "")) |
| 238 | + (reduced false))) |
| 239 | + true nm0))))) |
188 | 240 | (extend-type NodeList |
189 | 241 | ;specify! (.. (node-list []) -constructor -prototype) |
190 | 242 | ISeqable |
191 | | - (-seq [nl] (map as-node (array-seq nl))) |
| 243 | + (-seq [nl] (seq (map as-node (array-seq nl)))) |
192 | 244 | ISequential |
193 | 245 | ICounted |
194 | 246 | (-count [nl] (alength nl)) |
|
202 | 254 | nf))) |
203 | 255 | IEquiv |
204 | 256 | (-equiv [nl0 nl1] |
205 | | - (and (identical? (count nl0) (count nl1)) |
206 | | - (reduce (fn [_ n] |
207 | | - (or (= (nth nl0 n) (nth nl1 n)) |
208 | | - (reduced false))) |
209 | | - true (range (count nl0)))))) |
| 257 | + (println "NodeList.-equiv") |
| 258 | + (or (identical? nl0 nl1) |
| 259 | + (and (identical? (count nl0) (count nl1)) |
| 260 | + (reduce (fn [_ n] |
| 261 | + (or (= (nth nl0 n) (nth nl1 n)) |
| 262 | + (reduced false))) |
| 263 | + true (range (count nl0))))))) |
210 | 264 | (extend-type Text |
211 | 265 | IEquiv |
212 | 266 | (-equiv [t0 t1] |
213 | | - (identical? (.-nodeValue t0) (.-nodeValue t1)))) |
| 267 | + (identical? (.-nodeValue t0) |
| 268 | + (if (instance? Text t1) |
| 269 | + (.-nodeValue t1) |
| 270 | + t1)))) |
| 271 | + (extend-type Attr |
| 272 | + ISeqable |
| 273 | + (-seq [attr] (array-seq #js[(key attr) (key attr)])) |
| 274 | + IMapEntry |
| 275 | + (-key [attr] (dom-element-tag attr)) |
| 276 | + (-val [attr] (.-value attr)) |
| 277 | + ISequential |
| 278 | + ICounted |
| 279 | + (-count [_] 2) |
| 280 | + IIndexed |
| 281 | + (-nth |
| 282 | + ([attr n] (case n |
| 283 | + 0 (key attr) |
| 284 | + 1 (val attr))) |
| 285 | + ([attr n nf] |
| 286 | + (case n |
| 287 | + 0 (dom-element-tag attr) |
| 288 | + 1 (.-value attr) |
| 289 | + nf)))) |
214 | 290 | {'Text Text |
215 | 291 | 'Element Element |
216 | 292 | 'NamedNodeMap NamedNodeMap |
|
0 commit comments