Browse Source

Fast, Multi, qs allowed

1. More faster with iolists
2. Multi DOM manage with requestAnimationFrame
3. qs(selector) allowed for actions (partially)
m-2k 8 years ago
parent
commit
b07706191a

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+ebin
+.DS_Store

+ 6 - 0
include/nitro.hrl

@@ -185,6 +185,12 @@
 % Actions
 -record(action,  {?ACTION_BASE(undefined)}).
 -record(wire,    {?ACTION_BASE(action_wire)}).
+
+-record(replace, {?ACTION_BASE(action_manage), elements}).
+-record(insert,  {?ACTION_BASE(action_manage), elements, position = beforeend}).
+-record(multi,   {?ACTION_BASE(action_manage)}).
+-record(focus,   {?ACTION_BASE(action_ui)}).
+
 -record(api,     {?ACTION_BASE(action_api), name, tag, delegate }).
 -record(event,   {?ACTION_BASE(action_event), type=default, postback, delegate, validation=[]}).
 -record(bind,    {?ACTION_BASE(action_bind), type=click, postback=[]}).

+ 1 - 1
src/actions/action_alert.erl

@@ -3,4 +3,4 @@
 -include_lib("nitro/include/nitro.hrl").
 -compile(export_all).
 
-render_action(Record) -> nitro:f("alert(\"~s\");", [nitro:js_escape(Record#alert.text)]).
+render_action(#alert{text=T}) -> ["alert(\"",nitro:js_escape(T),"\");"].

+ 5 - 4
src/actions/action_api.erl

@@ -3,9 +3,10 @@
 -include_lib("nitro/include/nitro.hrl").
 -compile(export_all).
 
-render_action(Record) ->
-    Name = Record#api.name,
+-define(B(E), nitro:to_binary(E)).
+
+render_action(#api{name=Name,delegate=Delegate}) ->
     Data = "utf8_toByteArray(JSON.stringify(data))",
-    PostbackScript = wf_event:new(Name, "document", Record#api.delegate, api_event, Data, []),
-    nitro:f("~s = function(data) {",  [Name]) ++ binary_to_list(PostbackScript) ++ "};".
+    PostbackScript = wf_event:new(Name, "document", Delegate, api_event, Data, []),
+    [?B(Name),"=function(data){",PostbackScript,"};"].
 

+ 4 - 1
src/actions/action_bind.erl

@@ -3,5 +3,8 @@
 -include_lib("nitro/include/nitro.hrl").
 -compile(export_all).
 
+-define(B(E), nitro:to_binary(E)).
+-define(T(T), wf_event:target(T)).
+
 render_action(#bind{postback=Code,target=Control,type=Type}) ->
-    [list_to_binary(nitro:f("{ var x=qi('~s'); if(x)x.addEventListener('~s', function(e) { ~s }); }",[Control,Type,Code]))].
+    ["{var x=",?T(Control),"; x && x.addEventListener('",?B(Type),"',function(event){",?B(Code),"});}"].

+ 2 - 9
src/actions/action_confirm.erl

@@ -3,14 +3,7 @@
 -include_lib("nitro/include/nitro.hrl").
 -compile(export_all).
 
-render_action(Record) -> 
-    Control = Record#confirm.target,
-    Delegate = Record#confirm.delegate,
-    Postback = Record#confirm.postback,
+render_action(#confirm{target=Control,text=Text,postback=Postback,delegate=Delegate}) -> 
     PostbackScript = wf_event:new(Postback, Control, Delegate, event, "[]", []),
-    [
-        nitro:f("if (confirm(\"~s\")) {", [nitro:js_escape(Record#confirm.text)]),
-        PostbackScript,
-        "}"
-    ].
+    ["if (confirm(\"",nitro:js_escape(Text),"\")) {",PostbackScript,"}"].
 

+ 12 - 12
src/actions/action_event.erl

@@ -1,21 +1,21 @@
 -module(action_event).
-
+-author('Maxim Sokhatsky').
+-author('Andrey Martemyanov').
 -include_lib("nitro/include/nitro.hrl").
 -compile(export_all).
 
+-define(B(E), nitro:to_binary(E)).
+
 render_action(#event{source=undefined}) -> [];
 render_action(#event{postback=Postback,actions=_A,source=Source,target=Control,type=Type,delegate=D,validation=V}) ->
-    Element = nitro:to_list(Control),
+    E = ?B(Control),
     ValidationSource = [ S || S <- Source, not is_tuple(S) ],
-    PostbackBin = wf_event:new(Postback, Element, D, event, data(Element,Source), ValidationSource, V),
-    [list_to_binary([<<"{ var x=qi('">>,Element,<<"'); x && x.addEventListener('">>,
-        nitro:to_binary(Type),<<"',function (event){ ">>,
-        PostbackBin,<<"});};">>])].
+    PostbackBin = wf_event:new(Postback, E, D, event, data(E,Source), ValidationSource, V),
+    ["{var x=qi('",E,"'); x && x.addEventListener('",?B(Type),"',function (event){ ",PostbackBin,"});};"].
 
-data(Element,SourceList) ->
+data(E,SourceList) ->
     Type=fun(A) when is_atom(A) -> [ "atom('",atom_to_list(A),"')" ]; (A) -> [ "utf8_toByteArray('",A,"')" ] end,
-    list_to_binary([<<"[tuple(tuple(utf8_toByteArray('">>,Element,<<"'),bin('detail')),[])">>,
-        [ begin case S of
-                {Id,JsGetCode} -> [ ",tuple(",Type(Id),",",JsGetCode,")" ];
-                _ -> [ ",tuple(",Type(S),",querySource('",nitro:to_list(S),"'))" ]
-            end end || S <- SourceList ], <<"]">>]).
+    list_to_binary(["[tuple(tuple(utf8_toByteArray('",E,"'),bin('detail')),[])",
+        [ case S of {Id,Code} -> [ ",tuple(",Type(Id),",",Code,")" ];
+                            _ -> [ ",tuple(",Type(S),",querySource('",?B(S),"'))" ]
+          end || S <- SourceList ],"]"]).

+ 15 - 23
src/actions/action_jq.erl

@@ -1,28 +1,20 @@
 -module(action_jq).
+-author('Rusty Klophaus').
+-author('Andrey Martemyanov').
 -include_lib("nitro/include/nitro.hrl").
 -compile(export_all).
 
-render_action(Record=#jq{property=undefined,target=Target,method=Methods,args=Args0,format=_F}) ->
-    Args = case Record#jq.format of "'~s'" -> [nitro:render(Args0)]; _ -> Args0 end,
-    RenderedArgs = string:join([ case A of 
-        A when is_tuple(A) -> nitro:render(A);
-        A when is_list(A) -> A;
-        A when is_integer(A) -> nitro:to_list(A);
-        A -> A end || A <- Args],","),
-    string:join([ nitro:f("qi('~s').~s("++Record#jq.format++");",
-        [nitro:to_list(Target),nitro:to_list(Method),RenderedArgs]) || Method <- Methods],[]);
+-define(B(E), nitro:to_binary(E)).
+-define(R(E), nitro:render(E)).
+-define(T(T), wf_event:target(T)).
+-define(U, undefined).
 
-render_action(#jq{target=T,method=undefined,property=P,args=simple,right=R,format=_F}) ->
-    nitro:f("~s.~s = '~s';",
-        [nitro:to_list(T),nitro:to_list(P),binary_to_list(iolist_to_binary(nitro:render(R)))]);
-
-render_action(#jq{target=T,method=undefined,property=P,right=undefined}) ->
-    nitro:f("qi('~s').~s;", [nitro:to_list(T),nitro:to_list(P)]);
-
-render_action(#jq{target=T,method=undefined,property=P,right=#jq{}=R,format=_F}) ->
-    nitro:f("qi('~s').~s = ~s;",
-        [nitro:to_list(T),nitro:to_list(P),binary_to_list(iolist_to_binary(nitro:render(R)))]);
-
-render_action(#jq{target=T,method=undefined,property=P,right=R,format=_F}) ->
-    nitro:f("qi('~s').~s = '~s';",
-        [nitro:to_list(T),nitro:to_list(P),binary_to_list(iolist_to_binary(nitro:render(R)))]).
+render_action(#jq{property=?U,target=T,method=Methods,args=Args0,format=F}) ->
+    Args = case F of "'~s'" -> [ ?R(Args0) ]; _ -> Args0 end,
+    Format = fun(A) when is_tuple(A) orelse is_integer(A) -> ?R(A); (A) -> A end,
+    RenderedArgs = string:join([ Format(A) || A <- Args], ","),
+    [[?T(T),".",?B(M),"(",nitro:f(F,[RenderedArgs]),");"] || M <- Methods];
+render_action(#jq{target=T,method=?U,property=P,right=R,args=simple}) -> [?B(T),".",?B(P),"='",?R(R),"';"];
+render_action(#jq{target=T,method=?U,property=P,right=?U})            -> [?T(T),".",?B(P),";"];
+render_action(#jq{target=T,method=?U,property=P,right=#jq{}=R})       -> [?T(T),".",?B(P),"=", ?R(R), ";"];
+render_action(#jq{target=T,method=?U,property=P,right=R})             -> [?T(T),".",?B(P),"='",?R(R),"';"].

+ 20 - 0
src/actions/action_manage.erl

@@ -0,0 +1,20 @@
+-module(action_manage).
+-author('Andrey Martemyanov').
+-include_lib("nitro/include/nitro.hrl").
+-compile(export_all).
+
+-define(B(E), nitro:to_binary(E)).
+-define(R(E), nitro:render(E)).
+-define(T(T), wf_event:target(T)).
+
+render_action(#replace{target=T,elements=E}) -> ?R(#jq{target=T,property=outerHTML,right=E});
+render_action(#insert{target=T,elements=E,position=P}) ->
+    {Rendered,Actions}=render_element(E),
+    [?T(T),".insertAdjacentHTML('",?B(P),"','",Rendered,"');",?R(Actions)];
+render_action(#multi{actions=A}) -> ["window.requestAnimationFrame(function(timestamp){",?R(A),"});"].
+
+render_element(E) ->
+    Pid = self(),
+    Ref = make_ref(),
+    spawn(fun() -> Pid ! {?R(E),Ref,wf:actions()} end),
+    receive {Rendered, Ref, Actions} -> {Rendered,Actions} end.

+ 8 - 0
src/actions/action_ui.erl

@@ -0,0 +1,8 @@
+-module(action_ui).
+-author('Andrey Martemyanov').
+-include_lib("nitro/include/nitro.hrl").
+-compile(export_all).
+
+-define(T(T), wf_event:target(T)).
+
+render_action(#focus{target=T}) -> ["window.setTimeout(function(){var x=",?T(T),"; x && x.focus();},4);"].

+ 12 - 7
src/render/wf_event.erl

@@ -1,5 +1,6 @@
 -module(wf_event).
 -author('Maxim Sokhatsky').
+-author('Andrey Martemyanov').
 -include_lib ("nitro/include/nitro.hrl").
 -compile(export_all).
 
@@ -7,17 +8,21 @@
 -record(cx, { handlers, actions, req, module, lang, path, session, formatter, params, form, state=[] }).
 -define(CTX, (get(context))).
 
+-define(B(E), nitro:to_binary(E)).
+target({qs,S}) -> ["qs('",S,"')"];
+target(Id)     -> ["qi('",?B(Id),"')"].
+
 new(P,E,D,N,Data,Source) -> new(P,E,D,N,Data,Source,<<>>).
 
 new(bin,Data) -> <<"ws.send(enc(tuple(atom('bin'),bin('",(nitro:pickle(Data))/binary,"'))));">>.
 new(undefined, _, _, _, _, _, _) -> <<>>;
 new(Postback, Element, Delegate, Name, Data, Source, Validation) ->
     Module = nitro:coalesce([Delegate, ?CTX#cx.module]),
-    Join=fun([]) -> []; ([E]) -> [$'|E]++[$'];
-        ([H|T]) -> [[$'|H]++[$']] ++ [ [$,,$'|E]++[$'] || E <- T ] end,
+    Join=fun([]) -> [];
+           ([E]) -> [$'|E]++[$'];
+         ([H|T]) -> [[$'|H]++[$']] ++ [ [$,,$'|E]++[$'] || E <- T ] end,
     Event = #ev{name=Name, module=Module, msg=Postback, trigger=Element},
-    erlang:list_to_binary([ <<"{ if (validateSources([">>,
-        Join([ case is_atom(S) of true -> atom_to_list(S); false -> S end || S <- Source, S =/= []]),
-        <<"])) { ">>,nitro:to_binary(Validation),<<" ws.send(enc(tuple(atom('">>,
-        nitro:to_binary(application:get_env(n2o,event,pickle)),<<"'),bin('">>,Element,<<"'),bin('">>,
-        nitro:pickle(Event),<<"'),">>,Data,<<"))); } else console.log('Validation Error'); }">> ]).
+    list_to_binary(["{ if (validateSources([",
+        Join([ case is_atom(S) of true -> ?B(S); false -> S end || S <- Source, S =/= []]),
+        "])) { ",?B(Validation)," ws.send(enc(tuple(atom('",?B(application:get_env(n2o,event,pickle)),"'),bin('",
+        Element,"'),bin('",nitro:pickle(Event),"'),",Data,"))); } else console.log('Validation Error'); }"]).