Added support for directly nested ReactiveElement's. Enable diffing for the brave and true...

This commit is contained in:
Aaron Craelius 2014-11-26 22:16:06 -05:00
parent 7cfced0678
commit 6dc592f59f

View file

@ -54,6 +54,8 @@
(number? x) (str x) (number? x) (str x)
(satisfies? IDeref x) x
:default (-get-virtual-dom x)) :default (-get-virtual-dom x))
;; nil values treated as empty "placeholder" text nodes ;; nil values treated as empty "placeholder" text nodes
@ -100,12 +102,12 @@
(defn- dispose-node (defn- dispose-node
([dom-node] ([dom-node]
;(println "disposing" dom-node) ;(println "disposing" dom-node)
(let [node-id (get-node-id dom-node) (when-let [node-id (get-node-id dom-node)]
state (aget element-state-lookup node-id)] (when-let [state (aget element-state-lookup node-id)]
(dispose-node node-id state) (dispose-node node-id state)
(when-let [parent-state (.-parent-state state)] (when-let [parent-state (.-parent-state state)]
(when-let [child-states (.-child-states parent-state)] (when-let [child-states (.-child-states parent-state)]
(js-delete child-states node-id))))) (js-delete child-states node-id))))))
([child-key state] ([child-key state]
(when state (when state
(set! (.-disposed state) true) (set! (.-disposed state) true)
@ -511,7 +513,7 @@
(defn- text-node? [dom-node] (defn- text-node? [dom-node]
(identical? (.-nodeType dom-node) 3)) (identical? (.-nodeType dom-node) 3))
(def enable-diffing false) (def enable-diffing true)
(defn- can-diff-element [parent new-elem-spec cur-elem]) (defn- can-diff-element [parent new-elem-spec cur-elem])
@ -596,15 +598,21 @@
;(println "build hit" (first vdom) (first cur-vdom)) ;(println "build hit" (first vdom) (first cur-vdom))
(replace-node-completely parent vdom cur-dom-node top-level))))) (replace-node-completely parent vdom cur-dom-node top-level)))))
(declare bind-child)
(defn- replace-child [parent new-elem-spec cur-dom-node top-level] (defn- replace-child [parent new-elem-spec cur-dom-node top-level]
(let [new-virtual-dom (get-virtual-dom new-elem-spec)] (let [new-virtual-dom (get-virtual-dom new-elem-spec)]
(if (cond
(and (string? new-virtual-dom) (and (string? new-virtual-dom)
(text-node? cur-dom-node)) (text-node? cur-dom-node))
(do (do
(set! (.-textContent cur-dom-node) new-virtual-dom) (set! (.-textContent cur-dom-node) new-virtual-dom)
cur-dom-node) cur-dom-node)
(satisfies? IDeref new-virtual-dom)
(bind-child parent new-virtual-dom nil cur-dom-node)
:default
(if enable-diffing (if enable-diffing
(if top-level (if top-level
(do (do
@ -627,9 +635,11 @@
new-elem)) new-elem))
(defn- append-or-insert-child [parent new-elem before] (defn- append-or-insert-child [parent new-elem before]
(if before (if (satisfies? IDeref new-elem)
(insert-child parent new-elem before) (bind-child parent new-elem before nil)
(append-child parent new-elem))) (if before
(insert-child parent new-elem before)
(append-child parent new-elem))))
;(defn- do-show-element [parent new-elem nil] ;(defn- do-show-element [parent new-elem nil]
; (when new-elem ; (when new-elem
@ -678,7 +688,10 @@
(set! auto-reactive-id (inc auto-reactive-id)) (set! auto-reactive-id (inc auto-reactive-id))
(str "-r." id))) (str "-r." id)))
(deftype ReactiveElement [id parent cur-element dirty updating disposed animate invalidate] (deftype ReactiveElement [id parent ref cur-element dirty updating disposed
animate invalidate]
IElementSpec
(-get-virtual-dom [_] ref)
IRemove IRemove
(-remove! [this] (-remove! [this]
(set! (.-disposed this) true) (set! (.-disposed this) true)
@ -687,10 +700,11 @@
(when-let [parent-state (get-element-state parent)] (when-let [parent-state (get-element-state parent)]
(unregister-from-parent-state parent-state id)))) (unregister-from-parent-state parent-state id))))
(defn- bind-child* [parent child-ref before insert-child* replace-child* remove*] (defn- bind-child* [parent child-ref before cur insert-child* replace-child* remove*]
(if-let [[add-watch* remove-watch*] (r/get-add-remove-watch* child-ref)] (if-let [[add-watch* remove-watch*] (r/get-add-remove-watch* child-ref)]
(let [id (new-reactive-id) (let [id (new-reactive-id)
state (ReactiveElement. id parent nil false false false nil nil) state (ReactiveElement. id parent child-ref nil false false false
nil nil)
ref-meta (meta child-ref) ref-meta (meta child-ref)
@ -700,10 +714,19 @@
(or (non-reactively @child-ref) "")) (or (non-reactively @child-ref) ""))
show-new-elem (fn [new-elem cur] show-new-elem (fn [new-elem cur]
(let [new-node (let [cur
(if (instance? ReactiveElement cur)
(let [cur-elem (.-cur-element cur)]
(set! (.-disposed cur) true)
(set! (.-cur-element cur) nil)
cur-elem)
cur)
new-node
(if cur (if cur
(replace-child* parent new-elem cur true) (replace-child* parent new-elem cur true)
(insert-child* parent new-elem before))] (insert-child* parent new-elem before))]
(set! (.-cur-element state) new-node) (set! (.-cur-element state) new-node)
(set! (.-updating state) false) (set! (.-updating state) false)
(when (.-dirty state) (when (.-dirty state)
@ -713,7 +736,8 @@
animate animate
(fn animate [x] (fn animate [x]
(if (.-disposed state) (if (.-disposed state)
(remove! (.-cur-element state)) (when-let [cur (.-cur-element state)]
(remove! cur))
(do (do
(let [new-elem (get-new-elem) (let [new-elem (get-new-elem)
cur (.-cur-element state)] cur (.-cur-element state)]
@ -764,19 +788,19 @@
:binding-initialized)] :binding-initialized)]
(binding-initialized)) (binding-initialized))
(set! (.-updating state) false) (set! (.-updating state) false)
(show-new-elem (get-new-elem) nil) (show-new-elem (get-new-elem) cur)
state) state)
(mount-element parent @child-ref before))) (mount-element parent @child-ref before)))
(defn bind-child [parent child before] (defn bind-child [parent child before cur]
(bind-child* parent child before append-or-insert-child replace-child remove-dom-node)) (bind-child* parent child before cur append-or-insert-child replace-child remove-dom-node))
;; Building Elements ;; Building Elements
(defn insert-child! [parent child before] (defn insert-child! [parent child before]
(cond (cond
(satisfies? IDeref child) (satisfies? IDeref child)
(bind-child parent child before) (bind-child parent child before nil)
:default :default
(mount-element parent child before))) (mount-element parent child before)))