Fix phx_link, phx_button block style implementation

This commit is contained in:
Mitchell Hanberg 2019-06-30 14:28:44 -04:00
parent 883f0966ea
commit 52a27c3dc2
4 changed files with 94 additions and 17 deletions

View file

@ -41,15 +41,17 @@ defmodule Dsl do
import Phoenix.HTML.Link, except: [link: 1, link: 2]
import Phoenix.HTML.Form, only: []
{:ok, var!(buff, Dsl.Tags)} = Dsl.Utils.start_buffer([])
Dsl.Utils.lexical_scope(fn ->
{:ok, var!(buff, Dsl.Tags)} = Dsl.Utils.start_buffer([])
unquote(block)
unquote(block)
markup = Dsl.Utils.get_buffer(var!(buff, Dsl.Tags))
markup = Dsl.Utils.get_buffer(var!(buff, Dsl.Tags))
:ok = Dsl.Utils.stop_buffer(var!(buff, Dsl.Tags))
:ok = Dsl.Utils.stop_buffer(var!(buff, Dsl.Tags))
markup |> Enum.reverse() |> Enum.join("") |> Phoenix.HTML.raw()
markup |> Enum.reverse() |> Enum.join("") |> Phoenix.HTML.raw()
end)
end
end

View file

@ -9,9 +9,22 @@ defmodule Dsl.Link do
@doc """
Please see `Phoenix.HTML.Link.link/2` for details.
"""
defmacro phx_link(content_or_opts, opts_or_block) do
defmacro phx_link(opts, do: block) do
quote do
{:safe, link} = HTML.Link.link(unquote_splicing([content_or_opts, opts_or_block]))
{:safe, content} =
htm do
unquote(block)
end
{:safe, link} = HTML.Link.link(content, unquote(opts))
Utils.put_buffer(var!(buff, Dsl.Tags), link)
end
end
defmacro phx_link(content, opts) do
quote do
{:safe, link} = HTML.Link.link(unquote_splicing([content, opts]))
Utils.put_buffer(var!(buff, Dsl.Tags), link)
end
@ -20,9 +33,22 @@ defmodule Dsl.Link do
@doc """
Please see `Phoenix.HTML.Link.button/2` for details.
"""
defmacro phx_button(content_or_opts, opts_or_block) do
defmacro phx_button(opts, do: block) do
quote do
{:safe, link} = HTML.Link.button(unquote_splicing([content_or_opts, opts_or_block]))
{:safe, content} =
htm do
unquote(block)
end
{:safe, link} = HTML.Link.button(content, unquote(opts))
Utils.put_buffer(var!(buff, Dsl.Tags), link)
end
end
defmacro phx_button(content, opts) do
quote do
{:safe, link} = HTML.Link.button(unquote_splicing([content, opts]))
Utils.put_buffer(var!(buff, Dsl.Tags), link)
end

View file

@ -38,6 +38,10 @@ defmodule Dsl.Utils do
end
end
def lexical_scope(work) do
work.()
end
def start_buffer(initial_buffer), do: Agent.start(fn -> initial_buffer end)
def put_buffer(buff, content), do: Agent.update(buff, &[content | &1])
def get_buffer(buff), do: Agent.get(buff, & &1)

View file

@ -14,17 +14,36 @@ defmodule Dsl.LinkTest do
assert actual =~ ~s{hi}
end
test "emits a link when passed block" do
test "emits a link when passed block that has text" do
{:safe, actual} =
htm do
phx_link to: "/hello" do
"hi"
text "hi"
end
end
assert actual =~ ~s{<a}
assert String.starts_with?(actual, ~s{<a})
assert actual =~ ~s{href="/hello"}
assert actual =~ ~s{hi}
assert String.ends_with?(actual, ~s{</a>})
end
test "emits a link when passed block that has more markup" do
{:safe, actual} =
htm do
phx_link to: "/hello" do
div do
div "hi"
end
end
end
assert String.starts_with?(actual, ~s{<a})
assert actual =~ ~s{href="/hello"}
assert actual =~ ~s{&lt;div&gt;&lt;div&gt;}
assert actual =~ ~s{hi}
assert actual =~ ~s{&lt;/div&gt;&lt;/div&gt;}
assert String.ends_with?(actual, ~s{</a>})
end
test "emits a link with additional html attributes" do
@ -72,19 +91,43 @@ defmodule Dsl.LinkTest do
end
assert actual =~ ~s{<button}
assert actual =~ ~s{data-to="/hello"}
assert actual =~ ~s{data-method="post"}
assert actual =~ ~s{hi}
end
test "emits a button when passed block" do
test "emits a button when passed block that has text" do
{:safe, actual} =
htm do
phx_button to: "/hello" do
"hi"
text "hi"
end
end
assert actual =~ ~s{<button}
assert String.starts_with?(actual, ~s{<button})
assert actual =~ ~s{hi}
assert actual =~ ~s{data-to="/hello"}
assert actual =~ ~s{data-method="post"}
assert String.ends_with?(actual, ~s{</button>})
end
test "emits a button when passed block that has more markup" do
{:safe, actual} =
htm do
phx_button to: "/hello" do
div do
div "hi"
end
end
end
assert String.starts_with?(actual, ~s{<button})
assert actual =~ ~s{data-to="/hello"}
assert actual =~ ~s{data-method="post"}
assert actual =~ ~s{&lt;div&gt;&lt;div&gt;}
assert actual =~ ~s{hi}
assert actual =~ ~s{&lt;/div&gt;&lt;/div&gt;}
assert String.ends_with?(actual, ~s{</button>})
end
test "emits a button with additional html attributes" do
@ -99,11 +142,12 @@ defmodule Dsl.LinkTest do
)
end
assert actual =~ ~s{<button}
assert String.starts_with?(actual, ~s{<button})
assert actual =~ ~s{class="phoenix"}
assert actual =~ ~s{id="legendary"}
assert actual =~ ~s{data-confirm="Really?"}
assert actual =~ ~s{hi}
assert String.ends_with?(actual, ~s{</button>})
end
test "emits a button with a non GET method" do
@ -115,11 +159,12 @@ defmodule Dsl.LinkTest do
)
end
assert actual =~ ~s{<button}
assert String.starts_with?(actual, ~s{<button})
assert actual =~ ~s{data-csrf="}
assert actual =~ ~s{data-method="delete"}
assert actual =~ ~s{data-to="/hello"}
assert actual =~ ~s{hi}
assert String.ends_with?(actual, ~s{</button>})
end
end
end