From 76b5fcd4e6425f54e6acd85418a4cb465831694a Mon Sep 17 00:00:00 2001 From: Jeff Sandberg Date: Sat, 6 Jul 2019 18:14:42 -0700 Subject: [PATCH] Join list-attributes --- lib/slime/compiler.ex | 7 ++++--- lib/slime/parser/attributes_keyword.ex | 14 +++++++++++--- test/rendering/attributes_test.exs | 10 ++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/slime/compiler.ex b/lib/slime/compiler.ex index c9cfc12..ec8d24d 100644 --- a/lib/slime/compiler.ex +++ b/lib/slime/compiler.ex @@ -95,10 +95,11 @@ defmodule Slime.Compiler do ~s[ #{name}="#{quoted}"] end - defp render_attribute_code(name, _cotnent, quoted, safe) when is_binary(quoted) do - value = if :eex == safe, do: quoted, else: ~s[<%= {:safe, "#{quoted}"} %>] - ~s[ #{name}="#{value}"] + defp render_attribute_code(name, _content, quoted, _) when is_list(quoted) do + quoted |> Enum.map_join(" ", &Kernel.to_string/1) |> (& ~s[ #{name}="#{&1}"]).() end + defp render_attribute_code(name, _content, quoted, :eex) when is_binary(quoted), do: ~s[ #{name}="#{quoted}"] + defp render_attribute_code(name, _content, quoted, _) when is_binary(quoted), do: ~s[ #{name}="<%= {:safe, "#{quoted}"} %>"] # NOTE: string with interpolation or strings concatination defp render_attribute_code(name, content, {op, _, _}, safe) when op in [:<<>>, :<>] do diff --git a/lib/slime/parser/attributes_keyword.ex b/lib/slime/parser/attributes_keyword.ex index 527c716..94b0935 100644 --- a/lib/slime/parser/attributes_keyword.ex +++ b/lib/slime/parser/attributes_keyword.ex @@ -51,9 +51,17 @@ defmodule Slime.Parser.AttributesKeyword do defp dynamic_value?(_), do: false defp join_attribute_values(values, join_by) do - values |> Enum.map(&attribute_val/1) |> List.flatten |> Enum.join(join_by) + values |> Enum.map(&attribute_val(&1, join_by)) |> List.flatten |> Enum.join(join_by) end - defp attribute_val({:eex, content}), do: "\#{" <> content <> "}" - defp attribute_val(value), do: value + defp attribute_val({:eex, content}, join_by) do + case Code.string_to_quoted!(content) do + list when is_list(list) -> + list |> List.flatten |> Enum.join(join_by) + _ -> "\#{" <> content <> "}" + end + end + + defp attribute_val(value, _), do: value + end diff --git a/test/rendering/attributes_test.exs b/test/rendering/attributes_test.exs index 043e4a2..39bd3f9 100644 --- a/test/rendering/attributes_test.exs +++ b/test/rendering/attributes_test.exs @@ -101,6 +101,10 @@ defmodule RenderAttributesTest do ) == ~s() end + test "parses attributes with lists" do + assert render(~S{meta content=["a", "b", "c"]}) == ~s{} + end + test "attributes values can contain `=` character" do template = ~s(meta content="width=device-width, initial-scale=1") html = ~s() @@ -112,6 +116,12 @@ defmodule RenderAttributesTest do assert render(template) == ~s(
) end + test "shorthand and literal class attributes are merged with list awareness" do + + template = ~s(.class-one class=["class-two", "class-three"]) + assert render(template) == ~s(
) + end + test "attributes can have dynamic values" do assert render("div a=meta", meta: true) == ~s(
) assert render("div a=meta", meta: "test") == ~s(
)