aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mmmfs/browser.moon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mmmfs/browser.moon')
-rw-r--r--lib/mmmfs/browser.moon153
1 files changed, 73 insertions, 80 deletions
diff --git a/lib/mmmfs/browser.moon b/lib/mmmfs/browser.moon
index a4080c2..ce7709f 100644
--- a/lib/mmmfs/browser.moon
+++ b/lib/mmmfs/browser.moon
@@ -1,79 +1,70 @@
require = relative ..., 1
import Key from require '.fileder'
import get_conversions from require '.conversion'
-import ReactiveVar, ReactiveElement, text, elements from require 'lib.component'
+import ReactiveVar, get_or_create, text, elements from require 'lib.component'
import div, span, a, select, option from elements
-limit = (list, num) -> [v for i,v in ipairs list when i <= num]
-
class Browser
- new: (@root, @path={}, rehydrate=false) =>
- @path = ReactiveVar @path
- -- @path\subscribe (path) -> window.location.hash = '/' .. table.concat path, '/'
- @prop = ReactiveVar (@root\find 'mmm/dom') or next @root.props
- @active = @path\map (path) ->
- fileder = @root
- for name in *path
- local next
- for child in *fileder.children
- if name == child\get 'name', 'alpha'
- next = child
- break
+ new: (@root, path='/', rehydrate=false) =>
+ -- root fileder
+ assert @root, 'root fileder is nil'
- if not next
- return
+ -- active path
+ @path = ReactiveVar path
- fileder = next
+ if MODE == 'CLIENT'
+ -- update URL bar
+ @path\subscribe (path) ->
+ path ..= '/' unless path\match '/$'
+ window.history\pushState nil, '', path
- fileder
+ -- active fileder
+ -- (re)set every time @path changes
+ @active = @path\map @root\walk
- @active\subscribe (fileder) -> @prop\set (fileder\find 'mmm/dom') or next fileder.props
+ -- 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
- root = 'div'
- root = document\getElementById 'browser-root' if rehydrate
- @dom = ReactiveElement root, {
- id: 'browser-root'
- style: {
- position: 'absolute',
- top: 0,
- bottom: 0,
- left: 0,
- right: 0,
- display: 'flex',
- overflow: 'hidden',
- 'flex-direction': 'column',
- 'justify-content': 'space-between',
- }
- }
+ @dom = get_or_create 'div', 'browser-root'
- -- add or prepend the navbar
- if MODE == 'CLIENT'
- @dom\prepend div {
- style: {
- padding: '1em',
- flex: '0 0 auto',
- display: 'flex',
- 'justify-content': 'space-between',
- background: '#eeeeee',
- },
+ -- 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' }
- \append a 'root', href: '#', onclick: (_, e) ->
- e\preventDefault!
- @navigate {}
+ 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}"
- for i,name in ipairs path
\append '/'
- \append a name, href: '#', onclick: (_, e) ->
- e\preventDefault!
- @navigate limit path, i
+ \append path_segment name, href
span 'view property: ', @active\map (fileder) ->
onchange = (_, e) ->
@prop\set Key e.target.value
- current = @prop\get!\tostring!
- with select :onchange
+ 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!
@@ -81,49 +72,51 @@ class Browser
}
-- append or patch #browser-content
- node = 'div'
- node = document\getElementById 'browser-content' if rehydrate
- @dom\append ReactiveElement node, {
- id: 'browser-content',
- style: {
- flex: '1 0 0',
- overflow: 'auto',
- padding: '1em 2em',
- },
- @get_content rehydrate and node
- }
+ @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
- get_content: (wrapper) =>
- var = @prop\map (prop) ->
+ -- render #browser-content
+ get_content: () =>
+ disp_error = (msg) -> span msg, style: { color: '#f00' }
+ @prop\map (prop) ->
active = @active\get!
- ok, res = pcall ->
- conversions = assert (get_conversions 'mmm/dom', prop.type), "no conversion path"
+ 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
- if ok and res
- res
+ ok, res = if MODE == 'CLIENT'
+ pcall convert
else
- warn "error: ", res unless ok
- span "cannot display!", style: { color: '#f00' }
-
- -- wrapper was built already so take over the old value
- if wrapper
- var\set wrapper.lastElementChild
+ true, convert!
- var
+ 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,
+ :Browser
}