Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into clear-cache
Browse files Browse the repository at this point in the history
  • Loading branch information
grzm committed Nov 16, 2016
2 parents 3730085 + f9dc813 commit 5e1af73
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 117 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojurescript</artifactId>
<version>1.9.229</version>
<version>1.9.293</version>
<classifier>aot</classifier>
<scope>provided</scope>
<exclusions>
Expand Down Expand Up @@ -101,7 +101,7 @@
<dependency>
<groupId>com.cognitect</groupId>
<artifactId>transit-clj</artifactId>
<version>0.8.288</version>
<version>0.8.290</version>
</dependency>
<dependency>
<groupId>com.cognitect</groupId>
Expand Down
8 changes: 4 additions & 4 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject org.omcljs/om "1.0.0-alpha45"
(defproject org.omcljs/om "1.0.0-alpha48-SNAPSHOT"
:description "ClojureScript interface to Facebook's React"
:url "http://github.com/swannodette/om"
:license {:name "Eclipse"
Expand All @@ -11,13 +11,13 @@
:source-paths ["src/main" "src/devcards" "src/test"]

:dependencies [[org.clojure/clojure "1.9.0-alpha10" :scope "provided"]
[org.clojure/clojurescript "1.9.227" :scope "provided" :classifier "aot"
[org.clojure/clojurescript "1.9.293" :scope "provided" :classifier "aot"
:exclusions [org.clojure/clojure
org.clojure/data.json]]
[org.clojure/data.json "0.2.6" :scope "provided" :classifier "aot"]
[cljsjs/react "15.3.1-0"]
[cljsjs/react-dom "15.3.1-0"]
[com.cognitect/transit-clj "0.8.288"]
[com.cognitect/transit-clj "0.8.290"]
[com.cognitect/transit-cljs "0.8.239"]

[org.clojure/core.async "0.2.385" :scope "test"
Expand Down Expand Up @@ -63,7 +63,7 @@
:source-paths ["src" "examples/state_bug/src"]
:compiler {
:main examples.state-bug.core
:asset-path "out"
:asset-path "out"
:output-to "examples/state_bug/main.js"
:output-dir "examples/state_bug/out"
:source-map true
Expand Down
101 changes: 101 additions & 0 deletions src/devcards/om/devcards/bugs.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,107 @@
(fn [_ node]
(om/add-root! OM-738-reconciler OM-738-Root node))))

;; =============================================================================
;; OM-779

(defui ^:once PetListItem
static om/Ident
(ident [this {:keys [db/id]}]
[:pet/by-id id])
static om/IQuery
(query [this]
[:db/id :pet/name])
Object
(render [this]
(dom/li #js {:onClick #((om/get-computed (om/props this) :on-click) this)}
(:pet/name (om/props this)))))

(def pet-list-item (om/factory PetListItem))

(defui ^:once PetDetails
static om/Ident
(ident [this {:keys [db/id]}]
[:pet/by-id id])
static om/IQuery
(query [this]
[:db/id :pet/name :pet/favorite-toy])
Object
(render [this]
(dom/div nil
(dom/h1 nil (:pet/name (om/props this)))
(dom/p nil (str "Favorite toy: " (:pet/favorite-toy (om/props this)))))))

(def pet-details (om/factory PetDetails))

(defui ^:once PetsPage
static om/IQueryParams
(params [this]
{:selected-pet [:pet/by-id 0]})
static om/IQuery
(query [this]
[{[:app/current-user '_] [{:user/pets (om/get-query PetListItem)}]}
{'?selected-pet (om/get-query PetDetails)}])
Object
(render [this]
(js/console.debug (pr-str (om/props this)))
(let [orgs (get-in (om/props this) [:app/current-user :user/pets])
selected-pet-ident (:selected-pet (om/get-params this))
selected-pet (get (om/props this) selected-pet-ident)]
(dom/div nil
(dom/div #js {:style {:display "flex"}}
(dom/div #js {:style {:width "300px"}}
(dom/ul nil
(for [org orgs]
(pet-list-item
(om/computed org
{:on-click
#(om/set-query! this
{:params
{:selected-pet (om/get-ident %)}})})))))
(dom/div nil
(when selected-pet
(pet-details selected-pet))))))))

(def pets-page (om/factory PetsPage))

(defui ^:once OM-779-Root
static om/IQuery
(query [this]
[{::route-data (om/get-query PetsPage)}])
Object
(render [this]
(pets-page (::route-data (om/props this)))))

(def om-779-state
(atom {:app/current-user
{:user/pets [[:pet/by-id 0]
[:pet/by-id 1]]}
:pet/by-id {0 {:db/id 0
:pet/name "Alfred"
:pet/favorite-toy "Stuffed Bear"}
1 {:db/id 1
:pet/name "Jasmine"
:pet/favorite-toy "Squeeky Toy"}}}))

(def om-779-reconciler
(om/reconciler
{:state om-779-state
:parser (om/parser {:read (fn [{:keys [state query] :as env} key _]
(let [st @state]
{:value (om/db->tree query st st)}))})}))

(defcard test-query-setting
(dom-node
(fn [_ node]
(om/add-root! om-779-reconciler OM-779-Root node))))

(defcard om-799-card
(dom/svg #js {:viewBox "0 0 400 100"}
(dom/rect #js {:id "rectangle" :x "100" :y "20"
:width "50" :height "50" :fill "#29e"})
(dom/create-element "use" #js {:xlinkHref "#rectangle"
:x "150"})))

(comment

(require '[cljs.pprint :as pprint])
Expand Down
103 changes: 62 additions & 41 deletions src/main/om/dom.cljc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns om.dom
(:refer-clojure :exclude [map meta time use])
(:refer-clojure :exclude [map meta time])
#?(:clj
(:require [clojure.string :as str]
[om.next.protocols :as p]
Expand Down Expand Up @@ -134,8 +134,7 @@
polygon
radialGradient
stop
tspan
use])
tspan])

(defn ^:private gen-react-dom-inline-fn [tag]
`(defmacro ~tag [opts# & children#]
Expand Down Expand Up @@ -306,6 +305,36 @@
(doseq [s rest]
(.append sb s)))))

#?(:clj
(defn escape-html ^String [^String s]
(let [len (count s)]
(loop [^StringBuilder sb nil
i (int 0)]
(if (< i len)
(let [char (.charAt s i)
repl (case char
\& "&amp;"
\< "&lt;"
\> "&gt;"
\" "&quot;"
\' "&#x27;"
nil)]
(if (nil? repl)
(if (nil? sb)
(recur nil (inc i))
(recur (doto sb
(.append char))
(inc i)))
(if (nil? sb)
(recur (doto (StringBuilder.)
(.append s 0 i)
(.append repl))
(inc i))
(recur (doto sb
(.append repl))
(inc i)))))
(if (nil? sb) s (str sb)))))))

#?(:clj
(defrecord Element [tag attrs react-key children]
p/IReactDOMElement
Expand All @@ -320,14 +349,14 @@
p/IReactDOMElement
(-render-to-string [this react-id sb]
(assert (string? s))
(append! sb s))))
(append! sb (escape-html s)))))

#?(:clj
(defrecord ReactText [text]
p/IReactDOMElement
(-render-to-string [this react-id sb]
(assert (string? text))
(append! sb "<!-- react-text: " @react-id " -->" text "<!-- /react-text -->")
(append! sb "<!-- react-text: " @react-id " -->" (escape-html text) "<!-- /react-text -->")
(vswap! react-id inc))))

#?(:clj
Expand Down Expand Up @@ -425,36 +454,6 @@
(contains? colon-between-attrs k) (camel->colon-between k)
:else k)))

#?(:clj
(defn escape-html ^String [^String s]
(let [len (count s)]
(loop [^StringBuilder sb nil
i (int 0)]
(if (< i len)
(let [char (.charAt s i)
repl (case char
\& "&amp;"
\< "&lt;"
\> "&gt;"
\" "&quot;"
\' "&#x27;"
nil)]
(if (nil? repl)
(if (nil? sb)
(recur nil (inc i))
(recur (doto sb
(.append char))
(inc i)))
(if (nil? sb)
(recur (doto (StringBuilder.)
(.append s 0 i)
(.append repl))
(inc i))
(recur (doto sb
(.append repl))
(inc i)))))
(if (nil? sb) s (str sb)))))))

#?(:clj
(defn render-xml-attribute! [sb name value]
(let [name (coerce-attr-key (clojure.core/name name))]
Expand Down Expand Up @@ -489,12 +488,13 @@
(not value))
nil

(= key :style)
(identical? key :style)
(render-styles! sb value)

;; TODO: not sure if we want to limit values to strings/numbers - António
(and (or (contains? supported-attrs (name key))
(.startsWith (name key) "data-"))
(or (true? value) (string? value) (number? value)))
(.startsWith (name key) "data-"))
(or (true? value) (string? value) (number? value)))
(if (true? value)
(append! sb " " (coerce-attr-key (name key)))
(render-xml-attribute! sb key value))
Expand Down Expand Up @@ -524,13 +524,19 @@
#{"area" "base" "br" "col" "command" "embed" "hr" "img" "input" "keygen" "link"
"meta" "param" "source" "track" "wbr"}))

#?(:clj
(defn render-unescaped-html! [sb m]
(if-not (contains? m :__html)
(throw (IllegalArgumentException. "`props.dangerouslySetInnerHTML` must be in the form `{:__html ...}`")))
(when-let [html (:__html m)]
(append! sb html))))

#?(:clj
(defn container-tag?
"Returns true if the tag has content or is not a void tag. In non-HTML modes,
all contentless tags are assumed to be void tags."
[tag content]
(or content
(and (not (void-tags tag))))))
(or content (and (not (void-tags tag))))))

#?(:clj
(defn render-element!
Expand All @@ -546,7 +552,9 @@
(if (container-tag? tag (seq children))
(do
(append! sb ">")
(run! #(p/-render-to-string % react-id sb) children)
(if-let [html-map (:dangerouslySetInnerHTML attrs)]
(render-unescaped-html! sb html-map)
(run! #(p/-render-to-string % react-id sb) children))
(append! sb "</" tag ">"))
(append! sb "/>"))))

Expand Down Expand Up @@ -601,3 +609,16 @@
([component name]
{:pre [(satisfies? p/IReactComponent component)]}
(some-> @(p/-refs component) (get name) p/-render))))

#?(:clj
(defn create-element
"Create a DOM element for which there exists no corresponding function.
Useful to create DOM elements not included in React.DOM. Equivalent
to calling `js/React.createElement`"
([tag]
(create-element tag nil))
([tag opts & children]
(element {:tag tag
:attrs (dissoc opts :ref :key)
:react-key (:key opts)
:children children}))))
9 changes: 9 additions & 0 deletions src/main/om/dom.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,12 @@
(js/ReactDOM.findDOMNode component))
([component name]
(some-> (.-refs component) (gobj/get name) (js/ReactDOM.findDOMNode))))

(defn create-element
"Create a DOM element for which there exists no corresponding function.
Useful to create DOM elements not included in React.DOM. Equivalent
to calling `js/React.createElement`"
([tag]
(create-element tag nil))
([tag opts & children]
(js/React.createElement tag opts children)))
Loading

0 comments on commit 5e1af73

Please sign in to comment.