 
 (declare get-transition)
 
-(defn- init-element-meta! [state element-spec tag attrs]
+(defn- init-element-meta! [state element-spec tag ]
   (let [m (meta element-spec)]
     (set! (.-meta state) m)
     (when-let [on-disposed (get m :node-disposed)]
       (set! (.-disposed-callback state) on-disposed)))
-  (set! (.-tag state) tag)
-  (set! (.-attrs state) attrs))
-
-(defn- reset-element-spec! [state spec tag attrs]
+  (set! (.-tag state) tag))
+
+(defn- reset-element-spec! [state spec tag]
   (when-let [on-disposed (.-disposed-callback state)]
     (on-disposed)
     (set! (.-disposed-callback state) nil))
-  (set! (.-element-spec state) spec)
-  (init-element-meta! state spec tag attrs))
-
-(defn- init-element-state! [dom-node element-spec tag attrs]
+  (set! (.-element-spec state) spec))
+
+(defn- init-element-state! [dom-node element-spec tag]
   (let [node-id (str auto-node-id)
         state (ElementState. node-id false element-spec nil)]
     (set! auto-node-id (inc auto-node-id))
     (set-attr! dom-node "data-freactive-id" node-id)
-    (init-element-meta! state element-spec tag attrs)
+    (init-element-meta! state element-spec tag)
     (aset element-state-lookup node-id state)
     (set! (.-freactive-state dom-node) state)
     state))

      (if (keyword-identical? new-tag cur-tag)
        (do
          ;(println "diff hit" (first vdom) (.-id cur-state))
          (let [old-attrs (.-attrs cur-state)
                new-attrs? (second vdom)
                new-attrs (when (map? new-attrs?) new-attrs?)]
            (reset-element-spec! cur-state vdom new-tag new-attrs)
            (replace-attrs! cur-dom-node
                            cur-state
                            old-attrs
                            new-attrs)
            (let [new-children (if new-attrs (nnext vdom) (next vdom))
                  dangling-child (try-diff-subseq cur-dom-node (.-firstChild cur-dom-node) new-children)]

      (let [k (name k)]
        (rebind-attr! node k v node-state)))))

;(defn- replace-attrs!* [node node-state old-attrs new-attrs rebinder]
;  (let [hit #js {}]
;    (doseq [[attr-name new-val] new-attrs]
;      ;(println "rebinding" attr-name new-val)
;      (rebinder node attr-name new-val node-state)
;      (when (get old-attrs attr-name)
;          (aset hit (str attr-name) true)))
;    (doseq [[attr-name _] old-attrs]
;      (let [attr-str (str attr-name)]
;        (when-not (aget hit attr-str)
;          ;(println "unbinding" attr-name)
;          (rebinder node attr-name nil node-state))))))

(defn- replace-attrs!* [node node-state old-attrs new-attrs rebinder]
  (let [new-attrs-js #js {}]
    (doseq [[attr-name new-val] new-attrs]
      (let [attr-str (if-let [attr-ns (namespace attr-name)]
                       (str attr-ns "/" (name attr-name))
                       (name attr-name))]
        (rebinder node attr-name new-val node-state)
        (js-delete old-attrs attr-str)
        (aset new-attrs-js attr-str new-val)))
    (goog.object/forEach old-attrs
      (fn [_ attr-str _]
        (rebinder node (keyword attr-str) nil node-state)))
    new-attrs-js))

;(defn- replace-attrs!* [node node-state old-attrs new-attrs rebinder]
;  (loop [[[k new-val] & new-attrs] (seq new-attrs)
