Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

feat(editor-export): uniq-id for each editor blocks #293

Merged
merged 7 commits into from
Feb 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions lib/helper/converter/editor_to_html/frags/header.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -19,7 +20,9 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do
eyebrow_class = @class["eyebrow_title"]
footer_class = @class["footer_title"]

~s(<div class="#{wrapper_class}">
anchor_id = Utils.uid(:html, data)

~s(<div id="#{anchor_id}" class="#{wrapper_class}">
<div class="#{eyebrow_class}">#{eyebrow_title}</div>
<h#{level} class="#{header_class}">#{text}</h#{level}>
<div class="#{footer_class}">#{footer_title}</div>
Expand All @@ -33,7 +36,9 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do
header_class = @class["header"]
eyebrow_class = @class["eyebrow_title"]

~s(<div class="#{wrapper_class}">
anchor_id = Utils.uid(:html, data)

~s(<div id="#{anchor_id}" class="#{wrapper_class}">
<div class="#{eyebrow_class}">#{eyebrow_title}</div>
<h#{level} class="#{header_class}">#{text}</h#{level}>
</div>)
Expand All @@ -46,13 +51,16 @@ defmodule Helper.Converter.EditorToHTML.Frags.Header do
header_class = @class["header"]
footer_class = @class["footer_title"]

~s(<div class="#{wrapper_class}">
anchor_id = Utils.uid(:html, data)
~s(<div id="#{anchor_id}" class="#{wrapper_class}">
<h#{level} class="#{header_class}">#{text}</h#{level}>
<div class="#{footer_class}">#{footer_title}</div>
</div>)
end

def get(%{"text" => text, "level" => level}) do
"<h#{level}>#{text}</h#{level}>"
def get(%{"text" => text, "level" => level} = data) do
anchor_id = Utils.uid(:html, data)

~s(<h#{level} id="#{anchor_id}">#{text}</h#{level}>)
end
end
55 changes: 32 additions & 23 deletions lib/helper/converter/editor_to_html/frags/list.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do
@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)
Expand All @@ -31,14 +34,17 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do
</div>)
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)
Expand All @@ -53,14 +59,17 @@ defmodule Helper.Converter.EditorToHTML.Frags.List do
</div>)
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)
Expand Down
15 changes: 10 additions & 5 deletions lib/helper/converter/editor_to_html/frags/quote.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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(<blockquote class="#{wrapper_class}">
anchor_id = Utils.uid(:html, data)

~s(<blockquote id="#{anchor_id}" class="#{wrapper_class}">
<div class="#{text_class}">#{text}</div>
</blockquote>)
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(<blockquote class="#{wrapper_class}">
anchor_id = Utils.uid(:html, data)

~s(<blockquote id="#{anchor_id}" class="#{wrapper_class}">
<div class="#{text_class}">#{text}</div>
#{caption}
</blockquote>)
Expand Down
7 changes: 5 additions & 2 deletions lib/helper/converter/editor_to_html/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ defmodule Helper.Converter.EditorToHTML do
acc <> Frags.List.get_item(mode |> String.to_atom(), item)
end)

~s(<div class="#{list_wrapper_class}">#{items_content}</div>)
anchor_id = Utils.uid(:html, data)
~s(<div id="#{anchor_id}" class="#{list_wrapper_class}">#{items_content}</div>)
end

defp parse_block(%{"type" => "table", "data" => data}) do
Expand All @@ -74,7 +75,9 @@ defmodule Helper.Converter.EditorToHTML do

table_wrapper_class = get_in(@root_class, ["table", "wrapper"])

~s(<div class="#{table_wrapper_class}">
anchor_id = Utils.uid(:html, data)

~s(<div id="#{anchor_id}" class="#{table_wrapper_class}">
<table>
<tbody>
#{rows_content}
Expand Down
24 changes: 19 additions & 5 deletions lib/helper/converter/editor_to_html/validator/editor_schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand All @@ -26,27 +26,37 @@ 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],
"footerTitle" => [:string, required: false]
}
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]},
parent: %{
"id" => [:string, required: false],
"mode" => [enum: @valid_list_mode],
"items" => [:list]
},
item: %{
"checked" => [:boolean],
"hideLabel" => [:boolean],
Expand All @@ -61,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],
Expand Down
4 changes: 2 additions & 2 deletions lib/helper/converter/html_sanitizer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand All @@ -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",
Expand Down
11 changes: 11 additions & 0 deletions lib/helper/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading