From 5085cf8b7ff67b42d788e3c0647dcfd7a0685b3d Mon Sep 17 00:00:00 2001 From: Zaydek Michels-Gualtieri Date: Sun, 2 Aug 2020 01:08:13 +0900 Subject: [PATCH] Reworked resolvers implementation --- ...{DispatchContext.js => ContextDispatch.js} | 0 ...atchContext.js => ContextPrefsDispatch.js} | 0 src/EditorApp/EditorApp.js | 12 +- .../MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js | 4 +- .../MemoFixedTopPreferences.js | 4 +- src/EditorApp/resolvers.js | 105 ------------------ src/EditorApp/usePreferences/index.js | 1 + src/EditorApp/usePreferences/resolvers.js | 86 ++++++++++++++ .../usePreferences/resolvers.test.js | 1 + .../{ => usePreferences}/usePreferences.js | 6 +- 10 files changed, 101 insertions(+), 118 deletions(-) rename src/EditorApp/{DispatchContext.js => ContextDispatch.js} (100%) rename src/EditorApp/{PrefsDispatchContext.js => ContextPrefsDispatch.js} (100%) delete mode 100644 src/EditorApp/resolvers.js create mode 100644 src/EditorApp/usePreferences/index.js create mode 100644 src/EditorApp/usePreferences/resolvers.js create mode 100644 src/EditorApp/usePreferences/resolvers.test.js rename src/EditorApp/{ => usePreferences}/usePreferences.js (95%) diff --git a/src/EditorApp/DispatchContext.js b/src/EditorApp/ContextDispatch.js similarity index 100% rename from src/EditorApp/DispatchContext.js rename to src/EditorApp/ContextDispatch.js diff --git a/src/EditorApp/PrefsDispatchContext.js b/src/EditorApp/ContextPrefsDispatch.js similarity index 100% rename from src/EditorApp/PrefsDispatchContext.js rename to src/EditorApp/ContextPrefsDispatch.js diff --git a/src/EditorApp/EditorApp.js b/src/EditorApp/EditorApp.js index ad0991e..f879e30 100644 --- a/src/EditorApp/EditorApp.js +++ b/src/EditorApp/EditorApp.js @@ -1,9 +1,9 @@ +import ContextDispatch from "./ContextDispatch" +import ContextPrefsDispatch from "./ContextPrefsDispatch" import ctrlOrCmd from "lib/Client/ctrlOrCmd" -import DispatchContext from "./DispatchContext" import keyCodeFor from "lib/Client/keyCodeFor" import MemoFixedBottomWYSIWYGMenu from "./MemoFixedBottomWYSIWYGMenu" import MemoFixedTopPreferences from "./MemoFixedTopPreferences" -import PrefsDispatchContext from "./PrefsDispatchContext" import React from "react" import useKeydown from "lib/x/handlers/useKeydown" import usePreferences from "./usePreferences" @@ -83,8 +83,8 @@ const App = () => { }) return ( - - + +
@@ -134,8 +134,8 @@ const App = () => {
-
-
+ + ) } diff --git a/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js b/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js index 6714aba..933223d 100644 --- a/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js +++ b/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js @@ -1,10 +1,10 @@ -import DispatchContext from "../DispatchContext" +import ContextDispatch from "../ContextDispatch" import React from "react" import userAgent from "lib/Client/userAgent" import { TopTooltip as Tooltip } from "../Tooltips" const WYSIWYGMenu = ({ rangeTypes }) => { - const dispatch = React.useContext(DispatchContext) + const dispatch = React.useContext(ContextDispatch) const [tooltip, setTooltip] = React.useState("") diff --git a/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js b/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js index 346b26d..0028264 100644 --- a/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js +++ b/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js @@ -1,5 +1,5 @@ +import ContextPrefsDispatch from "../ContextPrefsDispatch" import MemoHighlight from "lib/PrismJS/MemoHighlight" -import PrefsDispatchContext from "../PrefsDispatchContext" import React from "react" import Releases from "./Releases" import tabSize from "lib/x/tabSize" @@ -11,7 +11,7 @@ import { } from "../Tooltips" const MemoFixedTopPreferences = React.memo(({ prefs }) => { - const dispatch = React.useContext(PrefsDispatchContext) + const dispatch = React.useContext(ContextPrefsDispatch) const [tooltip, setTooltip] = React.useState("") diff --git a/src/EditorApp/resolvers.js b/src/EditorApp/resolvers.js deleted file mode 100644 index e4dd745..0000000 --- a/src/EditorApp/resolvers.js +++ /dev/null @@ -1,105 +0,0 @@ -import escape from "lodash/escape" -import toArray from "lib/x/toArray" -import toTree from "Editor/components/toReactTree/toTree" - -// Mocks the browser API; reads text content from tree- -// shaped children. -function treeTextContent(children) { - let str = "" - for (const each of toArray(children)) { - if (typeof each === "string") { - str += each - continue - } - str += treeTextContent(each.props.children) - } - return str -} - -// TODO: Add support for alternate syntax? -const gfm = { - em: el => `_${resolveTreeChildren(el.props.children, gfm)}_`, - strong: el => `**${resolveTreeChildren(el.props.children, gfm)}**`, - code: el => `\`${treeTextContent(el.props.children)}\``, - strike: el => `~~${resolveTreeChildren(el.props.children, gfm)}~~`, - - // !el.props.href ? `[${resolveTreeChildren(el.props.children, gfm)}](${el.props.href})` : el.props.children, - a: el => `[${resolveTreeChildren(el.props.children, gfm)}](${el.props.href || "TODO"})`, - - "h1": el => `# ${resolveChildren(el.props.children, gfm)}`, - "h2": el => `## ${resolveChildren(el.props.children, gfm)}`, - "h3": el => `### ${resolveChildren(el.props.children, gfm)}`, - "h4": el => `#### ${resolveChildren(el.props.children, gfm)}`, - "h5": el => `##### ${resolveChildren(el.props.children, gfm)}`, - "h6": el => `###### ${resolveChildren(el.props.children, gfm)}`, - "p": el => resolveChildren(el.props.children, gfm), -} - -// TODO: Add support for options; show ID, show wrapped URL, -// etc. -const html = { - em: el => `${resolveTreeChildren(el.props.children, html)}`, - strong: el => `${resolveTreeChildren(el.props.children, html)}`, - code: el => `${resolveTreeChildren(el.props.children, html)}`, - strike: el => `${resolveTreeChildren(el.props.children, html)}`, - - // target="_blank" rel="noopener noreferrer" - a: el => `${resolveTreeChildren(el.props.children, html)}`, - - "h1": el => `

\n\t${resolveChildren(el.props.children, html) || "
"}\n

`, - "h2": el => `

\n\t${resolveChildren(el.props.children, html) || "
"}\n

`, - "h3": el => `

\n\t${resolveChildren(el.props.children, html) || "
"}\n

`, - "h4": el => `

\n\t${resolveChildren(el.props.children, html) || "
"}\n

`, - "h5": el => `
\n\t${resolveChildren(el.props.children, html) || "
"}\n
`, - "h6": el => `
\n\t${resolveChildren(el.props.children, html) || "
"}\n
`, - "p": el => `

\n\t${resolveChildren(el.props.children, html) || "
"}\n

`, -} - -// if (children === null || typeof children === "string") { -// if (resolver === cmapText) { -// return children || "" -// } -// // Return an escaped string or a break: -// return (resolver !== cmapReact_js ? escape(children) : reactEscape(children)) || -// (resolver !== cmapReact_js ? "
" : "
") -// } - -// Resolves tree-shaped children to a resolver-type. -function resolveTreeChildren(children, resolver) { - let str = "" - for (const each of toArray(children)) { - if (typeof each === "string") { - str += resolver !== html ? each : escape(each) - continue - } - str += resolver[each.type](each) - } - return str -} - -// Resolves children to a resolver-type. -function resolveChildren(children, resolver) { - return resolveTreeChildren(toTree(children), resolver) -} - -// Resolves elements to a resolver-type. -function resolveElements(elements, resolver) { - let str = "" - for (const each of elements) { - str += resolver[each.type](each) - if (each !== elements[elements.length - 1]) { - str += "\n" - } - } - return str -} - -// Converts an array of elements to GFM. -export function toGFM(elements) { - return resolveElements(elements, gfm) -} - -// Converts an array of elements to HTML. -export function toHTML(elements) { - return resolveElements(elements, html) -} diff --git a/src/EditorApp/usePreferences/index.js b/src/EditorApp/usePreferences/index.js new file mode 100644 index 0000000..7f888e3 --- /dev/null +++ b/src/EditorApp/usePreferences/index.js @@ -0,0 +1 @@ +export { default } from "./usePreferences" diff --git a/src/EditorApp/usePreferences/resolvers.js b/src/EditorApp/usePreferences/resolvers.js new file mode 100644 index 0000000..b2548f9 --- /dev/null +++ b/src/EditorApp/usePreferences/resolvers.js @@ -0,0 +1,86 @@ +import escape from "lodash/escape" +import toArray from "lib/x/toArray" +import toTree from "Editor/components/toReactTree/toTree" + +const markdown = { + em: element => `_${toText(element.props.children, markdown)}_`, + strong: element => `**${toText(element.props.children, markdown)}**`, + code: element => `\`${text(element.props.children)}\``, + strike: element => `~~${toText(element.props.children, markdown)}~~`, + a: element => `[${toText(element.props.children, markdown)}](${element.props.href || "TODO"})`, + "h1": element => `# ${toText(toTree(element.props.children, markdown))}`, + "h2": element => `## ${toText(toTree(element.props.children, markdown))}`, + "h3": element => `### ${toText(toTree(element.props.children, markdown))}`, + "h4": element => `#### ${toText(toTree(element.props.children, markdown))}`, + "h5": element => `##### ${toText(toTree(element.props.children, markdown))}`, + "h6": element => `###### ${toText(toTree(element.props.children, markdown))}`, + "p": element => toText(toTree(element.props.children), markdown), +} + +const markup = { + em: element => `${toText(element.props.children, markup)}`, + strong: element => `${toText(element.props.children, markup)}`, + code: element => `${toText(element.props.children, markup)}`, + strike: element => `${toText(element.props.children, markup)}`, + a: element => `${toText(element.props.children, markup)}`, + "h1": element => `

\n\t${toText(toTree(element.props.children), markup) || "
"}\n

`, + "h2": element => `

\n\t${toText(toTree(element.props.children), markup) || "
"}\n

`, + "h3": element => `

\n\t${toText(toTree(element.props.children), markup) || "
"}\n

`, + "h4": element => `

\n\t${toText(toTree(element.props.children), markup) || "
"}\n

`, + "h5": element => `
\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`, + "h6": element => `
\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`, + "p": element => `

\n\t${toText(toTree(element.props.children), markup) || "
"}\n

`, +} + +// Reads text from tree-shaped text nodes. Does not use a +// resolver-type. +function text(treeTextNodes) { + let str = "" + for (const each of toArray(treeTextNodes)) { + if (typeof each === "string") { + str += each + continue + } + str += each.props.children && + text(each.props.children) + } + return str +} + +// Reads text from non-tree-shaped text nodes and a +// resolver-type. +function toText(children, resolver) { + let str = "" + for (const each of toArray(children)) { + if (typeof each === "string") { + str += resolver !== markup ? each : escape(each) + continue + } + str += resolver[each.type](each) + } + return str +} + +// Converts to GFM. +export function toMarkdown(elements) { + let str = "" + for (const each of elements) { + str += markdown[each.type](each) + if (each !== elements[elements.length - 1]) { + str += "\n" + } + } + return str +} + +// Converts to HTML. +export function toMarkup(elements) { + let str = "" + for (const each of elements) { + str += markup[each.type](each) + if (each !== elements[elements.length - 1]) { + str += "\n" + } + } + return str +} diff --git a/src/EditorApp/usePreferences/resolvers.test.js b/src/EditorApp/usePreferences/resolvers.test.js new file mode 100644 index 0000000..70b786d --- /dev/null +++ b/src/EditorApp/usePreferences/resolvers.test.js @@ -0,0 +1 @@ +// TODO diff --git a/src/EditorApp/usePreferences.js b/src/EditorApp/usePreferences/usePreferences.js similarity index 95% rename from src/EditorApp/usePreferences.js rename to src/EditorApp/usePreferences/usePreferences.js index 2b537a8..24ff44b 100644 --- a/src/EditorApp/usePreferences.js +++ b/src/EditorApp/usePreferences/usePreferences.js @@ -1,8 +1,8 @@ import { useImmerReducer } from "use-immer" -import { // Unsorted - toGFM as toMarkdown, // TODO - toHTML as toMarkup, // TODO +import { + toMarkdown, + toMarkup, } from "./resolvers" const init = elements => ({