diff options
Diffstat (limited to 'app/component.client.moon')
| -rw-r--r-- | app/component.client.moon | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/app/component.client.moon b/app/component.client.moon deleted file mode 100644 index c012427..0000000 --- a/app/component.client.moon +++ /dev/null @@ -1,128 +0,0 @@ -{ :document } = js.global - --- 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 ... - -class ReactiveElement - @isinstance: (val) -> 'table' == (type val) and val.node - - new: (element, ...) => - @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) => - 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 - - append: (child, last) => - if ReactiveVar.isinstance child - table.insert @_subscriptions, child\subscribe (...) -> @append ... - child = child\get! - - if 'string' == type last - error 'cannot replace string node' - - child = tohtml child - ok, last = pcall tohtml, last - if ok - @node\replaceChild child, last - else - @node\appendChild child - - remove: (child) => - @node\removeChild tohtml child - if 'table' == (type child) and child.destroy - child\destroy! - -with exports = { - :ReactiveVar, - :ReactiveElement, - :tohtml, - :append, - :text, - } - add = (e) -> exports[e] = (...) -> ReactiveElement e, ... - - for e in *{'div', 'form', 'span', 'a', 'p', 'button', 'ul', 'ol', 'li', 'i', 'b', 'u', 'tt'} do add e - for e in *{'article', 'section', 'header', 'footer', 'content'} do add e - for e in *{'br', 'hr', 'img', 'input', 'p', 'textarea'} do add e - for i=1,8 do add "h" .. i |
