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

feat(editor): list for read-only article #283

Merged
merged 10 commits into from
Feb 22, 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
2 changes: 1 addition & 1 deletion cover/excoveralls.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/groupher_server/cms/delegates/community_sync.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule GroupherServer.CMS.Delegate.CommunitySync do
alias GroupherServer.CMS

alias Helper.ORM
alias Helper.SpecType, as: T
alias Helper.Types, as: T

alias CMS.{
Community,
Expand Down
48 changes: 48 additions & 0 deletions lib/helper/converter/editor_to_html/class.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule Helper.Converter.EditorToHTML.Class do
@moduledoc """
html article class names parsed from editor.js's json data

currently use https://editorjs.io/ as rich-text editor
# NOTE: DONOT CHANGE ONCE SET, OTHERWISE IT WILL CAUSE INCOMPATIBILITY ISSUE
"""

@doc """
get all the class names of the parsed editor.js's html parts
"""
def article() do
%{
# root wrapper
"viewer" => "article-viewer-wrapper",
"unknow_block" => "unknow-block",
"invalid_block" => "invalid-block",
# header
"header" => %{
"wrapper" => "header-wrapper",
"eyebrow_title" => "eyebrow-title",
"footer_title" => "footer-title"
},
# list
"list" => %{
"wrapper" => "list-wrapper",
"label" => "list-label",
"label__default" => "list-label__default",
"label__red" => "list-label__red",
"label__green" => "list-label__green",
"label__warn" => "list-label__warn",
"unorder_list_prefix" => "list__item-unorder-prefix",
"order_list_prefix" => "list__item-order-prefix",
"list_item" => "list-item",
"checklist_item" => "list-checklist__item",
"checklist_checkbox" => "checklist__item-checkbox",
"checklist_checkbox_checked" => "checklist__item-check-sign-checked",
"checklist_checksign" => "checklist__item-check-sign",
"text" => "list-item-text",
"checklist_text" => "list-checklist__item-text",
"indent_0" => "",
"indent_1" => "list-indent-1",
"indent_2" => "list-indent-2",
"indent_3" => "list-indent-3"
}
}
end
end
55 changes: 55 additions & 0 deletions lib/helper/converter/editor_to_html/frags/header.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
defmodule Helper.Converter.EditorToHTML.Frags.Header do
@moduledoc """
parse editor.js's block fragments, use for test too

see https://editorjs.io/
"""
alias Helper.Types, as: T

alias Helper.Converter.EditorToHTML.Class

@class get_in(Class.article(), ["header"])

@spec get(T.editor_header()) :: T.html()
def get(%{"eyebrowTitle" => eyebrow_title, "footerTitle" => footer_title} = data) do
%{"text" => text, "level" => level} = data

wrapper_class = @class["wrapper"]
eyebrow_class = @class["eyebrow_title"]
footer_class = @class["footer_title"]

~s(<div class="#{wrapper_class}">
<div class="#{eyebrow_class}">#{eyebrow_title}</div>
<h#{level}>#{text}</h#{level}>
<div class="#{footer_class}">#{footer_title}</div>
</div>)
end

def get(%{"eyebrowTitle" => eyebrow_title} = data) do
%{"text" => text, "level" => level} = data

wrapper_class = @class["wrapper"]
eyebrow_class = @class["eyebrow_title"]

~s(<div class="#{wrapper_class}">
<div class="#{eyebrow_class}">#{eyebrow_title}</div>
<h#{level}>#{text}</h#{level}>
</div>)
end

def get(%{"footerTitle" => footer_title} = data) do
%{"text" => text, "level" => level} = data

wrapper_class = @class["wrapper"]
footer_class = @class["footer_title"]

~s(<div class="#{wrapper_class}">
<h#{level}>#{text}</h#{level}>
<div class="#{footer_class}">#{footer_title}</div>
</div>)
end

def get(%{"text" => text, "level" => level}) do
"<h#{level}>#{text}</h#{level}>"
end
end
144 changes: 144 additions & 0 deletions lib/helper/converter/editor_to_html/frags/list.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
defmodule Helper.Converter.EditorToHTML.Frags.List do
@moduledoc """
parse editor.js's block fragments, use for test too

see https://editorjs.io/
"""
alias Helper.Converter.EditorToHTML.Class
alias Helper.Types, as: T

@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
prefix_frag = frag(:unorder_list_prefix)
label_frag = if hide_label, do: "", else: frag(:label, label_type, indent, label)
text_frag = frag(:text, text)

item_class = @class["list_item"]
indent_class = @class["indent_#{indent}"]

~s(<div class="#{item_class} #{indent_class}">
#{prefix_frag}
#{label_frag}
#{text_frag}
</div>)
end

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)

item_class = @class["list_item"]
indent_class = @class["indent_#{indent}"]

~s(<div class="#{item_class} #{indent_class}">
#{prefix_frag}
#{label_frag}
#{text_frag}
</div>)
end

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)
text_frag = frag(:checkbox, :text, text)

item_class = @class["checklist_item"]
indent_class = @class["indent_#{indent}"]

~s(<div class="#{item_class} #{indent_class}">
#{checkbox_frag}
#{label_frag}
#{text_frag}
</div>)
end

@spec frag(:label, T.editor_list_label_type(), T.editor_list_indent(), String.t()) :: T.html()
def frag(:label, label_type, indent, label) do
label_class = @class["label"]
label_type_class = @class["label__#{label_type}"]

~s(<div class="#{label_class} #{label_type_class}" data-index="#{indent}">
#{label}
</div>)
end

@spec frag(:unorder_list_prefix) :: T.html()
def frag(:unorder_list_prefix) do
unorder_list_prefix_class = @class["unorder_list_prefix"]

~s(<div class="#{unorder_list_prefix_class}"></div>)
end

@spec frag(:order_list_prefix, String.t()) :: T.html()
def frag(:order_list_prefix, prefix_index) when is_binary(prefix_index) do
order_list_prefix_class = @class["order_list_prefix"]

~s(<div class="#{order_list_prefix_class}">#{prefix_index}</div>)
end

@spec frag(:checkbox, Boolean.t()) :: T.html()
def frag(:checkbox, checked) when is_boolean(checked) do
checked_svg = svg(:checked)

checkbox_class = @class["checklist_checkbox"]
checkbox_checked_class = if checked, do: @class["checklist_checkbox_checked"], else: ""
checkbox_checksign_class = @class["checklist_checksign"]

~s(<div class="#{checkbox_class} #{checkbox_checked_class}">
<div class="#{checkbox_checksign_class}">
#{checked_svg}
</div>
</div>)
end

@spec frag(:text, String.t()) :: T.html()
def frag(:text, text) when is_binary(text) do
text_class = @class["text"]

~s(<div class="#{text_class}">
#{text}
</div>)
end

@spec frag(:checkbox, :text, String.t()) :: T.html()
def frag(:checkbox, :text, text) do
text_class = @class["checklist_text"]

~s(<div class="#{text_class}">
#{text}
</div>)
end

defp svg(type) do
# workarround for https://github.com/rrrene/html_sanitize_ex/issues/48
svg_frag(type) |> String.replace(" viewBox=\"", " viewbox=\"")
end

defp svg_frag(:checked) do
~s(<svg t="1592049095081" width="20px" height="20px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9783"><path d="M853.333333 256L384 725.333333l-213.333333-213.333333" p-id="9784"></path></svg>)
end
end
18 changes: 18 additions & 0 deletions lib/helper/converter/editor_to_html/frontend_test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">

<title>The HTML5 Herald</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">

<link rel="stylesheet" href="./styles.css?v=1.0">
<div id="article"></div>
</head>

<body>
<script src="./script.js"></script>
</body>
</html>
6 changes: 6 additions & 0 deletions lib/helper/converter/editor_to_html/frontend_test/script.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading