From a6f3e8e04b1c870bea3660b4e4215ffec4c3b741 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 13:11:20 +0800 Subject: [PATCH 1/7] feat(editor-export): add uid anchor_id for header --- .../converter/editor_to_html/frags/header.ex | 18 ++- .../editor_to_html/validator/editor_schema.ex | 12 +- lib/helper/converter/html_sanitizer.ex | 2 +- lib/helper/utils.ex | 11 ++ mix.exs | 2 +- .../editor_to_html_test/header_test.exs | 144 ++++++++---------- .../editor_to_html_test/quote_test.exs | 10 +- 7 files changed, 107 insertions(+), 92 deletions(-) diff --git a/lib/helper/converter/editor_to_html/frags/header.ex b/lib/helper/converter/editor_to_html/frags/header.ex index e58ea7bb5..d2b9038b6 100644 --- a/lib/helper/converter/editor_to_html/frags/header.ex +++ b/lib/helper/converter/editor_to_html/frags/header.ex @@ -5,6 +5,7 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do see https://editorjs.io/ """ alias Helper.Types, as: T + alias Helper.Utils alias Helper.Converter.EditorToHTML.Class @@ -19,7 +20,9 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do eyebrow_class = @class["eyebrow_title"] footer_class = @class["footer_title"] - ~s(
+ anchor_id = Utils.uid(:html, data) + + ~s(
#{eyebrow_title}
#{text}
#{footer_title}
@@ -33,7 +36,9 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do header_class = @class["header"] eyebrow_class = @class["eyebrow_title"] - ~s(
+ anchor_id = Utils.uid(:html, data) + + ~s(
#{eyebrow_title}
#{text}
) @@ -46,13 +51,16 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do header_class = @class["header"] footer_class = @class["footer_title"] - ~s(
+ anchor_id = Utils.uid(:html, data) + ~s(
#{text}
#{footer_title}
) end - def get(%{"text" => text, "level" => level}) do - "#{text}" + def get(%{"text" => text, "level" => level} = data) do + anchor_id = Utils.uid(:html, data) + + ~s(#{text}) end end diff --git a/lib/helper/converter/editor_to_html/validator/editor_schema.ex b/lib/helper/converter/editor_to_html/validator/editor_schema.ex index f48529585..0a9f172e4 100644 --- a/lib/helper/converter/editor_to_html/validator/editor_schema.ex +++ b/lib/helper/converter/editor_to_html/validator/editor_schema.ex @@ -15,7 +15,7 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do # table @valid_table_align ["left", "center", "right"] - @spec get(String.t()) :: map + @spec get(String.t()) :: map | [parent: map, item: map] def get("editor") do %{ "time" => [:number], @@ -26,6 +26,7 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do def get("header") do %{ + "id" => [:string, required: false], "text" => [:string], "level" => [enum: @valid_header_level], "eyebrowTitle" => [:string, required: false], @@ -33,17 +34,22 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do } end - def get("paragraph"), do: %{"text" => [:string]} + def get("paragraph") do + %{ + "id" => [:string, required: false], + "text" => [:string] + } + end def get("quote") do %{ + "id" => [:string, required: false], "text" => [:string], "mode" => [enum: @valid_quote_mode], "caption" => [:string, required: false] } end - @spec get(String.t()) :: [parent: map, item: map] def get("list") do [ parent: %{"mode" => [enum: @valid_list_mode], "items" => [:list]}, diff --git a/lib/helper/converter/html_sanitizer.ex b/lib/helper/converter/html_sanitizer.ex index 172e55951..78fc1b14f 100644 --- a/lib/helper/converter/html_sanitizer.ex +++ b/lib/helper/converter/html_sanitizer.ex @@ -33,7 +33,7 @@ defmodule Helper.Converter.HtmlSanitizer do # Meta.allow_tag_with_these_attributes("h6", ["class"]) Meta.allow_tag_with_these_attributes("p", ["class"]) Meta.allow_tag_with_these_attributes("img", ["class", "src"]) - Meta.allow_tag_with_these_attributes("div", ["class", "data-index"]) + Meta.allow_tag_with_these_attributes("div", ["id", "class", "data-index"]) Meta.allow_tag_with_these_attributes("ul", ["class"]) Meta.allow_tag_with_these_attributes("ol", ["class"]) Meta.allow_tag_with_these_attributes("li", ["class"]) diff --git a/lib/helper/utils.ex b/lib/helper/utils.ex index 5afd540a8..dc2a80580 100644 --- a/lib/helper/utils.ex +++ b/lib/helper/utils.ex @@ -6,6 +6,8 @@ defmodule Helper.Utils do import Helper.ErrorHandler import Helper.ErrorCode + import Helper.Validator.Guards, only: [g_none_empty_str: 1] + alias Helper.Cache def get_config(section, key, app \\ :groupher_server) @@ -282,4 +284,13 @@ defmodule Helper.Utils do def less_than(value, target, :no_equal) when is_integer(value) and is_integer(target) do value < target end + + @doc "html uniq id generator for editorjs" + @spec uid(:html, map) :: String.t() + def uid(:html, %{"id" => id}) when g_none_empty_str(id), do: id + + def uid(:html, _) do + # number is invalid for html id(if first letter) + Nanoid.generate(5, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + end end diff --git a/mix.exs b/mix.exs index 654397fc4..6c8489698 100644 --- a/mix.exs +++ b/mix.exs @@ -92,7 +92,7 @@ defmodule GroupherServer.Mixfile do {:excoveralls, "~> 0.8", only: :test}, {:sentry, "~> 7.1"}, {:recase, "~> 0.7.0"}, - {:nanoid, "~> 2.0.0"}, + {:nanoid, "~> 2.0.5"}, # mailer {:bamboo, "1.3.0"}, # mem cache diff --git a/test/helper/converter/editor_to_html_test/header_test.exs b/test/helper/converter/editor_to_html_test/header_test.exs index bac2f08cd..82d16d501 100644 --- a/test/helper/converter/editor_to_html_test/header_test.exs +++ b/test/helper/converter/editor_to_html_test/header_test.exs @@ -14,6 +14,19 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do @footer_class @class["footer_title"] describe "[header block unit]" do + defp set_data(data) do + %{ + "time" => 1_567_250_876_713, + "blocks" => [ + %{ + "type" => "header", + "data" => data + } + ], + "version" => "2.15.0" + } + end + @editor_json %{ "time" => 1_567_250_876_713, "blocks" => [ @@ -56,99 +69,83 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do ~s(
#{h1_frag}#{h2_frag}#{h3_frag}
) end - @editor_json %{ - "time" => 1_567_250_876_713, - "blocks" => [ - %{ - "type" => "header", - "data" => %{ - "text" => "header content", - "level" => 1, - "eyebrowTitle" => "eyebrow title content", - "footerTitle" => "footer title content" - } - } - ], - "version" => "2.15.0" - } - @tag :wip + @tag :wip2 test "full header parse should work" do - {:ok, editor_string} = Jason.encode(@editor_json) + editor_json = + set_data(%{ + "text" => "header content", + "level" => 1, + "eyebrowTitle" => "eyebrow title content", + "footerTitle" => "footer title content" + }) + + {:ok, editor_string} = Jason.encode(editor_json) {:ok, converted} = Parser.to_html(editor_string) # header_class = @class["header"] - - # IO.inspect(converted, label: "header converted") + assert Utils.str_occurence(converted, "id=") == 1 # assert Utils.str_occurence(converted, header_class) == 1 assert Utils.str_occurence(converted, @eyebrow_class) == 1 assert Utils.str_occurence(converted, @footer_class) == 1 end - @editor_json %{ - "time" => 1_567_250_876_713, - "version" => "2.15.0" - } - @tag :wip + @tag :wip2 + test "edit exsit block will not change id value" do + editor_json = + set_data(%{ + "id" => "exist", + "text" => "header content", + "level" => 1, + "eyebrowTitle" => "eyebrow title content", + "footerTitle" => "footer title content" + }) + + {:ok, editor_string} = Jason.encode(editor_json) + {:ok, converted} = Parser.to_html(editor_string) + + assert Utils.str_occurence(converted, ~s(id="exist")) == 1 + end + + @tag :wip2 test "optional field should valid properly" do - json = - Map.merge(@editor_json, %{ - "blocks" => [ - %{ - "type" => "header", - "data" => %{ - "text" => "header content", - "level" => 1, - "eyebrowTitle" => "eyebrow title content" - } - } - ] + editor_json = + set_data(%{ + "text" => "header content", + "level" => 1, + "eyebrowTitle" => "eyebrow title content" }) - {:ok, editor_string} = Jason.encode(json) + {:ok, editor_string} = Jason.encode(editor_json) {:ok, converted} = Parser.to_html(editor_string) assert Utils.str_occurence(converted, @eyebrow_class) == 1 assert Utils.str_occurence(converted, @footer_class) == 0 - json = - Map.merge(@editor_json, %{ - "blocks" => [ - %{ - "type" => "header", - "data" => %{ - "text" => "header content", - "level" => 1, - "footerTitle" => "footer title content" - } - } - ] + editor_json = + set_data(%{ + "text" => "header content", + "level" => 1, + "footerTitle" => "footer title content" }) - {:ok, editor_string} = Jason.encode(json) + {:ok, editor_string} = Jason.encode(editor_json) {:ok, converted} = Parser.to_html(editor_string) assert Utils.str_occurence(converted, @eyebrow_class) == 0 assert Utils.str_occurence(converted, @footer_class) == 1 end - @tag :wip + @tag :wip2 test "wrong header format data should have invalid hint" do - json = - Map.merge(@editor_json, %{ - "blocks" => [ - %{ - "type" => "header", - "data" => %{ - "text" => "header content", - "level" => 1, - "eyebrowTitle" => [], - "footerTitle" => true - } - } - ] + editor_json = + set_data(%{ + "text" => "header content", + "level" => 1, + "eyebrowTitle" => [], + "footerTitle" => true }) - {:ok, editor_string} = Jason.encode(json) + {:ok, editor_string} = Jason.encode(editor_json) {:error, error} = Parser.to_html(editor_string) assert error == @@ -167,20 +164,13 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do } ] - json = - Map.merge(@editor_json, %{ - "blocks" => [ - %{ - "type" => "header", - "data" => %{ - "text" => "header content", - "level" => [] - } - } - ] + editor_json = + set_data(%{ + "text" => "header content", + "level" => [] }) - {:ok, editor_string} = Jason.encode(json) + {:ok, editor_string} = Jason.encode(editor_json) {:error, error} = Parser.to_html(editor_string) assert error == [%{block: "header", field: "level", message: "should be: 1 | 2 | 3"}] end diff --git a/test/helper/converter/editor_to_html_test/quote_test.exs b/test/helper/converter/editor_to_html_test/quote_test.exs index 3a29216cd..b68c0d79a 100644 --- a/test/helper/converter/editor_to_html_test/quote_test.exs +++ b/test/helper/converter/editor_to_html_test/quote_test.exs @@ -41,7 +41,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do } end - @tag :wip2 + @tag :wip test "short quote parse should work" do editor_json = set_data("short", "short quote") {:ok, editor_string} = Jason.encode(editor_json) @@ -55,7 +55,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do assert Utils.str_occurence(converted, caption_class) == 0 end - @tag :wip2 + @tag :wip test "long quote parse should work" do editor_json = set_data("long", "long quote", "caption") {:ok, editor_string} = Jason.encode(editor_json) @@ -69,7 +69,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do assert Utils.str_occurence(converted, caption_text_class) == 1 end - @tag :wip2 + @tag :wip test "long quote without caption parse should work" do editor_json = set_data("long", "long quote") {:ok, editor_string} = Jason.encode(editor_json) @@ -84,7 +84,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do assert Utils.str_occurence(converted, caption_text_class) == 0 end - @tag :wip2 + @tag :wip test "long quote without empty caption parse should work" do editor_json = set_data("long", "long quote", "") {:ok, editor_string} = Jason.encode(editor_json) @@ -111,7 +111,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do # ], # "version" => "2.15.0" # } - @tag :wip2 + @tag :wip test "invalid quote should have invalid hint" do editor_json = set_data("none_exsit", "long quote", "") {:ok, editor_string} = Jason.encode(editor_json) From 41d7edc0648484ef3b69ccf3a42203efad37541a Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 15:00:04 +0800 Subject: [PATCH 2/7] feat(editor-export): add uid anchor_id for list --- .../converter/editor_to_html/frags/list.ex | 56 +++++++++++-------- lib/helper/converter/editor_to_html/index.ex | 3 +- .../editor_to_html/validator/editor_schema.ex | 12 +++- .../editor_to_html_test/list_test.exs | 33 ++++++++++- 4 files changed, 76 insertions(+), 28 deletions(-) diff --git a/lib/helper/converter/editor_to_html/frags/list.ex b/lib/helper/converter/editor_to_html/frags/list.ex index 32f8d5d9e..953e0e3e7 100644 --- a/lib/helper/converter/editor_to_html/frags/list.ex +++ b/lib/helper/converter/editor_to_html/frags/list.ex @@ -6,17 +6,21 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do """ alias Helper.Converter.EditorToHTML.Class alias Helper.Types, as: T + alias Helper.Utils @class get_in(Class.article(), ["list"]) @spec get_item(:checklist | :unorder_list | :order_list, T.editor_list_item()) :: T.html() - def get_item(:unorder_list, %{ - "hideLabel" => hide_label, - "indent" => indent, - "label" => label, - "labelType" => label_type, - "text" => text - }) do + def get_item( + :unorder_list, + %{ + "hideLabel" => hide_label, + "indent" => indent, + "label" => label, + "labelType" => label_type, + "text" => text + } + ) do prefix_frag = frag(:unorder_list_prefix) label_frag = if hide_label, do: "", else: frag(:label, label_type, indent, label) text_frag = frag(:text, text) @@ -31,14 +35,17 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do
) end - def get_item(:order_list, %{ - "hideLabel" => hide_label, - "indent" => indent, - "label" => label, - "labelType" => label_type, - "prefixIndex" => prefix_index, - "text" => text - }) do + def get_item( + :order_list, + %{ + "hideLabel" => hide_label, + "indent" => indent, + "label" => label, + "labelType" => label_type, + "prefixIndex" => prefix_index, + "text" => text + } + ) do prefix_frag = frag(:order_list_prefix, prefix_index) label_frag = if hide_label, do: "", else: frag(:label, label_type, indent, label) text_frag = frag(:text, text) @@ -53,14 +60,17 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do
) end - def get_item(:checklist, %{ - "checked" => checked, - "hideLabel" => hide_label, - "indent" => indent, - "label" => label, - "labelType" => label_type, - "text" => text - }) do + def get_item( + :checklist, + %{ + "checked" => checked, + "hideLabel" => hide_label, + "indent" => indent, + "label" => label, + "labelType" => label_type, + "text" => text + } + ) do # local fragments checkbox_frag = frag(:checkbox, checked) label_frag = if hide_label, do: "", else: frag(:label, label_type, indent, label) diff --git a/lib/helper/converter/editor_to_html/index.ex b/lib/helper/converter/editor_to_html/index.ex index 16b042637..083b6b173 100644 --- a/lib/helper/converter/editor_to_html/index.ex +++ b/lib/helper/converter/editor_to_html/index.ex @@ -57,7 +57,8 @@ defmodule Helper.Converter.EditorToHTML do acc <> Frags.List.get_item(mode |> String.to_atom(), item) end) - ~s(
#{items_content}
) + anchor_id = Utils.uid(:html, data) + ~s(
#{items_content}
) end defp parse_block(%{"type" => "table", "data" => data}) do diff --git a/lib/helper/converter/editor_to_html/validator/editor_schema.ex b/lib/helper/converter/editor_to_html/validator/editor_schema.ex index 0a9f172e4..4a7a09b08 100644 --- a/lib/helper/converter/editor_to_html/validator/editor_schema.ex +++ b/lib/helper/converter/editor_to_html/validator/editor_schema.ex @@ -52,7 +52,11 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do def get("list") do [ - parent: %{"mode" => [enum: @valid_list_mode], "items" => [:list]}, + parent: %{ + "id" => [:string, required: false], + "mode" => [enum: @valid_list_mode], + "items" => [:list] + }, item: %{ "checked" => [:boolean], "hideLabel" => [:boolean], @@ -67,7 +71,11 @@ defmodule Helper.Converter.EditorToHTML.Validator.EditorSchema do def get("table") do [ - parent: %{"columnCount" => [:number, min: 2], "items" => [:list]}, + parent: %{ + "id" => [:string, required: false], + "columnCount" => [:number, min: 2], + "items" => [:list] + }, item: %{ "text" => [:string], "align" => [enum: @valid_table_align], diff --git a/test/helper/converter/editor_to_html_test/list_test.exs b/test/helper/converter/editor_to_html_test/list_test.exs index 7577a0c4d..ead7a5d90 100644 --- a/test/helper/converter/editor_to_html_test/list_test.exs +++ b/test/helper/converter/editor_to_html_test/list_test.exs @@ -11,13 +11,14 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do @class get_in(@root_class, ["list"]) describe "[list block unit]" do - defp set_items(mode, items) do + defp set_items(mode, items, id \\ "") do %{ "time" => 1_567_250_876_713, "blocks" => [ %{ "type" => "list", "data" => %{ + "id" => id, "mode" => mode, "items" => items } @@ -64,7 +65,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do assert Utils.str_occurence(converted, unorder_list_prefix_class) == 3 end - @tag :wip + @tag :wip2 test "basic order list parse should work" do editor_json = set_items("order_list", [ @@ -101,10 +102,38 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do {:ok, editor_string} = Jason.encode(editor_json) {:ok, converted} = Parser.to_html(editor_string) + assert Utils.str_occurence(converted, "id=") == 1 + order_list_prefix_class = @class["order_list_prefix"] assert Utils.str_occurence(converted, order_list_prefix_class) == 3 end + @tag :wip2 + test "edit exsit block will not change id value" do + editor_json = + set_items( + "order_list", + [ + %{ + "checked" => true, + "hideLabel" => false, + "indent" => 0, + "label" => "label", + "labelType" => "default", + "prefixIndex" => "1.", + "text" => + "一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。一个带着中文的很长的句子。" + } + ], + "exsit" + ) + + {:ok, editor_string} = Jason.encode(editor_json) + {:ok, converted} = Parser.to_html(editor_string) + + assert Utils.str_occurence(converted, "id=\"exsit\"") == 1 + end + @tag :wip test "basic checklist parse should work" do editor_json = From 50b3c2d6de6385700c9e8de06f99069f9084d8e5 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 15:05:47 +0800 Subject: [PATCH 3/7] feat(editor-export): add uid anchor_id for table --- lib/helper/converter/editor_to_html/index.ex | 4 ++- .../editor_to_html_test/quote_test.exs | 12 ------- .../editor_to_html_test/table_test.exs | 36 +++++++++++++++++-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/helper/converter/editor_to_html/index.ex b/lib/helper/converter/editor_to_html/index.ex index 083b6b173..0fe170ffe 100644 --- a/lib/helper/converter/editor_to_html/index.ex +++ b/lib/helper/converter/editor_to_html/index.ex @@ -75,7 +75,9 @@ defmodule Helper.Converter.EditorToHTML do table_wrapper_class = get_in(@root_class, ["table", "wrapper"]) - ~s(
+ anchor_id = Utils.uid(:html, data) + + ~s(
#{rows_content} diff --git a/test/helper/converter/editor_to_html_test/quote_test.exs b/test/helper/converter/editor_to_html_test/quote_test.exs index b68c0d79a..2e517c401 100644 --- a/test/helper/converter/editor_to_html_test/quote_test.exs +++ b/test/helper/converter/editor_to_html_test/quote_test.exs @@ -99,18 +99,6 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do assert Utils.str_occurence(converted, caption_text_class) == 0 end - # @editor_json %{ - # "time" => 1_567_250_876_713, - # "blocks" => [ - # %{ - # "type" => "paragraph", - # "data" => %{ - # "text" => [] - # } - # } - # ], - # "version" => "2.15.0" - # } @tag :wip test "invalid quote should have invalid hint" do editor_json = set_data("none_exsit", "long quote", "") diff --git a/test/helper/converter/editor_to_html_test/table_test.exs b/test/helper/converter/editor_to_html_test/table_test.exs index acf1885bb..965b248a1 100644 --- a/test/helper/converter/editor_to_html_test/table_test.exs +++ b/test/helper/converter/editor_to_html_test/table_test.exs @@ -11,13 +11,14 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do @class get_in(@root_class, ["table"]) describe "[table block unit]" do - defp set_items(column_count, items) do + defp set_items(column_count, items, id \\ "") do %{ "time" => 1_567_250_876_713, "blocks" => [ %{ "type" => "table", "data" => %{ + "id" => id, "columnCount" => column_count, "items" => items } @@ -27,7 +28,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do } end - @tag :wip + @tag :wip2 test "basic table parse should work" do editor_json = set_items(4, [ @@ -97,6 +98,8 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do {:ok, editor_string} = Jason.encode(editor_json) {:ok, converted} = Parser.to_html(editor_string) + assert Utils.str_occurence(converted, "id=") == 1 + th_header_class = @class["th_header"] td_stripe_class = @class["td_stripe"] @@ -104,6 +107,35 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do assert Utils.str_occurence(converted, td_stripe_class) == 3 end + @tag :wip2 + test "edit exsit block will not change id value" do + editor_json = + set_items( + 4, + [ + %{ + "align" => "left", + "isHeader" => true, + "isStripe" => false, + "text" => "title 0" + }, + %{ + "align" => "center", + "isHeader" => true, + "isStripe" => false, + "text" => "title 1", + "width" => "180px" + } + ], + "exist" + ) + + {:ok, editor_string} = Jason.encode(editor_json) + {:ok, converted} = Parser.to_html(editor_string) + + assert Utils.str_occurence(converted, ~s(id="exist")) == 1 + end + @tag :wip test "invalid table field parse should raise error message" do editor_json = set_items("aa", "bb") From 1f227bf05de37a5794ad92d68803e5058b70e9f6 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 15:10:12 +0800 Subject: [PATCH 4/7] feat(editor-export): add uid anchor_id for quote --- lib/helper/converter/editor_to_html/frags/list.ex | 1 - .../converter/editor_to_html/frags/quote.ex | 15 ++++++++++----- lib/helper/converter/html_sanitizer.ex | 2 +- .../converter/editor_to_html_test/quote_test.exs | 4 +++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/helper/converter/editor_to_html/frags/list.ex b/lib/helper/converter/editor_to_html/frags/list.ex index 953e0e3e7..645c1e597 100644 --- a/lib/helper/converter/editor_to_html/frags/list.ex +++ b/lib/helper/converter/editor_to_html/frags/list.ex @@ -6,7 +6,6 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do """ alias Helper.Converter.EditorToHTML.Class alias Helper.Types, as: T - alias Helper.Utils @class get_in(Class.article(), ["list"]) diff --git a/lib/helper/converter/editor_to_html/frags/quote.ex b/lib/helper/converter/editor_to_html/frags/quote.ex index ca126a589..f49c62a2e 100644 --- a/lib/helper/converter/editor_to_html/frags/quote.ex +++ b/lib/helper/converter/editor_to_html/frags/quote.ex @@ -6,29 +6,34 @@ defmodule Helper.Converter.EditorToHTML.Frags.Quote do """ import Helper.Validator.Guards, only: [g_none_empty_str: 1] - alias Helper.Types, as: T alias Helper.Converter.EditorToHTML.Class + alias Helper.Types, as: T + alias Helper.Utils @class get_in(Class.article(), ["quote"]) @spec get(T.editor_quote()) :: T.html() - def get(%{"mode" => "short", "text" => text}) do + def get(%{"mode" => "short", "text" => text} = data) do wrapper_class = @class["short_wrapper"] text_class = @class["text"] - ~s(
+ anchor_id = Utils.uid(:html, data) + + ~s(
#{text}
) end - def get(%{"mode" => "long", "text" => text, "caption" => caption}) + def get(%{"mode" => "long", "text" => text, "caption" => caption} = data) when g_none_empty_str(caption) do wrapper_class = @class["long_wrapper"] text_class = @class["text"] caption = frag(:caption, caption) - ~s(
+ anchor_id = Utils.uid(:html, data) + + ~s(
#{text}
#{caption}
) diff --git a/lib/helper/converter/html_sanitizer.ex b/lib/helper/converter/html_sanitizer.ex index 78fc1b14f..c01ff2987 100644 --- a/lib/helper/converter/html_sanitizer.ex +++ b/lib/helper/converter/html_sanitizer.ex @@ -46,7 +46,7 @@ defmodule Helper.Converter.HtmlSanitizer do Meta.allow_tag_with_these_attributes("td", ["class", "style"]) # blockquote - Meta.allow_tag_with_these_attributes("blockquote", ["class"]) + Meta.allow_tag_with_these_attributes("blockquote", ["id", "class"]) Meta.allow_tag_with_these_attributes("svg", [ "t", diff --git a/test/helper/converter/editor_to_html_test/quote_test.exs b/test/helper/converter/editor_to_html_test/quote_test.exs index 2e517c401..6fbe4ba18 100644 --- a/test/helper/converter/editor_to_html_test/quote_test.exs +++ b/test/helper/converter/editor_to_html_test/quote_test.exs @@ -41,12 +41,14 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do } end - @tag :wip + @tag :wip2 test "short quote parse should work" do editor_json = set_data("short", "short quote") {:ok, editor_string} = Jason.encode(editor_json) {:ok, converted} = Parser.to_html(editor_string) + assert Utils.str_occurence(converted, "id=") == 1 + short_wrapper_class = @class["short_wrapper"] caption_class = @class["caption"] From 343eb8b8218a732b4f2d5c1e4ceba1bf28a3e6df Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 15:10:44 +0800 Subject: [PATCH 5/7] feat(editor-export): clean up wip2 tags --- test/helper/converter/editor_to_html_test/header_test.exs | 8 ++++---- test/helper/converter/editor_to_html_test/list_test.exs | 4 ++-- test/helper/converter/editor_to_html_test/quote_test.exs | 2 +- test/helper/converter/editor_to_html_test/table_test.exs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/helper/converter/editor_to_html_test/header_test.exs b/test/helper/converter/editor_to_html_test/header_test.exs index 82d16d501..92aaa045a 100644 --- a/test/helper/converter/editor_to_html_test/header_test.exs +++ b/test/helper/converter/editor_to_html_test/header_test.exs @@ -69,7 +69,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do ~s(
#{h1_frag}#{h2_frag}#{h3_frag}
) end - @tag :wip2 + @tag :wip test "full header parse should work" do editor_json = set_data(%{ @@ -89,7 +89,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do assert Utils.str_occurence(converted, @footer_class) == 1 end - @tag :wip2 + @tag :wip test "edit exsit block will not change id value" do editor_json = set_data(%{ @@ -106,7 +106,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do assert Utils.str_occurence(converted, ~s(id="exist")) == 1 end - @tag :wip2 + @tag :wip test "optional field should valid properly" do editor_json = set_data(%{ @@ -135,7 +135,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do assert Utils.str_occurence(converted, @footer_class) == 1 end - @tag :wip2 + @tag :wip test "wrong header format data should have invalid hint" do editor_json = set_data(%{ diff --git a/test/helper/converter/editor_to_html_test/list_test.exs b/test/helper/converter/editor_to_html_test/list_test.exs index ead7a5d90..765b4fbca 100644 --- a/test/helper/converter/editor_to_html_test/list_test.exs +++ b/test/helper/converter/editor_to_html_test/list_test.exs @@ -65,7 +65,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do assert Utils.str_occurence(converted, unorder_list_prefix_class) == 3 end - @tag :wip2 + @tag :wip test "basic order list parse should work" do editor_json = set_items("order_list", [ @@ -108,7 +108,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.List do assert Utils.str_occurence(converted, order_list_prefix_class) == 3 end - @tag :wip2 + @tag :wip test "edit exsit block will not change id value" do editor_json = set_items( diff --git a/test/helper/converter/editor_to_html_test/quote_test.exs b/test/helper/converter/editor_to_html_test/quote_test.exs index 6fbe4ba18..03e87203c 100644 --- a/test/helper/converter/editor_to_html_test/quote_test.exs +++ b/test/helper/converter/editor_to_html_test/quote_test.exs @@ -41,7 +41,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Quote do } end - @tag :wip2 + @tag :wip test "short quote parse should work" do editor_json = set_data("short", "short quote") {:ok, editor_string} = Jason.encode(editor_json) diff --git a/test/helper/converter/editor_to_html_test/table_test.exs b/test/helper/converter/editor_to_html_test/table_test.exs index 965b248a1..c6139a352 100644 --- a/test/helper/converter/editor_to_html_test/table_test.exs +++ b/test/helper/converter/editor_to_html_test/table_test.exs @@ -28,7 +28,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do } end - @tag :wip2 + @tag :wip test "basic table parse should work" do editor_json = set_items(4, [ @@ -107,7 +107,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Table do assert Utils.str_occurence(converted, td_stripe_class) == 3 end - @tag :wip2 + @tag :wip test "edit exsit block will not change id value" do editor_json = set_items( From f4f725f31551d5edf39fb3c8d4e62c9a0719592f Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 15:24:22 +0800 Subject: [PATCH 6/7] feat(editor-export): add tests for uid generator --- test/helper/utils_test.exs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/helper/utils_test.exs b/test/helper/utils_test.exs index 228690048..8851b057d 100644 --- a/test/helper/utils_test.exs +++ b/test/helper/utils_test.exs @@ -162,4 +162,20 @@ defmodule GroupherServer.Test.Helper.UtilsTest do assert false == Utils.less_than("lang", 4, :no_equal) end end + + describe "[uid generator]" do + test "should gen uniq id with lengh of 5" do + uid_str = Utils.uid(:html, "what_ever") + assert String.length(uid_str) == 5 + end + + test "should never contains number" do + uid_str = Utils.uid(:html, %{"id" => ""}) + assert String.match?(uid_str, ~r/[0-9]/) == false + end + + test "exsit id will stay the same" do + assert "exsit_id" == Utils.uid(:html, %{"id" => "exsit_id"}) + end + end end From 838421a9e5f93e39851dc2dff55ea86557f132bf Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Feb 2021 15:36:32 +0800 Subject: [PATCH 7/7] test(editor-export): fix header test --- .../editor_to_html_test/header_test.exs | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/test/helper/converter/editor_to_html_test/header_test.exs b/test/helper/converter/editor_to_html_test/header_test.exs index 92aaa045a..b2907b968 100644 --- a/test/helper/converter/editor_to_html_test/header_test.exs +++ b/test/helper/converter/editor_to_html_test/header_test.exs @@ -4,7 +4,7 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do use GroupherServerWeb.ConnCase, async: true alias Helper.Converter.EditorToHTML, as: Parser - alias Helper.Converter.EditorToHTML.{Class, Frags} + alias Helper.Converter.EditorToHTML.Class alias Helper.Utils @root_class Class.article() @@ -33,40 +33,35 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHTML.Header do %{ "type" => "header", "data" => %{ - "text" => "header content", + "text" => "header1 content", "level" => 1 } }, %{ "type" => "header", "data" => %{ - "text" => "header content", + "text" => "header2 content", "level" => 2 } }, %{ "type" => "header", "data" => %{ - "text" => "header content", + "text" => "header3 content", "level" => 3 } } ], "version" => "2.15.0" } - @tag :wip + @tag :wip2 test "header parse should work" do {:ok, editor_string} = Jason.encode(@editor_json) {:ok, converted} = Parser.to_html(editor_string) - h1_frag = Frags.Header.get(%{"text" => "header content", "level" => 1}) - h2_frag = Frags.Header.get(%{"text" => "header content", "level" => 2}) - h3_frag = Frags.Header.get(%{"text" => "header content", "level" => 3}) - - viewer_class = @root_class["viewer"] - - assert converted == - ~s(
#{h1_frag}#{h2_frag}#{h3_frag}
) + assert Utils.str_occurence(converted, "header1 content") == 1 + assert Utils.str_occurence(converted, "header2 content") == 1 + assert Utils.str_occurence(converted, "header3 content") == 1 end @tag :wip