aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-10-29 11:52:56 +0000
committers-ol <s-ol@users.noreply.github.com>2019-10-29 11:52:56 +0000
commit4b8d9be10e4517114c0c216fa24aaaa310503d4a (patch)
tree27d01bc5f352ca46e4030071e84ccca0b53bd4ad
parentfix syntax highlighting in markdown (diff)
downloadmmm-4b8d9be10e4517114c0c216fa24aaaa310503d4a.tar.gz
mmm-4b8d9be10e4517114c0c216fa24aaaa310503d4a.zip
save edited changes
-rw-r--r--build/server.moon86
-rw-r--r--mmm/mmmfs/fileder.moon15
-rw-r--r--mmm/mmmfs/layout.moon12
-rw-r--r--mmm/mmmfs/plugins/code.moon41
-rw-r--r--mmm/mmmfs/stores/init.moon15
-rw-r--r--mmm/mmmfs/stores/web.moon28
-rw-r--r--scss/codemirror.scss1
7 files changed, 138 insertions, 60 deletions
diff --git a/build/server.moon b/build/server.moon
index 906f89a..68cf4db 100644
--- a/build/server.moon
+++ b/build/server.moon
@@ -38,7 +38,43 @@ class Server
print "[#{@@__name}]", "running at #{ip}:#{port}"
assert @server\loop!
- handle: (method, path, facet) =>
+ handle_interactive: (fileder, facet) =>
+ root = Fileder @store
+ browser = Browser root, fileder.path, facet.name
+
+ deps = [[
+ <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>]]
+
+ render browser\todom!, fileder, noview: true, scripts: deps .. "
+ <script type=\"text/lua\">
+ on_load = on_load or {}
+ table.insert(on_load, function()
+ local path = #{string.format '%q', fileder.path}
+ local facet = #{string.format '%q', facet.name}
+ local browser = require 'mmm.mmmfs.browser'
+ local fileder = require 'mmm.mmmfs.fileder'
+ local web = require 'mmm.mmmfs.stores.web'
+
+ local store = web.WebStore({ verbose = true })
+ local root = fileder.Fileder(store, store:get_index(nil, -1))
+
+ local err_and_trace = function (msg) return debug.traceback(msg, 2) end
+ local ok, browser = xpcall(browser.Browser, err_and_trace, root, path, facet, true)
+ if not ok then error(browser) end
+ end)
+ </script>"
+
+ handle: (method, path, facet, value) =>
fileder = Fileder @store, path
if not fileder
@@ -57,41 +93,7 @@ class Server
convert 'table', facet.type, index, fileder, facet.name
else
if facet.type == 'text/html+interactive'
- root = Fileder @store
- browser = Browser root, path, facet.name
-
- deps = [[
- <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>
- ]]
-
- render browser\todom!, fileder, noview: true, scripts: deps .. "
- <script type=\"text/lua\">
- on_load = on_load or {}
- table.insert(on_load, function()
- local path = #{string.format '%q', path}
- local facet = #{string.format '%q', facet.name}
- local browser = require 'mmm.mmmfs.browser'
- local fileder = require 'mmm.mmmfs.fileder'
- local web = require 'mmm.mmmfs.stores.web'
-
- local store = web.WebStore({ verbose = true })
- local root = fileder.Fileder(store, store:get_index(nil, -1))
-
- local err_and_trace = function (msg) return debug.traceback(msg, 2) end
- local ok, browser = xpcall(browser.Browser, err_and_trace, root, path, facet, true)
- if not ok then error(browser) end
- end)
- </script>"
+ @handle_interactive fileder, facet
else if not fileder\has_facet facet.name
404, "facet '#{facet.name}' not found in fileder '#{path}'"
else
@@ -101,6 +103,15 @@ class Server
200, val
else
406, "cant convert facet '#{facet.name}' to '#{facet.type}'"
+ when 'POST'
+ @store\create_facet path, facet.name, facet.type, value
+ 200, 'ok'
+ when 'PUT'
+ @store\update_facet path, facet.name, facet.type, value
+ 200, 'ok'
+ when 'DELETE'
+ @store\remove_facet path, facet.name, facet.type
+ 200, 'ok'
else
501, "not implemented"
@@ -119,7 +130,8 @@ class Server
type = type\match '%s*(.*)'
facet = Key facet, type
- ok, status, body = xpcall @.handle, err_and_trace, @, method, path, facet
+ value = stream\get_body_as_string!
+ ok, status, body = xpcall @.handle, err_and_trace, @, method, path, facet, value
if not ok
warn "Error handling request (#{method} #{path} #{facet}):\n#{status}"
body = "Internal Server Error:\n#{status}"
diff --git a/mmm/mmmfs/fileder.moon b/mmm/mmmfs/fileder.moon
index f545bd8..5b65496 100644
--- a/mmm/mmmfs/fileder.moon
+++ b/mmm/mmmfs/fileder.moon
@@ -278,6 +278,21 @@ class Fileder
assert value, "#{@} doesn't have value for '#{want}'"
value, key
+ -- set a facet value and propagate to the store
+ set: (key, key2, value) =>
+ if value
+ key = Key key, key2
+ else
+ key = Key key
+ value = key2
+
+ if @facet_keys[key]
+ @store\update_facet @path, key.name, key.type, value
+ else
+ @store\create_facet @path, key.name, key.type, value
+
+ @facets[key] = value
+
__tostring: => "Fileder:#{@path}"
{
diff --git a/mmm/mmmfs/layout.moon b/mmm/mmmfs/layout.moon
index 05bc38b..7fd3091 100644
--- a/mmm/mmmfs/layout.moon
+++ b/mmm/mmmfs/layout.moon
@@ -130,8 +130,7 @@ render = (content, fileder, opts={}) ->
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/style/:text/css" />
- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />
- ]]
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />]]
buf ..= "
#{get_meta fileder}
</head>
@@ -140,19 +139,16 @@ render = (content, fileder, opts={}) ->
#{content}
- #{footer}
- "
+ #{footer}"
buf ..= [[
<script type="text/javascript" src="/static/highlight-pack/:text/javascript"></script>
<script type="text/javascript">hljs.initHighlighting()</script>
- <script type="text/javascript" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
- ]]
+ <script type="text/javascript" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>]]
buf ..= opts.scripts
buf ..= "
</body>
-</html>
- "
+</html>"
buf
diff --git a/mmm/mmmfs/plugins/code.moon b/mmm/mmmfs/plugins/code.moon
index c3c6c50..bd28c79 100644
--- a/mmm/mmmfs/plugins/code.moon
+++ b/mmm/mmmfs/plugins/code.moon
@@ -1,4 +1,4 @@
-import div from require 'mmm.dom'
+import div, button from require 'mmm.dom'
import languages from require 'mmm.highlighting'
class Editor
@@ -10,7 +10,27 @@ class Editor
obj[k] = v
new: (value, mode, @fileder, @key) =>
- @node = div class: 'editor'
+ @node = div {
+ class: 'editor'
+ style:
+ display: 'flex'
+ 'flex-direction': 'column'
+ 'justify-content': 'space-around'
+
+ div {
+ style:
+ display: 'flex'
+ flex: '0'
+ 'justify-content': 'flex-end'
+ 'border-bottom': '2px solid var(--gray-dark)'
+ 'padding-bottom': '0.5em'
+ 'margin': '-0.5em 0 0.5em'
+
+ with @saveBtn = button 'save changes'
+ .disabled = true
+ .onclick = (_, e) -> @save e
+ }
+ }
@cm = window\CodeMirror @node, o {
:value
:mode
@@ -20,23 +40,36 @@ class Editor
theme: 'hybrid'
}
+ @lastSave = @cm\getDoc!\changeGeneration true
+
@cm\on 'changes', (_, mirr) ->
+ doc = @cm\getDoc!
+ @saveBtn.disabled = doc\isClean @lastSave
+
window\clearTimeout @timeout if @timeout
@timeout = window\setTimeout (-> @change!), 300
change: =>
@timeout = nil
doc = @cm\getDoc!
- if @lastState and doc\isClean @lastState
+
+ if @lastPreview and doc\isClean @lastPreview
-- no changes since last event
return
- @lastState = doc\changeGeneration true
+ @lastPreview = doc\changeGeneration!
value = doc\getValue!
@fileder.facets[@key] = value
BROWSER\refresh!
+ save: (e) =>
+ e\preventDefault!
+
+ doc = @cm\getDoc!
+ @fileder\set @key, doc\getValue!
+ @lastSave = doc\changeGeneration true
+
-- syntax-highlighted code
{
converts: {
diff --git a/mmm/mmmfs/stores/init.moon b/mmm/mmmfs/stores/init.moon
index bbca33f..905188f 100644
--- a/mmm/mmmfs/stores/init.moon
+++ b/mmm/mmmfs/stores/init.moon
@@ -26,6 +26,21 @@ class Store
children: [@get_index child, depth - 1 for child in @list_fileders_in path]
}
+ create_fileder: => error "not implemented"
+ remove_fileder: => error "not implemented"
+ rename_fileder: => error "not implemented"
+ move_fileder: => error "not implemented"
+
+ list_facets: => error "not implemented"
+ create_facet: => error "not implemented"
+ remove_facet: => error "not implemented"
+ load_facet: => error "not implemented"
+ rename_facet: (path, name, type, next_name) =>
+ @log "renaming facet #{path} | #{name}: #{type} -> #{next_name}"
+ blob = assert "no such facet", @load_facet path, name, type
+ @create_facet path, next_name, type, blob
+ @remove_facet path, name, type update_facet: => error "not implemented"
+
close: =>
log: (...) =>
diff --git a/mmm/mmmfs/stores/web.moon b/mmm/mmmfs/stores/web.moon
index ea17b5a..ed3f6d7 100644
--- a/mmm/mmmfs/stores/web.moon
+++ b/mmm/mmmfs/stores/web.moon
@@ -10,10 +10,14 @@ dir_base = (path) ->
dir, base
-fetch = (url) ->
+req = (method, url, content=js.null) ->
+ if not url
+ url = method
+ method = 'GET'
+
request = js.new XMLHttpRequest
- request\open 'GET', url, false
- request\send js.null
+ request\open method, url, false
+ request\send content
assert request.status == 200, "unexpected status code: #{request.status}"
request.responseText
@@ -45,13 +49,13 @@ class WebStore extends Store
get_index: (path='', depth=1) =>
pseudo = if depth > 1 or depth < 0 '?tree' else '?index'
- json = fetch "#{@host .. path}/#{pseudo}: text/json"
+ json = req "#{@host .. path}/#{pseudo}: text/json"
parse_json json
-- fileders
list_fileders_in: (path='') =>
coroutine.wrap ->
- json = fetch "#{@host .. path}/?index: text/json"
+ json = req "#{@host .. path}/?index: text/json"
index = parse_json json
for child in js.of index.children
coroutine.yield child.path
@@ -75,30 +79,32 @@ class WebStore extends Store
-- facets
list_facets: (path) =>
coroutine.wrap ->
- json = fetch "#{@host .. path}/?index: text/json"
+ json = req "#{@host .. path}/?index: text/json"
index = JSON\parse json
for facet in js.of index.facets
coroutine.yield facet.name, facet.type
load_facet: (path, name, type) =>
@log "loading facet #{path} #{name}: #{type}"
- fetch "#{@host .. path}/#{name}: #{type}"
+ req "#{@host .. path}/#{name}: #{type}"
create_facet: (path, name, type, blob) =>
@log "creating facet #{path} | #{name}: #{type}"
- error "not implemented"
+ req 'POST', "#{@host .. path}/#{name}: #{type}", blob
remove_facet: (path, name, type) =>
@log "removing facet #{path} | #{name}: #{type}"
- error "not implemented"
+ req 'DELETE', "#{@host .. path}/#{name}: #{type}"
rename_facet: (path, name, type, next_name) =>
@log "renaming facet #{path} | #{name}: #{type} -> #{next_name}"
- error "not implemented"
+ blob = assert "no such facet", @load_facet path, name, type
+ @create_facet path, next_name, type, blob
+ @remove_facet path, name, type
update_facet: (path, name, type, blob) =>
@log "updating facet #{path} | #{name}: #{type}"
- error "not implemented"
+ req 'PUT', "#{@host .. path}/#{name}: #{type}", blob
{
:WebStore
diff --git a/scss/codemirror.scss b/scss/codemirror.scss
index 1967f8c..fd50b00 100644
--- a/scss/codemirror.scss
+++ b/scss/codemirror.scss
@@ -8,6 +8,7 @@
background: #1d1f21;
height: auto;
+ flex: 1;
/*selection color*/
.CodeMirror-selected,