Skip to content

Commit

Permalink
5-10% speed improvement with protocols
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Granger <ibdknox@gmail.com>
  • Loading branch information
ibdknox committed Jan 17, 2013
1 parent 8e04f14 commit 16f285b
Showing 1 changed file with 25 additions and 20 deletions.
45 changes: 25 additions & 20 deletions src/dommy/template.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
(ns dommy.template
(:require [clojure.string :as str]))

(defprotocol element
(-elem [this] "return the element representation of this"))

(defn add-class! [node c]
(.setAttribute node "class"
(if-let [cur-c (.getAttribute node "class")]
Expand Down Expand Up @@ -54,14 +57,6 @@
(recur (.substring str next-idx))))))
node))

(defn element? [data]
(or (keyword? data)
(and (coll? data) (keyword? (first data)))
(instance? js/HTMLElement data)))

(defn node? [data]
(or (element? data) (string? data) (number? data) (instance? js/Text data)))

(declare node)

(defn compound-element
Expand All @@ -71,26 +66,36 @@
attrs (when (map? (second data)) (second data))
tail (drop (if attrs 2 1) data)
;; Remove one level of nesting for cases like [:div [[:span][:span]]]
tail (mapcat (fn [group] (if (node? group) [group] group)) tail)]
tail (mapcat (fn [group] (if (satisfies? element group) [group] group)) tail)]
(when attrs
(add-attrs! n attrs))
(doseq [child tail]
(.appendChild n (node child)))
n))

(defn element [data]
(cond
(keyword? data) (base-element data)
(and (coll? data) (keyword? (first data))) (compound-element data)
(instance? js/HTMLElement data) data
:else (throw (str "Don't know how to make element from " (pr-str data)))))
(extend-protocol element
js/HTMLElement
(-elem [this] this)

Keyword

This comment has been minimized.

Copy link
@mpenet

mpenet Jan 18, 2013

Contributor

I dont think this would work, keywords are just strings in cljs at the moment.

an old gist that shows the issue: https://gist.github.com/4104635

edit: oh nevermind, I just noticed you fixed that :)

(-elem [this] (base-element this))

PersistentVector
(-elem [this] (compound-element this))

js/Text
(-elem [this] this)

number
(-elem [this] (.createTextNode js/document (str this)))

string
(-elem [this] (.createTextNode js/document (str this))))

(defn node [data]
(cond
(element? data) (element data)
(or (number? data) (string? data)) (.createTextNode js/document (str data))
(instance? js/Text data) data
:else (throw (str "Don't know how to make node from " (pr-str data)))))
(if (satisfies? element data)
(-elem data)
(throw (str "Don't know how to make node from " (pr-str data)))))

(defn html->nodes [html]
(let [parent (.createElement js/document "div")]
Expand Down

0 comments on commit 16f285b

Please sign in to comment.