diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2018-05-03 21:51:07 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2018-05-03 21:53:41 +0000 |
| commit | d8e5f36cd7fc2d063f7f4bc992d2168b34f68b1c (patch) | |
| tree | 323ee024080f35d1e206548757a7d72a8b658943 | |
| parent | add submodule tracking gh-pages (diff) | |
| download | mmm-d8e5f36cd7fc2d063f7f4bc992d2168b34f68b1c.tar.gz mmm-d8e5f36cd7fc2d063f7f4bc992d2168b34f68b1c.zip | |
add component framework + todo
| -rw-r--r-- | app/component.moon | 93 | ||||
| -rw-r--r-- | app/html.moon | 2 | ||||
| -rw-r--r-- | app/index.moon | 9 | ||||
| -rw-r--r-- | app/todo.moon | 30 | ||||
| m--------- | dist | 0 | ||||
| -rw-r--r-- | webpack.config.js | 2 |
6 files changed, 131 insertions, 5 deletions
diff --git a/app/component.moon b/app/component.moon new file mode 100644 index 0000000..1f56679 --- /dev/null +++ b/app/component.moon @@ -0,0 +1,93 @@ +{ :document } = js.global + +asnode = (val) -> + if 'table' == type val + assert val.node, "Table doesn't have .node" + val = val.node + if 'string' == type val + val = document\createTextNode val + 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}" + +iscallback = (val) -> 'table' == (type val) and val.subscribe + +class Callback + new: (@value) => + @listeners = setmetatable {}, __mode: 'kv' + + set: (value) => + old = @value + @value = value + for k, callback in pairs @listeners + callback @value, old + + get: => @value + + subscribe: (callback) => + with callback + @listeners[callback] = callback + + unsubscribe: (callback) => + @listeners[callback] = nil + + chain: (transform) => + with Callback transform @value + .upstream = @subscribe (...) -> \set transform ... + +class CallbackElement + new: (element, attributes, ...) => + @node = document\createElement element + @_callbacks = {} + + children = { ... } + + if 'table' != (type attributes) or attributes.__class == @@ or attributes.__class == Callback + table.insert children, 1, attributes + attributes = {} + + for k,v in pairs attributes + @set k, v if 'string' == type k + for child in *children + @append child + + set: (attr, value) => + if 'table' == (type value) and value.__class == Callback + table.insert @_callbacks, 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 iscallback child + table.insert @_callbacks, child\subscribe (...) -> @append ... + child = child\get! + + child = asnode child + ok, last = pcall asnode, last + if ok + @node\removeChild last + @node\appendChild child + + remove: (child) => + @node\removeChild asnode child + +text = (...) -> document\createTextNode table.concat { ... }, ' ' + +with exports = { + :Callback, + :CallbackElement, + :text, + } + add = (e) -> exports[e] = (...) -> CallbackElement e, ... + + for e in *{'div', 'form', 'span', 'a', 'p', 'button', 'ul', 'li', 'i', 'b', 'u', 'tt'} do add e + for e in *{'br', 'img', 'input', 'p', 'textarea'} do add e + for i=1,8 do add "h" .. i diff --git a/app/html.moon b/app/html.moon index cf4a6e6..3565f32 100644 --- a/app/html.moon +++ b/app/html.moon @@ -4,7 +4,7 @@ element = (element) -> (attrs = {}, ...) -> if 'table' != type attrs attrs = { attrs, ... } with e = document\createElement element - for k,v in pairs(attrs) + for k,v in pairs attrs continue unless 'string' == type k e[k] = v for child in *attrs diff --git a/app/index.moon b/app/index.moon index b501d57..e43b318 100644 --- a/app/index.moon +++ b/app/index.moon @@ -8,12 +8,15 @@ back_button = -> document.body\appendChild p a { '< back', href: '/' } switch window.location.search - when "?twisted" + when '?twisted' back_button! require './twisted.moon' - when "?center-of-mass" then + when '?center-of-mass' then back_button! require './centerofmass.moon' + when '?todo' then + back_button! + require './todo.moon' else document.body\appendChild h1 'mmm' document.body\appendChild p { @@ -29,7 +32,7 @@ switch window.location.search '.' } document.body\appendChild p 'current demos:' - document.body\appendChild ul for name in *{'twisted', 'center-of-mass'} + document.body\appendChild ul for name in *{'twisted', 'center-of-mass', 'todo'} li a { name, href: "/?#{name}" } document.body\appendChild p { diff --git a/app/todo.moon b/app/todo.moon new file mode 100644 index 0000000..c38ce26 --- /dev/null +++ b/app/todo.moon @@ -0,0 +1,30 @@ +{ :document } = js.global +import Callback, CallbackElement, text, div, form, span, h3, a, input, textarea, button from require './component.moon' + +parent = div! +todoItem = (desc, done) -> + -- convert into reactive data sources + desc, done = (Callback desc), Callback done + with me = div style: + margin: '8px' + padding: '8px' + background: '#eeeeee' + \append h3 style: 'margin: 0;', desc + \append span done\chain (done) -> text if done then 'done' else 'not done yet' + \append input type: 'checkbox', checked: done, onchange: (e) => done\set e.target.checked + \append a href: '#', onclick: ((e) => parent\remove me), text 'delete' + +parent\append todoItem 'write a Component System' +parent\append todoItem 'eat Lasagna', true + +form = with form action: '', style: 'margin 2px;' + desc = input type: 'text', value: 'start' + \append desc + \append input type: 'submit', value: 'add' + \set 'onsubmit', (e) => + e\preventDefault! + parent\append todoItem desc.node.value + desc.node.value = '' + +document.body\appendChild parent.node +document.body\appendChild form.node diff --git a/dist b/dist -Subproject 8de7ba386d87e74ffd83fec00d50ad8f6bfd301 +Subproject b1ee5409d7fcf9ee3c24afbcfcce1ef1e20eb7d diff --git a/webpack.config.js b/webpack.config.js index c5d22c3..1ac757b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -17,6 +17,6 @@ module.exports = { ] }, plugins: [ - new HtmlWebpackPlugin('MMM: lunar low-gravity scripting playground'), + new HtmlWebpackPlugin({ title: 'MMM: lunar low-gravity scripting playground' }), ], } |
