         [domina           :only [append! destroy-children! detach! nodes
                                  single-node]]
         [one.sample.model :only [docs]])
+  (:use-macros [crate.macros :only [defpartial]])
   (:require [goog.events               :as event]
             [goog.editor.Field         :as editor-iframe]
             [goog.editor.SeamlessField :as editor-div]

            (str substr "..."))
          trimmed)))))

(defn list-documents [documents]
  (let [element ($ "#sidebar-documents > ol")
        sorted  (reverse (sort-by :ts (vals documents)))]
    (destroy-children! element)
    (doseq [{id :id :as doc} sorted]
      (append! element
               (crate/html [:li {:id (name id)}
                            [:div.excerpt
                             [:span (excerpt (:content doc) 20)]]
                            [:div.document-id
                             [:span
                              [:a.bookmark {:href (str \# (name id))}
                               (name id)]]]])))
    (add-documents-list-listeners)))

(dispatch/react-to #{:documents-changed}

(def CHANGE goog.editor.Field.EventType.DELAYEDCHANGE)
(def CLICK  goog.events.EventType.CLICK)

(defn- strip-html [s]
  (-> s
      (.replace "</div>" "</div> ")
      (.replace "<br>" "\n")
      (.replace "&nbsp;" " ")
      (.replace (js/RegExp. "(<([^>]+)>)" "ig") "")))

(defn- excerpt [s chars]
  (let [stripped (strip-html s)
        trimmed  (.trim stripped)
        length   (.-length trimmed)
