Skip to content

Commit

Permalink
Use CellJS adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
jessedijkstra committed Nov 24, 2017
1 parent 995afc1 commit 8fa7eaa
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 156 deletions.
12 changes: 5 additions & 7 deletions lib/ex_cell/adapters/cell_js.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ defmodule ExCell.Adapters.CellJS do
def data_attribute(name, data \\ [], params \\ %{})
def data_attribute(name, data, params) when is_nil(data), do:
data_attribute(name, [], params)

def data_attribute(name, data, params) when is_list(data) do
data
|> Keyword.merge(cell: name, cell_params: Poison.encode!(params))
end
def data_attribute(name, data, params) when is_list(data), do:
Keyword.merge(data, cell: name, cell_params: Poison.encode!(params))

def attributes(name, attributes \\ [], params \\ %{}) do
Keyword.put(
Expand All @@ -24,10 +21,11 @@ defmodule ExCell.Adapters.CellJS do
name: name,
attributes: attributes,
params: params,
tag: tag,
closing_tag: closing_tag,
content: content
}) do
{tag, attributes} = Keyword.pop(attributes, :tag, :div)
{closing_tag, attributes} = Keyword.pop(attributes, :closing_tag, true)

attributes = attributes(name, attributes, params)

case closing_tag do
Expand Down
44 changes: 3 additions & 41 deletions lib/ex_cell/base.ex
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
defmodule ExCell.Base do
@moduledoc false
@dialyzer [{:no_match, relative_name: 2}]

def relative_name(module, namespace) do
parts = case namespace do
nil -> Module.split(module)
_ -> ExCell.module_relative_to(module, namespace)
end

Enum.join(parts, "-")
end

def class_attribute(name, class) do
[name, class]
|> List.flatten
|> Enum.reject(&is_nil/1)
|> Enum.join(" ")
end

defmacro __using__(opts \\ []) do
quote do
import ExCell.View
import ExCell.Base

@adapter unquote(opts[:adapter] || ExCell.Adapters.CellJS)
@namespace unquote(opts[:namespace])
Expand All @@ -38,7 +18,8 @@ defmodule ExCell.Base do
iex(1)> User.AvatarCell.name()
"User-AvatarCell"
"""
def name, do: relative_name(__MODULE__, @namespace)
def __adapter__, do: @adapter
def name, do: ExCell.relative_name(__MODULE__, @namespace)

@doc """
Generates the CSS class name based on the cell name. Can be overriden
Expand Down Expand Up @@ -135,26 +116,7 @@ defmodule ExCell.Base do
def container(%{} = params, options) when is_list(options), do:
container(params, options, [do: nil])
def container(%{} = params, options, [do: content]) when is_list(options), do:
@adapter.container(adapter_options(params, options, content))

def adapter_options(params \\ %{}, attributes \\ [], content \\ nil) do
{tag, attributes} = Keyword.pop(attributes, :tag, :div)
{closing_tag, attributes} = Keyword.pop(attributes, :closing_tag, true)
{cell_name, attributes} =
Keyword.pop(attributes, :cell_name, cell_name())

class_attribute =
class_attribute(class_name(), Keyword.get(attributes, :class))

%{
name: cell_name,
attributes: Keyword.put(attributes, :class, class_attribute),
params: params(params),
tag: tag,
closing_tag: closing_tag,
content: content
}
end
ExCell.container(__MODULE__, params, options, [do: content])

defoverridable [class_name: 0, cell_name: 0, params: 0]
end
Expand Down
33 changes: 33 additions & 0 deletions lib/ex_cell/ex_cell.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule ExCell do
@moduledoc false
@dialyzer [{:no_match, relative_name: 2}]

def module_relative_to(module, relative_to) do
module
Expand All @@ -12,4 +13,36 @@ defmodule ExCell do
|> Application.get_env(__MODULE__, [])
|> Keyword.get(keyword, fallback)
end


def relative_name(module, namespace) do
parts = case namespace do
nil -> Module.split(module)
_ -> ExCell.module_relative_to(module, namespace)
end

Enum.join(parts, "-")
end

def class_name(name, classes) do
[name, classes]
|> List.flatten
|> Enum.reject(&is_nil/1)
|> Enum.join(" ")
end

def container(module, params, attributes, [do: content]) do
options(module, params, attributes, content)
|> module.__adapter__().container()
end

def options(module, params, attributes, content) do
%{
name: module.cell_name(),
params: module.params(params),
attributes: Keyword.put(attributes, :class,
class_name(module.class_name(), Keyword.get(attributes, :class))),
content: content
}
end
end
114 changes: 91 additions & 23 deletions test/ex_cell/adapters/cell_js_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ defmodule ExCell.Adapters.CellJSTest do
import Phoenix.HTML
alias Phoenix.HTML.Tag

alias ExCell.Cell
alias ExCell.Adapters.CellJS

defmodule MockCell do
use Cell, namespace: ExCell.Adapters.CellJSTest
end

describe "attributes/3" do
test "it rejects nil values" do
assert CellJS.attributes(nil, [], %{}) ==
Expand Down Expand Up @@ -55,48 +50,121 @@ defmodule ExCell.Adapters.CellJSTest do

describe "container/1" do
test "defaults to a :div as tag" do
assert safe_to_string(CellJS.container(MockCell.adapter_options()))
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell"
],
params: %{},
content: nil
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\"></div>"
end

test "custom tag" do
assert safe_to_string(CellJS.container(MockCell.adapter_options(%{}, tag: :p)))
attributes = %{
name: "MockCell",
attributes: [
tag: :p,
class: "MockCell"
],
params: %{},
content: nil
}

assert safe_to_string(CellJS.container(attributes))
== "<p class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\"></p>"
end

test "content" do
assert safe_to_string(CellJS.container(MockCell.adapter_options(%{}, [], "TestContent")))
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell"
],
params: %{},
content: "TestContent"
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\">TestContent</div>"
end

test "unsafe content" do
assert safe_to_string(
CellJS.container(MockCell.adapter_options(%{}, [], Tag.content_tag(:div, "TestContent")))
) == "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\"><div>TestContent</div></div>"
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell"
],
params: %{},
content: Tag.content_tag(:div, "TestContent")
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\"><div>TestContent</div></div>"
end

test "cell params" do
assert safe_to_string(
CellJS.container(MockCell.adapter_options(%{ foo: "bar" }))
) == "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{&quot;foo&quot;:&quot;bar&quot;}\"></div>"
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell"
],
params: %{
foo: "bar"
},
content: nil
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{&quot;foo&quot;:&quot;bar&quot;}\"></div>"
end

test "attributes" do
assert safe_to_string(
CellJS.container(MockCell.adapter_options(%{}, foo: "bar"))
) == "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\" foo=\"bar\"></div>"
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell",
foo: "bar"
],
params: %{},
content: nil
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\" foo=\"bar\"></div>"
end

test "data attributes" do
assert safe_to_string(
CellJS.container(MockCell.adapter_options(%{}, data: [foo: "bar"]))
) == "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\" data-foo=\"bar\"></div>"
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell",
data: [foo: "bar"]
],
params: %{},
content: nil
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\" data-foo=\"bar\"></div>"
end

test "no closing tag" do
assert safe_to_string(
CellJS.container(MockCell.adapter_options(%{}, closing_tag: false, data: [foo: "bar"]))
) == "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\" data-foo=\"bar\">"
attributes = %{
name: "MockCell",
attributes: [
class: "MockCell",
closing_tag: false
],
params: %{},
content: nil
}

assert safe_to_string(CellJS.container(attributes))
== "<div class=\"MockCell\" data-cell=\"MockCell\" data-cell-params=\"{}\">"
end
end
end
35 changes: 0 additions & 35 deletions test/ex_cell/base_test.exs

This file was deleted.

Loading

0 comments on commit 8fa7eaa

Please sign in to comment.