Current section

Files

Jump to
live_view_native lib live_view_native template.ex
Raw

lib/live_view_native/template.ex

defmodule LiveViewNative.Template do
@doc """
Return all template engines for registered plugins
"""
def engines() do
Application.get_env(:live_view_native, :plugins)
|> Enum.into(%{html: Phoenix.LiveView.Engine}, fn(plugin) ->
plugin = struct(plugin)
{plugin.format, plugin.template_engine}
end)
end
def attributes_escape(attrs) when is_list(attrs) do
{:safe, build_attrs(attrs)}
end
def attributes_escape(attrs) do
{:safe, attrs |> Enum.to_list() |> build_attrs()}
end
defp build_attrs([{_, nil} | t]),
do: build_attrs(t)
defp build_attrs([{:class, v} | t]),
do: [" class=\"", class_value(v), ?" | build_attrs(t)]
defp build_attrs([{:style, v} | t]),
do: [" style=\"", style_value(v), ?" | build_attrs(t)]
defp build_attrs([{:aria, v} | t]) when is_list(v),
do: nested_attrs(v, " aria", t)
defp build_attrs([{:data, v} | t]) when is_list(v),
do: nested_attrs(v, " data", t)
defp build_attrs([{:phx, v} | t]) when is_list(v),
do: nested_attrs(v, " phx", t)
defp build_attrs([{"class", v} | t]),
do: [" class=\"", class_value(v), ?" | build_attrs(t)]
defp build_attrs([{"style", v} | t]),
do: [" style=\"", style_value(v), ?" | build_attrs(t)]
defp build_attrs([{"aria", v} | t]) when is_list(v),
do: nested_attrs(v, " aria", t)
defp build_attrs([{"data", v} | t]) when is_list(v),
do: nested_attrs(v, " data", t)
defp build_attrs([{"phx", v} | t]) when is_list(v),
do: nested_attrs(v, " phx", t)
defp build_attrs([{k, v} | t]),
do: [?\s, key_escape(k), ?=, ?", attr_escape(v), ?" | build_attrs(t)]
defp build_attrs([]), do: []
defp nested_attrs([{_, bool_atom} | kv], attr, t) when bool_atom in [true, false, nil],
do: nested_attrs(kv, attr, t)
defp nested_attrs([{k, v} | kv], attr, t) when is_list(v),
do: [nested_attrs(v, "#{attr}-#{key_escape(k)}", []) | nested_attrs(kv, attr, t)]
defp nested_attrs([{k, v} | kv], attr, t),
do: [attr, ?-, key_escape(k), ?=, ?", attr_escape(v), ?" | nested_attrs(kv, attr, t)]
defp nested_attrs([], _attr, t),
do: build_attrs(t)
defp nested_attrs(list, attr, t),
do: [attr, list, t]
defp class_value(value) when is_list(value) do
value
|> list_class_value()
|> attr_escape()
end
defp class_value(value) do
attr_escape(value)
end
defp list_class_value(value) do
list_value(value, " ")
end
def style_value(value) when is_list(value) do
value
|> list_style_value()
|> attr_escape()
end
def style_value(value) do
attr_escape(value)
end
defp list_style_value(value) do
list_value(value, ";")
end
def list_value(value, joiner) do
value
|> Enum.flat_map(fn
nil -> []
false -> []
inner when is_list(inner) -> [list_value(inner, joiner)]
other -> [other]
end)
|> Enum.join(joiner)
end
defp key_escape(value) when is_atom(value), do: String.replace(Atom.to_string(value), "_", "-")
defp key_escape(value), do: attr_escape(value)
defp attr_escape(attr)
defp attr_escape({:safe, data}), do: data
defp attr_escape(nil), do: []
defp attr_escape(other) when is_binary(other), do: Phoenix.HTML.Engine.html_escape(other)
defp attr_escape(other), do: LiveViewNative.Template.Safe.to_iodata(other)
end