Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 16 #181

Merged
merged 1 commit into from
Jan 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.org
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
* Changelog
** Unreleased

** 0.8.3

- [[https://github.com/r0man/sablono/pull/181][#181]] Update React to =16.2.0=.

** 0.8.2

- [[https://github.com/r0man/sablono/pull/183][#183]] Allow non strings as :value.
- [[https://github.com/r0man/sablono/pull/180][#180]] Update dependencies.

** 0.8.1

- [[https://github.com/r0man/sablono/pull/174][#174]] Update React to =15.6.1=.
- [[https://github.com/r0man/sablono/pull/167][#167]] Update React to =15.5.0-0= and get rid of =React.createClass=.

** 0.8.0
Expand Down
20 changes: 17 additions & 3 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
provide the dependencies yourself like this:

#+BEGIN_SRC clojure :exports code :results silent
[cljsjs/react "15.4.2-2"]
[cljsjs/react-dom "15.4.2-2"]
[cljsjs/react "16.2.0-3"]
[cljsjs/react-dom "16.2.0-3"]
#+END_SRC

If you want to do server rendering and use the =render= or
=render-static= functions from the =sablono.server= namespace you
need to add the following dependency as well:

#+BEGIN_SRC clojure :exports code :results silent
[cljsjs/react-dom-server "15.4.2-2"]
[cljsjs/react-dom-server "16.2.0-3"]
#+END_SRC

** Usage
Expand Down Expand Up @@ -131,6 +131,20 @@
lein doo phantom none auto
#+END_SRC

*** Why is there a compiler and an interpreter?

The interpreter is executed at *run time*, and it's job is to
evaluate Hiccup forms and produce React elements. The compiler on
the other hand, is executed at *compile time* and can optimize
certain Hiccup forms. It's job is to evaluate Hiccup forms and
produce executable code.

A good introduction to this topic can be found in Peter Seibel's
[[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html][Practical Common Lisp]]:

- [[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html][An HTML Generation Library, the Interpreter]]
- [[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html][An HTML Generation Library, the Compiler]]

** Thanks

This library is based on James Reeves excellent [[https://github.com/weavejester/hiccup][Hiccup]] library.
Expand Down
51 changes: 29 additions & 22 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
:min-lein-version "2.0.0"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0-alpha16"]
[org.omcljs/om "1.0.0-beta1"]]
:dependencies [[org.clojure/clojure "1.9.0"]
[org.omcljs/om "1.0.0-beta2"]]
:npm {:dependencies [[benchmark "1.0.0"]
[react "15.5.4"]
[react-dom "15.5.4"]]}
[react "16.2.0"]
[react-dom "16.2.0"]]}
:profiles {:dev {:dependencies [[criterium "0.4.4"]
[devcards "0.2.4" :exclusions [sablono]]
[doo "0.1.8"]
Expand All @@ -18,17 +18,18 @@
[org.clojure/test.check "0.9.0"]
[perforate-x "0.1.0"]
[reagent "0.7.0"]
[rum "0.10.8" :exclusions [sablono]]]
[rum "0.11.0" :exclusions [sablono]]]
:plugins [[lein-cljsbuild "1.1.7"]
[lein-doo "0.1.8"]
[lein-figwheel "0.5.14"]
[lein-npm "0.6.2"]
[perforate "0.3.4"]]
:resource-paths ["test-resources" "target"]}
:provided {:dependencies [[cljsjs/react "15.6.1-0"]
[cljsjs/react-dom "15.6.1-0"]
[cljsjs/react-dom-server "15.6.1-0"]
[org.clojure/clojurescript "1.9.562"]]}
:provided {:dependencies [[cljsjs/create-react-class "15.6.2-0"]
[cljsjs/react "16.2.0-3"]
[cljsjs/react-dom "16.2.0-3"]
[cljsjs/react-dom-server "16.2.0-3"]
[org.clojure/clojurescript "1.9.946"]]}
:repl {:dependencies [[com.cemerick/piggieback "0.2.2"]]
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}}
:aliases {"ci" ["do"
Expand All @@ -44,18 +45,7 @@
"deploy" ["do" "clean," "deploy" "clojars"]}
:clean-targets ^{:protect false} [:target-path]
:cljsbuild {:builds
[{:id "benchmark"
:compiler
{:asset-path "target/benchmark/out"
:main sablono.benchmark
:output-dir "target/benchmark/out"
:output-to "target/benchmark/sablono.js"
:optimizations :none
:target :nodejs
:pretty-print true
:verbose false}
:source-paths ["src" "benchmark"]}
{:id "devcards"
[{:id "devcards"
:compiler
{:asset-path "devcards"
:main sablono.test.runner
Expand All @@ -67,6 +57,17 @@
:verbose false}
:figwheel {:devcards true}
:source-paths ["src" "test"]}
{:id "benchmark"
:compiler
{:asset-path "target/benchmark/out"
:main sablono.benchmark
:output-dir "target/benchmark/out"
:output-to "target/benchmark/sablono.js"
:optimizations :none
:target :nodejs
:pretty-print true
:verbose false}
:source-paths ["src" "benchmark"]}
{:id "nodejs"
:compiler
{:asset-path "target/nodejs/out"
Expand Down Expand Up @@ -95,8 +96,14 @@
{:asset-path "target/advanced/out"
:main sablono.test.runner
:output-dir "target/advanced/out"
:output-to "target/advanced/sablono.js"
:optimizations :advanced
:output-to "target/advanced/sablono.js"
;; Polyfills needed for PhantomJS and Nashorn
:preamble ["polyfills/symbol.js"
"polyfills/symbol.iterator.js"
"polyfills/map.js"
"polyfills/set.js"
"polyfills/number.isnan.js"]
:pretty-print true
:verbose false}
:source-paths ["src" "test"]}
Expand Down
36 changes: 28 additions & 8 deletions src/sablono/compiler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
(defprotocol IJSValue
(to-js [x]))

(defn fragment?
"Returns true if `tag` is the fragment tag \"*\", otherwise false."
[tag]
(= (name tag) "*"))

(defmulti compile-attr (fn [name value] name))

(defmethod compile-attr :class [_ value]
Expand Down Expand Up @@ -47,6 +52,13 @@
(html-to-dom-attrs)
(to-js)))

(defn- compile-constructor
"Return the symbol of a fn that build a React element. "
[type]
(if (contains? #{:input :select :textarea} (keyword type))
'sablono.interpreter/create-element
'js/React.createElement))

(defn compile-merge-attrs [attrs-1 attrs-2]
(let [empty-attrs? #(or (nil? %1) (and (map? %1) (empty? %1)))]
(cond
Expand All @@ -63,12 +75,20 @@
:else `(sablono.interpreter/attributes
(sablono.normalize/merge-with-class ~attrs-1 ~attrs-2)))))

(defn- compile-tag
"Replace fragment syntax (`:*`) by 'js/React.Fragment, otherwise the
name of the tag"
[tag]
(if (fragment? tag)
'js/React.Fragment
(name tag)))

(defn compile-react-element
"Render an element vector as a HTML element."
[element]
(let [[tag attrs content] (normalize/element element)]
`(~(react-fn tag)
~(name tag)
`(~(compile-constructor tag)
~(compile-tag tag)
~(compile-attrs attrs)
~@(if content (compile-react content)))))

Expand Down Expand Up @@ -204,8 +224,8 @@
(defmethod compile-element ::literal-tag-and-attributes
[[tag attrs & content]]
(let [[tag attrs _] (normalize/element [tag attrs])]
`(~(react-fn tag)
~(name tag)
`(~(compile-constructor tag)
~(compile-tag tag)
~(compile-attrs attrs)
~@(map compile-html content))))

Expand All @@ -222,8 +242,8 @@
(let [[tag tag-attrs _] (normalize/element [tag])
attrs-sym (gensym "attrs")]
`(let [~attrs-sym ~attrs]
(apply ~(react-fn tag)
~(name tag)
(apply ~(compile-constructor tag)
~(compile-tag tag)
~(compile-merge-attrs tag-attrs attrs-sym)
~(when-not (empty? content)
(mapv compile-html content))))))
Expand All @@ -233,8 +253,8 @@
(let [[tag tag-attrs _] (normalize/element [tag])
attrs-sym (gensym "attrs")]
`(let [~attrs-sym ~attrs]
(apply ~(react-fn tag)
~(name tag)
(apply ~(compile-constructor tag)
~(compile-tag tag)
(if (map? ~attrs-sym)
~(compile-merge-attrs tag-attrs attrs-sym)
~(compile-attrs tag-attrs))
Expand Down
7 changes: 0 additions & 7 deletions src/sablono/util.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,6 @@
(remove nil?)))
(str/join " ")))

(defn react-fn
"Return the symbol of a fn that build a React element. "
[type]
(if (contains? #{:input :select :textarea} (keyword type))
'sablono.interpreter/create-element
'js/React.createElement))

#?(:cljs
(extend-protocol ToString
cljs.core.Keyword
Expand Down
Loading