Add support for img tags

This commit is contained in:
Thelonius Kort
2023-01-15 17:27:51 +01:00
parent b520df2561
commit f2dd8de143
4 changed files with 98 additions and 1 deletions

View File

@ -5,6 +5,8 @@ defmodule Outlook.InternalTree.Html do
@desirable_atts %{"a" => [:href], "img" => [:src]} @desirable_atts %{"a" => [:href], "img" => [:src]}
@void_elements ~w(img br hr)
def strip_attributes([%InternalNode{type: :element} = node | rest]) do def strip_attributes([%InternalNode{type: :element} = node | rest]) do
d_atts = Map.get(@desirable_atts, node.name, []) d_atts = Map.get(@desirable_atts, node.name, [])
atts = Map.reject(node.attributes, fn {k,_} -> k not in d_atts end) atts = Map.reject(node.attributes, fn {k,_} -> k not in d_atts end)
@ -22,6 +24,11 @@ defmodule Outlook.InternalTree.Html do
def strip_attributes([]), do: [] def strip_attributes([]), do: []
def to_html([%{type: :element} = node | rest]) when node.name in @void_elements do
attr_string = Enum.map_join(node.attributes, "", fn {k,v} -> " #{k}=\"#{v}\"" end)
"<#{node.name}#{attr_string}>" <> to_html(rest)
end
def to_html([%{type: :element} = node | rest]) do def to_html([%{type: :element} = node | rest]) do
attr_string = Enum.map_join(node.attributes, "", fn {k,v} -> " #{k}=\"#{v}\"" end) attr_string = Enum.map_join(node.attributes, "", fn {k,v} -> " #{k}=\"#{v}\"" end)
"<#{node.name}#{attr_string}>" <> "<#{node.name}#{attr_string}>" <>

View File

@ -10,6 +10,7 @@ defmodule Outlook.InternalTree.RawInternalBasic do
@splitmarker "@@translationunit@@" @splitmarker "@@translationunit@@"
@nonperiodmarker "@@nonperiod@@" @nonperiodmarker "@@nonperiod@@"
@void_elements ~w(img br hr)
def set_split_markers([ %InternalNode{type: :text} = textnode | rest ]) do def set_split_markers([ %InternalNode{type: :text} = textnode | rest ]) do
[ %InternalNode{textnode | [ %InternalNode{textnode |
@ -68,9 +69,14 @@ defmodule Outlook.InternalTree.RawInternalBasic do
|> strip_empty_tunits() |> strip_empty_tunits()
end end
def partition_inlinelevel([ node | rest ]) when node.name in @void_elements do
[ node | partition_inlinelevel(rest) ]
end
def partition_inlinelevel([ %InternalNode{type: :element} = node | rest ]) do def partition_inlinelevel([ %InternalNode{type: :element} = node | rest ]) do
[ partition_inlinelevel(node.content) [ partition_inlinelevel(node.content)
|> chunk_with_list() |> chunk_with_list()
# elements without content are being dropped here
|> Enum.map(fn nodelist -> %InternalNode{node | content: nodelist} end) |> Enum.map(fn nodelist -> %InternalNode{node | content: nodelist} end)
| partition_inlinelevel(rest) ] | partition_inlinelevel(rest) ]
end end
@ -93,7 +99,7 @@ defmodule Outlook.InternalTree.RawInternalBasic do
def partition_inlinelevel([]), do: [] def partition_inlinelevel([]), do: []
def strip_empty_nodes([%{type: :element} = node | rest]) when node.name in ~w(img br) do def strip_empty_nodes([%{type: :element} = node | rest]) when node.name in @void_elements do
[ node | strip_empty_nodes(rest) ] [ node | strip_empty_nodes(rest) ]
end end

View File

@ -30,6 +30,12 @@ defmodule OutlookWeb.HtmlDocComponent do
""" """
end end
def dnode(assigns) when assigns.node.name == "img" do
~H"""
<img {@node.attributes |> Map.merge(Map.get(@node.eph, :attributes, %{})) |> Map.merge(%{nid: @node.nid})}>
"""
end
def dnode(assigns) when assigns.node.type == :element do def dnode(assigns) when assigns.node.type == :element do
~H""" ~H"""
<.dynamic_tag name={@node.name} nid={@node.nid} {@node.attributes |> Map.merge(Map.get(@node.eph, :attributes, %{}))}> <.dynamic_tag name={@node.name} nid={@node.nid} {@node.attributes |> Map.merge(Map.get(@node.eph, :attributes, %{}))}>

View File

@ -208,5 +208,83 @@ defmodule Outlook.InternalTreeTest do
} }
] ]
end end
test "img tag won't be considered an empty element" do
tree = [
%Outlook.InternalTree.InternalNode{
name: "p",
attributes: %{},
type: :element,
nid: "cGK7c5koxnjH",
content: [
%Outlook.InternalTree.InternalNode{
name: "img",
attributes: %{src: "/images/flower.png"},
type: :element,
nid: "druVejfHcuX7",
content: [],
eph: %{sibling_with: :inline}
}
],
eph: %{sibling_with: :block}
}
]
assert InternalTree.partition_text(tree) |> unify_nids_in_tunits() == [
%Outlook.InternalTree.InternalNode{
name: "p",
attributes: %{},
type: :element,
nid: "cGK7c5koxnjH",
content: [
%Outlook.InternalTree.TranslationUnit{
status: :untranslated,
nid: "xxxxxx",
content: "<img src=\"/images/flower.png\">",
eph: %{}
}
],
eph: %{sibling_with: :block}
}
]
end
test "br tag won't be considered an empty element" do
tree = [
%Outlook.InternalTree.InternalNode{
name: "p",
attributes: %{},
type: :element,
nid: "cGK7c5koxnjH",
content: [
%Outlook.InternalTree.InternalNode{
name: "br",
attributes: %{},
type: :element,
nid: "druVejfHcuX7",
content: [],
eph: %{sibling_with: :inline}
}
],
eph: %{sibling_with: :block}
}
]
assert InternalTree.partition_text(tree) |> unify_nids_in_tunits() == [
%Outlook.InternalTree.InternalNode{
name: "p",
attributes: %{},
type: :element,
nid: "cGK7c5koxnjH",
content: [
%Outlook.InternalTree.TranslationUnit{
status: :untranslated,
nid: "xxxxxx",
content: "<br>",
eph: %{}
}
],
eph: %{sibling_with: :block}
}
]
end
end end
end end