Reagent
This commit is contained in:
parent
2548e78966
commit
d8fef42c64
8 changed files with 238 additions and 39 deletions
12
deps.edn
12
deps.edn
|
|
@ -3,13 +3,13 @@
|
||||||
:deps
|
:deps
|
||||||
{org.clojure/clojure {:mvn/version "1.10.3"}
|
{org.clojure/clojure {:mvn/version "1.10.3"}
|
||||||
borkdude/sci {:git/url "https://github.com/borkdude/sci"
|
borkdude/sci {:git/url "https://github.com/borkdude/sci"
|
||||||
:sha "4de7c78024bfdb5c52e273be372144d46228939a"}}
|
:sha "4de7c78024bfdb5c52e273be372144d46228939a"}
|
||||||
|
reagent/reagent {:mvn/version "1.0.0"}
|
||||||
|
cljsjs/react {:mvn/version "17.0.2-0"}
|
||||||
|
cljsjs/react-dom {:mvn/version "17.0.2-0"}
|
||||||
|
cljsjs/react-dom-server {:mvn/version "17.0.2-0"}}
|
||||||
|
|
||||||
:aliases
|
:aliases
|
||||||
{:dev
|
{:dev
|
||||||
{:extra-paths ["dev"]
|
{:extra-paths ["dev"]
|
||||||
:extra-deps {thheller/shadow-cljs {:mvn/version "2.12.5"}}}
|
:extra-deps {thheller/shadow-cljs {:mvn/version "2.12.5"}}}}}
|
||||||
|
|
||||||
:test
|
|
||||||
{:extra-paths ["test"]
|
|
||||||
:extra-deps {lambdaisland/kaocha {:mvn/version "1.0.829"}}}}}
|
|
||||||
|
|
|
||||||
119
package-lock.json
generated
Normal file
119
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
{
|
||||||
|
"name": "sci-script-tag",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"react": "17.0.1",
|
||||||
|
"react-dom": "17.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/js-tokens": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||||
|
},
|
||||||
|
"node_modules/loose-envify": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"loose-envify": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react": {
|
||||||
|
"version": "17.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz",
|
||||||
|
"integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-dom": {
|
||||||
|
"version": "17.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz",
|
||||||
|
"integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"scheduler": "^0.20.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "17.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/scheduler": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"js-tokens": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||||
|
},
|
||||||
|
"loose-envify": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||||
|
"requires": {
|
||||||
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"version": "17.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz",
|
||||||
|
"integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"version": "17.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz",
|
||||||
|
"integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"scheduler": "^0.20.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scheduler": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
package.json
Normal file
6
package.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"react": "17.0.1",
|
||||||
|
"react-dom": "17.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,28 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script src="js/main.js" type="application/javascript"></script>
|
<script src="js/sci-script-tag.js" type="application/javascript"></script>
|
||||||
|
<script src="js/sci-script-tag-plugin-reagent.js" type="application/javascript"></script>
|
||||||
|
|
||||||
<script type="application/x-sci">
|
<script type="application/x-sci">
|
||||||
(defn my-alert []
|
(defn my-alert []
|
||||||
(js/alert "alert!"))
|
(js/alert "alert!"))
|
||||||
|
|
||||||
|
(require '[reagent.core :as r]
|
||||||
|
'[reagent.dom :as rdom])
|
||||||
|
|
||||||
|
(def state (r/atom {:clicks 0}))
|
||||||
|
|
||||||
|
(defn my-component []
|
||||||
|
[:div
|
||||||
|
[:p "Clicks: " (:clicks @state)]
|
||||||
|
[:p [:button {:on-click #(swap! state update :clicks inc)}
|
||||||
|
"Click me!"]]])
|
||||||
|
|
||||||
|
(rdom/render [my-component] (.getElementById js/document "app"))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>SCI script tag</h1>
|
<h1>SCI script tag</h1>
|
||||||
|
|
@ -20,16 +35,16 @@
|
||||||
bound to happen. Feedback is welcome on <a href="https://github.com/borkdude/sci-script-tag">Github</a>.</p>
|
bound to happen. Feedback is welcome on <a href="https://github.com/borkdude/sci-script-tag">Github</a>.</p>
|
||||||
<p>
|
<p>
|
||||||
You can get a copy
|
You can get a copy
|
||||||
of <tt>sci_script_tag.js</tt> <a href="https://borkdude.github.io/sci-script-tag/js/sci_script_tag.js">here</a>. If
|
of <tt>sci-script-tag.js</tt> <a href="https://borkdude.github.io/sci-script-tag/js/sci-script-tag.js">here</a>. If
|
||||||
you want a pinned version of <tt>sci_script_tag.js</tt>, your best bet is to
|
you want a pinned version of <tt>sci-script-tag.js</tt>, your best bet is to
|
||||||
download your own copy and host it yourself.
|
download your own copy and host it yourself.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Example usage</h2>
|
<h2><a href="#usage">Usage</a></h2>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<head>
|
<head>
|
||||||
<script src="https://borkdude.github.io/sci-script-tag/js/sci_script_tag.js" type="application/javascript"></script>
|
<script src="https://borkdude.github.io/sci-script-tag/js/sci-script-tag.js" type="application/javascript"></script>
|
||||||
<script type="application/x-sci">
|
<script type="application/x-sci">
|
||||||
(defn my-alert []
|
(defn my-alert []
|
||||||
(js/alert "alert!"))
|
(js/alert "alert!"))
|
||||||
|
|
@ -46,5 +61,30 @@
|
||||||
<button onclick="user.myAlert()">
|
<button onclick="user.myAlert()">
|
||||||
Click me
|
Click me
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<h2><a href="#reagent">Reagent plugin<a/></h2>
|
||||||
|
|
||||||
|
To enable <a href="https://github.com/reagent-project/reagent">reagent</a>,
|
||||||
|
in addition to <tt>sci-script-tag.js</tt>, you need to include <tt>sci-script-tag-plugin-reagent.js</tt>.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<script src="https://borkdude.github.io/sci-script-tag/js/sci-script-tag-plugin-reagent.js" type="application/javascript"></script>
|
||||||
|
<script type="application/x-sci">
|
||||||
|
(require '[reagent.core :as r]
|
||||||
|
'[reagent.dom :as rdom])
|
||||||
|
|
||||||
|
(def state (r/atom {:clicks 0}))
|
||||||
|
|
||||||
|
(defn my-component []
|
||||||
|
[:div
|
||||||
|
[:p "Clicks: " (:clicks @state)]
|
||||||
|
[:p [:button {:on-click #(swap! state update :clicks inc)}
|
||||||
|
"Click me!"]]])
|
||||||
|
|
||||||
|
(rdom/render [my-component] (.getElementById js/document "app"))
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div id="app"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,23 @@
|
||||||
#!/usr/bin/env bb
|
#!/usr/bin/env bb
|
||||||
|
|
||||||
(require '[babashka.fs :as fs]
|
(require '[babashka.fs :as fs]
|
||||||
'[babashka.tasks :refer [shell]]
|
'[babashka.tasks :refer [shell]])
|
||||||
'[clojure.string :as str])
|
|
||||||
|
|
||||||
(fs/copy "resources/public/index.html" "gh-pages"
|
(fs/copy "resources/public/index.html" "gh-pages"
|
||||||
{:replace-existing true})
|
{:replace-existing true})
|
||||||
(shell "clojure -M:dev -m shadow.cljs.devtools.cli release main")
|
(shell "clojure -M:dev -m shadow.cljs.devtools.cli release main")
|
||||||
(def index-file (fs/file "gh-pages" "index.html"))
|
(def index-file (fs/file "gh-pages" "index.html"))
|
||||||
(spit index-file (str/replace (slurp index-file) "main.js" "sci_script_tag.js"))
|
|
||||||
(fs/create-dirs (fs/file "gh-pages" "js"))
|
(def js-source-dir (fs/file "resources" "public" "js"))
|
||||||
(fs/copy (fs/file "resources" "public" "js" "main.js")
|
(def js-target-dir (fs/file "gh-pages" "js"))
|
||||||
(fs/file "gh-pages" "js" "sci_script_tag.js")
|
(fs/create-dirs js-target-dir)
|
||||||
{:replace-existing true})
|
|
||||||
|
(run! (fn [f]
|
||||||
|
(println "Copying" (str f))
|
||||||
|
(fs/copy f
|
||||||
|
js-target-dir
|
||||||
|
{:replace-existing true}))
|
||||||
|
(fs/glob js-source-dir "sci-script-tag*.js"))
|
||||||
|
|
||||||
(def with-gh-pages (partial shell {:dir "gh-pages"}))
|
(def with-gh-pages (partial shell {:dir "gh-pages"}))
|
||||||
(with-gh-pages "git add .")
|
(with-gh-pages "git add .")
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
:builds
|
:builds
|
||||||
{:main
|
{:main
|
||||||
{:target :browser
|
{:target :browser
|
||||||
:modules {:main {:entries [sci.script-tag]}}
|
:modules
|
||||||
|
{:sci-script-tag {:entries [sci.script-tag]}
|
||||||
|
:sci-script-tag-plugin-reagent {:entries [sci.script-tag.plugin-reagent]
|
||||||
|
:depends-on #{:sci-script-tag}}}
|
||||||
:output-dir "resources/public/js"
|
:output-dir "resources/public/js"
|
||||||
:devtools {:repl-pprint true}}}}
|
:devtools {:repl-pprint true}}}}
|
||||||
|
|
|
||||||
|
|
@ -9,35 +9,41 @@
|
||||||
(fn [s]
|
(fn [s]
|
||||||
(str/upper-case (.charAt s 1)))))
|
(str/upper-case (.charAt s 1)))))
|
||||||
|
|
||||||
(defn defn-macro [_ _ fn-name & args]
|
(defn- defn-macro [_ _ fn-name & args]
|
||||||
`(let [ns# (ns-name *ns*)]
|
`(let [ns# (ns-name *ns*)]
|
||||||
(clojure.core/defn ~fn-name ~@args)
|
(clojure.core/defn ~fn-name ~@args)
|
||||||
(sci.script-tag/-export ~fn-name (str ns# "." '~fn-name))))
|
(sci.script-tag/-export ~fn-name (str ns# "." '~fn-name))))
|
||||||
|
|
||||||
(def ctx (sci/init {:namespaces {'sci.script-tag
|
(def ctx (atom (sci/init {:namespaces {'sci.script-tag
|
||||||
{'defn (with-meta defn-macro
|
{'defn (with-meta defn-macro
|
||||||
{:sci/macro true})
|
{:sci/macro true})
|
||||||
'-export (fn [f k]
|
'-export (fn [f k]
|
||||||
(let [parts (str/split k #"\.")]
|
(let [parts (str/split k #"\.")]
|
||||||
(loop [parts parts
|
(loop [parts parts
|
||||||
prev js/window]
|
prev js/window]
|
||||||
(let [fpart (first parts)
|
(let [fpart (first parts)
|
||||||
fpart (kebab->camel fpart)]
|
fpart (kebab->camel fpart)]
|
||||||
(if (= 1 (count parts))
|
(if (= 1 (count parts))
|
||||||
(gobject/set prev fpart f)
|
(gobject/set prev fpart f)
|
||||||
(do (gobject/set prev fpart #js {})
|
(if-let [obj (gobject/get prev fpart)]
|
||||||
(recur (rest parts)
|
(recur (rest parts) obj)
|
||||||
(gobject/get prev fpart))))))
|
(let [obj #js {}]
|
||||||
(gobject/set js/window k f)))}
|
(gobject/set prev fpart obj)
|
||||||
'clojure.core {'println println}}
|
(recur (rest parts)
|
||||||
:classes {'js js/window
|
obj))))))
|
||||||
:allow :all}}))
|
(gobject/set js/window k f)))}
|
||||||
|
'clojure.core {'println println}}
|
||||||
|
:classes {'js js/window
|
||||||
|
:allow :all}})))
|
||||||
|
|
||||||
(defn eval-string [s]
|
(defn eval-string [s]
|
||||||
(sci/eval-string* ctx
|
(sci/eval-string* @ctx
|
||||||
(str "(require '[sci.script-tag :refer :all])"
|
(str "(require '[sci.script-tag :refer :all])"
|
||||||
s)))
|
s)))
|
||||||
|
|
||||||
|
(defn merge-ctx [opts]
|
||||||
|
(swap! ctx sci/merge-opts opts))
|
||||||
|
|
||||||
(js/document.addEventListener
|
(js/document.addEventListener
|
||||||
"DOMContentLoaded"
|
"DOMContentLoaded"
|
||||||
(fn []
|
(fn []
|
||||||
|
|
|
||||||
20
src/sci/script_tag/plugin_reagent.cljs
Normal file
20
src/sci/script_tag/plugin_reagent.cljs
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
(ns sci.script-tag.plugin-reagent
|
||||||
|
(:require [reagent.core :as r]
|
||||||
|
[reagent.dom :as rdom]
|
||||||
|
[sci.core :as sci]
|
||||||
|
[sci.script-tag :as st]))
|
||||||
|
|
||||||
|
(def rns (sci/create-ns 'reagent.core nil))
|
||||||
|
|
||||||
|
(def reagent-namespace
|
||||||
|
{'atom (sci/copy-var r/atom rns)})
|
||||||
|
|
||||||
|
(def rdns (sci/create-ns 'reagent.dom nil))
|
||||||
|
|
||||||
|
(def reagent-dom-namespace
|
||||||
|
{'render (sci/copy-var rdom/render rdns)})
|
||||||
|
|
||||||
|
(println :merging)
|
||||||
|
(st/merge-ctx {:namespaces {'reagent.core reagent-namespace
|
||||||
|
'reagent.dom reagent-dom-namespace}})
|
||||||
|
(println :done-merging)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue