Skip to content

Commit c2ae00c

Browse files
committed
Added View module for updating view based on state passed in
1 parent 52d09c4 commit c2ae00c

File tree

5 files changed

+126
-17
lines changed

5 files changed

+126
-17
lines changed

lib/elixir_script/lib/html.ex

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,42 @@ defmodule ElixirScript.Html do
3030
@doc """
3131
Defines a macro for the html element, #{tag}
3232
"""
33-
defmacro unquote(tag)(attributes \\ [], block \\ [do: nil]) do
33+
defmacro unquote(tag)(attrs, do: inner) do
3434
tag = Atom.to_string(unquote(tag))
35+
{ inner, attributes } = do_tag(inner, attrs)
3536

36-
inner = case Keyword.get(block, :do) do
37-
{:__block__, [], params} ->
38-
params
39-
nil ->
40-
[]
41-
x ->
42-
[x]
37+
quote do
38+
Elixir.VirtualDOM.h(unquote(tag), unquote(attributes), unquote_splicing(inner))
4339
end
40+
end
41+
42+
defmacro unquote(tag)(attrs \\ []) do
43+
tag = Atom.to_string(unquote(tag))
4444

45-
attributes = config_to_map(attributes)
45+
{ inner, attributes } = Dict.pop(attrs, :do)
46+
{ inner, attributes } = do_tag(inner, attributes)
4647

4748
quote do
4849
Elixir.VirtualDOM.h(unquote(tag), unquote(attributes), unquote_splicing(inner))
4950
end
5051
end
5152
end
5253

54+
defp do_tag(inner, attributes) do
55+
inner = case inner do
56+
{:__block__, [], params} ->
57+
params
58+
nil ->
59+
[]
60+
x ->
61+
[x]
62+
end
63+
64+
attributes = config_to_map(attributes)
65+
66+
{inner, attributes}
67+
end
68+
5369
defp config_to_map(config) do
5470
config = Enum.map(config, fn({key, value}) ->
5571
if is_atom(key) do

lib/elixir_script/translator/function.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ defmodule ElixirScript.Translator.Function do
55
alias ElixirScript.Translator.Utils
66
alias ElixirScript.PatternMatching.Match
77
alias ElixirScript.Preprocess.Variables
8-
alias ElixirScript.Translator.Map
98

109
@standard_libs [
1110
:Patterns, :Kernel, :Atom, :Enum, :Integer, :JS,
1211
:List, :Range, :Tuple, :Agent, :Keyword, :BitString,
1312
:Base, :String, :Bitwise, :Collectable, :Enumerable,
14-
:Inspect, :Map, :MapSet, :Set, :VirtualDom, :ViewAgent
13+
:Inspect, :Map, :MapSet, :Set, :VirtualDom, :View
1514
]
1615

1716
def update_alias({:__aliases__, context, [:List, :Chars]}) do

priv/elixir.js

Lines changed: 49 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/javascript/elixir.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ export { default as Set } from './lib/set';
2525
export { default as MapSet } from './lib/map_set';
2626
export { IntegerType, FloatType } from './lib/protocol';
2727
export { default as VirtualDOM } from './lib/virtual-dom';
28+
export { default as View } from './lib/view';

src/javascript/lib/view.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import Kernel from './kernel';
2+
import Keyword from './keyword';
3+
import VirtualDOM from './virtual-dom';
4+
5+
6+
const start = function(domRoot, renderFn, initialState, options = []){
7+
const name = Keyword.has_key__qm__(options, Kernel.SpecialForms.atom("name")) ? Keyword.get(options, Kernel.SpecialForms.atom("name")) : Symbol();
8+
9+
self.post_office.add_mailbox(name);
10+
11+
const tree = renderFn.apply(this, initialState);
12+
const rootNode = VirtualDOM.create(tree);
13+
14+
domRoot.appendChild(rootNode);
15+
self.post_office.send(name, Kernel.SpecialForms.tuple(rootNode, tree, renderFn));
16+
17+
return Kernel.SpecialForms.tuple(Kernel.SpecialForms.atom("ok"), name);
18+
}
19+
20+
const stop = function(agent, timeout = 5000){
21+
self.post_office.remove_mailbox(agent);
22+
return Kernel.SpecialForms.atom("ok");
23+
}
24+
25+
26+
const update = function(agent, state){
27+
28+
const current_state = self.post_office.receive(agent);
29+
30+
let rootNode = Kernel.elem(current_state, 0);
31+
let tree = Kernel.elem(current_state, 1);
32+
let renderFn = Kernel.elem(current_state, 2);
33+
34+
let newTree = renderFn.apply(this, state);
35+
36+
let patches = VirtualDOM.diff(tree, newTree)
37+
rootNode = VirtualDOM.patch(rootNode, patches)
38+
39+
40+
self.post_office.send(agent, Kernel.SpecialForms.tuple(rootNode, newTree, renderFn));
41+
42+
return Kernel.SpecialForms.atom("ok");
43+
}
44+
45+
46+
export default {
47+
start,
48+
stop,
49+
update
50+
}

0 commit comments

Comments
 (0)