Skip to content

Commit 2425a56

Browse files
committed
Add ElixirScript.JS.mutate
1 parent cc6e624 commit 2425a56

File tree

4 files changed

+98
-10
lines changed

4 files changed

+98
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88

99
### Added
1010
- ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI`
11+
- ElixirScript.JS.mutate/2
12+
- ElixirScript.JS.mutate/3
1113

1214
### Changed
1315
- Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+

lib/elixir_script/lib/js.ex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,18 @@ defmodule ElixirScript.JS do
3737
The current JavaScript context
3838
"""
3939
defmacro this()
40+
41+
@doc """
42+
Mutates an existing JavaScript object.
43+
ex:
44+
ElixirScript.JS.mutate elem, %{"width" => 100}
45+
"""
46+
defmacro update(object, map)
47+
48+
@doc """
49+
Mutates an existing JavaScript object.
50+
ex:
51+
ElixirScript.JS.mutate elem, "width", 100
52+
"""
53+
defmacro update(object, key, value)
4054
end

lib/elixir_script/passes/translate/forms/js.ex

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,6 @@ defmodule ElixirScript.Translate.Forms.JS do
1616
)
1717
end
1818

19-
def global() do
20-
J.member_expression(
21-
J.member_expression(
22-
J.identifier("Bootstrap"),
23-
J.identifier("Core")
24-
),
25-
J.identifier("global")
26-
)
27-
end
28-
2919
def compile({{:., _, [ElixirScript.JS, :debugger]}, _, _}, state) do
3020
ast = J.debugger_statement()
3121
{ast, state}
@@ -77,4 +67,35 @@ defmodule ElixirScript.Translate.Forms.JS do
7767

7868
{ast, state}
7969
end
70+
71+
def compile({{:., _, [ElixirScript.JS, :mutate]}, _, [object, map]}, state) do
72+
ast = J.call_expression(
73+
J.member_expression(
74+
J.identifier("Object"),
75+
J.identifier("assign")
76+
),
77+
[
78+
Form.compile!(object, state),
79+
Form.compile!(map, state)
80+
]
81+
)
82+
83+
{ast, state}
84+
end
85+
86+
def compile({{:., _, [ElixirScript.JS, :mutate]}, _, [object, key, value]}, state) do
87+
ast = J.assignment_expression(
88+
:=,
89+
J.member_expression(
90+
Form.compile!(object, state),
91+
Form.compile!(key, state),
92+
true
93+
),
94+
[
95+
Form.compile!(value, state)
96+
]
97+
)
98+
99+
{ast, state}
100+
end
80101
end

test/passes/translate/forms/js_test.exs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,55 @@ defmodule ElixirScript.Translate.Forms.JS.Test do
6464
[J.literal("react")]
6565
)
6666
end
67+
68+
test "mutate/2" do
69+
properties = [{"a", 1}]
70+
map_ast = {:%{}, [], properties}
71+
72+
ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [{:%{}, [], []}, map_ast]}
73+
state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}}
74+
75+
{js_ast, _} = Form.compile(ast, state)
76+
assert js_ast == J.call_expression(
77+
J.member_expression(
78+
J.identifier("Object"),
79+
J.identifier("assign")
80+
),
81+
[
82+
J.object_expression([]),
83+
J.object_expression([
84+
J.property(
85+
J.identifier("a"),
86+
J.literal(1)
87+
)
88+
])
89+
]
90+
)
91+
end
92+
93+
test "mutate/3" do
94+
properties = [{"a", 1}]
95+
map_ast = {:%{}, [], properties}
96+
97+
ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [map_ast, "a", 2]}
98+
state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}}
99+
100+
{js_ast, _} = Form.compile(ast, state)
101+
assert js_ast == J.assignment_expression(
102+
:=,
103+
J.member_expression(
104+
J.object_expression([
105+
J.property(
106+
J.identifier("a"),
107+
J.literal(1)
108+
)
109+
]),
110+
J.literal("a"),
111+
true
112+
),
113+
[
114+
J.literal(2)
115+
]
116+
)
117+
end
67118
end

0 commit comments

Comments
 (0)