Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

refactor(new-editor): editor.js convert & parse#264

Merged
mydearxym merged 23 commits intodevfromeditor-thing
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
23 commits
Select commitHold shift + click to select a range
76b0eee
chore(clean-up): remove old wip tags
mydearxymFeb 7, 2021
72f3813
test(editor): paragraph and header basic test
mydearxymFeb 7, 2021
f527057
test(editor): re-org codebase by parse header part
mydearxymFeb 8, 2021
995e602
test(editor): parse workflow adjust
mydearxymFeb 9, 2021
80b8831
test(editor-parse): re-org dir structure based on blocks
mydearxymFeb 10, 2021
7392f79
test(editor-parse): clean up imports
mydearxymFeb 10, 2021
221c050
test(editor): add basic paragraph block test
mydearxymFeb 10, 2021
e074944
test(editor): using macro && clean up
mydearxymFeb 10, 2021
fd8831c
refactor(editor): re-org the editor json validte workflow
mydearxymFeb 15, 2021
b255880
refactor(editor): return map fmt when error raised
mydearxymFeb 15, 2021
ba9b230
fix(editor): utils
mydearxymFeb 15, 2021
efa82d5
fix(editor): error message alert
mydearxymFeb 15, 2021
dc5f0cf
fix(editor): add :lang to tursted_atoms
mydearxymFeb 16, 2021
0ea6c34
refactor(editor): use string-fmt map instead of atom-fmt
mydearxymFeb 16, 2021
50d6108
fix(editor): re-org validate workflow by using config
mydearxymFeb 16, 2021
39ff354
fix(editor): add list to validator workflow as general
mydearxymFeb 16, 2021
2ece8ea
refactor(editor): use common schema to validate editor-fmt json
mydearxymFeb 17, 2021
e244d89
refactor(editor): use macros to reduce similar code
mydearxymFeb 17, 2021
89c2e2a
refactor(editor): adjust guard name in schema matchers
mydearxymFeb 17, 2021
23085c8
refactor(editor): re-org / rename the schema validator
mydearxymFeb 18, 2021
bad9428
refactor(editor): adjust parent schema cast logic
mydearxymFeb 18, 2021
e8d940e
refactor(editor): validate_with logic re-org
mydearxymFeb 18, 2021
0d43e6a
refactor(editor): adjust xss test && clean up
mydearxymFeb 18, 2021
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: 2 additions & 0 deletions.iex.exs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
# see: https://github.com/blackode/elixir-tips#loading-project-module-aliases-iexexs
alias Helper.Converter.EditorToHTML
3 changes: 1 addition & 2 deletionsMakefile
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -171,9 +171,8 @@ test.watch.wip:
# test.watch not work now, see: https://github.com/lpil/mix-test.watch/issues/116
# mix test.watch --only wip --stale
test.watch.wip2:
mix test --listen-on-stdin --stale --trace --only wip2
mix test --listen-on-stdin --stale --only wip2
# mix test.watch --only wip2
mix test.watch --only wip2
test.watch.bug:
mix test.watch --only bug
test.report:
Expand Down
2 changes: 1 addition & 1 deletionlib/helper/converter/assets/delimiter_icons.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
defmodule Helper.Converter.EditorToHtml.Assets.DelimiterIcons do
defmodule Helper.Converter.EditorToHTML.Assets.DelimiterIcons do
@moduledoc """
svg icons for delimiter block
NOTE: those svg should be sync with frontend svg
Expand Down
80 changes: 80 additions & 0 deletionslib/helper/converter/editor_to_html/header.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
defmodule Helper.Converter.EditorToHTML.Header do
@moduledoc """
parse editor.js's header block

see https://editorjs.io/
"""

# @behaviour Helper.Converter.EditorToHTML.Parser

defmacro __using__(_opts) do
quote do
alias Helper.Metric

@clazz Metric.Article.class_names(:html)

defp parse_block(%{
"type" => "header",
"data" =>
%{
"text" => text,
"level" => level,
"eyebrowTitle" => eyebrow_title,
"footerTitle" => footer_title
} = data
}) do
"""
<div class="#{@clazz.header.wrapper}">
<div class="#{@clazz.header.eyebrow_title}">#{eyebrow_title}</div>
<h#{level}>#{text}</h#{level}>
<div class="#{@clazz.header.footer_title}">#{footer_title}</div>
</div>
"""
end

defp parse_block(%{
"type" => "header",
"data" =>
%{
"text" => text,
"level" => level,
"eyebrowTitle" => eyebrow_title
} = data
}) do
"""
<div class="#{@clazz.header.wrapper}">
<div class="#{@clazz.header.eyebrow_title}">#{eyebrow_title}</div>
<h#{level}>#{text}</h#{level}>
</div>
"""
end

defp parse_block(%{
"type" => "header",
"data" =>
%{
"text" => text,
"level" => level,
"footerTitle" => footer_title
} = data
}) do
"""
<div class="#{@clazz.header.wrapper}">
<h#{level}>#{text}</h#{level}>
<div class="#{@clazz.header.footer_title}">#{footer_title}</div>
</div>
"""
end

defp parse_block(%{
"type" => "header",
"data" => %{
"text" => text,
"level" => level
}
}) do
"<h#{level}>#{text}</h#{level}>"
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,58 @@
defmodule Helper.Converter.EditorToHtml do
# defmodule Helper.Converter.EditorToHTML.Parser do
# @moduledoc false

# # TODO: map should be editor_block
# @callback parse_block(editor_json :: Map.t()) :: String.t()
# end

defmodule Helper.Converter.EditorToHTML do
@moduledoc """
parse editor.js's json data to raw html and sanitize it

see https://editorjs.io/
"""
alias Helper.Converter.HtmlSanitizer
alias Helper.Converter.EditorToHtml.Assets
alias Helper.Utils

alias Assets.{DelimiterIcons}
use Helper.Converter.EditorToHTML.Header
use Helper.Converter.EditorToHTML.Paragraph
use Helper.Converter.EditorToHTML.List

alias Helper.Converter.EditorToHTML.Validator
alias Helper.Converter.{EditorToHTML, HtmlSanitizer}
alias Helper.{Metric, Utils}

alias EditorToHTML.Assets.{DelimiterIcons}

@html_class_prefix "cps-viewer"
@clazz Metric.Article.class_names(:html)

@spec to_html(binary | maybe_improper_list) :: false | {:ok, <<_::64, _::_*8>>}
def to_html(string) when is_binary(string) do
with {:ok, parsed} = string_to_json(string),
true<-valid_editor_data?(parsed) do
{:ok, _}<-Validator.is_valid(parsed) do
content =
Enum.reduce(parsed["blocks"], "", fn block, acc ->
clean_html = block |> parse_block |> HtmlSanitizer.sanitize()
acc <> clean_html
end)

{:ok, "<div class=\"#{@html_class_prefix}\">#{content}<div>"}
{:ok, "<div class=\"#{@clazz.viewer}\">#{content}<div>"}
end
end

@doc "used for markdown ast to editor"
def to_html(editor_blocks) when is_list(editor_blocks) do
content =
Enum.reduce(editor_blocks, "", fn block, acc ->
clean_html = block |> Utils.keys_to_strings() |> parse_block |> HtmlSanitizer.sanitize()
acc <> clean_html
end)

{:ok, "<div class=\"#{@html_class_prefix}\">#{content}<div>"}
end

# IO.inspect(data, label: "parse header")
defp parse_block(%{"type" => "header", "data" => data}) do
text = get_in(data, ["text"])
level = get_in(data, ["level"])

"<h#{level} class=\"#{@html_class_prefix}-header\">#{text}</h#{level}>"
{:ok, "<div class=\"#{@clazz.viewer}\">#{content}<div>"}
end

# IO.inspect(data, label: "parse paragraph")
defp parse_block(%{"type" => "paragraph", "data" => data}) do
text = get_in(data, ["text"])

"<p class=\"#{@html_class_prefix}-paragraph\">#{text}</p>"
end

# IO.inspect(data, label: "parse image")
defp parse_block(%{"type" => "image", "data" => data}) do
url = get_in(data, ["file", "url"])

"<div class=\"#{@html_class_prefix}-image\"><img src=\"#{url}\"></div>"
"<div class=\"#{@clazz.viewer}-image\"><img src=\"#{url}\"></div>"
# |> IO.inspect(label: "iamge ret")
end

Expand All@@ -77,7 +74,6 @@ defmodule Helper.Converter.EditorToHtml do
"<ol>#{content}</ol>"
end

# IO.inspect(items, label: "checklist items")
# TODO: add item class
defp parse_block(%{"type" => "checklist", "data" => %{"items" => items}}) do
content =
Expand All@@ -94,31 +90,31 @@ defmodule Helper.Converter.EditorToHtml do
end
end)

"<div class=\"#{@html_class_prefix}-checklist\">#{content}</div>"
"<div class=\"#{@clazz.viewer}-checklist\">#{content}</div>"
# |> IO.inspect(label: "jjj")
end

defp parse_block(%{"type" => "delimiter", "data" => %{"type" => type}}) do
svg_icon = DelimiterIcons.svg(type)

# TODO: left-wing, righ-wing staff
{:skip_sanitize, "<div class=\"#{@html_class_prefix}-delimiter\">#{svg_icon}</div>"}
{:skip_sanitize, "<div class=\"#{@clazz.viewer}-delimiter\">#{svg_icon}</div>"}
end

# IO.inspect(data, label: "parse linkTool")
# TODO: parse the link-card info
defp parse_block(%{"type" => "linkTool", "data" => data}) do
link = get_in(data, ["link"])

"<div class=\"#{@html_class_prefix}-linker\"><a href=\"#{link}\" target=\"_blank\">#{link}</a></div>"
"<div class=\"#{@clazz.viewer}-linker\"><a href=\"#{link}\" target=\"_blank\">#{link}</a></div>"
# |> IO.inspect(label: "linkTool ret")
end

# IO.inspect(data, label: "parse quote")
defp parse_block(%{"type" => "quote", "data" => data}) do
text = get_in(data, ["text"])

"<div class=\"#{@html_class_prefix}-quote\">#{text}</div>"
"<div class=\"#{@clazz.viewer}-quote\">#{text}</div>"
# |> IO.inspect(label: "quote ret")
end

Expand All@@ -132,18 +128,8 @@ defmodule Helper.Converter.EditorToHtml do
end

defp parse_block(_block) do
# IO.puts("[unknow block]")
"[unknow block]"
"<div class=\"#{@clazz.unknow_block}\">[unknow block]</div>"
end

def string_to_json(string), do: Jason.decode(string)

defp valid_editor_data?(map) when is_map(map) do
Map.has_key?(map, "time") and
Map.has_key?(map, "version") and
Map.has_key?(map, "blocks") and
is_list(map["blocks"]) and
is_binary(map["version"]) and
is_integer(map["time"])
end
end
Loading

[8]ページ先頭

©2009-2025 Movatter.jp