Namdak Tonpa 3 лет назад
Родитель
Сommit
649e4a686f
8 измененных файлов с 634 добавлено и 300 удалено
  1. 0 1
      lib/NITRO.ex
  2. 1 1
      mix.exs
  3. 16 0
      rebar.config
  4. 1 1
      src/nitro.app.src
  5. 229 98
      src/nitro.erl
  6. 192 104
      src/nitro_conv.erl
  7. 119 60
      src/nitro_n2o.erl
  8. 76 35
      src/nitro_static.erl

+ 0 - 1
lib/NITRO.ex

@@ -15,7 +15,6 @@ defmodule NITRO do
       Enum.each(
         Record.extract_all(from_lib: "nitro/include/" <> t),
         fn {name, definition} ->
-#          IO.inspect({name, definition, t})
           prev = :application.get_env(:kernel, :nitro_tables, [])
 
           case :lists.member(name, prev) do

+ 1 - 1
mix.exs

@@ -4,7 +4,7 @@ defmodule NITRO.Mixfile do
   def project do
     [
       app: :nitro,
-      version: "6.9.1",
+      version: "6.11.0",
       description: "NITRO Nitrogen Web Framework",
       package: package(),
       deps: deps()

+ 16 - 0
rebar.config

@@ -1,3 +1,19 @@
 {lib_dirs,[".."]}.
 {erl_opts, [nowarn_export_all,nowarn_deprecated_function]}.
 {deps, []}.
+{project_plugins, [rebar3_format]}.
+{format, [
+    {files, ["src/*.erl", "test/*.erl"]},
+    {formatter, otp_formatter},
+    {options, #{ line_length => 108,
+                 paper => 250,
+                 spaces_around_fields => false,
+                 inlining => all,
+                 inline_clause_bodies => true,
+                 inline_expressions => true,
+                 inline_qualified_function_composition => true,
+                 inline_simple_funs => true,
+                 inline_items => all,
+                 inline_fields => true,
+                 inline_attributes => true
+                 }}]}.

+ 1 - 1
src/nitro.app.src

@@ -1,6 +1,6 @@
 {application, nitro, [
     {description,  "NITRO Nitrogen Web Framework"},
-    {vsn,          "6.6.0"},
+    {vsn,          "6.11.0"},
     {applications, [kernel, stdlib]},
     {modules, []},
     {registered,   []},

+ 229 - 98
src/nitro.erl

@@ -1,90 +1,150 @@
 -module(nitro).
+
 -include_lib("nitro/include/cx.hrl").
+
 -include_lib("nitro/include/nitro.hrl").
+
 -include_lib("nitro/include/event.hrl").
+
 -compile(export_all).
+
 -behaviour(application).
+
 -export([start/2, stop/1, init/1]).
 
-atom(List) when is_list(List) -> string:join([ nitro:to_list(L) || L <- List], "_");
+atom(List) when is_list(List) ->
+    string:join([nitro:to_list(L) || L <- List], "_");
 atom(Scalar) -> nitro:to_list(Scalar).
 
 q(Key) -> q(Key, []).
-q(Key, Def) -> case get(Key) of undefined -> Def; Val -> Val end.
 
-qc(Key) -> CX = get(context), qc(Key,CX#cx.req).
-qc(Key,Req) -> proplists:get_value(nitro:to_binary(Key),cowboy_req:parse_qs(Req)).
+q(Key, Def) ->
+    case get(Key) of
+        undefined -> Def;
+        Val -> Val
+    end.
+
+qc(Key) ->
+    CX = get(context),
+    qc(Key, CX#cx.req).
+
+qc(Key, Req) ->
+    proplists:get_value(nitro:to_binary(Key),
+                        cowboy_req:parse_qs(Req)).
+
+start(_StartType, _StartArgs) ->
+    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
 
-start(_StartType, _StartArgs) -> supervisor:start_link({local, ?MODULE}, ?MODULE, []).
 stop(_State) -> ok.
+
 init([]) -> {ok, {{one_for_one, 5, 10}, []}}.
 
 f(S) -> f(S, []).
+
 f(S, Args) -> lists:flatten(io_lib:format(S, Args)).
 
 coalesce([]) -> undefined;
 coalesce([H]) -> H;
-coalesce([undefined|T]) -> coalesce(T);
-coalesce([[]|T]) -> coalesce(T);
-coalesce([H|_]) -> H.
+coalesce([undefined | T]) -> coalesce(T);
+coalesce([[] | T]) -> coalesce(T);
+coalesce([H | _]) -> H.
 
 jse(X) -> js_escape(X).
-hte(X) when is_binary(X) -> nitro:to_binary(nitro_conv:html_encode(X));
+
+hte(X) when is_binary(X) ->
+    nitro:to_binary(nitro_conv:html_encode(X));
 hte(X) -> nitro_conv:html_encode(X).
 
 js_escape(Value) -> nitro_conv:js_escape(Value).
 
--define(IS_STRING(Term), (is_list(Term) andalso Term /= [] andalso is_integer(hd(Term)))).
+-define(IS_STRING(Term),
+        is_list(Term) andalso
+            Term /= [] andalso is_integer(hd(Term))).
 
 to_list(L) when ?IS_STRING(L) -> L;
-to_list(L) when is_list(L) -> SubLists = [inner_to_list(X) || X <- L], lists:flatten(SubLists);
+to_list(L) when is_list(L) ->
+    SubLists = [inner_to_list(X) || X <- L],
+    lists:flatten(SubLists);
 to_list(A) -> inner_to_list(A).
+
 inner_to_list(A) when is_atom(A) -> atom_to_list(A);
 inner_to_list(B) when is_binary(B) -> binary_to_list(B);
-inner_to_list(I) when is_integer(I) -> integer_to_list(I);
-inner_to_list(L) when is_tuple(L) -> lists:flatten(io_lib:format("~p", [L]));
+inner_to_list(I) when is_integer(I) ->
+    integer_to_list(I);
+inner_to_list(L) when is_tuple(L) ->
+    lists:flatten(io_lib:format("~p", [L]));
 inner_to_list(L) when is_list(L) -> L;
-inner_to_list(F) when is_float(F) -> float_to_list(F,[{decimals,9},compact]).
+inner_to_list(F) when is_float(F) ->
+    float_to_list(F, [{decimals, 9}, compact]).
 
 to_atom(A) when is_atom(A) -> A;
-to_atom(B) when is_binary(B) -> to_atom(binary_to_list(B));
-to_atom(I) when is_integer(I) -> to_atom(integer_to_list(I));
-to_atom(F) when is_float(F) -> to_atom(float_to_list(F,[{decimals,9},compact]));
-to_atom(L) when is_list(L) -> list_to_atom(binary_to_list(list_to_binary(L))).
-
-to_binary(A) when is_atom(A) -> atom_to_binary(A,latin1);
+to_atom(B) when is_binary(B) ->
+    to_atom(binary_to_list(B));
+to_atom(I) when is_integer(I) ->
+    to_atom(integer_to_list(I));
+to_atom(F) when is_float(F) ->
+    to_atom(float_to_list(F, [{decimals, 9}, compact]));
+to_atom(L) when is_list(L) ->
+    list_to_atom(binary_to_list(list_to_binary(L))).
+
+to_binary(A) when is_atom(A) ->
+    atom_to_binary(A, latin1);
 to_binary(B) when is_binary(B) -> B;
-to_binary(I) when is_integer(I) -> to_binary(integer_to_list(I));
-to_binary(F) when is_float(F) -> float_to_binary(F,[{decimals,9},compact]);
-to_binary(L) when is_list(L) ->  iolist_to_binary(L);
-to_binary(X) when is_tuple(X) ->  term_to_binary(X).
+to_binary(I) when is_integer(I) ->
+    to_binary(integer_to_list(I));
+to_binary(F) when is_float(F) ->
+    float_to_binary(F, [{decimals, 9}, compact]);
+to_binary(L) when is_list(L) -> iolist_to_binary(L);
+to_binary(X) when is_tuple(X) -> term_to_binary(X).
 
 -ifndef(PICKLER).
--define(PICKLER, (application:get_env(n2o,pickler,nitro_conv))).
+
+-define(PICKLER,
+        application:get_env(n2o, pickler, nitro_conv)).
+
 -endif.
 
-pickle(Data) -> ?PICKLER:pickle(Data).
-depickle(SerializedData) -> ?PICKLER:depickle(SerializedData).
+pickle(Data) -> (?PICKLER):pickle(Data).
 
-prolongate() -> case application:get_env(n2o,session) of {ok, M} -> M:prolongate(); undefined -> false end.
-authenticate(I, Auth) -> (application:get_env(n2o,session,n2o_session)):authenticate(I, Auth).
+depickle(SerializedData) ->
+    (?PICKLER):depickle(SerializedData).
+
+prolongate() ->
+    case application:get_env(n2o, session) of
+        {ok, M} -> M:prolongate();
+        undefined -> false
+    end.
+
+authenticate(I, Auth) ->
+    (application:get_env(n2o,
+                         session,
+                         n2o_session)):authenticate(I, Auth).
 
 render(X) -> wf_render:render(X).
+
 wire(Actions) -> action_wire:wire(Actions).
 
 unique_integer() -> erlang:unique_integer().
-temp_id() -> "auto" ++ integer_to_list(unique_integer() rem 1000000).
 
-html_encode(L,Fun) when is_function(Fun) -> Fun(L);
-html_encode(L,EncType) when is_atom(L) -> html_encode(nitro:to_list(L),EncType);
-html_encode(L,EncType) when is_integer(L) -> html_encode(integer_to_list(L),EncType);
-html_encode(L,EncType) when is_float(L) -> html_encode(float_to_list(L,[{decimals,9},compact]),EncType);
+temp_id() ->
+    "auto" ++ integer_to_list(unique_integer() rem 1000000).
+
+html_encode(L, Fun) when is_function(Fun) -> Fun(L);
+html_encode(L, EncType) when is_atom(L) ->
+    html_encode(nitro:to_list(L), EncType);
+html_encode(L, EncType) when is_integer(L) ->
+    html_encode(integer_to_list(L), EncType);
+html_encode(L, EncType) when is_float(L) ->
+    html_encode(float_to_list(L, [{decimals, 9}, compact]),
+                EncType);
 html_encode(L, false) -> L;
 html_encode(L, true) -> L;
-html_encode(L, whites) -> html_encode_whites(nitro:to_list(lists:flatten([L]))).
+html_encode(L, whites) ->
+    html_encode_whites(nitro:to_list(lists:flatten([L]))).
+
 html_encode(<<>>) -> [];
 html_encode([]) -> [];
-html_encode([H|T]) ->
+html_encode([H | T]) ->
     case H of
         $< -> "&lt;" ++ html_encode(T);
         $> -> "&gt;" ++ html_encode(T);
@@ -92,134 +152,205 @@ html_encode([H|T]) ->
         $' -> "&#39;" ++ html_encode(T);
         $& -> "&amp;" ++ html_encode(T);
         BigNum when is_integer(BigNum) andalso BigNum > 255 ->
-        [$&,$# | nitro:to_list(BigNum)] ++ ";" ++ html_encode(T);
-        Tup when is_tuple(Tup) -> throw({html_encode,encountered_tuple,Tup});
-        _ -> [H|html_encode(T)]
+            [$&, $# | nitro:to_list(BigNum)] ++
+                ";" ++ html_encode(T);
+        Tup when is_tuple(Tup) ->
+            throw({html_encode, encountered_tuple, Tup});
+        _ -> [H | html_encode(T)]
     end.
 
 html_encode_whites([]) -> [];
-html_encode_whites([H|T]) ->
+html_encode_whites([H | T]) ->
     case H of
         $\s -> "&nbsp;" ++ html_encode_whites(T);
-        $\t -> "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" ++ html_encode_whites(T);
+        $\t ->
+            "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" ++
+                html_encode_whites(T);
         $< -> "&lt;" ++ html_encode_whites(T);
         $> -> "&gt;" ++ html_encode_whites(T);
         $" -> "&quot;" ++ html_encode_whites(T);
         $' -> "&#39;" ++ html_encode_whites(T);
         $& -> "&amp;" ++ html_encode_whites(T);
         $\n -> "<br>" ++ html_encode_whites(T);
-        _ -> [H|html_encode_whites(T)]
+        _ -> [H | html_encode_whites(T)]
     end.
 
 script() -> get(script).
-script(Script) -> put(script,Script).
+
+script(Script) -> put(script, Script).
 
 % Update DOM nitro:update
 
 update(Target, Elements) ->
-    nitro:wire(#jq{target=Target,property=outerHTML,right=Elements,format="`~s`"}).
+    nitro:wire(#jq{target = Target, property = outerHTML,
+                   right = Elements, format = "`~s`"}).
 
-insert_top(Tag,Target, Elements) ->
+insert_top(Tag, Target, Elements) ->
     {Render, _Ref, Actions} = render_html(Elements),
-    nitro:wire(nitro:f(
-        "qi('~s').insertBefore("
-        "(function(){var div = qn('~s'); div.innerHTML = `~s`; return div.firstChild; })(),"
-        "qi('~s').firstChild);",
-        [Target,Tag,Render,Target])),
+    nitro:wire(nitro:f("qi('~s').insertBefore((function(){var "
+                       "div = qn('~s'); div.innerHTML = `~s`; "
+                       "return div.firstChild; })(),qi('~s').firstChi"
+                       "ld);",
+                       [Target, Tag, Render, Target])),
     nitro:wire(nitro:render(Actions)).
 
 insert_bottom(Tag, Target, Elements) ->
     {Render, _Ref, Actions} = render_html(Elements),
-    nitro:wire(nitro:f(
-        "(function(){ var div = qn('~s'); div.innerHTML = `~s`;"
-                     "qi('~s').appendChild(div.firstChild); })();",
-        [Tag,Render,Target])),
+    nitro:wire(nitro:f("(function(){ var div = qn('~s'); div.innerHTM"
+                       "L = `~s`;qi('~s').appendChild(div.firstChild)"
+                       "; })();",
+                       [Tag, Render, Target])),
     nitro:wire(nitro:render(Actions)).
 
-insert_before(Target, Elements) -> insert_adjacent(beforebegin, Target, Elements).
-insert_after(Target, Elements) -> insert_adjacent(afterend, Target, Elements).
+insert_before(Target, Elements) ->
+    insert_adjacent(beforebegin, Target, Elements).
+
+insert_after(Target, Elements) ->
+    insert_adjacent(afterend, Target, Elements).
+
+insert_adjacent(Command, Target, Elements) ->
+    insert_adjacent(Command, Target, Elements, "qi").
 
-insert_adjacent(Command, Target, Elements) -> insert_adjacent(Command, Target, Elements, "qi").
 insert_adjacent(Command, Target, Elements, Q) ->
     {Render, _Ref, Actions} = render_html(Elements),
-    nitro:wire(nitro:f("~s('~s').insertAdjacentHTML('~s', `~s`);",[Q,Target,Command,Render])),
+    nitro:wire(nitro:f("~s('~s').insertAdjacentHTML('~s', `~s`);",
+                       [Q, Target, Command, Render])),
     nitro:wire(nitro:render(Actions)).
 
-
 render_html(Elements) ->
     Pid = self(),
     Ref = make_ref(),
-    spawn(fun() -> R = nitro:render(Elements), Pid ! {R, Ref, nitro:actions()} end),
-    {Render, Ref, Actions} = receive {_, Ref, _} = A -> A end, 
+    spawn(fun () ->
+                  R = nitro:render(Elements),
+                  Pid ! {R, Ref, nitro:actions()}
+          end),
+    {Render, Ref, Actions} = receive
+                                 {_, Ref, _} = A -> A
+                             end,
     {Render, Ref, Actions}.
-    
 
 actions() -> get(actions).
-actions(Ac) -> put(actions,Ac).
 
-insert_top(Target, Elements) when element(1,Elements) == tr -> insert_top(tbody,Target, Elements);
-insert_top(Target, Elements) -> insert_top('div',Target, Elements).
-insert_bottom(Target, Elements) when element(1,Elements) == tr -> insert_bottom(tbody, Target, Elements);
-insert_bottom(Target, Elements) -> insert_bottom('div', Target, Elements).
+actions(Ac) -> put(actions, Ac).
 
+insert_top(Target, Elements)
+    when element(1, Elements) == tr ->
+    insert_top(tbody, Target, Elements);
+insert_top(Target, Elements) ->
+    insert_top('div', Target, Elements).
+
+insert_bottom(Target, Elements)
+    when element(1, Elements) == tr ->
+    insert_bottom(tbody, Target, Elements);
+insert_bottom(Target, Elements) ->
+    insert_bottom('div', Target, Elements).
 
 clear(Target) ->
-    nitro:wire("var x = qi('"++nitro:to_list(Target)++"'); while (x && x.firstChild) x.removeChild(x.firstChild);").
+    nitro:wire("var x = qi('" ++
+                   nitro:to_list(Target) ++
+                       "'); while (x && x.firstChild) x.removeChild(x"
+                       ".firstChild);").
 
 remove(Target) ->
-    nitro:wire("var x=qi('"++nitro:to_list(Target)++"'); x && x.parentNode.removeChild(x);").
+    nitro:wire("var x=qi('" ++
+                   nitro:to_list(Target) ++
+                       "'); x && x.parentNode.removeChild(x);").
 
 % Wire JavaScript nitro:wire
 
 state(Key) -> erlang:get(Key).
-state(Key,Value) -> erlang:put(Key,Value).
+
+state(Key, Value) -> erlang:put(Key, Value).
 
 % Redirect and purge connection nitro:redirect
 
-redirect(Url) -> nitro:wire(#jq{target='window',property=location,args=simple,right=Url}).
+redirect(Url) ->
+    nitro:wire(#jq{target = window, property = location,
+                   args = simple, right = Url}).
+
 %header(K,V) -> nitro:context((?CTX)#cx{req=cowboy_req:set_resp_header(K,V,?CTX#cx.req)}).
 
-setAttr(Element, Attr, Value) -> 
-    nitro:wire("{ var x = qi('"++ 
-    nitro:to_list(Element)++"'); if (x) x.setAttribute('"++nitro:to_list(Attr)++"', '"++nitro:to_list(Value)++"'); }").
+setAttr(Element, Attr, Value) ->
+    nitro:wire("{ var x = qi('" ++
+                   nitro:to_list(Element) ++
+                       "'); if (x) x.setAttribute('" ++
+                           nitro:to_list(Attr) ++
+                               "', '" ++ nitro:to_list(Value) ++ "'); }").
+
+style(Element, Style) ->
+    setAttr(Element, "style", Style).
+
+style(Element, Style, Value) ->
+    nitro:wire("{ var x = qi('" ++
+                   nitro:to_list(Element) ++
+                       "'); if (x) x.style." ++
+                           nitro:to_list(Style) ++
+                               " = '" ++ nitro:to_list(Value) ++ "'; }").
 
-style(Element, Style) -> setAttr(Element, "style", Style).
-style(Element, Style, Value) -> 
-            nitro:wire("{ var x = qi('"++ 
-                nitro:to_list(Element)++"'); if (x) x.style."++nitro:to_list(Style)++" = '"++nitro:to_list(Value)++"'; }").
+display(Element, Status) ->
+    style(Element, "display", Status).
 
-display(Element,Status) -> style(Element, "display", Status).
+show(Element) -> display(Element, block).
 
-show(Element) -> display(Element,block).
-hide(Element) -> display(Element,none).
+hide(Element) -> display(Element, none).
 
 compact([]) -> "[]";
 compact("\n") -> "[]";
-compact([X|_]=Y) when is_tuple(X) -> [ compact(F) || F <- Y ];
-compact(Tuple) when is_binary(Tuple) -> unicode:characters_to_binary(Tuple);
+compact([X | _] = Y) when is_tuple(X) ->
+    [compact(F) || F <- Y];
+compact(Tuple) when is_binary(Tuple) ->
+    unicode:characters_to_binary(Tuple);
 compact(Tuple) when is_tuple(Tuple) ->
-     Min = erlang:min(9,size(Tuple)),
-     Fields = lists:zip(lists:seq(1,Min),lists:sublist(tuple_to_list(Tuple),1,Min)),
-     "{" ++ string:join([ io_lib:format("~s",[compact(F)]) || {_,F}<- Fields ],",") ++ "}";
+    Min = erlang:min(9, size(Tuple)),
+    Fields = lists:zip(lists:seq(1, Min),
+                       lists:sublist(tuple_to_list(Tuple), 1, Min)),
+    "{" ++
+        string:join([io_lib:format("~s", [compact(F)])
+                     || {_, F} <- Fields],
+                    ",")
+            ++ "}";
 compact(Tuple) -> nitro:jse(nitro:to_list(Tuple)).
 
 meg(X) -> integer_to_list(X div 1000000) ++ "M".
+
 rev(X) -> lists:reverse(X).
-num(S) -> case rev(S) of
-               [$K|K] -> list_to_integer(rev(K)) * 1000;
-               [$M|M] -> list_to_integer(rev(M)) * 1000 * 1000;
-               [$G|G] -> list_to_integer(rev(G)) * 1000 * 1000 * 1000;
-               [$T|T] -> list_to_integer(rev(T)) * 1000 * 1000 * 1000 * 1000 end.
+
+num(S) ->
+    case rev(S) of
+        [$K | K] -> list_to_integer(rev(K)) * 1000;
+        [$M | M] -> list_to_integer(rev(M)) * 1000 * 1000;
+        [$G | G] ->
+            list_to_integer(rev(G)) * 1000 * 1000 * 1000;
+        [$T | T] ->
+            list_to_integer(rev(T)) * 1000 * 1000 * 1000 * 1000
+    end.
 
 cookie_expire(SecondsToLive) ->
-    Seconds = calendar:datetime_to_gregorian_seconds(calendar:local_time()),
-    DateTime = calendar:gregorian_seconds_to_datetime(Seconds + SecondsToLive),
+    Seconds =
+        calendar:datetime_to_gregorian_seconds(calendar:local_time()),
+    DateTime =
+        calendar:gregorian_seconds_to_datetime(Seconds +
+                                                   SecondsToLive),
     cow_date:rfc2109(DateTime).
 
-cookie(Id, Value) -> cookie(Id, Value, 2147483647). % expire never
+cookie(Id, Value) ->
+    cookie(Id, Value, 2147483647). % expire never
+
 cookie(Id, Value, Expire) ->
     Format = "document.cookie='~s=~s; path=/; expires=~s';",
-    nitro:wire(nitro:f(Format,[nitro:to_list(Id),nitro:to_list(Value), cookie_expire(Expire)])).
-
-cookies() -> cowboy_req:parse_cookies((get(context))#cx.req).
-cookie(Key) -> case lists:keyfind(Key, 1, cowboy_req:parse_cookies((get(context))#cx.req)) of false -> undefined; {_, Value} -> Value end.
+    nitro:wire(nitro:f(Format,
+                       [nitro:to_list(Id),
+                        nitro:to_list(Value),
+                        cookie_expire(Expire)])).
+
+cookies() ->
+    cowboy_req:parse_cookies((get(context))#cx.req).
+
+cookie(Key) ->
+    case lists:keyfind(Key,
+                       1,
+                       cowboy_req:parse_cookies((get(context))#cx.req))
+        of
+        false -> undefined;
+        {_, Value} -> Value
+    end.

+ 192 - 104
src/nitro_conv.erl

@@ -1,43 +1,66 @@
 -module(nitro_conv).
+
 -description('N2O Formatter: JSON, BERT').
+
 -author('Maxim Sokhatsky').
+
 -compile(export_all).
+
 -include_lib("nitro/include/nitro.hrl").
 
 % WF to_atom to_list to_binary
 
--define(IS_STRING(Term), (is_list(Term) andalso Term /= [] andalso is_integer(hd(Term)))).
+-define(IS_STRING(Term),
+        is_list(Term) andalso
+            Term /= [] andalso is_integer(hd(Term))).
 
 -ifndef(N2O_JSON).
--define(N2O_JSON, (application:get_env(n2o,json,jsone))).
--endif.
 
+-define(N2O_JSON,
+        application:get_env(n2o, json, jsone)).
+
+-endif.
 
 to_list(L) when ?IS_STRING(L) -> L;
-to_list(L) when is_list(L) -> SubLists = [inner_to_list(X) || X <- L], lists:flatten(SubLists);
+to_list(L) when is_list(L) ->
+    SubLists = [inner_to_list(X) || X <- L],
+    lists:flatten(SubLists);
 to_list(A) -> inner_to_list(A).
+
 inner_to_list(A) when is_atom(A) -> atom_to_list(A);
 inner_to_list(B) when is_binary(B) -> binary_to_list(B);
-inner_to_list(I) when is_integer(I) -> integer_to_list(I);
-inner_to_list(L) when is_tuple(L) -> lists:flatten(io_lib:format("~p", [L]));
+inner_to_list(I) when is_integer(I) ->
+    integer_to_list(I);
+inner_to_list(L) when is_tuple(L) ->
+    lists:flatten(io_lib:format("~p", [L]));
 inner_to_list(L) when is_list(L) -> L;
-inner_to_list(F) when is_float(F) -> float_to_list(F,[{decimals,9},compact]).
+inner_to_list(F) when is_float(F) ->
+    float_to_list(F, [{decimals, 9}, compact]).
 
 to_atom(A) when is_atom(A) -> A;
-to_atom(B) when is_binary(B) -> to_atom(binary_to_list(B));
-to_atom(I) when is_integer(I) -> to_atom(integer_to_list(I));
-to_atom(F) when is_float(F) -> to_atom(float_to_list(F,[{decimals,9},compact]));
-to_atom(L) when is_list(L) -> list_to_atom(binary_to_list(list_to_binary(L))).
-
-to_binary(A) when is_atom(A) -> atom_to_binary(A,latin1);
+to_atom(B) when is_binary(B) ->
+    to_atom(binary_to_list(B));
+to_atom(I) when is_integer(I) ->
+    to_atom(integer_to_list(I));
+to_atom(F) when is_float(F) ->
+    to_atom(float_to_list(F, [{decimals, 9}, compact]));
+to_atom(L) when is_list(L) ->
+    list_to_atom(binary_to_list(list_to_binary(L))).
+
+to_binary(A) when is_atom(A) ->
+    atom_to_binary(A, latin1);
 to_binary(B) when is_binary(B) -> B;
 to_binary(T) when is_tuple(T) -> term_to_binary(T);
-to_binary(I) when is_integer(I) -> to_binary(integer_to_list(I));
-to_binary(F) when is_float(F) -> float_to_binary(F,[{decimals,9},compact]);
-to_binary(L) when is_list(L) ->  iolist_to_binary(L).
-
-to_integer(A) when is_atom(A) -> to_integer(atom_to_list(A));
-to_integer(B) when is_binary(B) -> to_integer(binary_to_list(B));
+to_binary(I) when is_integer(I) ->
+    to_binary(integer_to_list(I));
+to_binary(F) when is_float(F) ->
+    float_to_binary(F, [{decimals, 9}, compact]);
+to_binary(L) when is_list(L) -> iolist_to_binary(L).
+
+to_integer(A) when is_atom(A) ->
+    to_integer(atom_to_list(A));
+to_integer(B) when is_binary(B) ->
+    to_integer(binary_to_list(B));
 to_integer(I) when is_integer(I) -> I;
 to_integer([]) -> 0;
 to_integer(L) when is_list(L) -> list_to_integer(L);
@@ -45,76 +68,100 @@ to_integer(F) when is_float(F) -> round(F).
 
 % HTML encode/decode
 
-html_encode(L,Fun) when is_function(Fun) -> Fun(L);
-html_encode(L,EncType) when is_atom(L) -> html_encode(nitro:to_list(L),EncType);
-html_encode(L,EncType) when is_integer(L) -> html_encode(integer_to_list(L),EncType);
-html_encode(L,EncType) when is_float(L) -> html_encode(float_to_list(L,[{decimals,9},compact]),EncType);
+html_encode(L, Fun) when is_function(Fun) -> Fun(L);
+html_encode(L, EncType) when is_atom(L) ->
+    html_encode(nitro:to_list(L), EncType);
+html_encode(L, EncType) when is_integer(L) ->
+    html_encode(integer_to_list(L), EncType);
+html_encode(L, EncType) when is_float(L) ->
+    html_encode(float_to_list(L, [{decimals, 9}, compact]),
+                EncType);
 html_encode(L, false) -> L;
 html_encode(L, true) -> L;
-html_encode(L, whites) -> html_encode_whites(nitro:to_list(lists:flatten([L]))).
+html_encode(L, whites) ->
+    html_encode_whites(nitro:to_list(lists:flatten([L]))).
+
 html_encode(<<>>) -> <<>>;
 html_encode([]) -> [];
-html_encode(B) when is_binary(B) -> html_encode(binary_to_list(B));
-html_encode([$\n|T]) -> "<br>" ++ html_encode(T);
-html_encode([H|T]) ->
-	case H of
-		$< -> "&lt;" ++ html_encode(T);
-		$> -> "&gt;" ++ html_encode(T);
-		$" -> "&quot;" ++ html_encode(T);
-		$` -> "&#39;" ++ html_encode(T);
-		$' -> "&#39;" ++ html_encode(T);
-		$& -> "&amp;" ++ html_encode(T);
-		BigNum when is_integer(BigNum) andalso BigNum > 255 ->
-			%% Any integers above 255 are converted to their HTML encode equivilant,
-			%% Example: 7534 gets turned into &#7534;
-			[$&,$# | nitro:to_list(BigNum)] ++ ";" ++ html_encode(T);
-		Tup when is_tuple(Tup) -> 
-			throw({html_encode,encountered_tuple,Tup});
-		_ -> [H|html_encode(T)]
-	end.
+html_encode(B) when is_binary(B) ->
+    html_encode(binary_to_list(B));
+html_encode([$\n | T]) -> "<br>" ++ html_encode(T);
+html_encode([H | T]) ->
+    case H of
+        $< -> "&lt;" ++ html_encode(T);
+        $> -> "&gt;" ++ html_encode(T);
+        $" -> "&quot;" ++ html_encode(T);
+        $` -> "&#39;" ++ html_encode(T);
+        $' -> "&#39;" ++ html_encode(T);
+        $& -> "&amp;" ++ html_encode(T);
+        BigNum when is_integer(BigNum) andalso BigNum > 255 ->
+            %% Any integers above 255 are converted to their HTML encode equivilant,
+            %% Example: 7534 gets turned into &#7534;
+            [$&, $# | nitro:to_list(BigNum)] ++
+                ";" ++ html_encode(T);
+        Tup when is_tuple(Tup) ->
+            throw({html_encode, encountered_tuple, Tup});
+        _ -> [H | html_encode(T)]
+    end.
 
 html_encode_whites([]) -> [];
-html_encode_whites([H|T]) ->
-	case H of
-		$\s -> "&nbsp;" ++ html_encode_whites(T);
-		$\t -> "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" ++ html_encode_whites(T);
-		$< -> "&lt;" ++ html_encode_whites(T);
-		$> -> "&gt;" ++ html_encode_whites(T);
-		$" -> "&quot;" ++ html_encode_whites(T);
-		$' -> "&#39;" ++ html_encode_whites(T);
-		$` -> "&#39;" ++ html_encode_whites(T);
-		$& -> "&amp;" ++ html_encode_whites(T);
-		$\n -> "<br>" ++ html_encode_whites(T);
-		_ -> [H|html_encode_whites(T)]
-	end.
+html_encode_whites([H | T]) ->
+    case H of
+        $\s -> "&nbsp;" ++ html_encode_whites(T);
+        $\t ->
+            "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" ++
+                html_encode_whites(T);
+        $< -> "&lt;" ++ html_encode_whites(T);
+        $> -> "&gt;" ++ html_encode_whites(T);
+        $" -> "&quot;" ++ html_encode_whites(T);
+        $' -> "&#39;" ++ html_encode_whites(T);
+        $` -> "&#39;" ++ html_encode_whites(T);
+        $& -> "&amp;" ++ html_encode_whites(T);
+        $\n -> "<br>" ++ html_encode_whites(T);
+        _ -> [H | html_encode_whites(T)]
+    end.
 
 %% URL encode/decode
 
 url_encode(S) -> quote_plus(S).
+
 url_decode(S) -> unquote(S).
 
 -define(PERCENT, 37).  % $\%
+
 -define(FULLSTOP, 46). % $\.
--define(IS_HEX(C), ((C >= $0 andalso C =< $9) orelse
-    (C >= $a andalso C =< $f) orelse
-    (C >= $A andalso C =< $F))).
--define(QS_SAFE(C), ((C >= $a andalso C =< $z) orelse
-    (C >= $A andalso C =< $Z) orelse
-    (C >= $0 andalso C =< $9) orelse
-    (C =:= ?FULLSTOP orelse C =:= $- orelse C =:= $~ orelse
-        C =:= $_))).
-
-quote_plus(Atom) when is_atom(Atom) -> quote_plus(atom_to_list(Atom));
-quote_plus(Int) when is_integer(Int) -> quote_plus(integer_to_list(Int));
-quote_plus(Bin) when is_binary(Bin) -> quote_plus(binary_to_list(Bin));
+
+-define(IS_HEX(C),
+        C >= $0 andalso C =< $9 orelse
+            C >= $a andalso C =< $f orelse C >= $A andalso C =< $F).
+
+-define(QS_SAFE(C),
+        C >= $a andalso C =< $z orelse
+            C >= $A andalso C =< $Z orelse
+                C >= $0 andalso C =< $9 orelse
+                    C =:= (?FULLSTOP) orelse
+                        C =:= $- orelse C =:= $~ orelse C =:= $_).
+
+quote_plus(Atom) when is_atom(Atom) ->
+    quote_plus(atom_to_list(Atom));
+quote_plus(Int) when is_integer(Int) ->
+    quote_plus(integer_to_list(Int));
+quote_plus(Bin) when is_binary(Bin) ->
+    quote_plus(binary_to_list(Bin));
 quote_plus(String) -> quote_plus(String, []).
 
 quote_plus([], Acc) -> lists:reverse(Acc);
-quote_plus([C | Rest], Acc) when ?QS_SAFE(C) -> quote_plus(Rest, [C | Acc]);
-quote_plus([$\s | Rest], Acc) -> quote_plus(Rest, [$+ | Acc]);
-quote_plus([C | Rest], Acc) -> <<Hi:4, Lo:4>> = <<C>>, quote_plus(Rest, [digit(Lo), digit(Hi), ?PERCENT | Acc]).
-
-unquote(Binary) when is_binary(Binary) -> unquote(binary_to_list(Binary));
+quote_plus([C | Rest], Acc) when ?QS_SAFE(C) ->
+    quote_plus(Rest, [C | Acc]);
+quote_plus([$\s | Rest], Acc) ->
+    quote_plus(Rest, [$+ | Acc]);
+quote_plus([C | Rest], Acc) ->
+    <<Hi:4, Lo:4>> = <<C>>,
+    quote_plus(Rest,
+               [digit(Lo), digit(Hi), ?PERCENT | Acc]).
+
+unquote(Binary) when is_binary(Binary) ->
+    unquote(binary_to_list(Binary));
 unquote(String) -> qs_revdecode(lists:reverse(String)).
 
 unhexdigit(C) when C >= $0, C =< $9 -> C - $0;
@@ -122,32 +169,50 @@ unhexdigit(C) when C >= $a, C =< $f -> C - $a + 10;
 unhexdigit(C) when C >= $A, C =< $F -> C - $A + 10.
 
 qs_revdecode(S) -> qs_revdecode(S, []).
+
 qs_revdecode([], Acc) -> Acc;
-qs_revdecode([$+ | Rest], Acc) -> qs_revdecode(Rest, [$\s | Acc]);
-qs_revdecode([Lo, Hi, ?PERCENT | Rest], Acc) when ?IS_HEX(Lo), ?IS_HEX(Hi) -> qs_revdecode(Rest, [(unhexdigit(Lo) bor (unhexdigit(Hi) bsl 4)) | Acc]);
-qs_revdecode([C | Rest], Acc) -> qs_revdecode(Rest, [C | Acc]).
+qs_revdecode([$+ | Rest], Acc) ->
+    qs_revdecode(Rest, [$\s | Acc]);
+qs_revdecode([Lo, Hi, ?PERCENT | Rest], Acc)
+    when ?IS_HEX(Lo), ?IS_HEX(Hi) ->
+    qs_revdecode(Rest,
+                 [unhexdigit(Lo) bor (unhexdigit(Hi) bsl 4) | Acc]);
+qs_revdecode([C | Rest], Acc) ->
+    qs_revdecode(Rest, [C | Acc]).
 
 %% JavaScript encode/decode
 
 js_escape(undefined) -> [];
-js_escape(Value) when is_list(Value) -> binary_to_list(js_escape(iolist_to_binary(Value)));
+js_escape(Value) when is_list(Value) ->
+    binary_to_list(js_escape(iolist_to_binary(Value)));
 js_escape(Value) -> js_escape(Value, <<>>).
-js_escape(<<"\\", Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, "\\\\">>);
-js_escape(<<"\r", Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, "\\r">>);
-js_escape(<<"\n", Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, "\\n">>);
-js_escape(<<"\"", Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, "\\\"">>);
-js_escape(<<"'",Rest/binary>>,Acc) -> js_escape(Rest, <<Acc/binary, "\\'">>);
-js_escape(<<"`",Rest/binary>>,Acc) -> js_escape(Rest, <<Acc/binary, "\\`">>);
-js_escape(<<"<script", Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, "<script">>);
-js_escape(<<"script>", Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, "script>">>);
-js_escape(<<C, Rest/binary>>, Acc) -> js_escape(Rest, <<Acc/binary, C>>);
+
+js_escape(<<"\\", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "\\\\">>);
+js_escape(<<"\r", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "\\r">>);
+js_escape(<<"\n", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "\\n">>);
+js_escape(<<"\"", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "\\\"">>);
+js_escape(<<"'", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "\\'">>);
+js_escape(<<"`", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "\\`">>);
+js_escape(<<"<script", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "<script">>);
+js_escape(<<"script>", Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, "script>">>);
+js_escape(<<C, Rest/binary>>, Acc) ->
+    js_escape(Rest, <<Acc/binary, C>>);
 js_escape(<<>>, Acc) -> Acc.
 
 % JOIN
 
-join([],_) -> [];
-join([Item],_Delim) -> [Item];
-join([Item|Items],Delim) -> [Item,Delim | join(Items,Delim)].
+join([], _) -> [];
+join([Item], _Delim) -> [Item];
+join([Item | Items], Delim) ->
+    [Item, Delim | join(Items, Delim)].
 
 % Fast HEX
 
@@ -168,40 +233,63 @@ digit(13) -> $d;
 digit(14) -> $e;
 digit(15) -> $f.
 
-hex(Bin) -> << << (digit(A1)),(digit(A2)) >> || <<A1:4,A2:4>> <= Bin >>.
-unhex(Hex) -> << << (erlang:list_to_integer([H1,H2], 16)) >> || <<H1,H2>> <= Hex >>.
+hex(Bin) ->
+    << <<(digit(A1)), (digit(A2))>>
+        || <<A1:4, A2:4>> <= Bin >>.
+
+unhex(Hex) ->
+    << <<(erlang:list_to_integer([H1, H2], 16))>>
+        || <<H1, H2>> <= Hex >>.
 
 f(S) -> f(S, []).
+
 f(S, Args) -> lists:flatten(io_lib:format(S, Args)).
 
 replace([], _, _) -> [];
-replace(String, S1, S2) when is_list(String), is_list(S1), is_list(S2) ->
+replace(String, S1, S2)
+    when is_list(String), is_list(S1), is_list(S2) ->
     Length = length(S1),
     case string:substr(String, 1, Length) of
-        S1 -> S2 ++ replace(string:substr(String, Length + 1), S1, S2);
-        _ -> [hd(String)|replace(tl(String), S1, S2)]
+        S1 ->
+            S2 ++
+                replace(string:substr(String, Length + 1), S1, S2);
+        _ -> [hd(String) | replace(tl(String), S1, S2)]
     end.
 
-coalesce({_,Y}) -> Y;
+coalesce({_, Y}) -> Y;
 coalesce(false) -> undefined;
 coalesce([]) -> undefined;
 coalesce([H]) -> H;
-coalesce([undefined|T]) -> coalesce(T);
-coalesce([[]|T]) -> coalesce(T);
-coalesce([H|_]) -> H.
+coalesce([undefined | T]) -> coalesce(T);
+coalesce([[] | T]) -> coalesce(T);
+coalesce([H | _]) -> H.
 
 indexof(Key, Fields) -> indexof(Key, Fields, 2).
+
 indexof(_Key, [], _N) -> undefined;
-indexof(Key, [Key|_T], N) -> N;
-indexof(Key, [_|T], N) -> indexof(Key, T, N + 1).
+indexof(Key, [Key | _T], N) -> N;
+indexof(Key, [_ | T], N) -> indexof(Key, T, N + 1).
 
-config(App, Key, Default) -> application:get_env(App,Key,Default).
+config(App, Key, Default) ->
+    application:get_env(App, Key, Default).
 
 os_env(Key) -> os_env(Key, "").
-os_env(Key, Default) -> case os:getenv(Key) of false -> Default; V -> V end.
+
+os_env(Key, Default) ->
+    case os:getenv(Key) of
+        false -> Default;
+        V -> V
+    end.
 
 % base64 encode/decode
-pickle(Data) -> base64:encode(term_to_binary({Data, os:timestamp()}, [compressed])).
+pickle(Data) ->
+    base64:encode(term_to_binary({Data, os:timestamp()},
+                                 [compressed])).
+
 depickle(PickledData) ->
-    try {Data, _PickleTime} = binary_to_term(base64:decode(nitro:to_binary(PickledData))), Data
-    catch _:_ -> undefined end.
+    try {Data, _PickleTime} =
+            binary_to_term(base64:decode(nitro:to_binary(PickledData))),
+        Data
+    catch
+        _:_ -> undefined
+    end.

+ 119 - 60
src/nitro_n2o.erl

@@ -1,104 +1,163 @@
 -module(nitro_n2o).
+
 -description('N2O Nitrogen Web Framework Protocol').
+
 -include_lib("nitro/include/n2o.hrl").
--export([info/3,render_actions/1,io/1,io/2,event/1]).
 
-% Nitrogen pickle handler
+-export([info/3,
+         render_actions/1,
+         io/1,
+         io/2,
+         event/1]).
 
-info({text,<<"N2O,",Auth/binary>>}, Req, State) ->
-    info(#init{token=Auth},Req,State);
+% Nitrogen pickle handler
 
-info(#init{token=Auth}, Req, State) ->
+info({text, <<"N2O,", Auth/binary>>}, Req, State) ->
+    info(#init{token = Auth}, Req, State);
+info(#init{token = Auth}, Req, State) ->
     {'Token', Token} = nitro:authenticate([], Auth),
-    Sid = case nitro:depickle(Token) of {{S,_},_} -> S; X -> X end,
+    Sid = case nitro:depickle(Token) of
+              {{S, _}, _} -> S;
+              X -> X
+          end,
     New = State#cx{session = Sid, token = Auth},
-    put(context,New),
-    {reply,{bert,case io(init, State) of
-                      {io,_,{stack,_}} = Io -> Io;
-                      {io,Code,_} -> {io,Code,{'Token',Token}} end},
-            Req,New};
-
-info(#client{data=Message}, Req, State) ->
+    put(context, New),
+    {reply,
+     {bert,
+      case io(init, State) of
+          {io, _, {stack, _}} = Io -> Io;
+          {io, Code, _} -> {io, Code, {'Token', Token}}
+      end},
+     Req,
+     New};
+info(#client{data = Message}, Req, State) ->
     nitro:actions([]),
-    {reply,{bert,io(#client{data=Message},State)},Req,State};
-
-info(#pickle{}=Event, Req, State) ->
+    {reply,
+     {bert, io(#client{data = Message}, State)},
+     Req,
+     State};
+info(#pickle{} = Event, Req, State) ->
     nitro:actions([]),
-    {reply,{bert,html_events(Event,State)},Req,State};
-
-info(#flush{data=Actions}, Req, State) ->
+    {reply, {bert, html_events(Event, State)}, Req, State};
+info(#flush{data = Actions}, Req, State) ->
     nitro:actions(Actions),
-    {reply,{bert,io(<<>>)},Req,State};
-
-info(#direct{data=Message}, Req, State) ->
+    {reply, {bert, io(<<>>)}, Req, State};
+info(#direct{data = Message}, Req, State) ->
     nitro:actions([]),
-    {reply,{bert,case io(Message, State) of
-                      {io,_,{stack,_}} = Io -> Io;
-                      {io,Code,Res} -> {io,Code,{direct,Res}} end},
-            Req,State};
-
-info(Message,Req,State) -> {unknown,Message,Req,State}.
+    {reply,
+     {bert,
+      case io(Message, State) of
+          {io, _, {stack, _}} = Io -> Io;
+          {io, Code, Res} -> {io, Code, {direct, Res}}
+      end},
+     Req,
+     State};
+info(Message, Req, State) ->
+    {unknown, Message, Req, State}.
 
 % double render: actions could generate actions
 
 render_actions(Actions) ->
     nitro:actions([]),
-    First  = nitro:render(Actions),
+    First = nitro:render(Actions),
     Second = nitro:render(nitro:actions()),
     nitro:actions([]),
-    nitro:to_binary([First,Second]).
+    nitro:to_binary([First, Second]).
 
 % n2o events
 
-html_events(#pickle{source=Source,pickled=Pickled,args=Linked}, State=#cx{token = Token}) ->
-    Ev  = nitro:depickle(Pickled),
-    L   = nitro:prolongate(),
+html_events(#pickle{source = Source, pickled = Pickled,
+                    args = Linked},
+            State = #cx{token = Token}) ->
+    Ev = nitro:depickle(Pickled),
+    L = nitro:prolongate(),
     Res = case Ev of
-          #ev{} when L =:= false -> render_ev(Ev,Source,Linked,State), <<>>;
-          #ev{} -> render_ev(Ev,Source,Linked,State), nitro:authenticate([], Token);
-          _CustomEnvelop -> %?LOG_ERROR("EV expected: ~p~n",[CustomEnvelop]),
-                           {error,"EV expected"} end,
+              #ev{} when L =:= false ->
+                  render_ev(Ev, Source, Linked, State),
+                  <<>>;
+              #ev{} ->
+                  render_ev(Ev, Source, Linked, State),
+                  nitro:authenticate([], Token);
+              _CustomEnvelop -> %?LOG_ERROR("EV expected: ~p~n",[CustomEnvelop]),
+                  {error, "EV expected"}
+          end,
     io(Res).
 
 % calling user code in exception-safe manner
 
 -ifdef(OTP_RELEASE).
 
-render_ev(#ev{module=M,name=F,msg=P,trigger=T},_Source,Linked,State) ->
+render_ev(#ev{module = M, name = F, msg = P,
+              trigger = T},
+          _Source, Linked, State) ->
     try case F of
-         api_event -> M:F(P,Linked,State);
-             event -> [erlang:put(K,V) || {K,V} <- Linked], M:F(P);
-                 _ -> M:F(P,T,State) end
-    catch E:R:S -> ?LOG_EXCEPTION(E,R,S), {stack,S} end.
-
-io(Event, #cx{module=Module}) ->
-    try X = Module:event(Event), {io,render_actions(nitro:actions()),X}
-    catch E:R:S -> ?LOG_EXCEPTION(E,R,S), {io,[],{stack,S}} end.
+            api_event -> M:F(P, Linked, State);
+            event ->
+                [erlang:put(K, V) || {K, V} <- Linked],
+                M:F(P);
+            _ -> M:F(P, T, State)
+        end
+    catch
+        E:R:S ->
+            ?LOG_EXCEPTION(E, R, S),
+            {stack, S}
+    end.
+
+io(Event, #cx{module = Module}) ->
+    try X = Module:event(Event),
+        {io, render_actions(nitro:actions()), X}
+    catch
+        E:R:S ->
+            ?LOG_EXCEPTION(E, R, S),
+            {io, [], {stack, S}}
+    end.
 
 io(Data) ->
-    try {io,render_actions(nitro:actions()),Data}
-    catch E:R:S -> ?LOG_EXCEPTION(E,R,S), {io,[],{stack,S}} end.
+    try {io, render_actions(nitro:actions()), Data} catch
+        E:R:S ->
+            ?LOG_EXCEPTION(E, R, S),
+            {io, [], {stack, S}}
+    end.
 
 -else.
 
-render_ev(#ev{module=M,name=F,msg=P,trigger=T},_Source,Linked,State) ->
+render_ev(#ev{module = M, name = F, msg = P,
+              trigger = T},
+          _Source, Linked, State) ->
     try case F of
-         api_event -> M:F(P,Linked,State);
-             event -> [erlang:put(K,V) || {K,V} <- Linked], M:F(P);
-                 _ -> M:F(P,T,State) end
-    catch E:R -> S = erlang:get_stacktrace(), ?LOG_EXCEPTION(E,R,S), {stack,S} end.
-
-io(Event, #cx{module=Module}) ->
-    try X = Module:event(Event), {io,render_actions(nitro:actions()),X}
-    catch E:R -> S = erlang:get_stacktrace(), ?LOG_EXCEPTION(E,R,S), {io,<<>>,{stack,S}} end.
+            api_event -> M:F(P, Linked, State);
+            event ->
+                [erlang:put(K, V) || {K, V} <- Linked],
+                M:F(P);
+            _ -> M:F(P, T, State)
+        end
+    catch
+        E:R ->
+            S = erlang:get_stacktrace(),
+            ?LOG_EXCEPTION(E, R, S),
+            {stack, S}
+    end.
+
+io(Event, #cx{module = Module}) ->
+    try X = Module:event(Event),
+        {io, render_actions(nitro:actions()), X}
+    catch
+        E:R ->
+            S = erlang:get_stacktrace(),
+            ?LOG_EXCEPTION(E, R, S),
+            {io, <<>>, {stack, S}}
+    end.
 
 io(Data) ->
-    try {io,render_actions(nitro:actions()),Data}
-    catch E:R -> S = erlang:get_stacktrace(), ?LOG_EXCEPTION(E,R,S), {io,<<>>,{stack,S}} end.
+    try {io, render_actions(nitro:actions()), Data} catch
+        E:R ->
+            S = erlang:get_stacktrace(),
+            ?LOG_EXCEPTION(E, R, S),
+            {io, <<>>, {stack, S}}
+    end.
 
 -endif.
 
 % event Nitrogen Web Framework protocol
 
 event(_) -> [].
-

+ 76 - 35
src/nitro_static.erl

@@ -1,68 +1,109 @@
 -module(nitro_static).
+
 -description('NITRO Static bridge for MAD containers').
+
 -author('Maxim Sokhatsky').
+
 -compile(export_all).
+
 -include_lib("kernel/include/file.hrl").
 
 init(_, _, _) -> {upgrade, protocol, cowboy_rest}.
 
-rest_init(Req, {dir, Path, Extra}) when is_binary(Path) -> rest_init(Req, {dir, binary_to_list(Path), Extra});
+rest_init(Req, {dir, Path, Extra})
+    when is_binary(Path) ->
+    rest_init(Req, {dir, binary_to_list(Path), Extra});
 rest_init(Req, {dir, Path, Extra}) ->
     {PathInfo, Req2} = cowboy_req:path_info(Req),
-    Info = {ok, #file_info{type=regular,size=0}},
-    FileName = filename:join([Path|PathInfo]),
+    Info = {ok, #file_info{type = regular, size = 0}},
+    FileName = filename:join([Path | PathInfo]),
     {ok, Req2, {FileName, Info, Extra}}.
 
-malformed_request(Req, State) -> {State =:= error, Req, State}.
+malformed_request(Req, State) ->
+    {State =:= error, Req, State}.
 
-forbidden(Req, State={_, {ok, #file_info{type=directory}}, _}) -> {true, Req, State};
-forbidden(Req, State={_, {error, eacces}, _}) -> {true, Req, State};
-forbidden(Req, State={_, {ok, #file_info{access=Access}}, _}) when Access =:= write; Access =:= none -> {true, Req, State};
+forbidden(Req,
+          State = {_, {ok, #file_info{type = directory}}, _}) ->
+    {true, Req, State};
+forbidden(Req, State = {_, {error, eacces}, _}) ->
+    {true, Req, State};
+forbidden(Req,
+          State = {_, {ok, #file_info{access = Access}}, _})
+    when Access =:= write; Access =:= none ->
+    {true, Req, State};
 forbidden(Req, State) -> {false, Req, State}.
 
-
-
-fixpath(Path) -> {Module,Fun} = application:get_env(n2o,fixpath,{nitro_static,fix}),
-                 Module:Fun(Path).
+fixpath(Path) ->
+    {Module, Fun} = application:get_env(n2o,
+                                        fixpath,
+                                        {nitro_static, fix}),
+    Module:Fun(Path).
 
 fix(A) -> A.
 
-content_types_provided(Req, State={Path, _, Extra}) ->
+content_types_provided(Req, State = {Path, _, Extra}) ->
     case lists:keyfind(mimetypes, 1, Extra) of
-         false -> {[{cow_mimetypes:web(Path), get_file}], Req, State};
-         {mimetypes, Module, Function} ->
-            {[{Module:Function(fixpath(Path)), get_file}], Req, State};
-         {mimetypes, Type} -> {[{Type, get_file}], Req, State}
+        false ->
+            {[{cow_mimetypes:web(Path), get_file}], Req, State};
+        {mimetypes, Module, Function} ->
+            {[{Module:Function(fixpath(Path)), get_file}],
+             Req,
+             State};
+        {mimetypes, Type} -> {[{Type, get_file}], Req, State}
     end.
 
-resource_exists(Req, State={_, {ok, #file_info{type=regular}}, _}) -> {true, Req, State};
+resource_exists(Req,
+                State = {_, {ok, #file_info{type = regular}}, _}) ->
+    {true, Req, State};
 resource_exists(Req, State) -> {false, Req, State}.
 
-generate_etag(Req, State={Path, {ok, #file_info{size=Size, mtime=Mtime}}, Extra}) ->
+generate_etag(Req,
+              State = {Path,
+                       {ok, #file_info{size = Size, mtime = Mtime}},
+                       Extra}) ->
     case lists:keyfind(etag, 1, Extra) of
-         false -> {generate_default_etag(Size, Mtime), Req, State};
-         {etag, Module, Function} -> {Module:Function(Path, Size, Mtime), Req, State};
-         {etag, false} -> {undefined, Req, State}
+        false ->
+            {generate_default_etag(Size, Mtime), Req, State};
+        {etag, Module, Function} ->
+            {Module:Function(Path, Size, Mtime), Req, State};
+        {etag, false} -> {undefined, Req, State}
     end.
 
 generate_default_etag(Size, Mtime) ->
-    {strong, list_to_binary(integer_to_list(erlang:phash2({Size, Mtime}, 16#ffffffff)))}.
+    {strong,
+     list_to_binary(integer_to_list(erlang:phash2({Size,
+                                                   Mtime},
+                                                  16#ffffffff)))}.
 
-last_modified(Req, State={_, {ok, #file_info{mtime=Modified}}, _}) -> {Modified, Req, State}.
+last_modified(Req,
+              State = {_, {ok, #file_info{mtime = Modified}}, _}) ->
+    {Modified, Req, State}.
 
-get_file(Req, State={P, {ok, #file_info{size=_Size}}, _}) ->
+get_file(Req,
+         State = {P, {ok, #file_info{size = _Size}}, _}) ->
     Path = fixpath(P),
-    StringPath = nitro:to_list(unicode:characters_to_binary(Path,utf8,utf8)),
-    [_Type,Name|RestPath] = filename:split(StringPath),
+    StringPath =
+        nitro:to_list(unicode:characters_to_binary(Path,
+                                                   utf8,
+                                                   utf8)),
+    [_Type, Name | RestPath] = filename:split(StringPath),
     FileName = filename:absname(StringPath),
     Raw = case file:read_file(FileName) of
-          {ok,Bin} -> Bin;
-          {error,_} ->
-              case mad_repl:load_file(StringPath) of
-                   {ok,ETSFile} -> ETSFile;
-                   {error,_} ->
-                        case file:read_file(filename:join([ code:lib_dir(list_to_atom(Name))|RestPath])) of
-                             {ok,ReleaseFile} -> ReleaseFile;
-                             {error,_} -> <<>> end end end,
-    Sendfile = fun (Socket, Transport) -> Transport:send(Socket, Raw) end,
+              {ok, Bin} -> Bin;
+              {error, _} ->
+                  case mad_repl:load_file(StringPath) of
+                      {ok, ETSFile} -> ETSFile;
+                      {error, _} ->
+                          case
+                              file:read_file(filename:join([code:lib_dir(list_to_atom(Name))
+                                                            | RestPath]))
+                              of
+                              {ok, ReleaseFile} -> ReleaseFile;
+                              {error, _} -> <<>>
+                          end
+                  end
+          end,
+    Sendfile = fun (Socket, Transport) ->
+                       Transport:send(Socket, Raw)
+               end,
     {{stream, size(Raw), Sendfile}, Req, State}.