Commit 35b581d2 authored by Bruno Burke's avatar Bruno Burke 🍔
Browse files

switch programming-exercise to codemirror6; fix dependencies in ce-blockly

parent 8a12793d
......@@ -33,3 +33,4 @@ package-lock.json
.lsp/
.shadow-cljs/
/.clj-kondo/.cache
*.~undo-tree~
(defproject wwsoftware/leukipp.components "1.3.11"
(defproject wwsoftware/leukipp.components "1.4.0"
:repositories [["internal" {:url "https://leukipp.fh-muenster.de:9082/releases"
:username "anonymous"}]]
:dependencies [[org.clojure/clojure "1.10.3"]
......
......@@ -4,7 +4,8 @@
[leukipp.components.content-elements.blockly.blocks :as bblock]
[leukipp.components.content-elements.core :as ce-core]
[oops.core :refer [oget]]
[reagent.core :as reagent]))
[reagent.core :as reagent]
["blockly/core" :as Blockly :refer [inject]]))
(defn code-editor [code]
......@@ -120,7 +121,7 @@
(fn [workspace content-element]
[:div
(if-not @prepare?
[:div.center
[:div.center
[:a.button {:on-click #(swap! prepare? not)}
[:span.icon [:i.fas.fa-sliders-h]]
[:span
......@@ -130,13 +131,15 @@
{:state (:workspace-xml @workspace)
:on-change #(do
(when-let [id (oget % "workspaceId")]
(when-let [jsworkspace (js/Blockly.Workspace.getById id)]
(when-let [jsworkspace (.getById (-> Blockly
.-Workspace) id)]
(js/console.debug "Save Workspace Changes")
(reset! temp-workspace
(js/Blockly.Xml.domToText
(js/Blockly.Xml.workspaceToDom
jsworkspace
))))))}]
(let [blockly-xml (-> Blockly
.-Xml)]
(reset! temp-workspace
(.domToText blockly-xml
(.workspaceToDom blockly-xml
jsworkspace)))))))}]
[:div.buttons
[:a.button.is-primary {:on-click #(do
(swap! prepare? not))}
......
......@@ -5,7 +5,12 @@
[leukipp.components.content-elements.blockly.blocks :refer [block-codes] :as bblock]
[leukipp.components.content-elements.core :as ce-core]
[leukipp.components.jshelper :refer [load-script]]
[reagent.core :as reagent]))
[reagent.core :as reagent]
["blockly/core" :as Blockly :refer [inject]]
["blockly/msg/de" :as blocklyDE]
["blockly/blocks"]
["blockly/python" :as blockly-python]
))
(defn blockly-component [element & {:keys [answer on-change status run-code]}]
......@@ -20,58 +25,45 @@
coderesult (reagent/atom nil)
code-runner-pending (reagent/atom false)]
(reagent/create-class
{
:component-name "blockly-content-element"
{:component-name "blockly-content-element"
:component-will-unmount (fn []
(js/console.debug "Dispose Blockly Workspace")
(.dispose @workspace))
:component-did-mount
(fn []
(load-script
"https://unpkg.com/blockly/blockly.js"
(fn []
(load-script
"https://unpkg.com/blockly/msg/de.js"
(fn []
(load-script
"https://unpkg.com/blockly/python.js"
(fn []
(load-script
"https://unpkg.com/blockly/blocks.js"
(fn []
(let [settings (:workspace-settings element)]
(reset! workspace
(js/Blockly.inject blockly-editor-id
(clj->js
(merge
{:toolbox (js/document.getElementById toolbox-id)}
(when (:collapse settings)
{:collapse true})
(when (:trashcan settings)
{:trashcan true})
(when (:sounds settings)
{:sounds true})
(when (:scrollbars settings)
{:scrollbars true})
(when (:grid settings)
{:grid {:spacing 20
:length 1
:colour "#888"
:snap true}})
(when (:zoom settings)
{:zoom {:controls true
:wheel true
:startScale 1
:maxScale 3
:minScale 0.3
:scaleSpeed 1.2}})
))))
(when-let [workspace-xml (get-in element [:workspace :workspace-xml])]
(js/Blockly.Xml.domToWorkspace
(js/Blockly.Xml.textToDom workspace-xml)
@workspace))
(.addChangeListener @workspace #(@update-fn %))
))))))))))
(let [settings (:workspace-settings element)]
(reset! workspace
(Blockly/inject blockly-editor-id
(clj->js
(merge
{:toolbox (js/document.getElementById toolbox-id)}
(when (:collapse settings)
{:collapse true})
(when (:trashcan settings)
{:trashcan true})
(when (:sounds settings)
{:sounds true})
(when (:scrollbars settings)
{:scrollbars true})
(when (:grid settings)
{:grid {:spacing 20
:length 1
:colour "#888"
:snap true}})
(when (:zoom settings)
{:zoom {:controls true
:wheel true
:startScale 1
:maxScale 3
:minScale 0.3
:scaleSpeed 1.2}})))))
(Blockly/setLocale blocklyDE)
(when-let [workspace-xml (get-in element [:workspace :workspace-xml])]
(let [blockly-xml (-> Blockly .-Xml)]
(.domToWorkspace blockly-xml
(.textToDom blockly-xml workspace-xml)
@workspace)))
(.addChangeListener @workspace #(@update-fn %))))
:reagent-render
(fn [element & {:keys [result answer on-change]}]
(let [selected-categories (set (map
......@@ -95,16 +87,12 @@
(= (:category block-data) (:name c))
#_(js/Blockly.Blocks.hasOwnProperty (str b)))]
(let [code (:code block-data)]
code
)
)]
)
code))])
(for [b (:blocks element)]
(let [code (get-in block-codes [(str b) :code])]
code
)
)
)
code)))
(when variables?
[:category {:name "Variables"
:colour "#a55b80"
......@@ -112,16 +100,15 @@
(when functions?
[:category {:name "Functions"
:colour "#995ba5"
:custom "PROCEDURE"}])
]
:custom "PROCEDURE"}])]
[:div {:id blockly-editor-id
:style {:height "480px"
:width "auto"}}]
[:div.columns
[:div.column.is-half
[:button.button {:on-click #(do
(reset! coderesult nil)
(reset! python-code (js/Blockly.Python.workspaceToCode @workspace)))}
(reset! coderesult nil)
(reset! python-code (blockly-python/workspaceToCode @workspace)))}
[:span.icon [:i.fab.fa-python]]
[:span
"Python Code"]]
......@@ -147,11 +134,7 @@
[ui/indeterminate-progress]
(if (:isError @coderesult)
[common/codebox (:stderr @coderesult)]
[common/codebox (:stdout @coderesult)]
))])
])]]
)
)})))
[common/codebox (:stdout @coderesult)]))])])]]))})))
......
......@@ -10,7 +10,31 @@
[reagent.core :as reagent]
[reagent.dom :as rdom]
[bulma-ui.core :as ui]
[clj-helper.vector :as vhelper]))
[clj-helper.vector :as vhelper]
[codemirror :refer [EditorView basicSetup]]
["@codemirror/language" :refer [StreamLanguage]]
["@codemirror/lang-javascript" :refer [javascript]]
["@codemirror/lang-cpp" :refer [cpp]]
["@codemirror/lang-markdown" :refer [markdown]]
["@codemirror/lang-python" :refer [python]]
["@codemirror/legacy-modes/mode/commonlisp" :refer [commonlisp]]
["@codemirror/legacy-modes/mode/r" :refer [r]]
["@codemirror/legacy-modes/mode/clike" :refer [clike]]
["@codemirror/legacy-modes/mode/clojure" :refer [clojure]]))
(defn get-codemirror-mode [language]
(let [language (or language "python")]
(case (name language)
"python2" (python)
"python3" (python)
"common-lisp" (.define StreamLanguage commonlisp)
"clojure" (.define StreamLanguage clojure)
"c" (.define StreamLanguage clike)
"r" (.define StreamLanguage r)
"rmarkdown" (markdown)
"markdown" (markdown)
(python))))
(defn is-correct [result]
(console.log (clj->js result))
......@@ -46,37 +70,50 @@
id (str (gensym) "_code_editor")]
(reagent/create-class
{:display-name "code-editor"
:component-will-unmount (fn [] (.toTextArea @cm-atom))
:component-did-mount
(fn [comp]
(let [dom-node (rdom/dom-node comp)
{:keys [language]} (reagent/props comp)
syntax-language (code-show/get-codemirror-mode language)
{:keys [language code]} (reagent/props comp)
syntax-language (get-codemirror-mode language)
code-editor (js/document.getElementById id)
cm-editor (.fromTextArea
js/CodeMirror dom-node
(clj->js {:mode syntax-language
:readOnly (when (true? read-only)
true ;;; this will allow copy on readonly code-editors
#_"nocursor")
:lineNumbers true}))]
(.on cm-editor "change" #(on-change (.getValue cm-editor)))
(.on cm-editor "copy" (fn [cm e]
(set! (.-codemirrorIgnore e) true)))
(.setOption cm-editor "mode" syntax-language)
(.setValue cm-editor (or code ""))
;(.setSize cm-editor nil 200)
(reset! cm-atom cm-editor)))
update-listener (fn [tr]
(let [new-text (-> tr
.-state
.-doc
.toString)]
(on-change new-text)))
initial-code (or code "")
cm-editor (new EditorView (clj->js {:extensions [basicSetup
(.of (-> EditorView
.-updateListener) update-listener)
(.of (-> EditorView
.-contentAttributes) (clj->js {:contenteditable (if (true? read-only)
false
true ;;; this will allow copy on readonly code-editors
)}))
syntax-language]
:parent code-editor}))]
(.dispatch cm-editor (clj->js {:changes {:from 0
:to (-> cm-editor
.-state
.-doc
.-length)
:insert initial-code}}))
#_(.setOption cm-editor "mode" syntax-language)
#_(.setValue cm-editor (or code ""))
;(.setSize cm-editor nil 200)
(reset! cm-atom cm-editor)
#_(reset! cm-atom cm-editor)))
:component-did-update
(fn [this]
(let [{:keys [language]} (reagent/props this)]
(when @cm-atom
(.setOption @cm-atom "mode" (code-show/get-codemirror-mode language)))))
#_(when @cm-atom
(.setOption @cm-atom "mode" (code-show/get-codemirror-mode language)))))
:reagent-render
(fn [{:keys [code language on-change]}]
[:textarea {:id id
:defaultValue code}])})))
[:div {:id id}]
#_[:textarea {:id id
:defaultValue code}])})))
(defn migrate-answer [exercise answer]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment