aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2018-11-01 10:17:55 +0000
committers-ol <s-ol@users.noreply.github.com>2018-11-01 10:17:55 +0000
commit30fb0dc40d595b9e0b7747ad8e5c4e8cf7e3023b (patch)
treedc56f20ec4d78115e15761c402589b5aec94ef55 /lib
parentdefer all scripts (diff)
downloadmmm-30fb0dc40d595b9e0b7747ad8e5c4e8cf7e3023b.tar.gz
mmm-30fb0dc40d595b9e0b7747ad8e5c4e8cf7e3023b.zip
move mmm code from lib to mmm etc
Diffstat (limited to 'lib')
-rw-r--r--lib/canvasapp.client.moon88
-rw-r--r--lib/color.moon20
-rw-r--r--lib/component.client.moon158
-rw-r--r--lib/component.server.moon130
-rw-r--r--lib/dom.client.moon33
-rw-r--r--lib/dom.server.moon40
-rw-r--r--lib/duct_tape.server.moon130
-rw-r--r--lib/init.client.moon49
-rw-r--r--lib/init.server.moon60
-rw-r--r--lib/mmmfs/browser.moon122
-rw-r--r--lib/mmmfs/conversion.moon118
-rw-r--r--lib/mmmfs/fileder.moon155
-rw-r--r--lib/mmmfs/init.moon34
-rw-r--r--lib/ordered.moon27
14 files changed, 0 insertions, 1164 deletions
diff --git a/lib/canvasapp.client.moon b/lib/canvasapp.client.moon
deleted file mode 100644
index 71ffa59..0000000
--- a/lib/canvasapp.client.moon
+++ /dev/null
@@ -1,88 +0,0 @@
-window = js.global
-js = require 'js'
-
-import a, canvas, div, button, script from require 'lib.dom'
-
-class CanvasApp
- width: 500
- height: 400
- new: (show_menu=false, @paused) =>
- @canvas = canvas width: @width, height: @height
-
- @ctx = @canvas\getContext '2d'
- @time = 0
-
- @canvas.tabIndex = 0
- @canvas\addEventListener 'click', (_, e) -> @click and @click e.offsetX, e.offsetY, e.button
- @canvas\addEventListener 'keydown', (_, e) -> @keydown and @keydown e.key, e.code
-
- lastMillis = window.performance\now!
-
- animationFrame = (_, millis) ->
- @update (millis - lastMillis) / 1000
- @ctx\resetTransform!
- @draw!
- lastMillis = millis
-
- if not @paused
- window\setTimeout (->
- window\requestAnimationFrame animationFrame
- ), 0
- window\requestAnimationFrame animationFrame
-
- @node = if show_menu
- div {
- className: 'canvas_app'
- @canvas
- div {
- className: 'overlay',
- button 'render 30fps', onclick: -> @\render 30
- button 'render 60fps', onclick: -> @\render 60
- }
- }
- else
- @canvas
-
-
- update: (dt) =>
- @time += dt
-
- if @length and @time > @length
- @time -= @length
- true
-
- render: (fps=60) =>
- assert @length, 'cannot render CanvasApp without length set'
- @paused = true
-
- actual_render = ->
- writer = js.new window.Whammy.Video, fps
-
- doFrame = ->
- done = @update 1/fps
- @ctx\resetTransform!
- @draw!
-
- writer\add @canvas
-
- if done or @time >= @length
- blob = writer\compile!
- name = "#{@@__name}_#{fps}fps.webm"
- @node.lastChild\appendChild a name, download: name, href: window.URL\createObjectURL blob
- else
- window\setTimeout doFrame
-
- @time = 0
- doFrame!
-
- if window.Whammy
- actual_render!
- else
- window.global = window.global or window
- document.body\appendChild script
- onload: actual_render
- src: 'https://cdn.jsdelivr.net/npm/whammy@0.0.1/whammy.min.js'
-
-{
- :CanvasApp
-}
diff --git a/lib/color.moon b/lib/color.moon
deleted file mode 100644
index 6233b47..0000000
--- a/lib/color.moon
+++ /dev/null
@@ -1,20 +0,0 @@
-rgb = (r, g, b) ->
- r, g, b = table.unpack r if 'table' == type r
- "rgb(#{r * 255}, #{g * 255}, #{b * 255})"
-
-rgba = (r, g, b, a) ->
- r, g, b, a = table.unpack r if 'table' == type r
- "rgba(#{r * 255}, #{g * 255}, #{b * 255}, #{a or 1})"
-
-hsl = (h, s, l) ->
- h, s, l = table.unpack h if 'table' == type h
- "hsl(#{h * 360}, #{s * 100}%, #{l * 100}%)"
-
-hsla = (h, s, l, a) ->
- h, s, l, a = table.unpack h if 'table' == type h
- "hsla(#{h * 360}, #{s * 100}%, #{l * 100}%, #{a or 1})"
-
-{
- :rgb, :rgba,
- :hsl, :hsla,
-}
diff --git a/lib/component.client.moon b/lib/component.client.moon
deleted file mode 100644
index ffeb084..0000000
--- a/lib/component.client.moon
+++ /dev/null
@@ -1,158 +0,0 @@
--- convert anything to a DOM Node
--- val must be one of:
--- * DOM Node (instanceof window.Node)
--- * MMMElement (have a .node value that is instanceof window.Node)
--- * string
--- note that strings won't survive identity comparisons after tohtml
-tohtml = (val) ->
- if 'string' == type val
- return document\createTextNode val
- if 'table' == type val
- assert val.node, "Table doesn't have .node"
- val = val.node
- if 'userdata' == type val
- assert (js.instanceof val, js.global.Node), "userdata is not a Node"
- val
- else
- error "not a Node: #{val}, #{type val}"
-
--- overloaded append
--- see tohtml for acceptable values
-g_append = append
-append = (value) -> g_append tohtml value
-
--- shorthand to form a text node from strings
-text = (...) -> document\createTextNode table.concat { ... }, ' '
-
-class ReactiveVar
- @isinstance: (val) -> 'table' == (type val) and val.subscribe
-
- new: (@value) =>
- @listeners = setmetatable {}, __mode: 'kv'
-
- set: (value) =>
- old = @value
- @value = value
- for k, callback in pairs @listeners
- callback @value, old
-
- get: => @value
-
- transform: (transform) => @set transform @get!
-
- subscribe: (callback) =>
- with -> @listeners[callback] = nil
- @listeners[callback] = callback
-
- map: (transform) =>
- with ReactiveVar transform @value
- .upstream = @subscribe (...) -> \set transform ...
-
--- join = do
--- update = (k, new) -> (old) ->
--- with copy = { k, v for k,v in pairs old }
--- copy[k] = new
---
--- (inputs) ->
--- values = {}
--- with ReactiveVar values
--- for k, input in pairs inputs
--- input = inputs[k]
--- values[i] = input\get!
--- input\subscribe (new) -> \transform update k, new
-
-class ReactiveElement
- @isinstance: (val) -> 'table' == (type val) and val.node
-
- new: (element, ...) =>
- if 'userdata' == type element
- @node = element
- else
- @node = document\createElement element
- @_subscriptions = {}
-
- children = { ... }
- -- attributes are last arguments but mustn't be a ReactiveVar
- attributes = children[#children]
- if 'table' == (type attributes) and
- (not ReactiveElement.isinstance attributes) and
- (not ReactiveVar.isinstance attributes)
- table.remove children
- else
- attributes = {}
-
- for k,v in pairs attributes
- @set k, v if 'string' == type k
-
- -- if there is only one argument,
- -- children can be in attributes table too
- if #children == 0
- children = attributes
-
- for child in *children
- @append child
-
- destroy: =>
- for unsub in *@_subscriptions do unsub!
-
- set: (attr, value) =>
- attr = 'className' if attr == 'class'
- if 'table' == (type value) and ReactiveVar.isinstance value
- table.insert @_subscriptions, value\subscribe (...) -> @set attr, ...
- value = value\get!
-
- if attr == 'style' and 'table' == type value
- for k,v in pairs value
- @node.style[k] = v
- return
-
- @node[attr] = value
-
- prepend: (child, last) => @append child, last, 'prepend'
- append: (child, last, mode='append') =>
- if ReactiveVar.isinstance child
- table.insert @_subscriptions, child\subscribe (...) -> @append ...
- child = child\get!
-
- if 'string' == type last
- error 'cannot replace string node'
-
- if child == nil
- if last
- @remove last
- return
-
- child = tohtml child
- ok, last = pcall tohtml, last
- if ok
- @node\replaceChild child, last
- else
- switch mode
- when 'append' then @node\appendChild child
- when 'prepend' then @node\insertBefore child, @node.firstChild
-
- remove: (child) =>
- @node\removeChild tohtml child
- if 'table' == (type child) and child.destroy
- child\destroy!
-
-get_or_create = (elem, id, ...) ->
- elem = (document\getElementById id) or elem
-
- with ReactiveElement elem, ...
- \set 'id', id
-
-elements = setmetatable {}, __index: (name) =>
- with val = (...) -> ReactiveElement name, ...
- @[name] = val
-
-{
- :ReactiveVar,
- :ReactiveElement,
- :get_or_create,
--- :join,
- :tohtml,
- :append,
- :text,
- :elements,
-}
diff --git a/lib/component.server.moon b/lib/component.server.moon
deleted file mode 100644
index 0026d32..0000000
--- a/lib/component.server.moon
+++ /dev/null
@@ -1,130 +0,0 @@
-import opairs from require 'lib.ordered'
-
-void_tags = { 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr' }
-void_tags = { t,t for t in *void_tags }
-
--- convert anything to HTML string
--- val must be one of:
--- * MMMElement (have a .render method that returns a string)
--- * string
-tohtml = (val) ->
- if 'table' == type val
- assert val.render, "Table doesn't have .render"
- val = val\render!
- if 'string' == type val
- val
- else
- error "not a Node: #{val}, #{type val}"
-
--- overloaded append
--- see tohtml for acceptable values
-g_append = append
-append = (value) -> g_append tohtml value
-
--- shorthand to form a text node from strings
-text = (...) -> table.concat { ... }, ' '
-
-class ReactiveVar
- @isinstance: (val) -> 'table' == (type val) and val.subscribe
-
- new: (@value) =>
-
- set: (value) =>
- error "attempting to update ReactiveVar serverside"
-
- get: => @value
-
- subscribe: (callback) =>
- warn "attempting to subscribe to ReactiveVar serverside"
-
- map: (transform) =>
- ReactiveVar transform @value
-
-class ReactiveElement
- @isinstance: (val) -> 'table' == (type val) and val.render
-
- new: (element, ...) =>
- @element = element
- @attrs = { style: {} }
- @children = {}
-
- children = { ... }
-
- -- attributes are last arguments but mustn't be a ReactiveVar
- attributes = children[#children]
- if 'table' == (type attributes) and
- (not ReactiveElement.isinstance attributes) and
- (not ReactiveVar.isinstance attributes)
- table.remove children
- else
- attributes = {}
-
- for k,v in pairs attributes
- @set k, v if 'string' == type k
-
- -- if there is only one argument,
- -- children can be in attributes table too
- if #children == 0
- children = attributes
-
- for child in *children
- @append child
-
- destroy: =>
-
- set: (attr, value) =>
- if attr == 'style' and 'table' == type value
- for k,v in opairs value
- @attrs.style[k] = v
- return
-
- @attrs[attr] = value
-
- append: (child, last) =>
- assert not last, "last passed to append on server"
- if ReactiveVar.isinstance child
- child = child\get!
-
- child = tohtml child
- table.insert @children, child
-
- remove: (child) =>
- error "remove called serverside"
-
- render: =>
- b = "<#{@element}"
- for k,v in opairs @attrs
- if 'table' == type v
- tmp = ''
- for kk, vv in opairs v
- tmp ..= "#{kk}: #{vv}; "
- v = tmp
- b ..= " #{k}=\"#{v}\""
-
- if void_tags[@element]
- assert #@children == 0, "void tag #{element} cannot have children!"
- b .. ">"
- else
- b .. ">"
- b ..= ">" .. table.concat @children, ''
- b ..= "</#{@element}>"
- b
-
-elements = setmetatable {}, __index: (name) =>
- with val = (...) -> ReactiveElement name, ...
- @[name] = val
-
-get_or_create = (elem, id, ...) ->
- with ReactiveElement elem, ...
- \set 'id', id
-
-{
- :ReactiveVar,
- :ReactiveElement,
- :get_or_create,
- :tohtml,
- :flush,
- :append,
- :text,
- :elements,
-}
diff --git a/lib/dom.client.moon b/lib/dom.client.moon
deleted file mode 100644
index acdbfa4..0000000
--- a/lib/dom.client.moon
+++ /dev/null
@@ -1,33 +0,0 @@
-element = (element) -> (...) ->
- children = { ... }
-
- -- attributes are last arguments but mustn't be a ReactiveVar
- attributes = children[#children]
- if 'table' == (type attributes) and not attributes.node
- table.remove children
- else
- attributes = {}
-
- with e = document\createElement element
- for k,v in pairs attributes
- k = 'className' if k == 'class'
- if k == 'style' and 'table' == type v
- for kk,vv in pairs v
- e.style[kk] = vv
- elseif 'string' == type k
- e[k] = v
-
- -- if there is only one argument,
- -- children can be in attributes table too
- if #children == 0
- children = attributes
-
- for child in *children
- if 'string' == type child
- child = document\createTextNode child
-
- e\appendChild child
-
-setmetatable {}, __index: (name) =>
- with val = element name
- @[name] = val
diff --git a/lib/dom.server.moon b/lib/dom.server.moon
deleted file mode 100644
index fe6b60c..0000000
--- a/lib/dom.server.moon
+++ /dev/null
@@ -1,40 +0,0 @@
-import opairs from require 'lib.ordered'
-
-void_tags = { 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr' }
-void_tags = { t,t for t in *void_tags }
-
-element = (element) -> (...) ->
- children = { ... }
-
- -- attributes are last arguments but mustn't be a ReactiveVar
- attributes = children[#children]
- if 'table' == (type attributes) and not attributes.node
- table.remove children
- else
- attributes = {}
-
- b = "<#{element}"
- for k,v in opairs attributes
- if k == 'style' and 'table' == type v
- tmp = ''
- for kk, vv in opairs v
- tmp ..= "#{kk}: #{vv}; "
- v = tmp
- b ..= " #{k}=\"#{v}\""
-
- -- if there is only one argument,
- -- children can be in attributes table too
- if #children == 0
- children = attributes
-
- if void_tags[element]
- assert #children == 0, "void tag #{element} cannot have children!"
- b .. ">"
- else
- b ..= ">" .. table.concat children, ''
- b ..= "</#{element}>"
- b
-
-setmetatable {}, __index: (name) =>
- with val = element name
- @[name] = val
diff --git a/lib/duct_tape.server.moon b/lib/duct_tape.server.moon
deleted file mode 100644
index b019ac8..0000000
--- a/lib/duct_tape.server.moon
+++ /dev/null
@@ -1,130 +0,0 @@
-package.noompath = './?.moon;./?/init.moon'
-
-export __FNDEF_NOOM_CACHE
-__FNDEF_NOOM_CACHE = setmetatable {}, __mode: 'k'
-
-assert MODE == 'SERVER', "duct_tape only works on the server"
-
-compile = require 'moonscript.compile'
-parse = require 'moonscript.parse'
-
-import smart_node, build from require 'moonscript.types'
-import dirsep from require 'moonscript.base'
-import get_options, unpack from require 'moonscript.util'
-
-line_tables = require 'moonscript.line_tables'
-lua = :loadstring, :load
-
-local *
-
-escape_str = (str) -> (str\gsub('\\', '\\\\')\gsub '"', '\\"'), nil
-
-deep_clone = (value) ->
- if 'table' == type value
- { deep_clone(k), deep_clone(v) for k,v in pairs value }
- else -- number, string, boolean, etc
- value
-
-transform_fndef = (fndef, parent, i) ->
- -- compile the function to Lua separately
- code, ltable, pos = compile.tree { deep_clone fndef }
- if not code
- return compile.format_error(ltable, pos, text)
-
- code = "(function() #{code} end)()"
-
- -- assign the lua code to __FNDEF_NOOM_CACHE[function] so it can be retrieved by `compile`
- fn = -> { 'ref', 'fn' }
- cache = build.chain {
- base: '__FNDEF_NOOM_CACHE',
- { 'index', fn! }
- }
-
- parent[i] = build.do {
- { 'declare_with_shadows', { 'fn' } }
- build.assign_one fn!, fndef
- build.assign_one cache, { 'string', '"', escape_str code }
- -- build.assign_one cache, { 'string', '[[', code }
- fn!
- }
-
- nil
-
-find_fndefs = (node, p, i) ->
- if node[1] == "fndef"
- transform_fndef node, p, i
- else
- for i = 1,#node
- v = node[i]
- find_fndefs v, node, i if 'table' == type v
-
-to_lua = (text, options={}) ->
- if "string" != type text
- t = type text
- return nil, "expecting string (got ".. t ..")"
-
- tree, err = parse.string text
- if not tree
- return nil, err
-
- find_fndefs tree
-
- code, ltable, pos = compile.tree tree, options
- if not code
- return nil, compile.format_error(ltable, pos, text)
-
- code, ltable
-
-noom_loader = (name, ...) ->
- name_path = name\gsub "%.", dirsep
-
- local file, file_path
- for path in package.noompath\gmatch "[^;]+"
- file_path = path\gsub "?", name_path
- file = io.open file_path
- break if file
-
- if file
- text = file\read "*a"
- file\close!
- res, err = loadstring text, "@#{file_path}"
- if not res
- error file_path .. ": " .. err
-
- return res
-
- return nil, "Could not find noom file"
-
-loadstring = (...) ->
- options, str, chunk_name, mode, env = get_options ...
- chunk_name or= "=(noom.loadstring)"
-
- code, ltable_or_err = to_lua str, options
- unless code
- return nil, ltable_or_err
-
- line_tables[chunk_name] = ltable_or_err if chunk_name
-
- -- the unpack prevents us from passing nil
- (lua.loadstring or lua.load) code, chunk_name, unpack { mode, env }
-
-do
- local compile
- insert_loader = (pos=2) ->
- -- if not package.moonpath
- -- package.moonpath = create_moonpath package.path
-
- loaders = package.loaders or package.searchers
- for loader in *loaders
- return false if loader == noom_loader
-
- table.insert loaders, pos, noom_loader
- true
-
- compile = (fn) -> with code = __FNDEF_NOOM_CACHE[fn]
- assert code, 'cannot compile function not loaded from noomscript source.'
-
- {
- :insert_loader
- :compile
- }
diff --git a/lib/init.client.moon b/lib/init.client.moon
deleted file mode 100644
index 144543b..0000000
--- a/lib/init.client.moon
+++ /dev/null
@@ -1,49 +0,0 @@
-export MODE, print, warn, relative, on_client
-export window, document
-
-window = js.global
-{ :document, :console } = window
-
-MODE = 'CLIENT'
-
-deep_tostring = (tbl, space='') ->
- return tbl if 'userdata' == type tbl
-
- buf = space .. tostring tbl
- return buf unless 'table' == type tbl
-
- buf = buf .. ' {\n'
- for k,v in pairs tbl
- buf = buf .. "#{space} [#{k}]: #{deep_tostring v, space .. ' '}\n"
- buf = buf .. "#{space}}"
- buf
-
-print = (...) ->
- contents = [deep_tostring v for v in *{ ... } ]
- console\log table.unpack contents
-
-warn = (...) ->
- contents = [deep_tostring v for v in *{ ... } ]
- console\warn table.unpack contents
-
--- package.path = '/?.client.moon.lua;/?.moon.lua;/?/init.moon.lua;/?.lua;/?/init.lua'
-package.path = '/?.lua;/?/init.lua'
-
--- relative imports
-relative = do
- _require = require
-
- (base, sub) ->
- sub = 0 unless 'number' == type sub
-
- for i=1, sub
- base = base\match '^(.*)%.%w+$'
-
- (name, x) ->
- name = base .. name if '.' == name\sub 1, 1
- _require name
-
-on_client = (f, ...) -> f ...
-
-if on_load
- for f in *on_load do f!
diff --git a/lib/init.server.moon b/lib/init.server.moon
deleted file mode 100644
index cc3851d..0000000
--- a/lib/init.server.moon
+++ /dev/null
@@ -1,60 +0,0 @@
-export MODE, print, warn, relative, on_client
-MODE = 'SERVER'
-
-deep_tostring = (tbl, space='') ->
- buf = space .. tostring tbl
-
- return buf unless 'table' == type tbl
-
- buf = buf .. ' {\n'
- for k,v in pairs tbl
- buf = buf .. "#{space} [#{k}]: #{deep_tostring v, space .. ' '}\n"
- buf = buf .. "#{space}}"
- buf
-
-print = do
- _print = print
- (...) ->
- contents = [deep_tostring v for v in *{ ... } ]
- _print table.unpack contents
-
--- warning messages
-warn = (...) ->
- contents = [deep_tostring v for v in *{ ... } ]
- io.stderr\write table.concat contents, '\t'
- io.stderr\write '\n'
-
--- relative imports
-relative = do
- _require = require
-
- (base, sub) ->
- sub = 0 unless 'number' == type sub
-
- for i=1, sub
- base = base\match '^(.*)%.%w+$'
-
- (name, x) ->
- name = base .. name if '.' == name\sub 1, 1
- _require name
-
-import compile, insert_loader from require 'lib.duct_tape'
-insert_loader!
-
-on_client = (fn, ...) ->
- args = {...}
- -- warn code
- "<script type=\"application/lua\">
- local fn = #{compile fn}
- on_load = on_load or {}
- table.insert(on_load, function()
- fn(#{table.concat [string.format '%q', v for v in *args ], ', '})
- end)
- </script>"
-
-{
- -- access / flush the appended data
- flush: ->
- with x = buffer
- buffer = ''
-}
diff --git a/lib/mmmfs/browser.moon b/lib/mmmfs/browser.moon
deleted file mode 100644
index ce7709f..0000000
--- a/lib/mmmfs/browser.moon
+++ /dev/null
@@ -1,122 +0,0 @@
-require = relative ..., 1
-import Key from require '.fileder'
-import get_conversions from require '.conversion'
-import ReactiveVar, get_or_create, text, elements from require 'lib.component'
-import div, span, a, select, option from elements
-
-class Browser
- new: (@root, path='/', rehydrate=false) =>
- -- root fileder
- assert @root, 'root fileder is nil'
-
- -- active path
- @path = ReactiveVar path
-
- if MODE == 'CLIENT'
- -- update URL bar
- @path\subscribe (path) ->
- path ..= '/' unless path\match '/$'
- window.history\pushState nil, '', path
-
- -- active fileder
- -- (re)set every time @path changes
- @active = @path\map @root\walk
-
- -- currently active property
- -- (re)set to default every time @active changes
- @prop = @active\map (fileder) ->
- return unless fileder
- (fileder\find 'mmm/dom') or next fileder.props
-
- -- retrieve or create the root
- @dom = get_or_create 'div', 'browser-root'
-
- -- prepend the navbar
- if MODE == 'SERVER'
- @dom\append div id: 'browser-navbar'
- else
- @dom\prepend get_or_create 'div', 'browser-navbar', {
- span 'path: ', @path\map (path) -> with div style: { display: 'inline-block' }
- path_segment = (name, href) ->
- a name, :href, onclick: (_, e) ->
- e\preventDefault!
- @navigate href
-
- href = ''
- path = path\match '^/(.*)'
-
- \append path_segment 'root', '/'
-
- while path
- name, rest = path\match '^(%w+)/(.*)'
- if not name
- name = path
-
- path = rest
- href = "#{href}/#{name}"
-
- \append '/'
- \append path_segment name, href
-
- span 'view property: ', @active\map (fileder) ->
- onchange = (_, e) ->
- @prop\set Key e.target.value
-
- current = @prop\get!
- current = current and current\tostring!
- with select :onchange, disabled: not fileder
- if fileder
- for key, _ in pairs fileder.props
- value = key\tostring!
- \append option value, :value, selected: value == current
- }
-
- -- append or patch #browser-content
- @dom\append with get_or_create 'div', 'browser-content'
- \append @get_content!, (rehydrate and .node.lastChild)
-
- if rehydrate
- -- force one rerender to set onclick handlers etc
- @prop\set @prop\get!
-
- -- export mmm/component interface
- @node = @dom.node
- @render = @dom\render
-
- -- render #browser-content
- get_content: () =>
- disp_error = (msg) -> span msg, style: { color: '#f00' }
- @prop\map (prop) ->
- active = @active\get!
-
- return disp_error "fileder not found!" unless active
- return disp_error "property not found!" unless prop
-
- convert = ->
- conversions = get_conversions 'mmm/dom', prop.type
- value = assert (active\get prop), "value went missing?"
-
- return unless conversions
-
- for i=#conversions,1,-1
- { :inp, :out, :transform } = conversions[i]
- value = transform value, active
-
- value
-
- ok, res = if MODE == 'CLIENT'
- pcall convert
- else
- true, convert!
-
- if ok
- res or disp_error "[no conversion path to mmm/dom]"
- else
- warn "error: ", res unless ok
- disp_error "[unknown error displaying]"
-
- navigate: (new) => @path\set new
-
-{
- :Browser
-}
diff --git a/lib/mmmfs/conversion.moon b/lib/mmmfs/conversion.moon
deleted file mode 100644
index 7f86aa4..0000000
--- a/lib/mmmfs/conversion.moon
+++ /dev/null
@@ -1,118 +0,0 @@
-import text, code from require 'lib.dom'
-import tohtml from require 'lib.component'
-
--- limit function to one argument
-single = (func) -> (val) -> func val
-
--- list of converts
--- converts each have
--- * inp - input type. can capture subtypes using `(.+)`
--- * out - output type. can substitute subtypes from inp with %1, %2 etc.
--- * transform - function (val: inp, fileder) -> val: out
-converts = {
- {
- inp: 'moon -> (.+)',
- out: '%1',
- transform: (val, fileder) -> val fileder
- },
- {
- inp: 'text/plain',
- out: 'mmm/dom',
- transform: single text
- },
- {
- inp: 'alpha',
- out: 'mmm/dom',
- transform: single code
- },
- {
- inp: 'URL -> .*',
- out: 'mmm/dom',
- transform: single code
- },
- {
- inp: 'mmm/component',
- out: 'mmm/dom',
- transform: single tohtml
- },
- {
- inp: 'mmm/dom',
- out: 'text/html',
- transform: (node) -> if MODE == 'SERVER' then node else node.outerHTML
- },
- {
- inp: 'text/html',
- out: 'mmm/dom',
- transform: if MODE == 'SERVER'
- (...) -> ...
- else
- (html) ->
- tmp = document\createElement 'div'
- tmp.innerHTML = html
- if tmp.childElementCount == 1
- tmp.firstChild
- else
- tmp
- }
-}
-
-do
- local markdown
- if MODE == 'SERVER'
- success, discount = pcall require, 'discount'
- markdown = discount if success
- else
- markdown = window and window.marked and window\marked
-
- if markdown
- table.insert converts, {
- inp: 'text/markdown',
- out: 'text/html',
- transform: single markdown
- }
-
-count = (base, pattern='->') -> select 2, base\gsub pattern, ''
-escape_inp = (inp) -> "^#{inp\gsub '([-/])', '%%%1'}$"
-
--- attempt to find a conversion path from 'have' to 'want'
--- * have - start type string or list of type strings
--- * want - stop type string
--- * limit - limit conversion amount
--- returns a list of conversion steps
-get_conversions = (want, have, limit=3) ->
- assert have, 'need starting type(s)'
-
- if 'string' == type have
- have = { have }
-
- assert #have > 0, 'need starting type(s) (list was empty)'
-
- iterations = limit + math.max table.unpack [count type for type in *have]
- have = [{ :start, rest: start, conversions: {} } for start in *have]
-
- for i=1, iterations
- next_have, c = {}, 1
- for { :start, :rest, :conversions } in *have
- if want == rest
- return conversions, start
- else
- for convert in *converts
- inp = escape_inp convert.inp
- matches = { rest\match inp }
- continue unless #matches > 0
- result = rest\gsub inp, convert.out
- if result
- next_have[c] = {
- :start,
- rest: result,
- conversions: { convert, table.unpack conversions }
- }
- c += 1
-
- have = next_have
- return unless #have > 0
-
-{
- :converts
- :get_conversions
-}
diff --git a/lib/mmmfs/fileder.moon b/lib/mmmfs/fileder.moon
deleted file mode 100644
index c3e40f7..0000000
--- a/lib/mmmfs/fileder.moon
+++ /dev/null
@@ -1,155 +0,0 @@
-require = relative ..., 1
-import get_conversions from require '.conversion'
-
--- Key of a Fileder Property
--- contains:
--- * @name - key name or '' for main content
--- * @type - type string (type -> type -> type)
-class Key
- -- instantiate from table w/ keys described above
- -- or string like '@name: @type' (name optional)
- new: (opts, second) =>
- if 'string' == type second
- @name, @type = (opts or ''), second
- elseif 'string' == type opts
- @name, @type = opts\match '(%w+): *(.+)'
- if not @name
- @name = ''
- @type = opts
- elseif 'table' == type opts
- @name = opts.name
- @type = opts.type
- else
- error "wrong argument type: #{type opts}, #{type second}"
-
- -- format as a string (see constructor)
- tostring: =>
- if @name == ''
- @type
- else
- "#{@name}: #{@type}"
-
--- Fileder itself
--- contains:
--- * @props - Property Map (Key to Value)
--- * @children - Children Array
-class Fileder
- -- instantiate from props and children tables
- -- or mix in one table (numeric keys are children, remainder props)
- -- prop-keys are passed to Key constructor
- new: (props, children) =>
- if not children
- children = for i, child in ipairs props
- props[i] = nil
- child
-
- -- automatically mount children on insert
- @children = setmetatable {}, __newindex: (t, k, child) ->
- rawset t, k, child
- if @path == '/'
- child\mount '/'
- elseif @path
- child\mount @path .. '/'
-
- -- copy children
- for i, child in ipairs children
- @children[i] = child
-
- -- automatically reify string keys on insert
- @props = setmetatable {}, __newindex: (t, key, v) ->
- rawset t, key, nil -- fix for fengari.io
- rawset t, (Key key), v
-
- -- copy props
- for k, v in pairs props
- @props[k] = v
-
- -- recursively walk to and return the fileder with @path == path
- -- * path - the path to walk to
- walk: (path) =>
- -- early-out if we are outside of the path already
- return unless path\match '^' .. @path
-
- -- gotcha
- return @ if path == @path
-
- for child in *@children
- result = child\walk path
- return result if result
-
- -- recursively mount fileder and children at path
- -- * path - the path to mount at (default: '/')
- -- * mount_as - dont append own name to path
- mount: (path='/', mount_as=false) =>
- assert not @path, "mounted twice: #{@path} and now #{path}"
-
- if mount_as
- @path = path
- else
- @path = path .. @gett 'name: alpha'
-
- if @path == '/'
- for child in *@children
- child\mount '/'
- else
- for child in *@children
- child\mount @path .. '/'
-
- -- recursively iterate all children (coroutine)
- -- * depth - depth to stop after; 1 = yield only self (default: infinite)
- iterate: (depth=0) =>
- coroutine.yield @
- return if depth == 1
-
- for child in *@children
- child\iterate depth - 1
-
- -- find property key according to criteria, nil if no value or conversion path
- -- * ... - arguments like Key
- find: (...) =>
- want = Key ...
-
- -- filter props by name
- matching = [ key for key in pairs @props when key.name == want.name ]
- return unless #matching > 0
-
- -- get shortest conversion path
- shortest_path, start = get_conversions want.type, [ key.type for key in *matching ]
-
- if start
- for key in *matching
- if key.type == start
- return key, shortest_path
-
- error "couldn't find key after resolution?"
-
- -- get property according to criteria, nil if no value or conversion path
- -- * ... - arguments like Key
- get: (...) =>
- want = Key ...
-
- -- find matching key and shortest conversion path
- key, conversions = @find want
-
- if key
- value = @props[key]
-
- -- apply conversions (in reverse order)
- for i=#conversions,1,-1
- { :inp, :out, :transform } = conversions[i]
- value = transform value, @
-
- value, key
-
- -- like @get, throw if no value or conversion path
- gett: (...) =>
- want = Key ...
-
- value, key = @get want
- assert value, "node doesn't have value for '#{want\tostring!}'"
- value, key
-
-{
- :Key
- :Fileder
-}
diff --git a/lib/mmmfs/init.moon b/lib/mmmfs/init.moon
deleted file mode 100644
index d0de45b..0000000
--- a/lib/mmmfs/init.moon
+++ /dev/null
@@ -1,34 +0,0 @@
-require = relative ...
-import Key, Fileder from require '.fileder'
-import Browser from require '.browser'
-import tohtml from require 'lib.component'
-
-define_fileders = (...) ->
- source_module = ...
-
- (...) ->
- with fileder = Fileder ...
- .source_module = source_module
-
-rehydrate = (path) ->
- import Browser from require 'lib.mmmfs.browser'
- root = require 'root'
- root\mount!
-
- export BROWSER
- BROWSER = Browser root, path, true
-
-render = (root, path) ->
- export BROWSER
- BROWSER = Browser root, path
-
- content = tohtml BROWSER
- content, on_client rehydrate, path
-
-{
- :Key
- :Fileder
- :render
- :define_fileders
- :module_roots
-}
diff --git a/lib/ordered.moon b/lib/ordered.moon
deleted file mode 100644
index 59c07bf..0000000
--- a/lib/ordered.moon
+++ /dev/null
@@ -1,27 +0,0 @@
--- ordered table iterator, for stable(r) renderers
-
-sort = (t, order_fn) ->
- with index = [k for k,v in pairs t when 'string' == type k]
- table.sort index, order_fn
-
--- ordered next(t)
-onext = (state, key) ->
- state.i += 1
- { :t, :index, :i } = state
-
- if key = index[i]
- key, t[key]
-
--- ordered pairs(t). order_fn is optional; see table.sort
-opairs = (t, order_fn) ->
- state = {
- :t,
- i: 0,
- index: sort t, order_fn
- }
- onext, state, nil
-
-{
- :onext
- :opairs
-}