diff --git a/lib/outlook/internal_tree/html.ex b/lib/outlook/internal_tree/html.ex index 7d68a2a..f5af203 100644 --- a/lib/outlook/internal_tree/html.ex +++ b/lib/outlook/internal_tree/html.ex @@ -5,6 +5,8 @@ defmodule Outlook.InternalTree.Html do @desirable_atts %{"a" => [:href], "img" => [:src]} + @void_elements ~w(img br hr) + def strip_attributes([%InternalNode{type: :element} = node | rest]) do d_atts = Map.get(@desirable_atts, node.name, []) 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 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 attr_string = Enum.map_join(node.attributes, "", fn {k,v} -> " #{k}=\"#{v}\"" end) "<#{node.name}#{attr_string}>" <> diff --git a/lib/outlook/internal_tree/raw_internal_basic.ex b/lib/outlook/internal_tree/raw_internal_basic.ex index 9b3db6b..bcb17fc 100644 --- a/lib/outlook/internal_tree/raw_internal_basic.ex +++ b/lib/outlook/internal_tree/raw_internal_basic.ex @@ -10,6 +10,7 @@ defmodule Outlook.InternalTree.RawInternalBasic do @splitmarker "@@translationunit@@" @nonperiodmarker "@@nonperiod@@" + @void_elements ~w(img br hr) def set_split_markers([ %InternalNode{type: :text} = textnode | rest ]) do [ %InternalNode{textnode | @@ -68,9 +69,14 @@ defmodule Outlook.InternalTree.RawInternalBasic do |> strip_empty_tunits() 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 [ partition_inlinelevel(node.content) |> chunk_with_list() + # elements without content are being dropped here |> Enum.map(fn nodelist -> %InternalNode{node | content: nodelist} end) | partition_inlinelevel(rest) ] end @@ -93,7 +99,7 @@ defmodule Outlook.InternalTree.RawInternalBasic 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) ] end diff --git a/lib/outlook_web/components/html_doc_component.ex b/lib/outlook_web/components/html_doc_component.ex index f92508b..7d265a2 100644 --- a/lib/outlook_web/components/html_doc_component.ex +++ b/lib/outlook_web/components/html_doc_component.ex @@ -30,6 +30,12 @@ defmodule OutlookWeb.HtmlDocComponent do """ end + def dnode(assigns) when assigns.node.name == "img" do + ~H""" + Map.merge(Map.get(@node.eph, :attributes, %{})) |> Map.merge(%{nid: @node.nid})}> + """ + end + def dnode(assigns) when assigns.node.type == :element do ~H""" <.dynamic_tag name={@node.name} nid={@node.nid} {@node.attributes |> Map.merge(Map.get(@node.eph, :attributes, %{}))}> diff --git a/test/outlook/internaltree_test.exs b/test/outlook/internaltree_test.exs index fa45228..827b849 100644 --- a/test/outlook/internaltree_test.exs +++ b/test/outlook/internaltree_test.exs @@ -208,5 +208,83 @@ defmodule Outlook.InternalTreeTest do } ] 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: "", + 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: "
", + eph: %{} + } + ], + eph: %{sibling_with: :block} + } + ] + end end end