diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-10-27 19:22:00 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-10-27 19:22:00 +0000 |
| commit | 28653c9ae46b2b3e42c2c75879589138c731f37b (patch) | |
| tree | 640251211409bcfada73438f3345c5b03dc7e0e0 | |
| parent | move converts into plugins (diff) | |
| download | mmm-28653c9ae46b2b3e42c2c75879589138c731f37b.tar.gz mmm-28653c9ae46b2b3e42c2c75879589138c731f37b.zip | |
facet editing with CodeMirror!
| -rw-r--r-- | build/server.moon | 5 | ||||
| -rw-r--r-- | mmm/mmmfs/browser.moon | 39 | ||||
| -rw-r--r-- | mmm/mmmfs/fileder.moon | 4 | ||||
| -rw-r--r-- | mmm/mmmfs/plugins/code.moon | 48 | ||||
| -rw-r--r-- | mmm/mmmfs/plugins/init.moon | 18 | ||||
| -rw-r--r-- | scss/_browser.scss | 2 | ||||
| -rw-r--r-- | scss/_footer.scss | 1 | ||||
| -rw-r--r-- | scss/codemirror.scss | 72 | ||||
| -rw-r--r-- | scss/main.scss | 1 |
9 files changed, 160 insertions, 30 deletions
diff --git a/build/server.moon b/build/server.moon index 33853c9..906f89a 100644 --- a/build/server.moon +++ b/build/server.moon @@ -64,6 +64,11 @@ class Server <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.6/svg.min.js"></script> <script type="text/javascript" src="//unpkg.com/mermaid@8.4.0/dist/mermaid.min.js"></script> <script type="text/javascript" src="//unpkg.com/marked@0.7.0/marked.min.js"></script> + <link rel="stylesheet" type="text/css" href="//unpkg.com/codemirror@5.49.2/lib/codemirror.css" /> + <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/lib/codemirror.js"></script> + <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/mode/lua/lua.js"></script> + <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/mode/markdown/markdown.js"></script> + <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/addon/display/autorefresh.js"></script> <script type="text/javascript" src="/static/fengari-web/:text/javascript"></script> <script type="text/lua" src="/static/mmm/:text/lua"></script> <script type="text/lua">require 'mmm'; require 'mmm.mmmfs'</script> diff --git a/mmm/mmmfs/browser.moon b/mmm/mmmfs/browser.moon index 35925d3..b63010b 100644 --- a/mmm/mmmfs/browser.moon +++ b/mmm/mmmfs/browser.moon @@ -1,9 +1,9 @@ require = relative ..., 1 import Key from require '.fileder' -import converts from require '.plugins' +import converts, editors from require '.plugins' import get_conversions, apply_conversions from require '.conversion' import ReactiveVar, get_or_create, text, elements, tohtml from require 'mmm.component' -import pre, div, nav, span, button, a, code, select, option from elements +import pre, div, nav, span, button, a, code, option from elements import languages from require 'mmm.highlighting' keep = (var) -> @@ -12,25 +12,24 @@ keep = (var) -> last = val or last last +combine = (...) -> + res = {} + lists = {...} + for list in *lists + for val in *list + table.insert res, val + + res + casts = { { - inp: 'text/.*', - out: 'mmm/dom', - cost: 0 - transform: (val) => - lang = @from\match 'text/(.*)' - languages[lang] val - } - { inp: 'URL.*' out: 'mmm/dom' cost: 0 transform: (href) => span a (code href), :href } } - -for convert in *converts - table.insert casts, convert +casts = combine casts, converts, editors export BROWSER class Browser @@ -128,7 +127,7 @@ class Browser current = @facet\get! current = current and current.name - with select :onchange, disabled: not fileder, value: @facet\map (f) -> f and f.name + with elements.select :onchange, disabled: not fileder, value: @facet\map (f) -> f and f.name has_main = fileder and fileder\has_facet '' \append option '(main)', value: '', disabled: not has_main, selected: current == '' if fileder @@ -146,11 +145,11 @@ class Browser -- append or patch #browser-content main\append with get_or_create 'div', 'browser-content', class: 'content' - content = ReactiveVar if rehydrate then .node.lastChild else @get_content @facet\get! - \append keep content + @content = ReactiveVar if rehydrate then .node.lastChild else @get_content @facet\get! + \append keep @content if MODE == 'CLIENT' @facet\subscribe (p) -> - window\setTimeout (-> content\set @get_content p), 150 + window\setTimeout (-> @refresh p), 150 if rehydrate -- force one rerender to set onclick handlers etc @@ -166,6 +165,10 @@ class Browser err_and_trace = (msg) -> debug.traceback msg, 2 default_convert = (key) => @get key.name, 'mmm/dom' + -- rerender main content + refresh: (facet=@facet\get!) => + @content\set @get_content facet + -- render #browser-content get_content: (prop, err=@error, convert=default_convert) => clear_error = -> @@ -218,7 +221,7 @@ class Browser { :name } = @facet\get! @inspect_prop\set Key e.target.value - with select :onchange + with elements.select :onchange \append option '(none)', value: '', disabled: true, selected: not value if fileder for value in pairs fileder.facet_keys diff --git a/mmm/mmmfs/fileder.moon b/mmm/mmmfs/fileder.moon index cdfc649..f545bd8 100644 --- a/mmm/mmmfs/fileder.moon +++ b/mmm/mmmfs/fileder.moon @@ -134,8 +134,8 @@ class Fileder rawset t, k, v - v = k unless v == nil - @facet_keys[k] = v + if not v + @facet_keys[k] = nil } -- this fails with JS objects from JSON.parse diff --git a/mmm/mmmfs/plugins/code.moon b/mmm/mmmfs/plugins/code.moon index ec22f71..3024c99 100644 --- a/mmm/mmmfs/plugins/code.moon +++ b/mmm/mmmfs/plugins/code.moon @@ -1,6 +1,42 @@ -import pre from require 'mmm.dom' +import div from require 'mmm.dom' import languages from require 'mmm.highlighting' +class Editor + o = do + mkobj = window\eval "(function () { return {}; })" + (tbl) -> + with obj = mkobj! + for k,v in pairs(tbl) + obj[k] = v + + new: (value, mode, @fileder, @key) => + @node = div class: 'editor' + @cm = window\CodeMirror @node, o { + :value + :mode + lineNumber: true + lineWrapping: true + autoRefresh: true + theme: 'hybrid' + } + + @cm\on 'changes', (_, mirr) -> + window\clearTimeout @timeout if @timeout + @timeout = window\setTimeout (-> @change!), 300 + + change: => + @timeout = nil + doc = @cm\getDoc! + if @lastState and doc\isClean @lastState + -- no changes since last event + return + + @lastState = doc\changeGeneration true + value = doc\getValue! + + @fileder.facets[@key] = value + BROWSER\refresh! + -- syntax-highlighted code { converts: { @@ -13,4 +49,14 @@ import languages from require 'mmm.highlighting' pre languages[lang] val } } + editors: if MODE == 'CLIENT' then { + { + inp: 'text/([^ ]*).*' + out: 'mmm/dom' + cost: 0 + transform: (value, fileder, key) => + mode = @from\match @convert.inp + Editor value, mode, fileder, key + } + } } diff --git a/mmm/mmmfs/plugins/init.moon b/mmm/mmmfs/plugins/init.moon index af4a2aa..12fb061 100644 --- a/mmm/mmmfs/plugins/init.moon +++ b/mmm/mmmfs/plugins/init.moon @@ -4,12 +4,6 @@ import find_fileder, link_to, embed from (require 'mmm.mmmfs.util') require 'mmm import render from require '.layout' import tohtml from require 'mmm.component' -keep = (var) -> - last = var\get! - var\map (val) -> - last = val or last - last - -- fix JS null values js_fix = if MODE == 'CLIENT' (arg) -> @@ -24,13 +18,14 @@ loadwith = (_load) -> (val, fileder, key) => func = assert _load val, "#{fileder}##{key}" func! --- list of converts +-- list of converts, editors -- converts each have -- * inp - input type. can capture subtypes using `(.+)` -- * out - output type. can substitute subtypes from inp with %1, %2 etc. -- * cost - conversion cost -- * transform - function (val: inp, fileder) => val: out -- @convert, @from, @to contain the convert and the concrete types +editors = {} converts = { { inp: 'fn -> (.+)', @@ -256,6 +251,10 @@ add_converts = (module) -> for convert in *plugin.converts table.insert converts, convert + if plugin.editors + for editor in *plugin.editors + table.insert editors, editor + add_converts 'code' add_converts 'markdown' add_converts 'mermaid' @@ -289,4 +288,7 @@ else f! } -:converts +{ + :converts + :editors +} diff --git a/scss/_browser.scss b/scss/_browser.scss index b9910e8..b843916 100644 --- a/scss/_browser.scss +++ b/scss/_browser.scss @@ -15,7 +15,7 @@ &.inspector { top: 0; position: sticky; - max-height: 100vh; + max-height: calc(100vh - 3rem); color: #c5c8c6; @include left-border; diff --git a/scss/_footer.scss b/scss/_footer.scss index 727ebda..4f1c8bd 100644 --- a/scss/_footer.scss +++ b/scss/_footer.scss @@ -1,6 +1,7 @@ footer { display: flex; padding: 1rem 2rem; + height: 1rem; position: sticky; bottom: 0; diff --git a/scss/codemirror.scss b/scss/codemirror.scss new file mode 100644 index 0000000..1967f8c --- /dev/null +++ b/scss/codemirror.scss @@ -0,0 +1,72 @@ +/* + vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid) +*/ + +/*background color*/ +.CodeMirror.cm-s-hybrid { + color: #c5c8c6; + background: #1d1f21; + + height: auto; + + /*selection color*/ + .CodeMirror-selected, + .CodeMirror-line::selection, + .CodeMirror-line > span::selection, + .CodeMirror-line > span > span::selection, { + background: #373b41; + } + + /*foreground color*/ + .CodeMirror-cursor { + border-color: #c5c8c6; + } + + /*color: fg_yellow*/ + .cm-keyword { + color: #f0c674; + } + + /*color: fg_comment*/ + .cm-comment, + .cm-meta { + color: #707880; + } + + /*color: fg_red*/ + .cm-number, + .cm-atom { + color: #cc6666 + } + + /*color: fg_green*/ + .cm-string, + .cm-string-2, + .cm-operator { + color: #b5bd68; + } + + /*color: fg_purple*/ + .cm-attribute, + .cm-propery { + color: #b294bb; + } + + /*color: fg_blue*/ + .cm-tag, + .cm-qualifier { + color: #81a2be; + } + + /*color: fg_aqua*/ + .cm-link, + .cm-header, + .cm-hr { + color: #8abeb7; + } + + /*color: fg_orange*/ + .cm-builtin, { + color: #de935f; + } +} diff --git a/scss/main.scss b/scss/main.scss index c1e9d38..08ce942 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -1,6 +1,7 @@ @import 'defs'; @import 'reset'; @import 'hljs'; +@import 'codemirror'; @import 'header'; @import 'footer'; @import 'browser'; |
