Skip to content

Instantly share code, notes, and snippets.

@swannodette
Created September 11, 2011 20:01

Revisions

  1. swannodette created this gist Sep 11, 2011.
    122 changes: 122 additions & 0 deletions gistfile1.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,122 @@
    ;; Copyright (c) Rich Hickey. All rights reserved.
    ;; The use and distribution terms for this software are covered by the
    ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
    ;; which can be found in the file epl-v10.html at the root of this distribution.
    ;; By using this software in any fashion, you are agreeing to be bound by
    ;; the terms of this license.
    ;; You must not remove this notice, or any other, from this software.

    (ns repl.test
    (:require [clojure.browser.repl :as repl]
    [clojure.string :as s]
    [goog.dom :as dom]
    [goog.events :as events]
    [goog.fx.dom :as fx]))

    (repl/connect "http://localhost:9000/repl")

    (def foo (atom "null"))

    (defn add-event [el e cb]
    (events/listen el (name e) cb))

    (defn fadein [el]
    (let [anim (fx/Fade. el 0 1 500)]
    (. anim (play))))

    (defn capitalize [s]
    (let [c (aget s 0)]
    (str (. c (toUpperCase)) (. s (substring 1 (.length s))))))

    (defn camelcase [s]
    (let [[f & r] (. (name s) (split "-"))]
    (apply str f (map #(capitalize %) r))))

    (defmulti parse-style (fn [p v] p))

    (defmethod parse-style :width [_ v] (str v "px"))
    (defmethod parse-style :height [_ v] (str v "px"))
    (defmethod parse-style :top [_ v] (str v "px"))
    (defmethod parse-style :left [_ v] (str v "px"))
    (defmethod parse-style :font-size [_ v] (str v "px"))
    (defmethod parse-style :padding [_ v] (->> v (map #(str % "px")) (s/join " ")))
    (defmethod parse-style :default [_ v] v)

    (defn array-like->seq [ar]
    (let [->seq (fn ->seq* [ar n]
    (if (= (.length ar) n)
    nil
    (lazy-seq
    (cons (aget ar n)
    (->seq* ar (inc n))))))]
    (->seq ar 0)))

    (extend-type js/CSSStyleDeclaration
    ISeq
    (first [this]
    (first (seq this)))
    (rest [this]
    (rest (seq this)))
    ISeqable
    (-seq [this] (array-like->seq this)))

    (extend-type js/NodeList
    ISeq
    (first [this]
    (first (seq this)))
    (rest [this]
    (rest (seq this)))
    ISeqable
    (-seq [this] (array-like->seq this)))

    (defn get-styles [el]
    (into {} (for [p (.style el)]
    [(keyword p) (aget (.style el) p)])))

    (defmulti get-style (fn [el p] p))

    (defmethod get-style :padding
    [el p] (let [s (.style el)]
    (into {} (map #(vector % (aget s (name %)))
    [:padding-top :padding-right :padding-bottom :padding-left]))))

    (defmethod get-style :default
    [el p] (aget el p))

    (defn set-styles! [el styles]
    (doseq [[k v] styles]
    (aset (.style el) (camelcase k) (parse-style k v))))

    (defn init []
    (let [div (dom/createDom "div" (.strobj {"id" "foo"}))
    text (dom/createTextNode "Hello, world!")
    body (aget (dom/getElementsByTagNameAndClass "body") 0)]
    (dom/appendChild div text)
    (dom/appendChild body div)
    (add-event div :click
    (fn [e]
    (. js/console (log "Hello!"))))
    (reset! foo div)))

    (init)

    (comment
    ;; hmm we have to eval the ns form first before we can just eval the following
    (fadein @foo)

    (set-styles! @foo {:color "white"
    :background-color "blue"
    :font-family "serif"
    :width 500
    :height 300})

    (set-styles! @foo {:display "block"
    :padding [10 10]
    :font-size 20})

    (:background-color (get-styles @foo))

    (get-styles @foo)

    (get-style @foo :padding)
    )