wysimark-lite 0.24.0 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +162 -134
- package/dist/index.mjs +1160 -1002
- package/dist/index.mjs.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +7 -13
- package/dist/index.d.ts +0 -1091
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx","../src/entry/index.tsx","../src/convert/parse/index.ts","../node_modules/devlop/lib/default.js","../node_modules/mdast-util-gfm-table/lib/index.js","../src/convert/parse/custom-gfm.ts","../src/convert/utils.ts","../src/convert/parse/parse-blockquote.ts","../src/convert/parse/parse-code-block.ts","../src/convert/parse/parse-footnote-definition.ts","../src/convert/parse/parse-phrasing-content/normalize-segments.ts","../src/convert/parse/parse-phrasing-content/normalize-segment.ts","../src/convert/serialize/serialize-line/utils/is-utils.ts","../src/convert/serialize/serialize-line/utils/mark-utils/mark-convert-utils.ts","../src/convert/serialize/serialize-line/utils/mark-utils/mark-get-utils.ts","../src/convert/serialize/serialize-line/utils/mark-utils/mark-order-utils.ts","../src/convert/serialize/serialize-line/utils/text-utils.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-generic-image.ts","../src/convert/parseUrl.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-utils.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-portive-image.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-uncommon-mark-image.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/image-parsers.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/index.ts","../src/convert/parse/parse-phrasing-content/parse-phrasing-content.ts","../src/convert/parse/parse-heading.ts","../src/convert/parse/parse-html.ts","../src/convert/parse/parse-list/parse-list-item-child.ts","../src/convert/parse/parse-list/parse-list-item.ts","../src/convert/parse/parse-list/parse-list.ts","../src/convert/parse/parse-paragraph.ts","../src/convert/parse/parse-table.ts","../src/convert/parse/parse-thematic-break.ts","../src/convert/parse/parse-content.ts","../src/convert/parse/transform-inline-links.ts","../src/convert/serialize/normalize/normalizeElementListDepths.ts","../src/convert/serialize/serialize-code-block/serialize-code-line.ts","../src/convert/serialize/serialize-code-block/index.ts","../src/convert/serialize/serialize-image-shared/serialize-generic-image-url.ts","../src/convert/serialize/serialize-image-shared/serialize-portive-image-url.ts","../src/convert/serialize/serialize-image-shared/serialize-uncommonmark-image-url.ts","../src/convert/serialize/serialize-image-shared/index.ts","../src/convert/serialize/serialize-image-block/index.ts","../src/convert/serialize/serialize-line/serialize-line.ts","../src/convert/serialize/serialize-line/diff-marks/find-marks-to-add.ts","../src/convert/serialize/serialize-line/diff-marks/find-marks-to-remove.ts","../src/convert/serialize/serialize-line/diff-marks/index.ts","../src/convert/serialize/serialize-line/normalize-line/index.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/merge-adjacent-spaces.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/move-spaces-out-of-anchors.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/must-have-one-text-child.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/slice-spaces-at-node-boundaries.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/trim-spaces-at-end-of-line.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/trim-spaces-at-start-of-line.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/index.ts","../src/convert/serialize/serialize-line/normalize-line/run-normalizers-on-node.ts","../src/convert/serialize/serialize-line/normalize-line/normalize-nodes.ts","../src/convert/serialize/serialize-line/segment/serialize-segment.ts","../src/convert/serialize/serialize-line/segment/serialize-code-text.ts","../src/convert/serialize/serialize-line/segment/serialize-anchor.ts","../src/convert/serialize/serialize-line/segment/serialize-non-code-text.ts","../src/convert/serialize/serialize-table/index.ts","../src/convert/serialize/serialize-element.ts","../src/convert/serialize/serialize-elements.ts","../src/convert/serialize/index.ts","../src/utils/translations.ts","../src/sink/create-plugin/index.ts","../src/sink/editable/index.tsx","../src/sink/editable/utils.ts","../src/sink/editable/create-decorate.ts","../src/sink/editable/create-editable.tsx","../src/sink/editable/create-handler.ts","../src/sink/editable/create-render-element.ts","../src/sink/editable/create-render-leaf.ts","../src/sink/editable/create-render-placeholder.tsx","../src/sink/editable/styles.tsx","../src/sink/editor/create-boolean-action.ts","../src/sink/editor/create-void-action.ts","../src/sink/editor/index.ts","../src/sink/create-sink/index.tsx","../src/sink/is-debug.ts","../src/sink/utils/core-utils/better-at.ts","../src/sink/utils/core-utils/curry.ts","../src/sink/utils/core-utils/is-mac.ts","../src/sink/utils/core-utils/stop-event.ts","../src/sink/utils/find-utils/find-element-up.ts","../src/sink/utils/standardize-utils/standardize-node-matcher.ts","../src/sink/utils/icon-utils/tabler-icon.tsx","../src/sink/utils/is-utils/is-collapsed.ts","../src/sink/utils/is-utils/is-element-type.ts","../src/sink/utils/is-utils/is-end-of-element.ts","../src/sink/utils/is-utils/is-in-empty-element.ts","../src/sink/utils/is-utils/is-start-of-element.ts","../src/sink/utils/key-utils/create-autocomplete-space-handler.tsx","../src/sink/utils/key-utils/is-better-hotkey.ts","../src/sink/utils/key-utils/create-hotkey-handler.ts","../src/sink/utils/normalize-utils/force-normalize-path.ts","../src/sink/utils/normalize-utils/normalize-siblings.ts","../src/sink/utils/select-utils/index.ts","../src/sink/utils/standardize-utils/target-element.ts","../src/sink/utils/transform-utils/insert-root-element.ts","../src/sink/utils/transform-utils/rewrap-element.ts","../src/sink/utils/transform-utils/set-nodes-dynamic.ts","../src/anchor-plugin/editable/on-paste.tsx","../src/anchor-plugin/methods/editLink.ts","../src/anchor-plugin/methods/insertLink.ts","../src/anchor-plugin/methods/removeLink.ts","../src/anchor-plugin/methods/index.ts","../src/anchor-plugin/normalize-node/index.ts","../src/anchor-plugin/render-element/anchor.tsx","../src/use-layer/layers.tsx","../src/use-layer/portal.tsx","../src/use-layer/use-layer.tsx","../src/anchor-plugin/styles.tsx","../src/anchor-plugin/render-element/AnchorDialog.tsx","../src/shared-overlays/components/CloseMask/index.tsx","../src/shared-overlays/styles/$CloseMask.tsx","../src/shared-overlays/components/Menu/formatHotkey.ts","../src/shared-overlays/components/Menu/Menu.tsx","../src/use-reposition/get-methods/get-fixed-rect.ts","../src/use-reposition/get-methods/get-absolute-rect.ts","../src/use-reposition/get-methods/get-fixed-viewport.ts","../src/use-reposition/get-methods/get-absolute-viewport.ts","../node_modules/just-map-values/index.mjs","../src/use-reposition/utils.ts","../src/use-reposition/hooks/use-reposition.tsx","../src/use-reposition/hooks/use-throttled-refresh.ts","../src/use-reposition/hooks/use-absolute-reposition.tsx","../src/use-reposition/position-methods/index.ts","../src/toolbar-plugin/styles/anchor-dialog-styles.ts","../src/shared-overlays/styles/$Panel.ts","../src/toolbar-plugin/styles/layout-styles.ts","../src/shared-layout/index.ts","../src/toolbar-plugin/styles/menu-styles.ts","../src/toolbar-plugin/styles/toolbar-styles.ts","../src/shared-overlays/components/Menu/MenuItem.tsx","../src/use-tooltip/index.tsx","../src/use-tooltip/tooltip.tsx","../src/use-tooltip/triangle.tsx","../src/anchor-plugin/render-element/AnchorEditDialog.tsx","../src/shared-styles/index.ts","../src/anchor-plugin/render-element/icons.tsx","../src/anchor-plugin/index.tsx","../src/atomic-delete-plugin/index.ts","../src/atomic-delete-plugin/is-safe-delete.ts","../src/image-plugin/index.tsx","../src/image-plugin/methods/index.ts","../src/image-plugin/normalize-node/index.ts","../src/image-plugin/render-element/image-block.tsx","../src/image-plugin/styles/image-block-styles.tsx","../src/image-plugin/render-element/image-with-controls/index.tsx","../src/image-plugin/styles/image-with-controls-styles/image-with-controls-styles.tsx","../src/image-plugin/render-element/image-with-controls/image-resize-controls/image-resize-control.tsx","../src/use-reposition/hooks/use-resize-browser.tsx","../src/image-plugin/styles/image-with-controls-styles/image-resize-handle-styles.tsx","../src/image-plugin/utils/min-max.ts","../src/image-plugin/utils/resize-utils.ts","../src/image-plugin/styles/image-with-controls-styles/image-size-status-styles.tsx","../src/image-plugin/render-element/image-with-controls/image-size-status/image-size-status.tsx","../src/image-plugin/styles/image-with-controls-styles/image-toolbar-styles.tsx","../src/image-plugin/styles/image-with-controls-styles/image-buttons-styles.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-preset-buttons/image-preset-button.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-preset-buttons/image-preset-button-group.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/block-image-type-button.tsx","../src/image-plugin/render-element/icons.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/convert-to-inline-image.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/inline-image-type-button.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/convert-to-block-image.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/image-type-button-group.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-toolbar.tsx","../src/image-plugin/render-element/image-inline.tsx","../src/image-plugin/styles/image-inline-styles.tsx","../src/image-plugin/render-element/index.tsx","../src/block-quote-plugin/index.tsx","../src/block-quote-plugin/styles.tsx","../src/code-block-plugin/index.tsx","../src/code-block-plugin/decorate.tsx","../src/code-block-plugin/methods/createCodeBlock.ts","../src/code-block-plugin/methods/setCodeBlockLanguage.ts","../src/code-block-plugin/methods/index.ts","../src/code-block-plugin/prism-theme.ts","../src/code-block-plugin/normalizeNode.tsx","../src/code-block-plugin/render-element/CodeBlock.tsx","../src/code-block-plugin/styles.ts","../src/code-block-plugin/render-element/CodeBlockLine.tsx","../src/code-block-plugin/render-element/index.tsx","../src/html-block-plugin/index.tsx","../src/html-block-plugin/styles.ts","../src/html-block-plugin/render-element.tsx","../src/collapsible-paragraph-plugin/index.tsx","../src/collapsible-paragraph-plugin/normalize-node/index.ts","../src/collapsible-paragraph-plugin/normalize-node/normalize-sibling-paragraphs.ts","../src/collapsible-paragraph-plugin/normalize-node/normalize-sibling-walls.ts","../src/collapsible-paragraph-plugin/render-element/paragraph.tsx","../src/collapsible-paragraph-plugin/render-element/styles.ts","../src/collapsible-paragraph-plugin/render-element/utils.ts","../src/convert-element-plugin/methods/add-convert-element-type.ts","../src/convert-element-plugin/methods/convert-elements.ts","../src/convert-element-plugin/methods/is-convert-element.ts","../src/convert-element-plugin/methods/index.ts","../src/convert-element-plugin/index.tsx","../src/heading-plugin/insert-break.ts","../src/heading-plugin/methods/index.ts","../src/heading-plugin/styles.ts","../src/heading-plugin/index.tsx","../src/horizontal-rule-plugin/horizontal-rule.tsx","../src/horizontal-rule-plugin/styles.tsx","../src/horizontal-rule-plugin/methods/index.ts","../src/horizontal-rule-plugin/index.tsx","../src/inline-code-plugin/styles.ts","../src/inline-code-plugin/index.tsx","../src/list-plugin/index.tsx","../src/list-plugin/methods/convert-list-item.ts","../src/list-plugin/methods/depth.ts","../src/list-plugin/methods/indent.ts","../src/list-plugin/methods/insert-break.ts","../src/list-plugin/methods/outdent.ts","../src/list-plugin/methods/toggleTaskListItem.ts","../src/list-plugin/methods/index.ts","../src/list-plugin/normalize-node/normalize-ordered-first-at-depth.ts","../src/list-plugin/normalize-node/index.ts","../src/list-plugin/render-element/ordered-list-item.tsx","../src/list-plugin/render-element/styles.ts","../src/list-plugin/render-element/task-list-item.tsx","../src/list-plugin/render-element/list-icons.tsx","../src/list-plugin/render-element/unordered-list-item.tsx","../src/list-plugin/render-element/index.tsx","../src/marks-plugin/index.tsx","../src/marks-plugin/methods/removeMarks.ts","../src/marks-plugin/methods/toggle-mark.ts","../src/marks-plugin/methods/index.ts","../src/marks-plugin/styles.tsx","../src/normalize-after-delete-plugin/index.tsx","../src/table-plugin/index.tsx","../src/table-plugin/delete-fragment/index.ts","../src/table-plugin/delete-fragment/get-reversed-delete-safe-ranges.ts","../src/table-plugin/methods/index.ts","../src/table-plugin/methods/get-table-info.ts","../src/table-plugin/methods/insert-column.ts","../src/table-plugin/methods/utils.ts","../src/table-plugin/methods/insert-row.ts","../src/table-plugin/methods/insert-table.ts","../src/table-plugin/methods/navigation/select-element.ts","../src/table-plugin/methods/navigation/utils.ts","../src/table-plugin/methods/navigation/index.ts","../src/table-plugin/methods/remove-column.ts","../src/table-plugin/methods/remove-table.ts","../src/table-plugin/methods/remove-row.ts","../src/table-plugin/methods/setTableColumnAlign.ts","../src/table-plugin/methods/tab.ts","../src/table-plugin/normalize/normalize-table.ts","../src/table-plugin/normalize/normalize-table-cell.ts","../src/table-plugin/render-element/table.tsx","../src/table-plugin/render-element/styles/index.ts","../src/table-plugin/render-element/styles/table-menu-styles.ts","../src/table-plugin/render-element/table-context.tsx","../src/table-plugin/render-element/table-cell/index.tsx","../src/table-plugin/render-element/table-cell/column-menu/index.tsx","../src/table-plugin/icons.tsx","../src/table-plugin/render-element/table-cell/row-menu/index.tsx","../src/table-plugin/render-element/table-cell/table-menu/$table-menu.tsx","../src/table-plugin/render-element/table-cell/table-menu/index.tsx","../src/table-plugin/render-element/table-content.tsx","../src/table-plugin/render-element/table-row.tsx","../src/table-plugin/render-element/index.tsx","../src/theme-plugin/index.tsx","../src/theme-plugin/global-styles.ts","../src/toolbar-plugin/render-editable/index.tsx","../src/toolbar-plugin/components/dialog/table-dialog.tsx","../src/toolbar-plugin/styles/table-styles.ts","../src/toolbar-plugin/components/toolbar/toolbar.tsx","../src/toolbar-plugin/icons.tsx","../src/toolbar-plugin/items/block-items.tsx","../src/toolbar-plugin/components/dialog/image-url-dialog.tsx","../src/toolbar-plugin/styles/file-dialog-styles.ts","../src/toolbar-plugin/components/dialog/anchor-dialog.tsx","../src/toolbar-plugin/styles/dialog-shared-styles.ts","../src/toolbar-plugin/items/dialogItems.tsx","../src/toolbar-plugin/items/mark-items.tsx","../src/toolbar-plugin/items/list-items.tsx","../src/toolbar-plugin/items/quote-items.tsx","../src/toolbar-plugin/items/raw-mode-item.tsx","../src/toolbar-plugin/items/index.tsx","../src/toolbar-plugin/components/toolbar/toolbar-button.tsx","../src/toolbar-plugin/index.tsx","../src/trailing-block-plugin/index.tsx","../src/paste-markdown-plugin/methods/index.ts","../src/paste-markdown-plugin/index.tsx","../src/placeholder-plugin/index.tsx","../src/entry/plugins.ts","../src/entry/SinkEditable.tsx","../src/entry/useEditor.tsx"],"sourcesContent":["// Ensure this package is treated as a client component (e.g. in Next.js App Router)\n'use client'\n\nimport {\n createRef,\n RefObject,\n useCallback,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\"\nimport { createRoot } from \"react-dom/client\"\nimport { Editable, useEditor, OnImageChangeHandler } from './entry/index'\n\nexport { Editable, useEditor }\nexport type { OnImageChangeHandler }\n\n/**\n * The options passed into the standalone version of Wysimark.\n */\ntype StandaloneOptions = Parameters<typeof useEditor>[0] & {\n onChange?: (markdown: string) => void\n placeholder?: string\n initialMarkdown?: string\n className?: string\n}\n\ntype StandaloneMethods = {\n getMarkdown: () => string\n setMarkdown: (markdown: string) => void\n}\n\n/**\n * The object returned by `createWysimark`\n */\nexport type Wysimark = {\n unmount: () => void\n getMarkdown: () => string\n setMarkdown: (markdown: string) => void\n}\n\nfunction StandaloneEditor({\n standaloneOptions: { onChange, placeholder, className, ...options },\n standaloneMethodsRef,\n}: {\n standaloneOptions: StandaloneOptions\n standaloneMethodsRef: RefObject<StandaloneMethods | null>\n}) {\n const [markdown, setMarkdown] = useState(options.initialMarkdown || \"\")\n const markdownRef = useRef(markdown)\n const editor = useEditor(options)\n\n markdownRef.current = markdown\n\n useImperativeHandle(\n standaloneMethodsRef,\n () => {\n return {\n getMarkdown() {\n return markdownRef.current\n },\n setMarkdown(markdown: string) {\n markdownRef.current = markdown\n setMarkdown(markdown)\n },\n }\n },\n [markdownRef, setMarkdown]\n )\n\n const onChangeEditable = useCallback(\n (markdown: string) => {\n /**\n * Setting the ref is important in the case where there is an attempt to\n * call the `getMarkdown` method from `onChange`. Otherwise the `ref`\n * doesn't get updated until the next render which happens sometime after\n * the `onChange` callback is called.\n */\n markdownRef.current = markdown\n setMarkdown(markdown)\n onChange?.(markdown)\n },\n [editor]\n )\n\n return (\n <Editable\n editor={editor}\n value={markdown}\n className={className || \"\"}\n onChange={onChangeEditable}\n placeholder={placeholder}\n />\n )\n}\n\n/**\n * The primary entry point for the standalone version of Wysimark.\n */\nexport function createWysimark(\n containerElement: HTMLElement,\n options: StandaloneOptions\n): Wysimark {\n const standaloneMethodsRef = createRef<StandaloneMethods | null>()\n\n const root = createRoot(containerElement)\n\n root.render(\n <StandaloneEditor\n standaloneMethodsRef={standaloneMethodsRef}\n standaloneOptions={options}\n />\n )\n\n return {\n unmount() {\n try {\n root.unmount()\n } catch (e) {\n /* ignore */\n }\n },\n getMarkdown() {\n return standaloneMethodsRef.current?.getMarkdown() || \"\"\n // const markdown = editorRef.current?.getMarkdown()\n // return typeof markdown === \"string\"\n // ? markdown\n // : options.initialMarkdown || \"\"\n },\n setMarkdown(markdown: string) {\n standaloneMethodsRef.current?.setMarkdown(markdown)\n },\n }\n}\n","import throttle from \"lodash.throttle\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { Descendant, Editor, Element, Transforms } from \"slate\"\nimport { ReactEditor, RenderLeafProps, Slate } from \"slate-react\"\n\nimport { parse, serialize, escapeUrlSlashes, unescapeUrlSlashes } from \"../convert\"\nimport { t } from \"../utils/translations\"\nimport { SinkEditable } from \"./SinkEditable\"\nimport { useEditor } from \"./useEditor\"\nimport * as Icon from \"../toolbar-plugin/icons\"\n\nexport type { Element, Text } from \"./plugins\"\n\nexport { useEditor }\n\nfunction renderLeaf({ children, attributes }: RenderLeafProps) {\n return <span {...attributes}>{children}</span>\n}\n\nexport type OnImageChangeHandler = (file: File) => Promise<string>\n\nexport type EditableProps = {\n // editor: BaseEditor & ReactEditor & HistoryEditor & SinkEditor & WysimarkEditor\n editor: Editor\n value: string\n onChange: (markdown: string) => void\n throttleInMs?: number\n placeholder?: string\n className?: string\n style?: React.CSSProperties\n onImageChange?: OnImageChangeHandler\n} // & Omit<React.TextareaHTMLAttributes<HTMLDivElement>, \"onChange\">\n\nexport function Editable({\n editor,\n value,\n onChange,\n throttleInMs = 1000,\n placeholder,\n className,\n style,\n onImageChange,\n}: EditableProps) {\n const [isRawMode, setIsRawMode] = useState(false)\n const [rawText, setRawText] = useState(value)\n const ignoreNextChangeRef = useRef<boolean>(false)\n\n /**\n * This is a temporary ref that is only used once to store the initial value\n * derived from the initial Markdown value.\n */\n const initialValueRef = useRef<Descendant[] | undefined>(undefined)\n\n /**\n * Track the previous value of the editor. This is used to determine if the\n * change from the editor resulted in a change in the contents of the editor\n * as opposed to just a cursor movement for example.\n */\n const prevValueRef = useRef<Descendant[] | undefined>(undefined)\n\n /**\n * Track the last value emitted via onChange. This is used to prevent\n * unnecessary reparsing when the parent component sets value to what\n * we just emitted.\n */\n const lastEmittedValueRef = useRef<string | undefined>(undefined)\n\n /**\n * Throttled version of `onChange` for the `Slate` component. This method gets\n * called on every change to the editor except for:\n *\n * - The first call to `onChange` when the component is mounted which would\n * be in response to the initial normalization pass that is always run to\n * make sure the content is in a good state.\n * - When the incoming value (markdown) to the editor is changed and we force\n * the editor to update its value after doing a `parse` on the markdown.\n * We don't want the `onChange` callback to be called for this because if\n * the change came from an edit to a textarea, for example, it would\n * serialize the editor and the value of the textarea would be updated with\n * a slightly different value. This would cause the selection to jump. This\n * is especially bad if the cursor is at the end of a line and the user\n * presses the spacebar. This is because Markdown does not support spaces\n * at the end of a line and the space would be removed and the cursor would\n * have nowhere to be.\n */\n const onThrottledSlateChange = useCallback(\n throttle(\n () => {\n const markdown = unescapeUrlSlashes(serialize(editor.children as Element[]))\n editor.wysimark.prevValue = {\n markdown,\n children: editor.children,\n }\n lastEmittedValueRef.current = markdown\n onChange(markdown)\n },\n throttleInMs,\n { leading: false, trailing: true }\n ),\n [editor, onChange, throttleInMs]\n )\n\n /**\n * This handles the initial `onChange` event from the `Slate` component and\n * makes sure to ignore any change events that don't change the content of\n * the editor. For example, if the user just moves the cursor around, we\n * don't want to call the `onChange` callback.\n *\n * If it's neither, then it passes the call to the throttled `onChange` method.\n *\n * Note: We no longer do reference comparison here because mark changes\n * (like custom highlight marks) may modify text nodes without changing\n * the children array reference. The throttle function handles rate limiting.\n */\n const onSlateChange = useCallback(\n (nextValue: Descendant[]) => {\n if (ignoreNextChangeRef.current) {\n ignoreNextChangeRef.current = false\n prevValueRef.current = nextValue\n return\n }\n prevValueRef.current = nextValue\n onThrottledSlateChange()\n },\n [onThrottledSlateChange]\n )\n\n /**\n * Handle the initial mounting of the component. This is where we set the\n * initial value of the editor. We also set the `prevValue` on the editor\n * which is used to determine if a change in the editor resulted in a change\n * in the contents of the editor vs just changing the cursor position for\n * example.\n *\n * We add a check for `initialValueRef.current` not being null because the\n * ref can be lost on a hot reload. This then reinitializes the editor with\n * the initial value.\n *\n * NOTE: This value hasn't been normalized yet.\n */\n if (editor.wysimark.prevValue == null || initialValueRef.current == null) {\n ignoreNextChangeRef.current = true\n // Only escape URL slashes when not in raw mode\n const valueToProcess = isRawMode ? value : escapeUrlSlashes(value);\n const children = parse(valueToProcess)\n editor.children = children\n prevValueRef.current = initialValueRef.current = children\n editor.wysimark.prevValue = {\n markdown: value, // Store the original unescaped value\n children,\n }\n lastEmittedValueRef.current = value\n } else {\n /**\n * Handle the case where the `value` differs from the last `markdown` value\n * set in the Wysimark editor. If it differs, that means the change came\n * from somewhere else and we need to set the editor value.\n *\n * Apart from setting `editor.children` we also need to set the selection\n * to the start of the document. This is because the selection may be set\n * to an invalid value based on the new document value.\n *\n * We also check against `lastEmittedValueRef.current` to prevent race\n * conditions during throttle delays. When throttled onChange fires, the\n * parent component receives the new value and passes it back as a prop.\n * However, `editor.wysimark.prevValue.markdown` may not be updated yet\n * due to the trailing throttle behavior. By also checking against the\n * last emitted value, we avoid unnecessary reparsing.\n */\n /**\n * In Raw Mode, synchronize prevValue.markdown with the current value prop.\n * This prevents unnecessary reparsing when the user edits in raw mode.\n * Without this, each keystroke in raw mode would trigger a reparse because\n * the value prop (updated via onChange) differs from prevValue.markdown.\n */\n if (isRawMode) {\n editor.wysimark.prevValue.markdown = value\n lastEmittedValueRef.current = value\n } else {\n const diffFromPrevValue = value !== editor.wysimark.prevValue.markdown\n const diffFromLastEmitted = value !== lastEmittedValueRef.current\n if (diffFromPrevValue && diffFromLastEmitted) {\n ignoreNextChangeRef.current = true\n // Only escape URL slashes when not in raw mode\n const valueToProcess = escapeUrlSlashes(value);\n const documentValue = parse(valueToProcess)\n editor.children = documentValue\n editor.selection = null\n Transforms.select(editor, Editor.start(editor, [0]))\n }\n }\n }\n\n const onSinkeEditableMouseDown = useCallback(() => {\n /**\n * For some reason, Firefox doesn't focus the editor when clicking on\n * it until the second try. This is a workaround for that.\n * Handled narrowly to avoid potentially breaking other browsers.\n */\n if (navigator.userAgent.toLowerCase().includes(\"firefox\")) {\n ReactEditor.focus(editor)\n }\n }, [editor])\n\n /**\n * When the user exits the editor, we want to call the `onChange` callback\n * immediately.\n */\n const onBlur = useCallback(() => {\n onThrottledSlateChange.flush()\n }, [onThrottledSlateChange])\n\n // Handle raw text change\n const handleRawTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newText = e.target.value;\n setRawText(newText);\n // Also update the editor's value through onChange\n onChange(newText);\n }\n\n // When switching from raw mode to visual mode\n const applyRawTextToEditor = useCallback(() => {\n if (rawText !== editor.getMarkdown()) {\n editor.setMarkdown(rawText);\n }\n }, [editor, rawText]);\n\n /**\n * When switching from visual mode to raw mode, populate the textarea\n * with the value prop instead of serializing from the editor.\n *\n * This is important because the parse->serialize round-trip can lose\n * formatting that exists in the original markdown but cannot be\n * represented in the Slate document structure. For example, if the\n * original markdown had an image followed by a heading without proper\n * newlines, the editor would parse them into the same paragraph.\n * Serializing from the editor would output broken markdown.\n *\n * By using the value prop directly, we preserve the exact markdown\n * that the parent component has, allowing users to fix formatting\n * issues in raw mode.\n */\n const updateRawTextFromEditor = useCallback(() => {\n setRawText(value);\n }, [value]);\n\n // Handle mode toggle\n const handleRawModeToggle = useCallback(() => {\n if (isRawMode) {\n // Switching from raw mode to visual mode\n applyRawTextToEditor();\n } else {\n // Switching from visual mode to raw mode\n updateRawTextFromEditor();\n }\n setIsRawMode(!isRawMode);\n }, [isRawMode, applyRawTextToEditor, updateRawTextFromEditor]);\n\n // Set the Raw mode state and toggle function on the editor\n // This allows the toolbar to access these properties\n editor.wysimark.isRawMode = isRawMode;\n // Only set toggleRawMode if raw mode is not disabled\n if (!editor.wysimark.disableRawMode) {\n editor.wysimark.toggleRawMode = handleRawModeToggle;\n }\n editor.wysimark.onImageChange = onImageChange;\n\n return (\n <div style={{ position: 'relative' }}>\n {/* Only show the Raw mode icon when in Raw mode */}\n {isRawMode && (\n <div style={{ position: 'absolute', top: '5px', right: '25px', zIndex: 10 }}>\n <div\n onClick={handleRawModeToggle}\n style={{\n background: 'none',\n border: '1px solid #4a90e2',\n cursor: 'pointer',\n padding: '6px',\n borderRadius: '4px',\n backgroundColor: 'rgba(74, 144, 226, 0.1)',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',\n transition: 'all 0.2s ease-in-out',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center'\n }}\n title={t(\"switchToVisualEditor\")}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n handleRawModeToggle();\n e.preventDefault();\n }\n }}\n >\n {/* Use the VisualEditor icon */}\n <span style={{ color: '#4a90e2', fontSize: '1.25em' }}>\n <Icon.VisualEditor />\n </span>\n </div>\n </div>\n )}\n\n {/* Raw mode textarea - always in DOM but hidden when not in raw mode */}\n <div style={{ display: isRawMode ? 'block' : 'none', textAlign: 'center' }}>\n <textarea\n value={unescapeUrlSlashes(rawText).replace(/ /g, '')}\n onChange={handleRawTextChange}\n placeholder={placeholder}\n className={className}\n style={{\n width: 'calc(100% - 60px)', /* Full width minus 200px on each side */\n margin: '0 auto', /* Center the textarea */\n minHeight: '200px',\n padding: '20px',\n fontFamily: 'monospace',\n fontSize: '14px',\n color: '#333',\n lineHeight: '1.5',\n backgroundColor: '#fff',\n border: '1px solid #ddd',\n borderRadius: '4px',\n ...style\n }}\n />\n </div>\n\n {/* Visual editor - always in DOM but hidden when in raw mode */}\n <div style={{ display: isRawMode ? 'none' : 'block' }}>\n <Slate\n editor={editor}\n initialValue={(initialValueRef.current ??\n editor.children) as Descendant[]}\n onChange={onSlateChange}\n >\n <SinkEditable\n renderLeaf={renderLeaf}\n onMouseDown={onSinkeEditableMouseDown}\n onBlur={onBlur}\n placeholder={placeholder}\n className={className}\n style={style}\n />\n </Slate>\n </div>\n </div>\n )\n}\n","import type { Root, TopLevelContent } from \"mdast\"\nimport remarkParse from \"remark-parse\"\nimport { unified } from \"unified\"\n\nimport { Element } from \"../types\"\nimport { customRemarkGfm } from \"./custom-gfm\"\nimport { parseContents } from \"./parse-content\"\nimport { transformInlineLinks } from \"./transform-inline-links\"\n\n// @ts-ignore - Ignore TypeScript errors for the unified plugin system\nconst parser = unified().use(remarkParse).use(customRemarkGfm())\n\nexport function parseToAst(markdown: string) {\n const ast = parser.parse(markdown) as Root\n /**\n * Takes linkReference and imageReference and turns them into link and image.\n */\n transformInlineLinks(ast)\n return ast\n}\n\n/**\n * Takes a Markdown string as input and returns a remarkParse AST\n */\nexport function parse(markdown: string): Element[] {\n const ast = parseToAst(markdown)\n /**\n * If there is no content, remark returns a root ast with no children (i.e.\n * no paragraphs) but for Slate, we need it to return an empty paragraph.\n *\n * So when this happens, we just generate an empty paragraph and return that\n * s he result.\n */\n if (ast.children.length === 0) {\n return [{ type: \"paragraph\", children: [{ text: \"\" }] }] as Element[]\n }\n\n return parseContents(ast.children as TopLevelContent[])\n}\n","export function deprecate(fn) {\n return fn\n}\n\nexport function equal() {}\n\nexport function ok() {}\n\nexport function unreachable() {}\n","/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('mdast').TableRow} TableRow\n *\n * @typedef {import('markdown-table').Options} MarkdownTableOptions\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').State} State\n * @typedef {import('mdast-util-to-markdown').Info} Info\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [tableCellPadding=true]\n * Whether to add a space of padding between delimiters and cells (default:\n * `true`).\n * @property {boolean | null | undefined} [tablePipeAlign=true]\n * Whether to align the delimiters (default: `true`).\n * @property {MarkdownTableOptions['stringLength'] | null | undefined} [stringLength]\n * Function to detect the length of table cell content, used when aligning\n * the delimiters between cells (optional).\n */\n\nimport {ok as assert} from 'devlop'\nimport {markdownTable} from 'markdown-table'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM tables in\n * markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM tables.\n */\nexport function gfmTableFromMarkdown() {\n return {\n enter: {\n table: enterTable,\n tableData: enterCell,\n tableHeader: enterCell,\n tableRow: enterRow\n },\n exit: {\n codeText: exitCodeText,\n table: exitTable,\n tableData: exit,\n tableHeader: exit,\n tableRow: exit\n }\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterTable(token) {\n const align = token._align\n assert(align, 'expected `_align` on table')\n this.enter(\n {\n type: 'table',\n align: align.map(function (d) {\n return d === 'none' ? null : d\n }),\n children: []\n },\n token\n )\n this.data.inTable = true\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitTable(token) {\n this.exit(token)\n this.data.inTable = undefined\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterRow(token) {\n this.enter({type: 'tableRow', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exit(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterCell(token) {\n this.enter({type: 'tableCell', children: []}, token)\n}\n\n// Overwrite the default code text data handler to unescape escaped pipes when\n// they are in tables.\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCodeText(token) {\n let value = this.resume()\n\n if (this.data.inTable) {\n value = value.replace(/\\\\([\\\\|])/g, replace)\n }\n\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'inlineCode')\n node.value = value\n this.exit(token)\n}\n\n/**\n * @param {string} $0\n * @param {string} $1\n * @returns {string}\n */\nfunction replace($0, $1) {\n // Pipes work, backslashes don’t (but can’t escape pipes).\n return $1 === '|' ? $1 : $0\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM tables in\n * markdown.\n *\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM tables.\n */\nexport function gfmTableToMarkdown(options) {\n const settings = options || {}\n const padding = settings.tableCellPadding\n const alignDelimiters = settings.tablePipeAlign\n const stringLength = settings.stringLength\n const around = padding ? ' ' : '|'\n\n return {\n unsafe: [\n {character: '\\r', inConstruct: 'tableCell'},\n {character: '\\n', inConstruct: 'tableCell'},\n // A pipe, when followed by a tab or space (padding), or a dash or colon\n // (unpadded delimiter row), could result in a table.\n {atBreak: true, character: '|', after: '[\\t :-]'},\n // A pipe in a cell must be encoded.\n {character: '|', inConstruct: 'tableCell'},\n // A colon must be followed by a dash, in which case it could start a\n // delimiter row.\n {atBreak: true, character: ':', after: '-'},\n // A delimiter row can also start with a dash, when followed by more\n // dashes, a colon, or a pipe.\n // This is a stricter version than the built in check for lists, thematic\n // breaks, and setex heading underlines though:\n // <https://github.com/syntax-tree/mdast-util-to-markdown/blob/51a2038/lib/unsafe.js#L57>\n {atBreak: true, character: '-', after: '[:|-]'}\n ],\n handlers: {\n inlineCode: inlineCodeWithTable,\n table: handleTable,\n tableCell: handleTableCell,\n tableRow: handleTableRow\n }\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {Table} node\n */\n function handleTable(node, _, state, info) {\n return serializeData(handleTableAsData(node, state, info), node.align)\n }\n\n /**\n * This function isn’t really used normally, because we handle rows at the\n * table level.\n * But, if someone passes in a table row, this ensures we make somewhat sense.\n *\n * @type {ToMarkdownHandle}\n * @param {TableRow} node\n */\n function handleTableRow(node, _, state, info) {\n const row = handleTableRowAsData(node, state, info)\n const value = serializeData([row])\n // `markdown-table` will always add an align row\n return value.slice(0, value.indexOf('\\n'))\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {TableCell} node\n */\n function handleTableCell(node, _, state, info) {\n const exit = state.enter('tableCell')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, {\n ...info,\n before: around,\n after: around\n })\n subexit()\n exit()\n return value\n }\n\n /**\n * @param {Array<Array<string>>} matrix\n * @param {Array<string | null | undefined> | null | undefined} [align]\n */\n function serializeData(matrix, align) {\n return markdownTable(matrix, {\n align,\n // @ts-expect-error: `markdown-table` types should support `null`.\n alignDelimiters,\n // @ts-expect-error: `markdown-table` types should support `null`.\n padding,\n // @ts-expect-error: `markdown-table` types should support `null`.\n stringLength\n })\n }\n\n /**\n * @param {Table} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<Array<string>>} */\n const result = []\n const subexit = state.enter('table')\n\n while (++index < children.length) {\n result[index] = handleTableRowAsData(children[index], state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @param {TableRow} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableRowAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<string>} */\n const result = []\n const subexit = state.enter('tableRow')\n\n while (++index < children.length) {\n // Note: the positional info as used here is incorrect.\n // Making it correct would be impossible due to aligning cells?\n // And it would need copy/pasting `markdown-table` into this project.\n result[index] = handleTableCell(children[index], node, state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {InlineCode} node\n */\n function inlineCodeWithTable(node, parent, state) {\n let value = defaultHandlers.inlineCode(node, parent, state)\n\n if (state.stack.includes('tableCell')) {\n value = value.replace(/\\|/g, '\\\\$&')\n }\n\n return value\n }\n}\n","import type { Plugin } from 'unified'\nimport { gfmTableFromMarkdown } from 'mdast-util-gfm-table'\nimport { gfm } from 'micromark-extension-gfm'\nimport { gfmToMarkdown } from 'mdast-util-gfm'\n\n/**\n * Custom wrapper around remark-gfm that ensures the data object is initialized\n * This fixes the \"Cannot set properties of undefined (setting 'inTable')\" error\n * that occurs when pasting tables\n */\nexport function customRemarkGfm(): Plugin {\n // Return a plugin function that initializes the data object\n return function(this: any) {\n // Make sure 'this' exists\n if (!this) {\n return;\n }\n \n // Initialize the data object on the processor\n // @ts-ignore - We're accessing internal properties to fix the issue\n if (!this.data) {\n // @ts-ignore\n this.data = {};\n } else if (typeof this.data === 'function') {\n // Call data() to ensure the data object is initialized\n this.data();\n }\n \n // Create a direct implementation of the remarkGfm plugin\n // This avoids calling the original plugin which might have issues\n \n // @ts-ignore - We're accessing internal properties\n const data = typeof this.data === 'function' ? this.data() : this.data;\n \n // Initialize the extensions arrays if they don't exist\n const micromarkExtensions = data.micromarkExtensions || (data.micromarkExtensions = []);\n const fromMarkdownExtensions = data.fromMarkdownExtensions || (data.fromMarkdownExtensions = []);\n const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);\n \n // Add the GFM extensions\n // We're using the original extensions from remark-gfm\n // @ts-ignore - We're accessing internal properties\n micromarkExtensions.push(gfm());\n \n // Create a patched version of gfmTableFromMarkdown\n const patchedFromMarkdown = function() {\n const extension = gfmTableFromMarkdown();\n \n // Make sure enter exists\n if (extension.enter) {\n // Patch the enterTable function\n const originalEnterTable = extension.enter.table;\n if (originalEnterTable) {\n extension.enter.table = function(token) {\n // Make sure this.data exists before the original function is called\n if (!this.data) {\n this.data = {};\n }\n \n // Call the original function\n originalEnterTable.call(this, token);\n \n // Make sure inTable is set\n this.data.inTable = true;\n };\n }\n }\n \n // Make sure exit exists and patch the exitTable function\n if (extension.exit) {\n const originalExitTable = extension.exit.table;\n if (originalExitTable) {\n extension.exit.table = function(token) {\n // Make sure this.data exists before the original function is called\n if (!this.data) {\n this.data = {};\n }\n \n // Call the original function\n originalExitTable.call(this, token);\n \n // Make sure inTable is safely unset\n if (this.data) {\n this.data.inTable = undefined;\n }\n };\n }\n }\n \n return extension;\n };\n \n // Add our patched extensions\n fromMarkdownExtensions.push(patchedFromMarkdown());\n // @ts-ignore - We're accessing internal properties\n toMarkdownExtensions.push(gfmToMarkdown());\n \n return undefined; // Return undefined as the plugin doesn't need to return anything\n }\n}\n","import { Element } from \"./types\"\n\n/**\n * Function to escape forward slashes in URLs, but only for plain text URLs (not in markdown links)\n * This is necessary because the markdown parser doesn't handle unescaped forward slashes in URLs correctly\n */\nexport function escapeUrlSlashes(text: string): string {\n // First, we need to identify markdown links to exclude them\n const markdownLinkPattern = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n\n // Store the markdown links to restore them later\n const links: string[] = [];\n let linkIndex = 0;\n\n // Replace markdown links with placeholders\n const textWithoutLinks = text.replace(markdownLinkPattern, (match) => {\n links.push(match);\n return `__MARKDOWN_LINK_${linkIndex++}__`;\n });\n\n // URL regex pattern to identify plain text URLs\n const urlPattern = /(https?:\\/\\/[^\\s]+)/g;\n\n // Escape forward slashes in plain text URLs\n const textWithEscapedUrls = textWithoutLinks.replace(urlPattern, (url) => {\n return url.replace(/\\//g, '\\\\/');\n });\n\n // Restore the markdown links\n let result = textWithEscapedUrls;\n for (let i = 0; i < links.length; i++) {\n result = result.replace(`__MARKDOWN_LINK_${i}__`, links[i]);\n }\n\n return result;\n}\n\n/**\n * Function to unescape forward slashes in URLs that were previously escaped\n * This is used when switching to raw mode to display the unescaped markdown\n */\nexport function unescapeUrlSlashes(text: string): string {\n // Unescape all escaped characters in the text\n return text.replace(/\\\\(.)/g, (match, char) => {\n return char;\n });\n}\n\nexport function assert(pass: boolean, message: string) {\n if (!pass) throw new Error(`${message}`)\n}\n\nexport function assertElementType(element: Element, type: Element[\"type\"]) {\n if (element.type !== type)\n throw new Error(\n `Expected element to be of type ${JSON.stringify(\n element\n )} but is ${JSON.stringify(element, null, 2)}`\n )\n}\n\nexport function assertUnreachable(x: never): never {\n throw new Error(\n `Didn't expect to get here with value ${JSON.stringify(x, null, 2)}`\n )\n}\n","import type { Blockquote } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { parseContents } from \"./parse-content\"\n\nexport function parseBlockquote(content: Blockquote): Element[] {\n return [{ type: \"block-quote\", children: parseContents(content.children) }]\n}\n","import type { Code } from \"mdast\"\n\nimport { Element } from \"../types\"\n\nexport function parseCodeBlock(content: Code): Element[] {\n const codeLines = content.value.split(\"\\n\")\n return [\n {\n type: \"code-block\",\n language: content.lang || \"text\",\n children: codeLines.map((codeLine) => ({\n type: \"code-block-line\",\n children: [{ text: codeLine }],\n })),\n },\n ]\n}\n","import type { FootnoteDefinition } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { parseContents } from \"./parse-content\"\n\n/**\n * GitHub Flavored Markdown does not support footnotes and therefore, at the\n * moment, Wysimark does not support footnotes.\n *\n * However, we do provide some compatibility. Remarks, by default, parses\n * Footnote Definitions and we convert them into a blockquote. We insert an\n * extra paragraph at the top that contains the footnote identifier in square\n * brackets like `[1]`\n */\nexport function parseFootnoteDefinition(\n footnote: FootnoteDefinition\n): Element[] {\n return [\n {\n type: \"block-quote\",\n children: [\n /**\n * Insert an initial paragraph with the footnote identifier in square\n * brackets.\n */\n { type: \"paragraph\", children: [{ text: `[${footnote.identifier}]` }] },\n /**\n * The rest of the children are parsed as is and supports the full range\n * of element types like headings, lists and nested block quotes.\n */\n ...parseContents(footnote.children),\n ],\n },\n ]\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { Segment } from \"../../types\"\nimport { normalizeSegment } from \"./normalize-segment\"\n\n/**\n * After generating segments by just pushing them onto an Array, we want to get\n * them into proper form for use in Slate.\n *\n * Slate expects its data structure to follow [certain\n * rules](https://docs.slatejs.org/concepts/11-normalizing) and we make sure\n * they are followed.\n *\n * These are the rules for segments (text/inline) that we enforce:\n *\n * - Rule 1: All Element nodes must contain at least one Text descendant\n * - Rule 2: Two adjacent texts with the same custom properties will be merged.\n * - Rule 4: Inline nodes cannot be the first or last child of a parent block,\n * nor can it be next to another inline node in the children array.\n *\n */\nexport function normalizeSegments(segments: Segment[]): Segment[] {\n const nextSegments: Segment[] = []\n\n /**\n * Rule 2:\n *\n * Build up the nextSegments. The `normalizeSegment` function called inside\n * does the work of checking to see if the segment before is a Text with the\n * exact same marks. If it is, then instead of pushing on another Text\n * segment, it merges the current segment Text into the previous Segment.\n *\n * Rule 4 (part 3):\n *\n * It also checks for two inline elements and inserts an empty Text node\n * between them by emitting a `{text: ''}` before the inline Element segment.\n */\n for (let i = 0; i < segments.length; i++) {\n /**\n * When we provide the `prevSegment` notice that is is actually the\n * `prevSegment` from our `nextSegments` and not `segments[i-1]`.\n *\n * This is important because `normalizeSegment` will mutate `prevSegment`\n */\n\n const mutablePrevSegment: Segment | undefined =\n nextSegments[nextSegments.length - 1]\n nextSegments.push(...normalizeSegment(segments[i], mutablePrevSegment))\n }\n\n /**\n * Rule 1:\n *\n * If there are no segments, we ensure there is at least one by inserting an\n * empty Text\n */\n if (nextSegments.length === 0) nextSegments.push({ text: \"\" })\n /**\n * Rule 4 (part 1 & part 2):\n *\n * If the first segment isn't Text, insert a Text\n */\n if (!SlateText.isText(nextSegments[0])) nextSegments.unshift({ text: \"\" })\n /**\n * Rule 4:\n *\n * If the last segment isn't Text, insert a Text\n */\n if (!SlateText.isText(nextSegments[nextSegments.length - 1]))\n nextSegments.push({ text: \"\" })\n return nextSegments\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { getMarksFromText } from \"../../serialize/serialize-line/utils\"\nimport { Segment, Text } from \"../../types\"\n\n/**\n * This is algorithm checks for equality of marks.\n */\nexport function areMarksEqual(a: Text, b: Text): boolean {\n const marksA = getMarksFromText(a)\n const marksB = getMarksFromText(b)\n /**\n *\n * WARNING:\n *\n * This algorithm is specific to our use case. a, b contain non-repeated\n * items. It will fail in other scenarios.\n *\n * > If you want to check if both arrays are equals, containing the same\n * > unsorted items (but not used multiple times)\n *\n * https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript#comment68674302_19746771\n */\n return (\n marksA.length == marksB.length && marksA.every((v) => marksB.includes(v))\n )\n}\n\n/**\n * Enforces Rule 2\n *\n * Two adjacent texts with the same custom properties will be merged.\n * https://docs.slatejs.org/concepts/11-normalizing\n *\n * normalizeSegment does most of the work for merging two segments with the same\n * marks together.\n *\n * Normally, this method emits the current `segment`; however, if the current\n * segment and the previous segment have the same marks, it instead emits an\n * empty array indicating not to add the current segment. Instead, it merges the\n * current segment text into the text of the previous segment.\n *\n * Enforce Rule 4 (part 3)\n *\n * \"Inline nodes cannot be the first or last child of a parent block, nor can it\n * be next to another inline node in the children array.\"\n *\n * Mainly, it's enforcing the part about the fact that there must be a Text node\n * between two inline Element nodes.\n */\nexport function normalizeSegment(\n segment: Segment,\n /**\n * Let's be explicit that we are doing something unusual here in that we are\n * mutating the previous segment by naming it as such.\n */\n mutablePrevSegment?: Segment\n): Segment[] {\n const segmentIsText = SlateText.isText(segment)\n const prevSegmentIsText = SlateText.isText(mutablePrevSegment)\n\n /**\n * Rule 4 (part 3):\n *\n * If there is a previous segment and the previous segment and the current\n * segment are both inline elements, we want to insert a space between them\n * which this does.\n *\n * It stops checking for merging two texts with each other since if they are\n * two inline elements, it doesn't need to check for text anymore.\n */\n if (mutablePrevSegment && !prevSegmentIsText && !segmentIsText) {\n return [{ text: \"\" }, segment]\n }\n\n /**\n * If the current segment is an Inline Element, then we can't merge it so we\n * return it as is\n */\n if (!segmentIsText) return [segment]\n /**\n * If the previous segment is an Inline Element or it's node defined, then we\n * can't merge into it so we return it as is\n */\n if (mutablePrevSegment === undefined || !prevSegmentIsText) return [segment]\n\n /**\n * If the two Text segments have the same marks, then merge them\n */\n const marksEqual = areMarksEqual(mutablePrevSegment, segment)\n if (marksEqual) {\n mutablePrevSegment.text = [mutablePrevSegment.text, segment.text].join(\"\")\n return []\n }\n\n return [segment]\n}\n","import * as Slate from \"slate\"\n\nimport { AnchorElement } from \"~/src/anchor-plugin\"\n\nimport { Segment, Text } from \"../../../types\"\nimport { LineElement, Node } from \"../normalize-line/types\"\n\n/**\n * Is this a Text Node\n */\nexport function isText(segment: Node | undefined): segment is Text {\n return Slate.Text.isText(segment)\n}\n\n/**\n * Is this an Element Node\n *\n * In the context of our normalizers, passing `isElement` means that it is\n * a `LineElement` or `AnchorElement`\n *\n * TODO:\n *\n * We should also add the following in the future:\n *\n * - `ImageInlineElement`\n * - `AttachmentElement`\n */\nexport function isElement(\n segment: Node\n): segment is LineElement | AnchorElement {\n return Slate.Element.isElement(segment)\n}\n\n/**\n * Identify this as a plain, non-code Text space. This is fairly specific\n * because we only want to manipulate non-code Text spaces. If the Text is\n * `code` then we can apply our marks next to it.\n *\n * - Does the passed in `Text` node made up of only one or more spaces\n * - The `Text` node must not be `code`\n */\nexport function isPlainSpace(segment: Segment): boolean {\n return (\n Slate.Text.isText(segment) && !!segment.text.match(/^\\s+$/) && !segment.code\n )\n}\n","import { MarkKey } from \"../../../../types\"\n\nexport const MARK_KEY_TO_TOKEN = {\n bold: \"**\",\n italic: \"_\",\n // ins: \"++\",\n strike: \"~~\",\n /**\n * IMPORTANT!\n *\n * We noop `code` here.\n *\n * We accept the `code` mark so as not to throw an error if it is found. We do\n * this because we handle `code` text specially because of the way it needs to\n * be escaped.\n *\n * This is handled in the `serializeLine` code.\n */\n code: \"\",\n /**\n * Highlight is handled specially in `serializeLine` using <mark> tags.\n */\n highlight: \"\",\n} as Record<MarkKey, string>\n\n/**\n * Convert a single mark to a string.\n * Unknown marks (e.g., custom plugin marks like \"highlight\") are ignored\n * and return an empty string.\n */\nfunction convertMarkToSymbol(mark: MarkKey): string {\n if (mark in MARK_KEY_TO_TOKEN) return MARK_KEY_TO_TOKEN[mark]\n // Ignore unknown marks (custom plugin marks)\n return \"\"\n}\n\n/**\n * Convert an array of marks to a string\n */\nexport function convertMarksToSymbolsExceptCode(marks: MarkKey[]) {\n return marks.map(convertMarkToSymbol).join(\"\")\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { MarkKey, Segment, Text } from \"../../../../types\"\nimport { isPlainSpace, isText } from \"../is-utils\"\n\n/**\n * Gets all the marks in current `Text`\n */\nexport function getMarksFromText(text: Text): MarkKey[] {\n /**\n * disable esling to eat the `_` without throwing an error\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { text: _, ...marks } = text\n return Object.keys(marks) as MarkKey[]\n}\n\n/**\n * Gets all the marks from the current segment\n */\nexport function getMarksFromSegment(segment: Segment): MarkKey[] {\n if (SlateText.isText(segment)) {\n if (isPlainSpace(segment)) {\n throw new Error(\n `You probably didn't mean to do this. We should only be getting marks from segments that are not plain space segments.`\n )\n }\n return getMarksFromText(segment)\n } else if (segment.type === \"anchor\") {\n return getCommonAnchorMarks(segment.children as Segment[])\n } else {\n /**\n * TODO: Need to handle images still.\n */\n throw new Error(`Unhandled type ${segment.type}`)\n }\n}\n\nexport function getCommonAnchorMarks(segments: Segment[]): MarkKey[] {\n let commonMarks: MarkKey[] | undefined\n for (const segment of segments) {\n if (!isText(segment)) {\n /**\n * Use this to test for images in anchors\n *\n * [](http://jamstack.club)\n */\n if (segment.type === \"image-inline\") continue\n /**\n * TODO: This is not actually true. It can be an inline image which we\n * still need to add.\n */\n throw new Error(\n `Expected every segment in an anchor to be a Text segment`\n )\n }\n if (isPlainSpace(segment)) continue\n const currentMarks = getMarksFromText(segment)\n if (commonMarks === undefined) {\n commonMarks = currentMarks\n continue\n }\n commonMarks = commonMarks.filter((commonMark) =>\n currentMarks.includes(commonMark)\n )\n }\n if (commonMarks === undefined)\n throw new Error(\n `No text segments were found as children in this anchor which should not be possible`\n )\n return commonMarks\n}\n","import { MarkKey } from \"../../../../types\"\n\n/**\n * When adding back marks, this is the order in which we add them back.\n *\n * The order is determined by an educated guess about which marks are more\n * likely to be chaging inside other marks. For example, this is probably pretty\n * common:\n *\n * **This is x^2^**\n *\n * Having a superscript inside of a bold. But it's probably rare to have bold\n * switched on/off inside a superscript.\n */\nconst ORDERED_MARK_KEYS: MarkKey[] = [\n \"bold\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"code\",\n]\n\n/**\n * Sort Algorithm\n *\n * https://stackoverflow.com/a/44063445\n */\nexport function sortMarks(marks: MarkKey[]): MarkKey[] {\n return marks\n .slice()\n .sort((a, b) => ORDERED_MARK_KEYS.indexOf(a) - ORDERED_MARK_KEYS.indexOf(b))\n}\n","const ESCAPES = [\n \"\\\\\", // escape\n \"`\", // code\n \"*\", // bold/italic/hr\n \"_\", // bold/italic/hr\n \"[\", // link/list\n \"]\", // link/list\n \"(\", // link\n \")\", // link\n \"#\", // headings\n \"+\", // list\n \"-\", // hr/list\n \".\", // numbered list\n \"!\", // image\n \"|\", // table\n \"^\", // sup\n \"~\", // sub/strikethrough\n \"<\", // link/html\n \">\", // link/html\n /**\n * Includes all the characters in the list of Backslash escapes in the example\n * for GitHub Flavored Markdown.\n *\n * https://github.github.com/gfm/#backslash-escapes\n */\n \"{\",\n \"}\",\n \"=\",\n \":\",\n \";\",\n \"$\",\n \"%\",\n \"&\",\n \"?\",\n '\"',\n \"'\",\n \",\",\n \"\\\\\",\n \"/\",\n \"@\",\n]\n\nconst ESCAPES_REGEXP = new RegExp(\n `(${ESCAPES.map((symbol) => `\\\\${symbol}`).join(\"|\")})`,\n \"g\"\n)\n\n/**\n * Escape text that could have an ambiguous meaning in markdown\n */\nexport function escapeText(s: string) {\n return s.replace(ESCAPES_REGEXP, (s: string) => `\\\\${s}`)\n // .replace(/\\n/g, \"<br>\")\n}\n","import type { Image } from \"mdast\"\n\nimport { ImageData } from \"./index\"\n\n/**\n * As a fallback, we don't\n */\nexport function parseGenericImage(image: Image): ImageData {\n return {\n url: image.url,\n title: image.title || undefined,\n alt: image.alt || undefined,\n }\n}\n","type ParsedUrl = {\n origin: string\n hostname: string\n pathname: string\n searchParams: URLSearchParams\n hash: string\n}\n\n/**\n * NOTE: As per the URL spec:\n *\n * - searchParams part does not include the \"?\"\n * - hash part includes the \"#\"\n */\nconst URL_REGEX = /^(\\/[^?#]*)(?:\\?([^#]*))?(#.*)?$/\n\nexport function parseUrl(url: string): ParsedUrl {\n try {\n const urlData = new URL(url)\n return {\n origin: urlData.origin,\n hostname: urlData.hostname,\n pathname: urlData.pathname,\n searchParams: urlData.searchParams,\n hash: urlData.hash,\n }\n } catch {\n const matchdata = url.match(URL_REGEX)\n if (matchdata === null)\n throw new Error(`Invalid format should not happen: ${url}`)\n const [, pathname, searchParams, hash] = [...matchdata]\n return {\n origin: \"\",\n hostname: \"\",\n pathname: pathname || \"\",\n searchParams: new URLSearchParams(searchParams),\n hash: hash || \"\",\n }\n }\n}\n","/**\n * Takes a `string` in the form `640x480` (i.e. number x number) and return an\n * ImageSize object with `width` and `height`.\n */\nexport function parseSize(\n s: string | null\n): { width: number; height: number } | null {\n if (typeof s !== \"string\") return null\n const sizeMatch = s.match(/^(\\d+)x(\\d+)$/)\n if (sizeMatch === null) return null\n return {\n width: parseInt(sizeMatch[1]),\n height: parseInt(sizeMatch[2]),\n }\n}\n","import type { Image } from \"mdast\"\n\nimport { parseUrl } from \"../../../parseUrl\"\nimport { ImageData } from \"./index\"\nimport { parseSize } from \"./parse-utils\"\n\nexport function parsePortiveImage(image: Image): ImageData | undefined {\n // const url = new URL(image.url)\n const url = parseUrl(image.url)\n /**\n * Only parse portive URL if it is a portive recognized domain\n */\n if (!url.hostname.match(/[.]portive[.]com$/i)) return\n /**\n * Should have a size param as part of the query string\n */\n const sizeParam = url.searchParams.get(\"size\")\n if (sizeParam === null) return\n /**\n * And the query string should parse properly as an ImageSize\n */\n const size = parseSize(sizeParam)\n if (size === null) return\n /**\n * The Portive image URL should end in something like `--640x480.jpg` which\n * identifies its width/height.\n */\n const srcSizeMatch = url.pathname.match(/[-][-](\\d+)x(\\d+)[.][a-zA-Z]+$/)\n if (srcSizeMatch === null) return\n /**\n * Return the `ImageData`\n */\n return {\n url: `${url.origin}${url.pathname}`,\n title: image.title || undefined,\n alt: image.alt || undefined,\n width: size.width,\n height: size.height,\n srcWidth: parseInt(srcSizeMatch[1]),\n srcHeight: parseInt(srcSizeMatch[2]),\n }\n}\n","import type { Image } from \"mdast\"\n\nimport { parseUrl } from \"../../../parseUrl\"\nimport { ImageData } from \"./index\"\nimport { parseSize } from \"./parse-utils\"\n\n/**\n * UncommonMark images are just regular images with some additional encoding in\n * the URL hash which allows us to embed extra information without affecting the\n * image that is rendered nor does it affect the `title` or `alt` attributes.\n */\nexport function parseUncommonMarkImage(image: Image): ImageData | undefined {\n const url = parseUrl(image.url)\n /**\n * If there's no hash, it's not UncommonMark\n */\n if (url.hash.length === 0) return\n /**\n * We use `URLSearchParams` to decode the size data after the `#` because it's\n * free (embedded in every browser without more code) and available (including\n * Node)!\n */\n const params = new URLSearchParams(url.hash.slice(1))\n const size = parseSize(params.get(\"size\"))\n const srcSize = parseSize(params.get(\"srcSize\"))\n if (!size || !srcSize) return\n /**\n * If we successfully parsed all the ImageSize info, then return the\n * `ImageData`\n */\n return {\n url: `${url.origin}${url.pathname}`,\n title: image.title || undefined,\n alt: image.alt || undefined,\n width: size.width,\n height: size.height,\n srcWidth: srcSize.width,\n srcHeight: srcSize.height,\n }\n}\n","import { parseGenericImage } from \"./parse-generic-image\"\nimport { parsePortiveImage } from \"./parse-portive-image\"\nimport { parseUncommonMarkImage } from \"./parse-uncommon-mark-image\"\n\nexport const imageParsers = [\n parsePortiveImage,\n parseUncommonMarkImage,\n parseGenericImage,\n]\n","import type { Image } from \"mdast\"\n\nimport { ImageSharedElement } from \"~/src/image-plugin/types\"\n\nimport { Segment } from \"../../../types\"\nimport { imageParsers } from \"./image-parsers\"\n\nexport type ImageData = Omit<ImageSharedElement, \"children\">\n\n/**\n * Iterate through all the image parsers utnil we find one that returns\n * `ImageData`. Combine that `ImageData` with the `type` and `children` and\n * return it as the `ImageInlineElement`\n */\nexport function parseInlineImage(image: Image): Segment[] {\n for (const imageParser of imageParsers) {\n const imageData = imageParser(image)\n if (!imageData) continue\n return [\n {\n type: \"image-inline\",\n ...imageData,\n children: [{ text: \"\" }],\n },\n ]\n }\n throw new Error(`Shouldn't get here because last parser always returns data`)\n}\n","import type { PhrasingContent } from \"mdast\"\n\nimport { MarkProps, Segment } from \"../../types\"\nimport { assertUnreachable } from \"../../utils\"\nimport { normalizeSegments } from \"./normalize-segments\"\nimport { parseInlineImage } from \"./parse-inline-image\"\nimport { Descendant } from \"slate\"\n\nexport function parsePhrasingContents(\n phrasingContents: PhrasingContent[],\n marks: MarkProps = {}\n): Segment[] {\n const segments: Segment[] = []\n for (const phrasingContent of phrasingContents) {\n segments.push(...parsePhrasingContent(phrasingContent, marks))\n }\n const nextInlines = normalizeSegments(segments)\n return nextInlines\n}\n\nfunction parsePhrasingContent(\n phrasingContent: PhrasingContent,\n marks: MarkProps = {}\n): Segment[] {\n switch (phrasingContent.type) {\n case \"delete\":\n return parsePhrasingContents(phrasingContent.children, {\n ...marks,\n strike: true,\n })\n case \"emphasis\":\n return parsePhrasingContents(phrasingContent.children, {\n ...marks,\n italic: true,\n })\n case \"footnoteReference\":\n return [{ text: `[${phrasingContent.identifier}]` }]\n case \"html\": {\n // Check for <mark>...</mark> pattern for highlight support\n const markMatch = phrasingContent.value.match(/^<mark>(.*)<\\/mark>$/s)\n if (markMatch) {\n return [{ text: markMatch[1], ...marks, highlight: true }]\n }\n return [{ text: phrasingContent.value, code: true }]\n }\n case \"image\":\n return parseInlineImage(phrasingContent)\n case \"inlineCode\": {\n return [{ text: phrasingContent.value, ...marks, code: true }]\n }\n case \"link\":\n return [\n {\n type: \"anchor\",\n href: phrasingContent.url,\n title:\n /**\n * Ensure that `title` is undefined if it's null.\n */\n phrasingContent.title == null ? undefined : phrasingContent.title,\n children: parsePhrasingContents(phrasingContent.children, marks) as Descendant[],\n },\n ]\n case \"strong\":\n return parsePhrasingContents(phrasingContent.children, {\n ...marks,\n bold: true,\n })\n case \"text\":\n return [{ text: phrasingContent.value, ...marks }]\n case \"linkReference\":\n case \"imageReference\":\n throw new Error(\n `linkReference and imageReference should be converted to link and image through our transformInlineLinks function`\n )\n case \"break\":\n /**\n * NOTE:\n *\n * I don't think this is doing anything at the moment as a \"\\n\" is being\n * read without being turned into a break. We can test this by doing a\n * console.log before the return below.\n */\n return [{ text: \"\\n\" }]\n case \"footnote\":\n /**\n * TODO: Support footnotes\n *\n * This is a footnote, and should be converte to a suitable alternative or\n * for us to explicitly support a Footnote type in the future. At the\n * moment, we don't explicitly support a footnote as it's (a) not part of\n * GFM and (b) not really that useful while (c) adding complexity to the\n * UI for something that's not used.\n */\n throw new Error(\"footnote is not supported yet\")\n }\n assertUnreachable(phrasingContent)\n}\n","import type { Heading } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { parsePhrasingContents } from \"./parse-phrasing-content/parse-phrasing-content\"\n\nexport function parseHeading(content: Heading): Element[] {\n return [\n {\n type: \"heading\",\n level: content.depth,\n children: parsePhrasingContents(content.children),\n },\n ]\n}\n","import type { HTML } from \"mdast\"\n\nimport { Element } from \"../types\"\n\nexport function parseHTML(content: HTML): Element[] {\n return [\n {\n type: \"html-block\",\n html: content.value,\n children: [{ text: \"\" }],\n },\n ]\n}\n","import type { ListItem } from \"mdast\"\n\nimport { Element } from \"../../types\"\nimport { parseContent } from \"../parse-content\"\nimport { parsePhrasingContents } from \"../parse-phrasing-content/parse-phrasing-content\"\nimport { parseList } from \"./parse-list\"\n\nexport function parseListItemChild(\n child: ListItem[\"children\"][number],\n {\n depth,\n ordered,\n checked,\n }: { depth: number; ordered: boolean; checked: boolean | null | undefined }\n): Element[] {\n switch (child.type) {\n case \"paragraph\":\n if (checked === true || checked === false) {\n return [\n {\n type: \"task-list-item\",\n depth,\n checked,\n children: parsePhrasingContents(child.children),\n },\n ]\n } else if (ordered) {\n return [\n {\n type: \"ordered-list-item\",\n depth,\n children: parsePhrasingContents(child.children),\n },\n ]\n } else {\n return [\n {\n type: \"unordered-list-item\",\n depth,\n children: parsePhrasingContents(child.children),\n },\n ]\n }\n case \"list\":\n return parseList(child, depth + 1)\n default:\n /**\n * NOTE:\n *\n * We break out of a list when the children of a list item are not more\n * lists/list items.\n *\n * This is one area where we don't strictly adhere to the Markdown\n * specification and it is intentional because adhering strictly to the\n * Markdown specification would create a harmful user experience.\n *\n * It appears that Markdown allows nesting other block types in lists\n * other than list items. For example, one can place a table, block\n * quote, heading or something else in a list item.\n *\n * There are a few problems with this from a user perspective:\n *\n * - It's unexpected. No other editors provide such a feature.\n * - If we were to adopt this as a feature, the user experience would be\n * terrible, namely because it would be unpredictable what commands do\n * toggle headings or list items should do if they were nested.\n *\n */\n return parseContent(child)\n }\n}\n","import type { ListItem } from \"mdast\"\n\nimport { Element } from \"../../types\"\nimport { parseListItemChild } from \"./parse-list-item-child\"\n\nexport function parseListItem(\n listItem: ListItem,\n options: { depth: number; ordered: boolean }\n): Element[] {\n const elements: Element[] = []\n for (const child of listItem.children) {\n elements.push(\n ...parseListItemChild(child, { ...options, checked: listItem.checked })\n )\n }\n return elements\n}\n","import type { List } from \"mdast\"\n\nimport { Element } from \"../../types\"\nimport { parseListItem } from \"./parse-list-item\"\n\nexport function parseList(list: List, depth = 0): Element[] {\n // console.log(JSON.stringify(list, null, 2))\n const elements: Element[] = []\n for (const listItem of list.children) {\n elements.push(\n ...parseListItem(listItem, { depth, ordered: !!list.ordered })\n )\n }\n return elements\n}\n","import type { Paragraph } from \"mdast\"\n\nimport { ImageBlockElement, ImageInlineElement } from \"~/src/image-plugin/types\"\n\nimport { Element, Segment } from \"../types\"\nimport { parsePhrasingContents } from \"./parse-phrasing-content/parse-phrasing-content\"\n\nfunction isImageBlock(segments: Segment[]): boolean {\n if (segments.length !== 3) return false\n if (!(\"text\" in segments[0]) || segments[0].text !== \"\") return false\n if (!(\"text\" in segments[2]) || segments[2].text !== \"\") return false\n if (!(\"type\" in segments[1]) || segments[1].type !== \"image-inline\")\n return false\n return true\n}\n\nconst NBSP = \"\\u00A0\"\n\nfunction isSingleNBSP(segments: Segment[]): boolean {\n if (segments.length !== 1) return false\n if (!(\"text\" in segments[0]) || segments[0].text !== NBSP) return false\n return true\n}\n\n/**\n * Parses to a Paragraph or an ImageBlock element.\n *\n * We need to do it this way because an ImageBlock is a Paragraph that happens\n * to have exactly one ImageInline child.\n */\nexport function parseParagraph(content: Paragraph): Element[] {\n const segments = parsePhrasingContents(content.children)\n if (isImageBlock(segments)) {\n const imageSegment = segments[1] as ImageInlineElement\n const imageBlockElement: ImageBlockElement = {\n ...imageSegment,\n type: \"image-block\",\n }\n return [imageBlockElement]\n }\n if (isSingleNBSP(segments)) {\n return [\n {\n type: \"paragraph\",\n children: [{ text: \"\" }],\n },\n ]\n }\n\n return [\n {\n type: \"paragraph\",\n children: segments,\n },\n ]\n}\n","import type { Table, TableCell, TableRow } from \"mdast\"\n\nimport {\n TableCellElement,\n TableElement,\n TableRowElement,\n} from \"~/src/table-plugin\"\n\nimport { parsePhrasingContents } from \"./parse-phrasing-content/parse-phrasing-content\"\n\nexport function parseTable(table: Table): [TableElement] {\n if (table.align == null)\n throw new Error(`Expected an array of AlignType for table.align`)\n return [\n {\n type: \"table\",\n columns: table.align.map((align) => ({\n align: align || \"left\",\n })),\n children: table.children.map(parseTableRow),\n },\n ]\n}\n\nfunction parseTableRow(row: TableRow): TableRowElement {\n if (row.type !== \"tableRow\") throw new Error(`Expected a tableRow`)\n return { type: \"table-row\", children: row.children.map(parseTableCell) }\n}\n\nfunction parseTableCell(cell: TableCell): TableCellElement {\n if (cell.type !== \"tableCell\") throw new Error(`Expected a tableCell`)\n return {\n type: \"table-cell\",\n children: [\n {\n type: \"table-content\",\n children: parsePhrasingContents(cell.children),\n },\n ],\n }\n}\n","import { Element } from \"../types\"\n\nexport function parseThematicBreak(): Element[] {\n return [\n {\n type: \"horizontal-rule\",\n children: [{ text: \"\" }],\n },\n ]\n}\n","import type { TopLevelContent } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { assertUnreachable } from \"../utils\"\nimport { parseBlockquote } from \"./parse-blockquote\"\nimport { parseCodeBlock } from \"./parse-code-block\"\nimport { parseFootnoteDefinition } from \"./parse-footnote-definition\"\nimport { parseHeading } from \"./parse-heading\"\nimport { parseHTML } from \"./parse-html\"\nimport { parseList } from \"./parse-list\"\nimport { parseParagraph } from \"./parse-paragraph\"\nimport { parseTable } from \"./parse-table\"\nimport { parseThematicBreak } from \"./parse-thematic-break\"\n\nexport function parseContents(contents: TopLevelContent[]): Element[] {\n const elements: Element[] = []\n for (const content of contents) {\n elements.push(...parseContent(content))\n }\n return elements\n}\n\nexport function parseContent(content: TopLevelContent): Element[] {\n switch (content.type) {\n case \"blockquote\":\n return parseBlockquote(content)\n case \"code\":\n return parseCodeBlock(content)\n case \"definition\":\n /**\n * A `definition` is used by a `linkRef` or `imageRef`; however, we inline\n * these with our `./remark-inline-links`\n */\n throw new Error(`The type \"definition\" should not exist. See comments`)\n case \"footnoteDefinition\":\n return parseFootnoteDefinition(content)\n case \"heading\":\n return parseHeading(content)\n case \"html\":\n return parseHTML(content)\n case \"list\":\n return parseList(content)\n case \"paragraph\":\n /**\n * Returns a `paragraph` or an `image-block` Element.\n */\n return parseParagraph(content)\n case \"table\":\n return parseTable(content)\n case \"thematicBreak\":\n return parseThematicBreak()\n case \"yaml\":\n /**\n * YAML FrontMatter is not used in Wysimark.\n */\n return []\n }\n assertUnreachable(content)\n}\n","import type { Content, Image, Link, Parent, Root } from \"mdast\"\nimport { definitions } from \"mdast-util-definitions\"\nimport type { Node } from \"unist\"\nimport { SKIP, visit } from \"unist-util-visit\"\n\n/**\n * Based on the code from `remark-inline-links` but rewritten here because, for\n * reasons unknown to me, the plugin doesn't seem to execute at all despite not\n * throwing an error. Looks like the function that `remarkInlineLinks` returns\n * is never executed. Not sure if this is due to a change in `unified` but I\n * can't seem to find any mention anywhere of this no longer working including\n * in discussion or issues and the list of plugins show that\n * `remark-inline-links` is currently working and compatible with the lateste\n * version.\n *\n * Never-the-less, pulling it out and working on the ast directly (this function\n * modifies the AST in place) seems to work.\n *\n * https://github.com/remarkjs/remark-inline-links\n */\nexport function transformInlineLinks(tree: Root): void {\n const definition = definitions(tree)\n\n visit<Node>(tree as Node, (n, index, p) => {\n const node = n as unknown as Content\n const parent = p as unknown as Parent | null\n if (\n node.type === \"definition\" &&\n parent !== null &&\n typeof index === \"number\"\n ) {\n parent.children.splice(index, 1)\n return [SKIP, index]\n }\n\n if (node.type === \"imageReference\" || node.type === \"linkReference\") {\n const identifier =\n \"identifier\" in node && typeof node.identifier === \"string\"\n ? node.identifier\n : \"\"\n const def = definition(identifier)\n\n if (def && parent !== null && typeof index === \"number\") {\n const replacement: Image | Link =\n node.type === \"imageReference\"\n ? { type: \"image\", url: def.url, title: def.title, alt: node.alt }\n : {\n type: \"link\",\n url: def.url,\n title: def.title,\n children: node.children,\n }\n\n parent.children[index] = replacement\n return [SKIP, index]\n }\n }\n })\n}\n","import { ListItemElement } from \"~/src/list-plugin/types\"\n\nimport { Element } from \"../../types\"\n\n/**\n * Provides a type guard for `ListItemElement`.\n */\nfunction isListItemElement(element: Element): element is ListItemElement {\n return (\n element.type === \"ordered-list-item\" ||\n element.type === \"unordered-list-item\" ||\n element.type === \"task-list-item\"\n )\n}\n\nexport function normalizeElementListDepths(elements: Element[]) {\n const normalizedElements: Element[] = []\n\n /**\n * previousDepth of -1 indicates that the previous element was not a list\n * item.\n */\n let previousDepth = -1\n\n for (const element of elements) {\n /**\n * If it's not a list item, just reset previousDepth and add the element\n * to `normalizedElements`.\n */\n if (!isListItemElement(element)) {\n normalizedElements.push(element)\n previousDepth = -1\n continue\n }\n\n /**\n * If it is a list item, we need to make sure the depth never increases by\n * more than 1. This is important because if we skip the first depth (i.e.\n * we start at depth of 2) then we get the first list indented which makes\n * Markdown think it's a code block. After the first list item, we don't\n * want to indent by more than one depth level because Markdown will assume\n * that's still a single depth level. When we outdent a level, Markdown\n * could get confused.\n *\n * WARNING:\n *\n * This does create a situation where the list in Wysimark is not saved and\n * loaded to return the same document; however, the alternative is that we\n * prevent the editor from creating a list which skips a depth. This could\n * be perceived as broken UI by the user. This appraoch feels less obtrusive\n * to the user.\n */\n const nextDepth =\n element.depth > previousDepth + 1 ? previousDepth + 1 : element.depth\n normalizedElements.push({ ...element, depth: nextDepth })\n previousDepth = nextDepth\n }\n\n return normalizedElements\n}\n","import { CodeBlockLineElement } from \"~/src/code-block-plugin\"\n\n/**\n * Serializing a code line is simple under the assumption that the normalizers\n * in Wysimark are working correctly. Technically, a code-line should have\n * exactly one child with one `Text` node with no marks in it.\n */\nexport function serializeCodeLine(codeLine: CodeBlockLineElement): string {\n /**\n * As a safety measure, we make sure that we are receiving a `codeLine`\n */\n if (codeLine.type !== \"code-block-line\")\n throw new Error(\n `Expected all children of code-block to be a codeline but is ${JSON.stringify(\n codeLine,\n null,\n 2\n )}`\n )\n /**\n * We are converting all segments under the assumption that they are text\n * segments.\n */\n return codeLine.children.map((segment) => segment.text).join(\"\")\n}\n","import { CodeBlockElement } from \"~/src/code-block-plugin\"\n\nimport { serializeCodeLine } from \"./serialize-code-line\"\n\n/**\n * Serializing a code block is usually three backticks folloed by the language,\n * then the code is raw verbatim and then three backticks to close.\n *\n * However, we have to account for if any line in the code starts with three\n * backticks. In that case, we need to start our code block with 4 backticks.\n * And if there are 4 backticks in the code, then we need to start it with 5.\n *\n * We always need to start our code block with one more backtick than can be\n * found starting any line in the code block.\n */\nexport function serializeCodeBlock(codeBlock: CodeBlockElement): string {\n const lines: string[] = []\n /**\n * Start with the default number of backticks\n */\n let backticks = 3\n for (const codeLine of codeBlock.children) {\n /**\n * Grab a raw code line from it\n */\n const lineOfCode = serializeCodeLine(codeLine)\n /**\n * Check if it starts with any backticks and if it does, make our backticks\n * one larger than the largest one.\n */\n const match = lineOfCode.match(/^([`]+)/)\n if (match) backticks = Math.max(backticks, match[1].length + 1)\n /**\n * Add it to our lines\n */\n lines.push(lineOfCode)\n }\n /**\n * At the very end, when we know how many backticks we need, add our backticks\n * and language at the start and the closing backticks at the end.\n */\n lines.unshift(`${\"`\".repeat(backticks)}${codeBlock.language}`)\n lines.push(`${\"`\".repeat(backticks)}`)\n return `${lines.join(\"\\n\")}\\n\\n`\n}\n","import { ImageSharedElement } from \"~/src/image-plugin/types\"\n\n/**\n * As a fallback, if there is no width/height or srcWidth/srcHeight info then\n * just save the image url and do not save with uncommonMark hints.\n */\nexport function serializeGenericImageUrl(image: ImageSharedElement): string {\n return image.url\n}\n","import { ImageSharedElement } from \"~/src/image-plugin/types\"\n\nimport { parseUrl } from \"../../parseUrl\"\n\n/**\n * When an image is in the `.portive.com` subdomain like `files.portive.com` or\n * `staging.files.portive.com` and if the image has a `width` and `height` then\n * we encode the `width` and `height in the `url` as part of the query string.\n *\n * https://files.portive.com/f/abcdef--640x480.jpg?size=320x240\n *\n * Indicates a src image of 640x480 that will be resized and sent to the browser\n * at 320x240\n *\n * This does these things:\n *\n * - When parsing the image URL, we are able to pull the width/height out of the\n * URL and use it to populate those values in the editor.\n *\n * - The query string will also physically resize the image before delivering it\n * from Portive. This means that in regular Markdown that doesn't have any\n * special understanding of Portive's special querystring encodings, the image\n * is still returned in the correct size.\n */\nexport function serializePortiveImageUrl(\n image: ImageSharedElement\n): string | undefined {\n if (image.url.startsWith(\"$\")) return \"\"\n const { hostname } = parseUrl(image.url)\n /**\n * Only parse portive URL if it is a portive recognized domain\n */\n if (hostname.match(/[.]portive[.]com$/i) && image.width && image.height)\n return `${image.url}?size=${image.width}x${image.height}`\n}\n","import { ImageSharedElement } from \"~/src/image-plugin/types\"\n\n/**\n * In UncommonMark, we provide hints after the hash `#` portion of the URL that\n * does not affect the URL of the image being delivered. It is usually used to\n * tell the browser to scroll to the given section in a linked document.\n *\n * https://imageservice.com/abcdefg.jpg#srcSize=1024x768&size=640x480\n */\nexport function serializeUncommonmarkImageUrl(\n image: ImageSharedElement\n): string | undefined {\n if (image.width && image.height && image.srcWidth && image.srcHeight)\n return `${image.url}#srcSize=${image.srcWidth}x${image.srcHeight}&size=${image.width}x${image.height}`\n}\n","import { ImageSharedElement } from \"~/src/image-plugin/types\"\n\nimport { serializeGenericImageUrl } from \"./serialize-generic-image-url\"\nimport { serializePortiveImageUrl } from \"./serialize-portive-image-url\"\nimport { serializeUncommonmarkImageUrl } from \"./serialize-uncommonmark-image-url\"\n\nconst urlSerializers = [\n serializePortiveImageUrl,\n serializeUncommonmarkImageUrl,\n serializeGenericImageUrl,\n]\n\nexport function serializeImageShared(image: ImageSharedElement): string {\n for (const urlSerializer of urlSerializers) {\n const url = urlSerializer(image)\n if (typeof url === \"string\") {\n /**\n * Sometimes the serialized URL will return \"\" which means that the URL\n * hasn't returned yet. When this happens, we don't want the markdown for\n * the image to be added to the final value because the image would be\n * invalid. This happens when the image is uploading.\n */\n if (url === \"\") return \"\"\n return ``\n }\n }\n /**\n * Shouldn't get here because the last url seializer `serializeGenericUrl`\n * always returns a value.\n */\n throw new Error(`Shouldn't get here`)\n}\n","import { ImageBlockElement } from \"~/src/image-plugin/types\"\n\nimport { serializeImageShared } from \"../serialize-image-shared\"\n\n/**\n * Serialize an image block element to markdown.\n *\n * Block-level images require trailing newlines (\\n\\n) to properly separate\n * them from subsequent content. Without these newlines, content immediately\n * following an image (like headings) would be parsed as part of the same\n * paragraph, breaking the markdown structure.\n *\n * Example:\n * Correct: \\n\\n# Heading\n * Incorrect: # Heading <- heading becomes plain text\n */\nexport function serializeImageBlock(element: ImageBlockElement): string {\n const imageMarkdown = serializeImageShared(element)\n return imageMarkdown ? `${imageMarkdown}\\n\\n` : \"\"\n}\n","import { Element as SlateElement, Text as SlateText } from \"slate\"\n\nimport { MarkKey, Segment } from \"../../types\"\nimport { diffMarks } from \"./diff-marks\"\nimport { normalizeLine } from \"./normalize-line\"\nimport { serializeSegment } from \"./segment/serialize-segment\"\nimport {\n convertMarksToSymbolsExceptCode,\n getMarksFromSegment,\n isPlainSpace,\n} from \"./utils\"\n\n/**\n * Takes a line (an array of Segment) and turns it into markdown.\n *\n * The majority of this code deals with how we convert marks like `bold` and\n * `italic` into symbols and where to place them. There are several complicated\n * cases we need to handle like:\n *\n * - Symbols must always be placed on the inside of spaces next to the word like\n * \" **bold** \" and not \"** bold **\". We need to be aware of our placement of\n * symbols around spaces but spaces themselves can safely and actually must\n * ignore the actual marks on them. A bold space and a not-bold space are\n * considered the same in Markdown.\n * - Anchors must have common marks moved out of them\n * - Anchors must have not common marks set inside of them\n */\nexport function serializeLine(\n inputSegments: Segment[],\n leadingMarks: MarkKey[] = [],\n trailingMarks: MarkKey[] = []\n): string {\n /**\n * Normalize line does a lot of the work here to take any spaces that can be\n * found around the edges of segments and turns them into their own segments.\n * We don't need to do this in spaces on the inside of segments though.\n *\n * This is important because at the boundaries of segments, that's when marks\n * change (e.g. bold/italic) and it is at these points, we need to put spaces\n * into separate segments so that we can place the symbols for the marks\n * around them.\n */\n const segments = normalizeLine(inputSegments)\n const substrings: string[] = []\n\n /**\n * In order to seed the loop, we start by creating a `leadingDiff` going from\n * the `leadingMarks` provided to this method and the marks in the first\n * segment.\n *\n * The `leadingMarks` will always be `[]` at the beginning. When we get into a\n * nested `anchor` though, there may be some marks that had been previously\n * set outside of the anchor that need to be considered.\n */\n let leadingDiff = diffMarks(leadingMarks, getMarksFromSegment(segments[0]))\n\n /**\n * In each iteration, we want to serialize the following:\n *\n * - Symbols that represent all the marks to add to this segment\n * - The markdown for the segment itself (text, inline code, anchor, inline\n * image)\n * - Symbols that represent all the marks to remove from this segment\n */\n for (let i = 0; i < segments.length; i++) {\n /**\n * This is the current segment that we are looking at.\n */\n const segment = segments[i]\n\n /**\n * If it's plain space, add it to markdown and start at the top of the loop\n * again\n *\n * Basically, ignore the symbols we need to add when it's a space.\n *\n * The symbols get handled by the non-space segments.\n *\n * When we continue, we end up with the same `leadingDiff` from the last\n * segment which is what we want. This is because the `leadingDiff` actually\n * applies to the next Segment which should be either a not space Text or an\n * Element.\n */\n if (SlateText.isText(segment) && isPlainSpace(segment)) {\n substrings.push(segment.text)\n continue\n }\n\n /**\n * Here is where we add the serialization of the segment.\n *\n * First we start by adding the symbols needed to add the marks to this\n * segment.\n */\n substrings.push(convertMarksToSymbolsExceptCode(leadingDiff.add))\n\n /**\n * Check if highlight mark is being added - if so, output <mark> tag\n */\n const hasHighlightOpen = leadingDiff.add.includes(\"highlight\" as MarkKey)\n if (hasHighlightOpen) {\n substrings.push(\"<mark>\")\n }\n\n /**\n * Then we add the Text or the Anchor for the segment\n */\n substrings.push(serializeSegment(segment))\n\n /**\n * Now we are searching for the next segment which we want to grab the marks\n * from. Basically, any segment that isn't a space. For clarity, in this\n * algorithm, we should never have two `isPlainSpace` segments in a row\n * because this would have been normalized to one `isPlainSpace` segment in\n * the call to `normalizeLine`\n */\n const nextMarks = getNextMarks(segments, i, trailingMarks)\n const trailingDiff = diffMarks(leadingDiff.nextOrderedMarks, nextMarks)\n\n /**\n * Check if highlight mark is being removed - if so, output </mark> tag\n */\n const hasHighlightClose = trailingDiff.remove.includes(\"highlight\" as MarkKey)\n if (hasHighlightClose) {\n substrings.push(\"</mark>\")\n }\n\n substrings.push(convertMarksToSymbolsExceptCode(trailingDiff.remove))\n\n /**\n * The `trailingDiff` becomes the new `leadingDiff`\n */\n leadingDiff = trailingDiff\n }\n return substrings.join(\"\")\n}\n\n/**\n * Looks for the next set of valid marks by\n *\n * This method is local to `serialize-line` as it's intimiately tied with the\n * call to `getNextMarks` in `serializeLine`\n */\nfunction getNextMarks(\n segments: Segment[],\n index: number,\n trailingMarks: MarkKey[]\n): MarkKey[] {\n /**\n * Starting at the index `i` following the current index `index`\n *\n * If it's a plain space, skip it.\n *\n * If it isn't, get the marks for the segment.\n *\n * NOTE:\n *\n * If the segment is an `anchor` we the common marks for all the segments in\n * the anchor not including the plain spaces.\n */\n for (let i = index + 1; i < segments.length; i++) {\n const segment = segments[i]\n if (isPlainSpace(segment)) continue\n if (SlateElement.isElement(segment)) {\n const element = segment as { type?: string }\n if (element.type === \"image-inline\") continue\n }\n return getMarksFromSegment(segment)\n }\n return trailingMarks\n}\n","import { MarkKey } from \"../../../types\"\nimport { sortMarks } from \"../utils\"\n\n/**\n * Find the marks to add in ordere to get our orderedMarks to match the\n * `targetMarks`.\n *\n * We do this in a smart, but perhaps, imperfect way.\n *\n * When we need to add marks, we add them in an order that is more likely to\n * reduce the number of marks we add. See the comments under `MARK_KEY_ORDER` to\n * find out how.\n *\n * That said, we could probably choose a more complex algorithm that looks at\n * all the text to find out how to most efficiently place which marks as outer\n * or inner marks; however, there will still be situations in which the choice\n * will be arbitrary and this would likely greatly increase the complexity of\n * the code.\n *\n * This feels like a good trade-off and is likely to cause an unreadable\n * markdown representation. I suppose if for some reason a user had a bunch of\n * superscripted text which was intermittently styled with bold and italic, then\n * we'd have less than ideal markdown.\n */\nexport function findMarksToAdd(\n orderedMarks: MarkKey[],\n targetMarks: MarkKey[]\n) {\n const marksWeNeedToAdd = targetMarks.filter(\n (mark) => !orderedMarks.includes(mark)\n )\n const orderedMarksToAdd = sortMarks(marksWeNeedToAdd)\n return { orderedMarksToAdd }\n}\n","import { MarkKey } from \"../../../types\"\n\n/**\n * Takes a list of our current `orderedMarks` (i.e. what marks have been applied\n * to our text and in which order) and then gives us a list of `targetMarks`\n * which, for clarity, the order doesn't matter.\n *\n * We then create a list of `orderedMarksToRemove` which is a list of marks we\n * need to remove in the correct order, in order to satisfy that there aren't\n * any marks left that aren't also in the `targetMarks`.\n */\nexport function findMarksToRemove(\n orderedMarks: MarkKey[],\n targetMarks: MarkKey[]\n): { orderedMarksToRemove: MarkKey[]; nextOrderedMarks: MarkKey[] } {\n /**\n * As a good practice, don't manipulate the incoming argument (even though\n * technically it doesn't matter here)\n */\n const nextOrderedMarks = [...orderedMarks]\n\n /**\n * Find the marks that we need to remove.\n */\n const marksWeNeedToRemove = orderedMarks.filter(\n (mark) => !targetMarks.includes(mark)\n )\n\n /**\n * An ordered array of marks to remove\n */\n const orderedMarksToRemove: MarkKey[] = []\n\n /**\n * We iterate a maximum number of times with an upper limit of\n * `nextOrderedMarks.length` to prevent infinite loops.\n *\n * If we meet our condition of removing all the `marksWeNeedToRemove` we are\n * going to break out of this loop early which is common. Used a for loop\n * instead of counting the number of loops and throwing an error.\n */\n for (let i = 0; i < orderedMarks.length; i++) {\n /**\n * If we don't have any more marks we need to remove, we are done so leave\n * the loop.\n */\n if (marksWeNeedToRemove.length === 0) break\n /**\n * Remove the last mark\n */\n const markToRemove = nextOrderedMarks.pop()\n if (markToRemove === undefined) {\n throw new Error(\n `This shouldn't happen unless we made a mistake in the algorithm`\n )\n }\n /**\n * Add to our `orderedMarkToRemove` which is done in the correct order\n * because we are popping them off from the right.\n */\n orderedMarksToRemove.push(markToRemove)\n\n /**\n * Whatever we added to our list of `orderedMarksToRemove` we can now take\n * off our list of `marksWeNeedToRemove`. Sometimes we will be removed marks\n * that don't take anything off our list of `marksWeNeedToRemove` because of\n * the order in which we need to remove marks.\n *\n * For this reason, the check to see if the `mark` was in our list of\n * `marksWeNeedToRemove` is important.\n */\n const index = marksWeNeedToRemove.indexOf(markToRemove)\n if (index !== -1) {\n marksWeNeedToRemove.splice(index, 1)\n }\n }\n\n return { orderedMarksToRemove, nextOrderedMarks }\n}\n","import { MarkKey } from \"../../../types\"\nimport { findMarksToAdd } from \"./find-marks-to-add\"\nimport { findMarksToRemove } from \"./find-marks-to-remove\"\n\n/**\n * Takes a set of incoming marks and a set of target markets and returns what\n * marks need to be removed including the order in which they need to be removed\n * and what marks need to be added including the order in which they needed to\n * be added.\n *\n * The algorithm, collectively, is a little complex because we must always\n * remove an inner set of mark symbols before we can remove an outer set. This\n * means that sometimes when we want to remove a mark, we end up actually having\n * to add one. Like in this scenario:\n *\n * **_bold italic_** _italic_\n *\n * In order to go from bold and italic to just italic, we need to first remove\n * the inner italic, then remove the outer bold, and because the italic was\n * removed we need to add back the italic.\n *\n * Note that the algorithm is asymmetrical. It's just the way it has to be.\n */\nexport function diffMarks(orderedMarks: MarkKey[], targetMarks: MarkKey[]) {\n /**\n * First we remove the marks in order to arrive at our target marks.\n *\n * The algorithm basically just takes off the inner-most (right-most) marks\n * and adds them to `marsToRemove` until we don't have any marks that aren't\n * also in the `targetMarks`.\n *\n * Because we may be over-removing the marks, the method returns a\n * `nextOrderedMarks` or basically the `orderedMarks` after the remove has\n * happened. We then use this as the basis to add any marks we need back to\n * arrive at our `targetMarks`.\n */\n const { orderedMarksToRemove, nextOrderedMarks } = findMarksToRemove(\n orderedMarks,\n targetMarks\n )\n /**\n * We call out to a method that adds the necessary marks back in. The\n * algorithm here is pretty straightforward. Just add back the marks we need\n * and to achieve some level of consistency, add them back in a specific order\n * that feels nice and makes sense. For example, superscript/subscript is more\n * nested than bold because they are more likely to be toggled.\n */\n const { orderedMarksToAdd } = findMarksToAdd(nextOrderedMarks, targetMarks)\n return {\n remove: orderedMarksToRemove,\n add: orderedMarksToAdd,\n nextOrderedMarks: [...nextOrderedMarks, ...orderedMarksToAdd],\n }\n}\n","import { Element } from \"slate\"\n\nimport { Segment } from \"../../../types\"\nimport { normalizeNodes } from \"./normalize-nodes\"\nimport { LineElement } from \"./types\"\n\n/**\n * A very focused duplicate function that only duplicates the `children` of\n * `anchor` elements.\n *\n * It's designed this way to be fast and to avoid duplicating the entire tree\n * as only anchors have children that will be manipulated.\n */\nconst duplicateSegments = (segments: Segment[]): Segment[] => {\n return segments.map((segment) => {\n if (Element.isElement(segment) && segment.type === \"anchor\") {\n return {\n ...segment,\n children: duplicateSegments(segment.children as Segment[]),\n }\n } else {\n return segment\n }\n })\n}\n\n/**\n * Entry Point for normalizing\n */\nexport function normalizeLine(segments: Segment[]) {\n /**\n * We need to duplicate `segments` because `normalizeNodes` will manipulate the\n * array but the original array coming from Slate will be readOnly.\n */\n const line: LineElement = {\n type: \"line\",\n children: duplicateSegments(segments),\n }\n normalizeNodes([line], undefined)\n return line.children\n}\n","import { isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\n/**\n * If we ever find two spaces next to each other, merge them together.\n *\n * This can happen, for example, if there were spaces next to each other but\n * with different marks. It can also happen from other normalizers. For example,\n * there is a normalizer that moves spaces at the outer edges of an anchor\n * outside of the anchor.\n */\nexport function mergeAdjacentSpaces({\n node,\n nextNode,\n nodes: nodes,\n index,\n}: NormalizeOptions): boolean {\n if (!isText(node) || !isPlainSpace(node) || node.code) return false\n if (!isText(nextNode) || !isPlainSpace(nextNode) || node.code) return false\n nodes.splice(index, 2, { text: `${node.text}${nextNode.text}` })\n return true\n}\n","import { Segment } from \"../../../../types\"\nimport { isElement, isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function moveSpacesAtStartOfAnchor({\n node,\n nodes,\n prevNode,\n index,\n}: NormalizeOptions): boolean {\n if (!isElement(node)) return false\n if (node.type !== \"anchor\") return false\n const firstChild = node.children[0] as Segment\n if (isText(firstChild) && isPlainSpace(firstChild)) {\n // remove the first child from the anchor\n node.children.splice(0, 1)\n // add the first child\n if (isText(prevNode) && isPlainSpace(prevNode)) {\n prevNode.text = `${prevNode.text}${firstChild.text}`\n } else {\n nodes.splice(index, 0, { text: firstChild.text })\n }\n return true\n }\n return false\n}\n\nexport function moveSpacesAtEndOfAnchor({\n node,\n nodes,\n nextNode,\n index,\n}: NormalizeOptions): boolean {\n if (!isElement(node)) return false\n if (node.type !== \"anchor\") return false\n const lastChild = node.children[node.children.length - 1] as Segment\n if (isText(lastChild) && isPlainSpace(lastChild)) {\n // remove the first child from the anchor\n node.children.splice(node.children.length - 1, 1)\n // add the first child\n if (isText(nextNode) && isPlainSpace(nextNode)) {\n nextNode.text = `${lastChild.text}${nextNode.text}`\n } else {\n nodes.splice(index + 1, 0, { text: lastChild.text })\n }\n return true\n }\n return false\n}\n","import { isElement } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function mustHaveOneTextChild({ node }: NormalizeOptions): boolean {\n if (!isElement(node)) return false\n if (node.type !== \"line\") return false\n if (node.children.length > 0) return false\n node.children.push({ text: \"\" })\n return true\n}\n","import { Text } from \"../../../../types\"\nimport { isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\n/**\n * If a Text Node has spaces at the very start, or at the very end, we slice\n * those spaces into their own nodes.\n *\n * This is to help us later with the serialize process because we need spaces\n * to be isolated so that when we apple tokens like `**bold**` we are able\n * to place the tokens so that they are always against the non-space characters.\n *\n * For example, `** bold**` would not bold the text because the `**` is not\n * touching the word `bold` on the left.\n *\n * The algorithm here works by looking for a RegExp match on spaces on the\n * left or the right. If either are found, then it splits it into three parts\n * (left space, middle and right space) and then filteres out any zero length\n * spaces at the end. In this way, we handle left and right spaces in one\n * pass.\n */\nexport function sliceSpacesAtNodeBoundaries({\n node,\n nodes,\n index,\n}: NormalizeOptions): boolean {\n if (!isText(node)) return false\n if (isPlainSpace(node)) return false\n /**\n * The content of Inline Code is literal so don't move the spaces out of it.\n */\n if (node.code) return false\n const match = node.text.match(/^(\\s*)(.*?)(\\s*)$/)\n if (!match) return false\n if (match[1].length === 0 && match[3].length === 0) return false\n const nextSegments: Text[] = [\n { text: match[1] },\n { ...node, text: match[2] },\n { text: match[3] },\n ].filter((text) => text.text !== \"\")\n nodes.splice(index, 1, ...nextSegments)\n return true\n}\n","import { isElement, isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function trimSpaceAtEndOfLine({\n index,\n nodes,\n node,\n parent,\n}: NormalizeOptions): boolean {\n if (index !== nodes.length - 1) return false\n if (nodes.length <= 1) return false\n if (!isText(node)) return false\n if (!isPlainSpace(node)) return false\n if (parent && isElement(parent) && parent.type === \"line\") {\n nodes.splice(nodes.length - 1, 1)\n return true\n }\n return false\n}\n","import { isElement, isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function trimSpaceAtStartOfLine({\n index,\n nodes,\n node,\n parent,\n}: NormalizeOptions): boolean {\n if (index !== 0) return false\n if (nodes.length === 0) return false\n if (!isText(node)) return false\n if (!isPlainSpace(node)) return false\n if (parent && isElement(parent) && parent.type === \"line\") {\n nodes.splice(0, 1)\n return true\n }\n return false\n}\n","import { NormalizeOptions } from \"../types\"\nimport { mergeAdjacentSpaces } from \"./merge-adjacent-spaces\"\nimport {\n moveSpacesAtEndOfAnchor,\n moveSpacesAtStartOfAnchor,\n} from \"./move-spaces-out-of-anchors\"\nimport { mustHaveOneTextChild } from \"./must-have-one-text-child\"\nimport { sliceSpacesAtNodeBoundaries } from \"./slice-spaces-at-node-boundaries\"\nimport { trimSpaceAtEndOfLine } from \"./trim-spaces-at-end-of-line\"\nimport { trimSpaceAtStartOfLine } from \"./trim-spaces-at-start-of-line\"\n\nexport const normalizers: Array<(options: NormalizeOptions) => boolean> = [\n sliceSpacesAtNodeBoundaries,\n moveSpacesAtStartOfAnchor,\n moveSpacesAtEndOfAnchor,\n mergeAdjacentSpaces,\n trimSpaceAtStartOfLine,\n trimSpaceAtEndOfLine,\n mustHaveOneTextChild,\n]\n","import { normalizers } from \"./normalizers\"\nimport { NormalizeOptions } from \"./types\"\n\n/**\n * Attempts to run all normalizers on the given Node one by one.\n *\n * If any normalizer makes an update, this function exits immediately and\n * returns a `true` value indicating that a normalizer has made an update.\n *\n * Because we don't know how that update modified the data structure, another\n * pass will be made at running all the normalizers.\n *\n * This is not the most efficient route, but there isn't a lot of processing\n * we need to do and this reduces the likelihood of bugs. Normalization is\n * similar to how it works in Slate but we don't keep track of dirty paths\n * and simply rerun the normalizations at the given level until it is clean.\n */\nexport function runNormalizersOnNode(normalizeOptions: NormalizeOptions) {\n for (const normalizer of normalizers) {\n const isHandled = normalizer(normalizeOptions)\n if (isHandled) {\n return true\n }\n }\n return false\n}\n","import { AnchorElement } from \"~/src/anchor-plugin\"\n\nimport { isElement } from \"../utils\"\nimport { runNormalizersOnNode } from \"./run-normalizers-on-node\"\nimport { LineElement, Node, NormalizeOptions } from \"./types\"\n\nconst MAX_RERUNS = 72\n\nexport function normalizeNodes(\n nodes: Node[],\n parent?: AnchorElement | LineElement\n): boolean {\n let isAnyUpdated = false\n let isUpdated\n let runs = 0\n const maxReruns = (nodes.length + 1) * MAX_RERUNS\n do {\n isUpdated = false\n runs = runs + 1\n if (runs > maxReruns)\n throw new Error(\n `There have been ${runs} normalization passes (72x the number of nodes at this level). This likely indicates a bug in the code.`\n )\n segmentLoop: for (let i = 0; i < nodes.length; i++) {\n const node: Node = nodes[i]\n /**\n * Normalize the children of the current Node before normalizing the\n * Node itself.\n */\n if (isElement(node)) {\n const isChildrenUpdated = normalizeNodes(\n node.children as Array<AnchorElement | LineElement>,\n node\n )\n if (isChildrenUpdated) {\n isUpdated = true\n isAnyUpdated = true\n break segmentLoop\n }\n }\n /**\n * Create the normalizeOptions\n */\n const prevNode: Node | undefined = nodes[i - 1]\n const nextNode: Node | undefined = nodes[i + 1]\n const options: NormalizeOptions = {\n parent,\n node,\n prevNode,\n nextNode,\n index: i,\n nodes,\n }\n\n /**\n * Run the normalizers on this node.\n */\n if (runNormalizersOnNode(options)) {\n isUpdated = true\n isAnyUpdated = true\n break segmentLoop\n }\n }\n } while (isUpdated)\n return isAnyUpdated\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { Segment } from \"../../../types\"\nimport { assertUnreachable } from \"../../../utils\"\nimport { serializeImageShared } from \"../../serialize-image-shared\"\nimport { serializeCodeText } from \"../segment/serialize-code-text\"\nimport { serializeAnchor } from \"./serialize-anchor\"\nimport { serializeNonCodeText } from \"./serialize-non-code-text\"\n\nexport function serializeSegment(segment: Segment): string {\n if (SlateText.isText(segment)) {\n /**\n * If the segment is a `code` segment, we need to use a different strategy\n * for escaping the `code` segment. This is why it needs a separate\n * serializing function.\n */\n if (segment.code) return serializeCodeText(segment)\n /**\n * Otherwise, we use the standard text escaping code.\n */\n return serializeNonCodeText(segment)\n }\n switch (segment.type) {\n case \"anchor\": {\n return serializeAnchor(segment)\n }\n case \"image-inline\":\n return serializeImageShared(segment)\n default:\n assertUnreachable(segment)\n }\n}\n","import { Text } from \"../../../types\"\n\nexport function serializeCodeText(text: Text): string {\n let max = 0\n for (const match of text.text.matchAll(/[`]+/g)) {\n max = Math.max(max, match[0].length)\n }\n if (max === 0) return `\\`${text.text.replace(/[`]/g, \"\\\\`\")}\\``\n return `${\"`\".repeat(max + 1)} ${text.text} ${\"`\".repeat(max + 1)}`\n}\n","import { AnchorElement } from \"~/src/anchor-plugin\"\n\nimport { Segment } from \"../../../types\"\nimport { serializeLine } from \"../serialize-line\"\nimport { getCommonAnchorMarks } from \"../utils\"\n\nfunction escapeTitle(title: string): string {\n return title.replace(/\"/g, '\\\\\"')\n}\n\nexport function serializeAnchor(anchor: AnchorElement): string {\n const commonAnchorMarks = getCommonAnchorMarks(anchor.children as Segment[])\n if (anchor.href.startsWith(\"$\"))\n return serializeLine(\n anchor.children as Segment[],\n commonAnchorMarks,\n commonAnchorMarks\n )\n if (typeof anchor.title === \"string\" && anchor.title.length > 0) {\n return (\n /**\n * TODO: Handle anchor children more elegantly in serializeAnchor.\n *\n * We type cast `children` as `Segment` here because the children of an\n * `anchor` is limited to be Inline types. There are two things to do\n * related to this though:\n *\n * - [ ] consider fixing the `anchor` type to actually limit the\n * children as expected.\n * - [ ] consider expanding the definition of `Segment` to include\n * inline images as that is an acceptable inline value which is\n * currently not defined as part of Segment.\n */\n `[${serializeLine(\n anchor.children as Segment[],\n commonAnchorMarks,\n commonAnchorMarks\n )}](${anchor.href} \"${escapeTitle(anchor.title)}\")`\n )\n } else {\n return (\n /**\n * TODO: Handle anchor children more elegantly in serializeAnchor.\n *\n * We type cast `children` as `Segment` here because the children of an\n * `anchor` is limited to be Inline types. There are two things to do\n * related to this though:\n *\n * - [ ] consider fixing the `anchor` type to actually limit the\n * children as expected.\n * - [ ] consider expanding the definition of `Segment` to include\n * inline images as that is an acceptable inline value which is\n * currently not defined as part of Segment.\n */\n `[${serializeLine(\n anchor.children as Segment[],\n commonAnchorMarks,\n commonAnchorMarks\n )}](${anchor.href})`\n )\n }\n}\n","import { Text } from \"../../../types\"\nimport { escapeText } from \"../utils\"\n\nexport function serializeNonCodeText(text: Text): string {\n return escapeText(text.text)\n}\n","import {\n TableCellElement,\n TableColumnAlign,\n TableContentElement,\n TableElement,\n TableRowElement,\n} from \"~/src/table-plugin\"\n\nimport { Segment } from \"../../types\"\nimport { assert, assertElementType } from \"../../utils\"\nimport { serializeLine } from \"../serialize-line\"\n\nexport function serializeTable(element: TableElement): string {\n const lines: string[] = []\n lines.push(serializeTableRow(element.children[0]))\n lines.push(serializeColumns(element.columns))\n element.children.slice(1).forEach((row) => {\n lines.push(serializeTableRow(row))\n })\n return `${lines.join(\"\\n\")}\\n\\n`\n}\n\nfunction serializeColumns(columns: TableElement[\"columns\"]): string {\n const isAllLeft = columns.every((column) => column.align === \"left\")\n /**\n * If all of the columns are to the left, it looks nicer if we don't specify\n * column alignment in the markdown at all. Just use the default `---` to\n * specify each column.\n */\n if (isAllLeft) {\n return `|${columns.map(() => \"---\").join(\"|\")}|`\n }\n /**\n * If one or more of the columns is not aligned left, let's add some clarity\n * and specify the alignment of all the columns including the `left` aligned\n * ones.\n */\n return `|${columns.map((column) => serializeAlign(column.align)).join(\"|\")}|`\n}\n\nfunction serializeAlign(align: TableColumnAlign) {\n switch (align) {\n case \"left\":\n return \":---\"\n case \"center\":\n return \":---:\"\n case \"right\":\n return \"---:\"\n }\n}\n\nfunction serializeTableRow(element: TableRowElement): string {\n assertElementType(element, \"table-row\")\n return `|${element.children.map(serializeTableCell).join(\"|\")}|`\n}\n\nfunction serializeTableCell(element: TableCellElement): string {\n assertElementType(element, \"table-cell\")\n assert(\n element.children.length === 1,\n `Expected table-cell to have one child but is ${JSON.stringify(\n element.children\n )}`\n )\n return element.children.map(serializeTableContent).join()\n}\n\nfunction serializeTableContent(element: TableContentElement): string {\n assertElementType(element, \"table-content\")\n return serializeLine(element.children as Segment[])\n}\n","import { Element, Segment } from \"../types\"\nimport { assertUnreachable } from \"../utils\"\nimport { serializeElements } from \"./serialize-elements\"\nimport { serializeCodeBlock } from \"./serialize-code-block\"\nimport { serializeImageBlock } from \"./serialize-image-block\"\nimport { serializeLine } from \"./serialize-line\"\nimport { serializeTable } from \"./serialize-table\"\n\nconst LIST_INDENT_SIZE = 4\n\nexport function serializeElement(element: Element, orders: number[]): string {\n switch (element.type) {\n case \"anchor\":\n return `[${serializeLine(element.children as Segment[])}](${element.href\n })`\n case \"block-quote\": {\n const lines = serializeElements(element.children as Element[])\n return `${lines\n .split(\"\\n\")\n .map((line) => `> ${line}`.trim())\n .join(\"\\n\")}\\n\\n`\n }\n case \"heading\":\n return `${\"#\".repeat(element.level)} ${serializeLine(\n element.children as Segment[]\n )}\\n\\n`\n case \"horizontal-rule\":\n return \"---\\n\\n\"\n case \"paragraph\":\n return `${serializeLine(element.children as Segment[])}\\n\\n`\n /**\n * Table\n */\n case \"table\":\n return serializeTable(element)\n case \"table-row\":\n case \"table-cell\":\n case \"table-content\":\n throw new Error(\n `Table elements should only be present as children of table which should be handled by serializeTable. Got ${element.type} may indicate an error in normalization.`\n )\n /**\n * List\n */\n case \"unordered-list-item\": {\n const indent = \" \".repeat(element.depth * LIST_INDENT_SIZE)\n return `${indent}- ${serializeLine(element.children as Segment[])}\\n`\n }\n case \"ordered-list-item\": {\n const indent = \" \".repeat(element.depth * LIST_INDENT_SIZE)\n return `${indent}${orders[element.depth]}. ${serializeLine(\n element.children as Segment[]\n )}\\n`\n }\n case \"task-list-item\": {\n const indent = \" \".repeat(element.depth * LIST_INDENT_SIZE)\n let line = serializeLine(element.children as Segment[])\n if (line.trim() === \"\") {\n line = \" \"\n }\n return `${indent}- [${element.checked ? \"x\" : \" \"}] ${line}\\n`\n }\n case \"image-block\":\n return serializeImageBlock(element)\n case \"code-block\":\n return serializeCodeBlock(element)\n case \"code-block-line\":\n throw new Error(\n `Code block line elements should only be present as children of code-block which should be handled by serializeCodeBlock. Got code-block-line may indicate an error in normalization.`\n )\n case \"html-block\":\n return `${element.html}\\n\\n`\n }\n assertUnreachable(element)\n}\n","import { Element } from \"../types\"\nimport { serializeElement } from \"./serialize-element\"\n\nexport function serializeElements(elements: Element[]): string {\n const segments: string[] = []\n\n /**\n * The orders array keeps track of the number of ordered list items at each\n * depth. This is used to generate the number for each ordered list item.\n */\n let orders: number[] = []\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n const nextElement = i < elements.length - 1 ? elements[i + 1] : null;\n\n if (element.type === \"ordered-list-item\") {\n /**\n * When we're at an ordered list item, we increment the order at the\n * current depth level and we remove any orders at a deeper depth level.\n */\n orders[element.depth] = (orders[element.depth] || 0) + 1\n orders = orders.slice(0, element.depth + 1)\n } else if (\n element.type === \"unordered-list-item\" ||\n element.type === \"task-list-item\"\n ) {\n /**\n * When we're at an unordered list item, we slice the orders array to\n * remove any orders at a deeper depth level.\n */\n orders = orders.slice(0, element.depth)\n } else {\n /**\n * When we're at any other element, we reset the orders array because\n * we're no longer in a list.\n */\n orders = []\n }\n\n // Get the serialized element\n let serialized = serializeElement(element, orders);\n\n // If this is a list item and the next element is not a list item,\n // add an extra newline to create proper spacing between list and paragraph\n if ((element.type === \"ordered-list-item\" ||\n element.type === \"unordered-list-item\" ||\n element.type === \"task-list-item\") &&\n (!nextElement ||\n (nextElement.type !== \"ordered-list-item\" &&\n nextElement.type !== \"unordered-list-item\" &&\n nextElement.type !== \"task-list-item\"))) {\n serialized = serialized.replace(/\\n$/, \"\\n\\n\");\n }\n\n segments.push(serialized);\n }\n /**\n * NOTE:\n *\n * We remove trailing whitespace because we want minimum viable markdown.\n * It also makes it easier to test.\n */\n const joined = segments.join(\"\") //.trim()\n\n /**\n * If there is no content return an empty string for the Markdown.\n */\n if (joined.trim() === \"\") return \"\"\n\n /**\n * The following code replaces consecutive newlines with a single newline\n * with a bit of additional logic to handle newlines at the beginning.\n */\n return replaceConsecutiveNewlines(replaceLeadingNewlines(joined)).trim()\n}\n\n/**\n * Replace two leading newlines with a non-breaking space to indicate a\n * paragraph that won't be collapsed.\n */\nfunction replaceLeadingNewlines(input: string): string {\n return input.replace(/^\\n\\n/g, \" \\n\\n\")\n}\n\n/**\n * In the rest of the Markdown, replace four or more consecutive newlines with\n * non-breaking spaces and newlines to indicate a paragraph that won't be\n * collapsed.\n */\nfunction replaceConsecutiveNewlines(input: string): string {\n return input.replace(/(\\n{4,})/g, (match) => {\n const newlineCount = match.length\n const count = Math.floor((newlineCount - 2) / 2)\n return \"\\n\\n\" + Array(count).fill(\" \").join(\"\\n\\n\") + \"\\n\\n\"\n })\n}\n","import { Element } from \"../types\"\nimport { normalizeElementListDepths } from \"./normalize/normalizeElementListDepths\"\nimport { serializeElements } from \"./serialize-elements\"\n\nexport function serialize(elements: Element[]): string {\n const normalizedElements = normalizeElementListDepths(elements)\n return serializeElements(normalizedElements)\n}\n","interface Translations {\n [key: string]: {\n bold: string;\n italic: string;\n strike: string;\n inlineCode: string;\n underline: string;\n highlight: string;\n increaseDepth: string;\n decreaseDepth: string;\n heading1: string;\n heading2: string;\n heading3: string;\n normal: string;\n paragraph: string;\n paragraphStyle: string;\n bulletList: string;\n numberedList: string;\n checkList: string;\n list: string;\n linkUrl: string;\n linkText: string;\n linkTextHint: string;\n tooltipText: string;\n tooltipHint: string;\n apply: string;\n cancel: string;\n insertLink: string;\n quote: string;\n insertTable: string;\n insertImage: string;\n insertImageFromUrl: string;\n insert: string;\n format: string;\n imageUrlRequired: string;\n altText: string;\n title: string;\n imageDescription: string;\n imageTitle: string;\n switchToVisualEditor: string;\n switchToRawMarkdown: string;\n codeBlock: string;\n increaseQuoteDepth: string;\n register: string;\n imageSourceUrl: string;\n imageSourceFile: string;\n selectFile: string;\n uploading: string;\n };\n}\n\nexport const translations: Translations = {\n ja: {\n bold: \"太字\",\n italic: \"斜体\",\n strike: \"取り消し線\",\n inlineCode: \"インラインコード\",\n underline: \"下線\",\n highlight: \"ハイライト\",\n increaseDepth: \"階層を深くする\",\n decreaseDepth: \"階層を浅くする\",\n heading1: \"見出し1\",\n heading2: \"見出し2\",\n heading3: \"見出し3\",\n normal: \"標準\",\n paragraph: \"段落\",\n paragraphStyle: \"段落スタイル\",\n bulletList: \"箇条書き\",\n numberedList: \"番号付きリスト\",\n checkList: \"チェックリスト\",\n list: \"リスト\",\n linkUrl: \"リンクのURL\",\n linkText: \"リンクテキスト\",\n linkTextHint: \"リンクとして表示されるテキスト\",\n tooltipText: \"ツールチップテキスト\",\n tooltipHint: \"マウスホバー時に表示されるツールチップ\",\n apply: \"適用\",\n cancel: \"キャンセル\",\n insertLink: \"リンク\",\n quote: \"引用\",\n insertTable: \"表\",\n insertImage: \"画像\",\n insertImageFromUrl: \"画像\",\n insert: \"挿入\",\n format: \"書式\",\n imageUrlRequired: \"画像URL(必須):\",\n altText: \"代替テキスト:\",\n title: \"ツールチップ:\",\n imageDescription: \"画像の説明\",\n imageTitle: \"画像のツールチップ\",\n switchToVisualEditor: \"ビジュアルエディタに切り替え\",\n switchToRawMarkdown: \"マークダウン表示に切り替え\",\n codeBlock: \"コードブロック\",\n increaseQuoteDepth: \"引用を重ねる\",\n register: \"登録\",\n imageSourceUrl: \"URL\",\n imageSourceFile: \"ファイル\",\n selectFile: \"ファイルを選択\",\n uploading: \"アップロード中...\",\n },\n en: {\n bold: \"Bold\",\n italic: \"Italic\",\n strike: \"Strikethrough\",\n inlineCode: \"Inline Code\",\n underline: \"Underline\",\n highlight: \"Highlight\",\n increaseDepth: \"Increase Depth\",\n decreaseDepth: \"Decrease Depth\",\n heading1: \"Heading 1\",\n heading2: \"Heading 2\",\n heading3: \"Heading 3\",\n normal: \"Normal\",\n paragraph: \"Paragraph\",\n paragraphStyle: \"Paragraph Style\",\n bulletList: \"Bullet List\",\n numberedList: \"Numbered List\",\n checkList: \"Check List\",\n list: \"List\",\n linkUrl: \"Link URL\",\n linkText: \"Link Text\",\n linkTextHint: \"Text displayed as the link\",\n tooltipText: \"Tooltip Text\",\n tooltipHint: \"Tooltip shown on mouse hover\",\n apply: \"Apply\",\n cancel: \"Cancel\",\n insertLink: \"Link\",\n quote: \"Quote\",\n insertTable: \"Table\",\n insertImage: \"Image\",\n insertImageFromUrl: \"Image\",\n insert: \"Insert\",\n format: \"Format\",\n imageUrlRequired: \"Image URL (required):\",\n altText: \"Alt Text:\",\n title: \"tooltip:\",\n imageDescription: \"Description of the image\",\n imageTitle: \"tooltip\",\n switchToVisualEditor: \"Switch to visual editor\",\n switchToRawMarkdown: \"Switch to raw markdown\",\n codeBlock: \"Code Block\",\n increaseQuoteDepth: \"Increase Quote Depth\",\n register: \"Register\",\n imageSourceUrl: \"URL\",\n imageSourceFile: \"File\",\n selectFile: \"Select File\",\n uploading: \"Uploading...\",\n },\n};\n\nexport type TranslationKey = keyof Translations[\"en\"];\n\nconst getLanguage = (): string => {\n try {\n // Check if we're in a browser environment\n if (typeof window !== 'undefined' && window.navigator) {\n return window.navigator.language.split(\"-\")[0];\n }\n } catch {\n // Ignore any errors\n }\n // Default to 'en' in server environment\n return 'en';\n};\n\nexport const t = (key: TranslationKey): string => {\n const lang = getLanguage();\n return translations[lang === \"ja\" ? \"ja\" : \"en\"][key];\n};\n\nexport const r = (value: string): string => {\n const lang = getLanguage();\n // 値がvalueと一致するキーを取得\n const key = Object.keys(translations[lang === \"ja\" ? \"ja\" : \"en\"]).find(\n (k) => translations[lang === \"ja\" ? \"ja\" : \"en\"][k as TranslationKey] === value\n ) as TranslationKey;\n return key || \"\";\n};\n","import { InputPluginSchema, TypedPluginFunction } from \"../types\"\nimport { BasePlugin } from \"../types/plugin/plugin\"\n\n/**\n * The `createPlugin` method here takes a function and returns the same\n * function.\n *\n * From a JavaScript point of view, it does nothing itself return itself.\n *\n * From a typing point of view, it takes these two arguments...\n *\n * - The CustomTypes used by the plugin as a Generic\n * - A function that when executed with an `Editor` object, returns a\n * PluginObject as a function argument\n *\n * ...and ensure that the function argument adheres to the limits of the\n * Generic Argument.\n *\n * For example, if the CustomTypes defines an `Element`, then the function\n * argument will have its element related methods constrained to the Element\n * given in CustomTypes.\n *\n * The benefit of this is that it helps the Plugin only see what is relevant\n * to this plugin. In fact, it insists on it. This will prevent accidental\n * dependency on another plugin.\n *\n * You can add dependencies between plugins, but when we do that, it insists\n * on having that done explicitly.\n */\nexport const createPlugin = <T extends InputPluginSchema>(\n fn: TypedPluginFunction<T>\n) => {\n return { fn } as BasePlugin\n}\n","import { useEffect, useMemo } from \"react\"\nimport { Editor } from \"slate\"\nimport { useSlateStatic } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { SinkEditor } from \"../types\"\nimport { createDecorate } from \"./create-decorate\"\nimport { createEditable } from \"./create-editable\"\nimport {\n createOnDrop,\n createOnKeyDown,\n createOnKeyUp,\n createOnPaste,\n} from \"./create-handler\"\nimport { createRenderElement } from \"./create-render-element\"\nimport { createRenderLeaf } from \"./create-render-leaf\"\nimport { createRenderPlaceholder } from \"./create-render-placeholder\"\nexport { SinkReset } from \"./styles\"\n\n/**\n * In Editable, we use the Slate context to grab the right things from\n * the editor.\n */\nexport function SinkEditable(originalProps: EditableProps): React.ReactElement {\n const editor = useSlateStatic() as unknown as Editor & SinkEditor\n\n /**\n * We ask Slate to normalize the editor once at the very start.\n *\n * This is helpful for plugins that need to store some useful state in the\n * document and to add or fix certain parts of the document. Not all of\n * these values are stored in the saved documents.\n *\n * Some examples:\n *\n * - inserting collapsible paragraphs between void components. These should\n * not be saved.\n *\n * - Add column and row indexes to help with rendering which should not\n * be saved.\n *\n * Ideally, we wouldn't have to do any of this but pragmatically, it is\n * the most performant route.\n *\n * Once we normalize the document once, the document is kept up to date\n * through regular normalizing steps that are more performance because\n * they only check changed nodes.\n */\n useEffect(() => {\n Editor.normalize(editor, { force: true })\n }, [])\n\n const { plugins } = editor.sink\n\n const nextProps: EditableProps = useMemo(\n () => ({\n ...originalProps,\n decorate: createDecorate(originalProps.decorate, plugins),\n renderElement: createRenderElement(originalProps.renderElement, plugins),\n renderLeaf: createRenderLeaf(originalProps.renderLeaf, plugins),\n renderPlaceholder: createRenderPlaceholder(\n originalProps.renderPlaceholder,\n plugins\n ),\n /**\n * NOTE: We skip `onKeyUp` as it is deprecated. If somebody needs it in new\n * code, we can add it back in.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event\n */\n onKeyDown: createOnKeyDown(originalProps.onKeyDown, plugins),\n onKeyUp: createOnKeyUp(originalProps.onKeyUp, plugins),\n onPaste: createOnPaste(originalProps.onPaste, plugins),\n onDrop: createOnDrop(originalProps.onDrop, plugins),\n }),\n Object.values(originalProps)\n )\n\n const NextEditable = useMemo(() => createEditable(plugins), [plugins])\n\n /**\n * NOTE:\n *\n * The following code is used to see if we are getting unnecessary re-renders.\n *\n * Comment it out when we are happy.\n *\n * - We SHOULD see `SinkeEditable render` whenever the markdown is updated\n * - We SHOULD NOT see `SinkEditable mount` or unmount at each update\n */\n // console.log(\"SinkEditable render\")\n\n // console.log(Object.values(nextProps))\n\n // useEffect(() => {\n // console.log(\"SinkEditable mount\")\n // return () => {\n // console.log(\"SinkEditable unmount\")\n // }\n // }, [NextEditable, nextProps])\n\n return <NextEditable {...nextProps} />\n}\n","export function defined<T>(value: T | undefined): value is T {\n return !!value\n}\n","import { NodeEntry, Range } from \"slate\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `decorate` method.\n *\n * With decorate, we are taking all the ranges from all the decorators and\n * combining them together, including the ranges created from the `decorate`\n * attribute on `SinkEditable`.\n */\nexport function createDecorate(\n originalFn: EditableProps[\"decorate\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"decorate\"]> {\n const fns = plugins\n .map((plugin) => plugin.editableProps?.decorate)\n .filter(defined)\n return function (entry: NodeEntry): Range[] {\n const ranges: Range[] = []\n for (const fn of fns) {\n const resultRanges = fn(entry)\n ranges.push(...resultRanges)\n }\n if (originalFn) ranges.push(...originalFn(entry))\n return ranges\n }\n}\n","import { Editable } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\ntype EditableType = (editableProps: EditableProps) => React.ReactElement\n\n/**\n * create a new Editable component that takes all the `renderEditable` functions\n * which are components and have them wrap around the original Editable component.\n */\nexport function createEditable(\n plugins: BasePluginPolicy[]\n): NonNullable<EditableType> {\n const fns = plugins.map((plugin) => plugin.renderEditable).filter(defined)\n\n /**\n * This creates the inner-most RenderEditable.\n */\n let CurrentRenderEditable = (props: EditableProps) => <Editable {...props} />\n /**\n * We iterate through all the `renderEditable` functions and wrap them\n * around the next inner-most `renderEditable`.\n */\n for (const fn of fns) {\n /**\n * Assigns the CurrentRenderEditable as the previous one so that we can\n * have it available to call in the NextRenderEditable\n */\n const PrevRenderEditable = CurrentRenderEditable\n\n CurrentRenderEditable = (props: EditableProps) => {\n /**\n * TODO:\n *\n * This should probably be fixed in the actual types; however, we\n * know at this point that `renderEditable` is defined because we\n * filtered it in an earlier step.\n */\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return fn({\n attributes: props,\n Editable: PrevRenderEditable,\n })\n }\n }\n\n return CurrentRenderEditable\n\n // return function SinkEditable(props) {\n // /**\n // * This creates the inner-most RenderEditable.\n // */\n // let CurrentRenderEditable = (props: EditableProps) => (\n // <Editable {...props} />\n // )\n // /**\n // * We iterate through all the `renderEditable` functions and wrap them\n // * around the next inner-most `renderEditable`.\n // */\n // for (const fn of fns) {\n // /**\n // * Assigns the CurrentRenderEditable as the previous one so that we can\n // * have it available to call in the NextRenderEditable\n // */\n // const PrevRenderEditable = CurrentRenderEditable\n // CurrentRenderEditable = (props: EditableProps) => {\n // /**\n // * TODO:\n // *\n // * This should probably be fixed in the actual types; however, we\n // * know at this point that `renderEditable` is defined because we\n // * filtered it in an earlier step.\n // */\n // // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n // return fn({\n // attributes: props,\n // Editable: PrevRenderEditable,\n // })\n // }\n // }\n // return <CurrentRenderEditable {...props} />\n // }\n}\n","import { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\n\n/**\n * Create the substituted event handler method.\n *\n * Generally, we are looking for the first result from any plugin or on\n * SinkEditable and return the first one that returns a value only.\n *\n * Iterate over all the plugin handlers. If one handler returns `false`\n * then we go to the next one until we get one that returns `true`. If we don't\n * fine on that returns `true`, then we go to the handler passed to the\n * `SinkEditable` component.\n */\n\n/**\n * TODO:\n *\n * It's probably not THAT important, but the holy grail as a programmer here is\n * to:\n *\n * 1. Have these functions created without the boilerplate. It really feels\n * like it could be one function that takes `plugins` and a `key` and all\n * the typing and stuff would work.\n *\n * 2. Build it in a way that's easy to reason about. There is probably a way\n * to do this that works, but nobody will ever be able to work on it if there\n * is a problem, and probably a way to do it where it's somewhat\n * comprehensible.\n */\n\n/**\n * Here we define strictly the type for a method that creates an Event Handler\n * on Editable. We define this separately because (a) it is easier to do it and\n * give clarity to it as a separate type and (b) we want to check the actual\n * method that we created against this type as an early warning signal if we\n * did something wrong.\n *\n * A method that creates a method, that pulls from a plugin a function that is\n * similar to, but not exactly, like the function that it is going to be\n * returning, is a bit of a nightmare and this helps make sure we don't make\n * mistakes.\n *\n * In other words, don't remove this and use the automatic typing as it's a\n * good way to make sure that this method is typed correctly.\n */\ntype CreateHandler<K extends keyof EditableProps> = (\n originalFn: EditableProps[K],\n plugins: BasePluginPolicy[]\n) => NonNullable<EditableProps[K]>\n\n/**\n * Takes an array of Plugin objects and extracts all of the specified\n * `editableProps` handler functions from it. If it's not defined, we skip it\n * so that we end up with an Array that is populated with the functions only\n * and no `undefined` in it.\n */\nfunction extractEditableFns<\n K extends keyof Required<BasePluginPolicy>[\"editableProps\"]\n>(\n plugins: BasePluginPolicy[],\n key: K\n): NonNullable<Required<BasePluginPolicy>[\"editableProps\"][K]>[] {\n const fns: NonNullable<Required<BasePluginPolicy>[\"editableProps\"][K]>[] = []\n for (const plugin of plugins) {\n const maybeFn = plugin.editableProps?.[key]\n if (maybeFn) fns.push(maybeFn)\n }\n return fns\n}\n\n/**\n * Takes an array of handler functions that will return a boolean which\n * indicates that an event was handled. If the function was handled, then we\n * return and stop execution immediately.\n *\n * We keep going through all the handlers until something handles it.\n *\n * If none of the plugin fns handle it, then we check to see if there was an\n * original function defined and execute that if there is.\n */\nfunction createHandlerFn<A>(\n fns: ((arg: A) => boolean)[],\n originalFn: ((arg: A) => void) | undefined\n) {\n return function (event: A) {\n for (const fn of fns) {\n if (fn(event)) return\n }\n originalFn?.(event)\n }\n}\n\n/**\n * keyDown handler\n */\nexport const createOnKeyDown: CreateHandler<\"onKeyDown\"> = (\n originalFn,\n plugins\n) => {\n const fns = extractEditableFns(plugins, \"onKeyDown\")\n return createHandlerFn(fns, originalFn)\n}\n\n/**\n * keyUp handler\n */\nexport const createOnKeyUp: CreateHandler<\"onKeyUp\"> = (\n originalFn,\n plugins\n) => {\n const fns = extractEditableFns(plugins, \"onKeyUp\")\n return createHandlerFn(fns, originalFn)\n}\n\n/**\n * onPaste handler\n */\nexport const createOnPaste: CreateHandler<\"onPaste\"> = (\n originalFn,\n plugins\n) => {\n const fns = extractEditableFns(plugins, \"onPaste\")\n return createHandlerFn(fns, originalFn)\n}\n\n/**\n * onDrop handler\n */\nexport const createOnDrop: CreateHandler<\"onDrop\"> = (originalFn, plugins) => {\n const fns = extractEditableFns(plugins, \"onDrop\")\n return createHandlerFn(fns, originalFn)\n}\n","import { RenderElementProps } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `renderElement` method.\n *\n * Generally, we are looking for the first result from any plugin or on\n * SinkEditable and return the first one that returns a value only.\n *\n * Iterate over all the plugin `renderElement`. If they return nothing\n * then we go to the next one until we hit a result. If we don't hit a\n * result, then we go to the `renderElement` passed to the `SinkEditable`\n * component.\n */\n\nexport function createRenderElement(\n originalFn: EditableProps[\"renderElement\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"renderElement\"]> {\n const fns = plugins\n .map((plugin) => plugin.editableProps?.renderElement)\n .filter(defined)\n return function renderElement(\n renderElementProps: RenderElementProps\n ): JSX.Element {\n for (const fn of fns) {\n const result = fn(renderElementProps)\n if (result) return result\n }\n if (originalFn === undefined) {\n throw new Error(\n `Element with type ${renderElementProps.element.type} not handled. Note that renderElement is not defined on SinkEditable so this is only the result of checking the Sink Plugins.`\n )\n }\n return originalFn(renderElementProps)\n }\n}\n","import { cloneElement } from \"react\"\nimport { RenderLeafProps } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `renderLeaf` method.\n *\n * Generally, we are looking for all the results from all the plugins and\n * SinkEditable and merge the results together by nesting the responses\n * starting from the first plugin on the outside to the `renderLeaf` method\n * on `SinkEditable` on the inside.\n */\n\nexport function createRenderLeaf(\n originalFn: EditableProps[\"renderLeaf\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"renderLeaf\"]> {\n if (originalFn === undefined) {\n throw new Error(`renderLeaf was not defined on SinkEditable`)\n }\n\n /**\n * These get handled in reverse order. We wrap the last one around the\n * actual `Text` and the earlier ones wrap around those. This\n * feels more natural because the first plugin handles the outermost\n * and we work our way inward.\n */\n const fns = plugins\n .map((plugin) => plugin.editableProps?.renderLeaf)\n .filter(defined)\n .reverse()\n\n return function (renderLeafProps) {\n let value = originalFn({\n ...renderLeafProps,\n /**\n * We override this because `attributes` should only appear on the\n * uppermost leaf element if there are several nested ones and it's\n * possible that this won't be the uppermost leaf.\n *\n * We add attributes back on at the very end so no need to worry if\n * we omit it here.\n */\n attributes: {} as RenderLeafProps[\"attributes\"],\n })\n for (const fn of fns) {\n const possibleValue = fn({\n ...renderLeafProps,\n children: value,\n })\n if (possibleValue) {\n value = possibleValue\n }\n }\n value = cloneElement(value, renderLeafProps.attributes) //{ key: 'your-unique-key-here' })\n return value\n }\n}\n","import { RenderPlaceholderProps } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `renderElement` method.\n *\n * Generally, we are looking for the first result from any plugin or on\n * SinkEditable and return the first one that returns a value only.\n *\n * Iterate over all the plugin `renderElement`. If they return nothing\n * then we go to the next one until we hit a result. If we don't hit a\n * result, then we go to the `renderElement` passed to the `SinkEditable`\n * component.\n */\n\nexport function createRenderPlaceholder(\n originalFn: EditableProps[\"renderPlaceholder\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"renderPlaceholder\"]> | undefined {\n if (originalFn) return originalFn\n const fns = plugins\n .map((plugin) => plugin.editableProps?.renderPlaceholder)\n .filter(defined)\n if (fns.length === 0) return undefined\n return function (\n renderPlaceholderProps: RenderPlaceholderProps\n ): JSX.Element {\n if (fns.length > 1) {\n throw new Error(\n `Only one plugin can define renderPlaceholder but there are ${fns.length}`\n )\n }\n const fn = fns[0]\n if (fn == null) throw new Error(`Expected fn to be defined`)\n return fn(renderPlaceholderProps)\n }\n}\n","import styled from \"@emotion/styled\"\n\nexport const SinkReset = styled(\"div\")`\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-size: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;\n box-sizing: border-box;\n`\n","import { Element, Node } from \"slate\"\n\nimport { BasePluginPolicy, FullSinkEditor } from \"../types\"\n\n/**\n * Creates an overrideable editor action that takes a `Node` and returns a\n * `boolean` and creates a new version of the action that incorporates the\n * plugins.\n *\n * If the plugin returns a boolean, it takes the result and returns it.\n *\n * If the plugin returns undefined, it tries the next one.\n *\n * If no plugin handles the result, it returns the result of the original action.\n */\nexport function createBooleanAction<\n K extends \"isVoid\" | \"isInline\" | \"isMaster\" | \"isSlave\" | \"isStandalone\"\n>(\n editor: FullSinkEditor,\n actionKey: K,\n plugins: BasePluginPolicy[]\n): (node: Element) => boolean {\n const originalAction = editor[actionKey]\n const actionPlugins = plugins.filter((plugin) => plugin.editor?.[actionKey])\n return function nextBooleanAction(node: Node): boolean {\n for (const plugin of actionPlugins) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const result = plugin.editor?.[actionKey]?.(node)\n if (typeof result === \"boolean\") return result\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return originalAction(node)\n }\n}\n","import { BaseEditor } from \"slate\"\n\nimport { BasePluginPolicy } from \"../types\"\n\n/**\n * Creates an overrideable editor action like `insertBreak` or `deleteBackward`\n * that usually returns `void` and creates a new version of the action that\n * adds the action from the plugin.\n *\n * If the plugin returns `true` it takes the result and returns it.\n *\n * If the plugin returns `false`, it tries the next one.\n *\n * If no plugin handles the result, it executed the original action.\n */\nexport function createVoidAction<\n K extends\n | \"normalizeNode\"\n | \"deleteBackward\"\n | \"deleteForward\"\n | \"deleteFragment\"\n | \"insertBreak\"\n | \"insertFragment\"\n | \"insertNode\"\n | \"insertText\"\n>(editor: BaseEditor, actionKey: K, plugins: BasePluginPolicy[]) {\n const originalAction = editor[actionKey]\n const actionPlugins = plugins.filter((plugin) => plugin.editor?.[actionKey])\n return function nextVoidAction(...args: Parameters<BaseEditor[K]>[]): void {\n let isHandled = false\n const afterHandledCallbacks: (() => void)[] = []\n for (const plugin of actionPlugins) {\n // @ts-ignore\n const response = plugin.editor?.[actionKey]?.(...args)\n if (typeof response === \"function\") {\n afterHandledCallbacks.push(response)\n } else if (response === true) {\n isHandled = true\n break\n }\n }\n if (!isHandled) {\n // @ts-ignore\n originalAction(...args)\n }\n afterHandledCallbacks.forEach((callback) => callback())\n }\n}\n","import { BaseEditor } from \"slate\"\n\nimport { BasePluginFn, ExtractedPluginSchema, FullSinkEditor } from \"../types\"\nimport { createBooleanAction } from \"./create-boolean-action\"\nimport { createVoidAction } from \"./create-void-action\"\n\nexport function createWithSink<T extends ExtractedPluginSchema>(\n pluginFns: BasePluginFn[]\n) {\n /**\n * The `editor` in the props can be a `BaseEditor` but we transform it\n * into a `SinkEditor` before returning it.\n */\n return <E extends BaseEditor>(\n originalEditor: E,\n options: T[\"Options\"]\n ): E & FullSinkEditor => {\n const editor = originalEditor as E & FullSinkEditor\n\n /**\n * Executes the plugin on the `editor` with every one of the\n * `pluginFunctions` to get the `pluginObject`\n */\n const plugins = pluginFns.map((plugin) =>\n plugin(editor, options, { createPolicy: (x) => x })\n )\n editor.sink = { plugins }\n\n /**\n * Create the default for SinkEditor methods if they don't already exist.\n */\n editor.isMaster = \"isMaster\" in editor ? editor.isMaster : () => false\n editor.isSlave = \"isSlave\" in editor ? editor.isSlave : () => false\n editor.isStandalone =\n \"isStandalone\" in editor ? editor.isStandalone : () => false\n\n Object.assign(editor, {\n /**\n * void\n */\n normalizeNode: createVoidAction(editor, \"normalizeNode\", plugins),\n deleteBackward: createVoidAction(editor, \"deleteBackward\", plugins),\n deleteForward: createVoidAction(editor, \"deleteForward\", plugins),\n deleteFragment: createVoidAction(editor, \"deleteFragment\", plugins),\n insertBreak: createVoidAction(editor, \"insertBreak\", plugins),\n insertFragment: createVoidAction(editor, \"insertFragment\", plugins),\n insertNode: createVoidAction(editor, \"insertNode\", plugins),\n insertText: createVoidAction(editor, \"insertText\", plugins),\n /**\n * boolean\n */\n isInline: createBooleanAction(editor, \"isInline\", plugins),\n isVoid: createBooleanAction(editor, \"isVoid\", plugins),\n isMaster: createBooleanAction(editor, \"isMaster\", plugins),\n isSlave: createBooleanAction(editor, \"isSlave\", plugins),\n isStandalone: createBooleanAction(editor, \"isStandalone\", plugins),\n })\n\n return editor\n }\n}\n","import { SinkEditable } from \"../editable\"\nimport { createWithSink } from \"../editor\"\nimport { BasePlugin, ExtractedPluginSchema } from \"../types\"\n\n/**\n * A sink is just a function\n */\nexport const createSink = <T extends ExtractedPluginSchema>(\n pluginFunctions: BasePlugin[]\n) => {\n const fns = pluginFunctions.map((plugin) => plugin.fn)\n const withSink = createWithSink<T>(fns)\n\n const returnValue = { withSink, SinkEditable }\n return returnValue\n}\n","export const isDebug = false\n","import { Editor, Element, Location } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\n/**\n * Defines a value you'd find in a function's parameters as a replacement for\n * `at`. The benefit of using `BetterAt` is that it allows you to search\n * using an `Element`.\n */\nexport type BetterAt = Location | Element | null\n\n/**\n * Takes a `BetterAt` type which can include an `Element` and returns a\n * Location.\n */\nexport function betterAt(editor: Editor, at: Location | Element): Location {\n if (!Element.isElement(at)) return at\n return ReactEditor.findPath(editor, at)\n}\n","/**\n * Takes a function and returns a new function with the first X arguments of\n * that function pre-filled with the provided values.\n *\n * NOTE:\n *\n * This is not a full implementation of a curry but gives us what we want in a\n * lightweight manner, with low complexity and good typing. Namely, we need to\n * specify how many arguments to curry.\n *\n * This can probably be done in a way where the argument number doesn't have to\n * be specified ahead of time; however, these are the reasons I've kept it this\n * way for now.\n *\n * - It's easier to understand. We don't need to create a recursive TypeScript\n * type.\n * - We only ever need currying a little anyways\n * - It's probably a little more performant this way\n *\n * WARNING FOR GENERICS:\n *\n * If the function you are currying has a generic, you will need to write a\n * generic manually for it then apply it manually using `as`. For example:\n *\n * const curriedToggleElements = curry(toggleElements, editor) as\n * CurriedToggleElements\n */\n\n/**\n * Curry one argument from the left\n */\nexport function curryOne<CurriedArg, RestArgs extends unknown[], R>(\n fn: (curriedArg: CurriedArg, ...restArgs: RestArgs) => R,\n curriedArg: CurriedArg\n): (...args: RestArgs) => R {\n return fn.bind(null, curriedArg)\n}\n\n/**\n * Curry two arguments from the left\n */\nexport function curryTwo<Arg1, Arg2, RestArgs extends unknown[], R>(\n fn: (arg1: Arg1, arg2: Arg2, ...restArgs: RestArgs) => R,\n arg1: Arg1,\n arg2: Arg2\n): (...args: RestArgs) => R {\n return fn.bind(null, arg1, arg2)\n}\n","const IS_MAC_REGEX = /mac os x|macintosh/i\n\nlet isMacValue: boolean | undefined = undefined\n\n/**\n * `isMac` is a function and not a const because `window.navigator` only exists\n * on the browser and will throw an Error on the server.\n */\nexport function isMac() {\n /**\n * Memoized for performance\n */\n if (isMacValue !== undefined) return isMacValue\n try {\n const { userAgent } = window.navigator\n isMacValue = IS_MAC_REGEX.test(userAgent)\n } catch {\n isMacValue = false\n }\n return isMacValue\n}\n","/**\n * Tiny helper to call `e.preventDefault()` and `e.stopPropagation()` as the\n * same time.\n */\nexport function stopEvent(e: Event | React.SyntheticEvent) {\n e.preventDefault()\n e.stopPropagation()\n}\n","import { Ancestor, Editor, Element, NodeEntry, Path } from \"slate\"\n\nimport { BetterAt, betterAt } from \"../core-utils/better-at\"\nimport {\n NodeMatcher,\n standardizeNodeMatcher,\n} from \"../standardize-utils/standardize-node-matcher\"\n\n/**\n * Checks to see if the current selection is inside of a Node that matches\n * `matchNode`.\n */\nexport function findElementUp<T extends Ancestor & Element = Element>(\n editor: Editor,\n matchNode: NodeMatcher,\n { at = editor.selection }: { at?: BetterAt } = {}\n): NodeEntry<T> | undefined {\n // if no selection, there will be no match\n if (at === null) return\n const nextAt = betterAt(editor, at)\n const match = standardizeNodeMatcher(matchNode)\n /**\n * Normally, we are looking up from a range or a point, but if the `at`\n * `Location` is a `Path`, then we need to check for an exact match at the\n * `at` `Location` in addition to looking `Editor.above` the current\n * `at` `Location`\n */\n if (Path.isPath(nextAt)) {\n const nodeEntryExactlyAt = Editor.node(editor, nextAt)\n if (nodeEntryExactlyAt && match(nodeEntryExactlyAt[0])) {\n return nodeEntryExactlyAt as NodeEntry<T>\n }\n }\n // look for a matching element\n return Editor.above(editor, { at: nextAt, match })\n}\n\nexport function findElementUpPath(...args: Parameters<typeof findElementUp>) {\n const entry = findElementUp(...args)\n return entry?.[1]\n}\n","import { Element, Node } from \"slate\"\n\nexport type NodeMatcher = string | string[] | ((node: Node) => boolean)\n\n/**\n * Takes a string or a function that matches a Node and in both cases,\n * returns a function that matches a Node.\n *\n * The `matchNode` argument can either be a function that takes a `Node` and\n * returns a boolean or it can be a string representing the `type` property of\n * an `Element`\n */\n\nexport function standardizeNodeMatcher(\n matchNode: NodeMatcher\n): (node: Node) => boolean {\n if (typeof matchNode === \"function\") return matchNode\n if (typeof matchNode === \"string\")\n return (node: Node) => Element.isElement(node) && node.type === matchNode\n if (Array.isArray(matchNode))\n return (node: Node) =>\n Element.isElement(node) && matchNode.includes(node.type)\n throw new Error(\n `Expected matchNode to be a function, string or array but is ${matchNode}`\n )\n}\n","import { SVGProps } from \"react\"\n\n/**\n * A shortcut type to SVGProps<SVGSVGElement> but also more explicit in its\n * intent and allows for changing the props in the future without another\n * refactor.\n */\nexport type TablerIconProps = SVGProps<SVGSVGElement>\n\n/**\n * Efficient way to create a Tabler Icon.\n *\n * https://tabler-icons.io/\n *\n * - Grab the SVG from the Tabler Icon.\n * - Run it through https://react-svgr.com/playground/?icon=true&typescript=true\n * - Grab everything EXCEPT the first `path` which is unnecessary\n * - Place it as the children of this `<Icon>`\n */\nexport const TablerIcon = ({\n strokeWidth = 1.5,\n ...props\n}: TablerIconProps) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n strokeWidth={strokeWidth}\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 24 24\"\n {...props}\n />\n)\n","import { Range } from \"slate\"\n\nexport function isCollapsed(\n selection: Range | null | undefined\n): selection is Range {\n if (selection == null) return false\n return Range.isCollapsed(selection)\n}\n","import { Element, Node } from \"slate\"\n\nexport function isElementType<T extends Element>(\n node: Node,\n type: T[\"type\"] | Array<T[\"type\"]>\n): node is T {\n if (Array.isArray(type)) {\n return Element.isElement(node) && type.includes(node.type)\n }\n if (typeof type === \"string\") {\n return Element.isElement(node) && node.type === type\n }\n throw new Error(\n `Expected elementType to be string or array of string but is ${type}`\n )\n}\n\nexport function createIsElementType<T extends Element>(\n type: T[\"type\"] | Array<T[\"type\"]>\n): (node: Node) => node is T {\n if (Array.isArray(type)) {\n return (node: Node): node is T =>\n Element.isElement(node) && type.includes(node.type)\n } else {\n return (node: Node): node is T =>\n Element.isElement(node) && type == node.type\n }\n}\n","import { Editor } from \"slate\"\n\nimport { findElementUp } from \"../find-utils/find-element-up\"\nimport { NodeMatcher } from \"../standardize-utils/standardize-node-matcher\"\nimport { isCollapsed } from \"./is-collapsed\"\n\n/**\n * Checks to see if the current selection is at the end of line for a node\n * that matches the `matchNode` argument.\n *\n * The `matchNode` argument can either be a function that takes a `Node` and\n * returns a boolean or it can be a string representing the `type` property of\n * an `Element`\n */\n\nexport function isEndOfElement(\n editor: Editor,\n matchNode: NodeMatcher\n): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const entry = findElementUp(editor, matchNode, { at: selection })\n return !!entry && Editor.isEnd(editor, selection.anchor, entry[1])\n}\n","import { Editor } from \"slate\"\n\nimport { findElementUp } from \"../find-utils/find-element-up\"\nimport { NodeMatcher } from \"../standardize-utils/standardize-node-matcher\"\nimport { isCollapsed } from \"./is-collapsed\"\n\n/**\n * Checks to see if we are currently in an empty element.\n *\n * All these must be true:\n *\n * - There is a selection\n * - The selection is inside the matching element\n * - The matching element is empty\n */\nexport function isInEmptyElement(\n editor: Editor,\n matchNode: NodeMatcher\n): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const entry = findElementUp(editor, matchNode)\n if (entry === undefined) return false\n return Editor.isEmpty(editor, entry[0])\n}\n","import { Editor } from \"slate\"\n\nimport { findElementUp } from \"../find-utils/find-element-up\"\nimport { NodeMatcher } from \"../standardize-utils/standardize-node-matcher\"\nimport { isCollapsed } from \"./is-collapsed\"\n\n/**\n * Checks to see if the current selection is at the end of line for a node\n * that matches the `matchNode` argument.\n *\n * The `matchNode` argument can either be a function that takes a `Node` and\n * returns a boolean or it can be a string representing the `type` property of\n * an `Element`\n */\n\nexport function isStartOfElement(\n editor: Editor,\n matchNode: NodeMatcher\n): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const entry = findElementUp(editor, matchNode, { at: selection })\n return !!entry && Editor.isStart(editor, selection.anchor, entry[1])\n}\n","import { isHotkey } from \"is-hotkey\"\nimport { Editor, Element as SlateElement, Range, Transforms } from \"slate\"\n\nimport { findElementUp, stopEvent } from \"~/src/sink\"\n\nexport const isSpace = isHotkey(\" \")\nexport const isShiftSpace = isHotkey(\"SHIFT+SPACE\")\n\nexport function createAutocompleteSpaceHandler(\n editor: Editor,\n methods: Record<string, undefined | (() => void)>\n) {\n return (e: React.SyntheticEvent<Element, KeyboardEvent>): boolean => {\n /**\n * We support `shift+space` as well because when we are typing something\n * like `## ` sometimes the finger hasn't left the shift key yet. In normal\n * usage, we still get a space and so the feature feels intermittently\n * broken if we don't support `shift+space`.\n */\n if (!isSpace(e.nativeEvent) && !isShiftSpace(e.nativeEvent)) return false\n\n /**\n * Make sure theere is a selection and it's collapsed\n */\n const { selection } = editor\n if (selection === null) return false\n if (Range.isExpanded(selection)) return false\n\n /**\n * Find a convertible block and if we can't find one, exit.\n */\n const convertibleBlockEntry = findElementUp(\n editor,\n (node) =>\n /**\n * NOTE: We alias to SlateElement because this page needs acces to both\n * the global Eleent and the Slate Element.\n */\n SlateElement.isElement(node) &&\n editor.convertElement.isConvertibleElement(node)\n )\n if (!convertibleBlockEntry) return false\n\n /**\n * Find a matching method. Note that the keys in `methods` are the `string`\n * prefixes we are looking for like `##` for heading level 2.\n *\n * If no match, exit.\n */\n const range = {\n anchor: Editor.start(editor, convertibleBlockEntry[1]),\n focus: selection.focus,\n }\n const text = Editor.string(editor, range)\n const method = methods[text]\n if (!method) return false\n\n /**\n * We have a match. Stop other event handlers.\n */\n stopEvent(e)\n\n /**\n * Delete the autocomplete text that came before the space bar was pressed.\n */\n const deleteRange = {\n anchor: Editor.start(editor, convertibleBlockEntry[1]),\n focus: selection.focus,\n }\n Transforms.delete(editor, { at: deleteRange })\n\n /**\n * Execute the matching method.\n */\n method()\n return true\n }\n}\n","import { isHotkey } from \"is-hotkey\"\n\nimport { isMac } from \"../core-utils/is-mac\"\n\nexport function isBetterHotkey(hotkey: string) {\n const modifiedHotkey = hotkey.replace(\n /\\bsuper\\b/g,\n isMac() ? \"cmd+alt\" : \"ctrl+shift\"\n )\n return isHotkey(modifiedHotkey)\n}\n","import { isBetterHotkey } from \"./is-better-hotkey\"\n\n/**\n * The function that is executed when the hotkey is pressed.\n *\n * If it returns `void` (undefined) we assume the Action was executed.\n * If we return a `boolean`, the Action is considered executed if it returns\n * `true` or not handled if it returns `false`.\n */\ntype Action = () => boolean | void\n\ntype IsKeyboardShortcut = (event: KeyboardEvent) => boolean\n\ntype ShortcutTuple = [IsKeyboardShortcut, Action]\n\n/**\n * Creates a `keyDown` handler from an object where the keys are the shortcut\n * and the values are the `Action` function to execute. If the\n * function returns `true`, the event is considered handled and the event\n * is stopped.\n *\n * In some situations, we don't want the event to be stopped.\n *\n * For example, hitting `up` or `down` in a table, starts a `setTimeout` but\n * we want the original keyboard event to be handled by the browser.\n */\n\nexport function createHotkeyHandler(shortcutsObject: Record<string, Action>) {\n /**\n * Don't populate the shortcuts at this point because it will run on the\n * server. We can't run it on the server because we need to determine if we\n * are on Mac or Windows and checking `window.navigate.userAgent` will cause\n * a failure.\n */\n let shortcuts: ShortcutTuple[] | null = null\n\n return function handleShortcuts(\n event: React.SyntheticEvent<Element, KeyboardEvent>\n ) {\n /**\n * We initialize shortcuts once on first usage.\n */\n if (shortcuts == null) {\n shortcuts = Object.entries(shortcutsObject).map(([shortcut, fn]) => [\n isBetterHotkey(shortcut),\n fn,\n ])\n }\n for (const [isShortcut, action] of shortcuts) {\n if (isShortcut(event.nativeEvent)) {\n /**\n * If the keyboardAction returns true then the event has been handled.\n * We can stop the event at this point and exit the loop.\n */\n const response = action()\n if (response === true || response === undefined) {\n event.preventDefault()\n event.stopPropagation()\n return true\n }\n }\n }\n return false\n }\n}\n","import { Editor, Path, Transforms } from \"slate\"\n\n/**\n * Takes a given and makes that specific path dirty with respect to\n * normalization and executes a normalization path (unless in a\n * `withoutNormalizing` block in which case it will wait until it is completed).\n *\n * A few things you should know:\n *\n * - It doesn't dirty the ancestors. So if you are targeting an Element to be\n * dirtied, make sure you aren't dirtying the Text node as that won't cause\n * the parent Element to be dirtied.\n *\n * - It works by setting a key that doesn't make sense to a value and then\n * unsetting it. This adds some unnecessary noise to the list of operations.\n *\n * The ideal method to implement this would be to modify the DIRTY_PATHS and\n * DIRTY_PATH_KEYS directly; however, these are presently not being exported.\n * This should probably be fixed in the future by an exported function called\n * something like `addDirtyPaths`.\n */\nexport function forceNormalizePath(editor: Editor, path: Path) {\n Editor.withoutNormalizing(editor, () => {\n Transforms.setNodes(\n editor,\n // @ts-ignore\n { __DOESNT_MATTER_JUST_TO_START_NORMALIZING__: \"123\" },\n { at: path }\n )\n Transforms.setNodes(\n editor,\n // @ts-ignore\n { __DOESNT_MATTER_JUST_TO_START_NORMALIZING__: null },\n { at: path }\n )\n })\n}\n","import { Descendant, Editor, NodeEntry } from \"slate\"\n\n/**\n * This normalization utility is useful when you need to adjust an Element\n * depending on the Element before or after it.\n *\n * For example, if two of the same nodes are next to each other, they can be\n * merged together.\n *\n * Or in the case of a numbered list, we want to reset the counter only if\n * the list is deeper than the previous one.\n *\n * The thing that makes these method efficient is that it can often replace\n * having to search through all children of the parent of the current element.\n * Normally, to compare siblings, you'd have to look at the parent in order\n * to make sure you normalize siblings propertly; however, this method will\n * look both at the pair before/current and current/after to make sure that\n * neighbor siblings do the right thing.\n *\n * When used through a full normalization, it can solve bigger problems. For\n * example, if you have 5 elements that are all the same and they need to\n * all be merged, one by one, they will merged into a single Element.\n *\n * HINT:\n *\n * If there is a bug related to not being able to find a Path, remember to\n * return `true` in the `transform` function when a `transform` is executed.\n *\n * After a `transform` is run, the state of the document is changed and\n * running the second `transform` may result in accessing an invalid path.\n */\nexport function normalizeSiblings<T extends Descendant>(\n editor: Editor,\n entry: NodeEntry<T>,\n transform: (a: NodeEntry<T>, b: NodeEntry<T>) => boolean\n): boolean {\n const [, path] = entry\n\n const prevEntry = Editor.previous<T>(editor, { at: path })\n if (prevEntry && transform(prevEntry, entry)) return true\n\n const nextEntry = Editor.next<T>(editor, { at: path })\n if (nextEntry && transform(entry, nextEntry)) return true\n\n return false\n}\n","import { Editor, Path, Transforms } from \"slate\"\n\n/**\n * Puts the selection at the start of a Node at the given path.\n */\nexport function selectStartOfElement(editor: Editor, path: Path) {\n Transforms.select(editor, Editor.start(editor, path))\n}\n\n/**\n * Puts the selection at the start of a Node at the given path.\n */\nexport function selectEndOfElement(editor: Editor, path: Path) {\n Transforms.select(editor, Editor.end(editor, path))\n}\n","import { Element } from \"slate\"\n\n/**\n * The TargetElement can be specified either as the actual value or as a\n * function that takes a srcElement and returns the targetElement.\n */\nexport type TargetElement<T extends Element = Element> =\n | Omit<T, \"children\">\n | ((srcElement: Element) => Omit<T, \"children\">)\n\n/**\n * TODO:\n *\n * This should probably just be moved into the `rewrapElement` function page\n * since it is not used outside of it. Originally, this may have served a\n * dual purpose but currently it seems like it only exists for the use of\n * `rewrapElement`.\n */\n\n/**\n * This function takes a `srcElement` and the idea is that we convert it into\n * some other type of element, which is the `targetElement`.\n *\n * The `TargetElement` can be specified either as:\n *\n * - an actual `Element` but without the `children`. This is because we are\n * converting the `srcElement` to the `targetElement` and the `targetElement`\n * will take on the `children` of the `srcElement`\n *\n * - A function that takes the `srcElement` and returns the `targetElement`\n * without the `children`. This form of `TargetElement` can be useful in\n * cases where we want to retain some of the properties of the `srcElement`.\n * An example of this is a list item where we convert from a bullet to a\n * numbered item. We would like to keep the `depth` information if it exists\n * in this scenario.\n */\nexport function createTargetElement<T extends Element>(\n srcElement: Element,\n targetElement: TargetElement<T>\n) {\n if (typeof targetElement !== \"function\") return targetElement\n return targetElement(srcElement)\n}\n","import { Editor, Element, Location, Path, Transforms } from \"slate\"\n\nimport { findElementUp } from \"~/src/sink\"\n\n/**\n * Inserts an Element into the document such that if it is in a `isMaster`\n * element (i.e. an Element that has a number of dependants like a table or\n * code block) then then inserted Element will appear after the `isMaster`\n * element.\n *\n * This prevents invalid states from happening like inserting a table inside\n * a table, or a code block in a table, or a table in a code block.\n */\nexport function insertRootElement(\n editor: Editor,\n element: Element,\n { at = editor.selection }: { at?: Location | null } = {}\n): boolean {\n /**\n * If there's no `at` then insertion does not happen\n */\n if (at == null) return false\n /**\n * Look for a parent that `isMaster`\n */\n const entry = findElementUp(\n editor,\n (node) => Element.isElement(node) && editor.isMaster(node)\n )\n if (entry == null) {\n /**\n * If not `isMaster` then do a regular insert, select the original\n * insertion point and move forward to select the first position inside\n * the newly inserted element.\n */\n const selection = editor.selection\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at })\n if (selection) {\n Transforms.select(editor, selection)\n Transforms.move(editor)\n }\n })\n } else {\n /**\n * If it `isMaster` then find the next adjacent path to the master, insert\n * there, and then select at the start of the insertion point.\n */\n const nextPath = Path.next(entry[1])\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at: nextPath })\n Transforms.select(editor, Editor.start(editor, nextPath))\n })\n }\n return true\n}\n","import { Editor, Element, NodeEntry, Path, Transforms } from \"slate\"\n\nimport {\n createTargetElement,\n TargetElement,\n} from \"../standardize-utils/target-element\"\n\n/**\n * Takes an existing Element at path `at` and swaps out that Element with a\n * new Element. It does this by unwrapping the Element and rewrapping it with\n * the new Element.\n *\n * This is useful because if we do it this way, we can preserve the selection.\n */\nexport function rewrapElement<T extends Element = Element>(\n editor: Editor,\n targetElement: TargetElement<T>,\n at: Path\n) {\n Editor.withoutNormalizing(editor, () => {\n const originalEntry = Editor.node(editor, at) as NodeEntry<Element>\n const nextElement = createTargetElement(originalEntry[0], targetElement)\n /**\n * Technicall, it's Omit<Element, 'children'> but `wrapNodes` actually\n * accepts that just fine so we override the type.\n */\n Transforms.wrapNodes(editor, nextElement as T, { at })\n Transforms.unwrapNodes(editor, { at: [...at, 0] })\n })\n}\n","import { Editor, EditorNodesOptions, Node, Transforms } from \"slate\"\n\n/**\n * An improved version of `setNodes` that takes a `convert` option.\n *\n * In existing `setNodes` we can specify how we want to setNodes statically.\n * That is, before we execute `setNodes` we need to know which properties\n * we want to set.\n *\n * This version of `setNodes` allows us to dynamically setNodes by allowing\n * us to specify a function argument. The function takes the original value of\n * an Element and returns the match.\n */\nexport function setNodesDynamic<T extends Node>(\n editor: Editor,\n convert: (node: T) => Partial<T>,\n options: EditorNodesOptions<T>\n) {\n const entries = Array.from(Editor.nodes<T>(editor, options))\n if (entries.length === 0) return false\n for (const entry of entries) {\n const [node] = entry\n Transforms.setNodes(editor, convert(node), { at: entry[1] })\n }\n return true\n}\n","import { Editor } from \"slate\"\n\nexport function onPaste(\n editor: Editor,\n e: React.ClipboardEvent<HTMLDivElement>\n) {\n const clipboardData = e.clipboardData\n const { types } = clipboardData\n\n // Remove debug console log\n // console.log(clipboardData.getData(\"text/html\"))\n\n /**\n * We don't want to handle it if it's not just plain text. If it is\n * plain text, it will have only one type and it will be \"text/plain\".\n * HTML, for example, also has \"text/plain\" but also \"text/html\"\n */\n if (types.length > 1) return false\n if (types[0] !== \"text/plain\") return false\n\n /**\n * Check to make sure the text is a URL\n */\n const text = clipboardData.getData(\"text/plain\")\n if (!isUrl(text)) return false\n\n /**\n * If it is a URL, then insert the link\n */\n e.preventDefault()\n e.stopPropagation()\n editor.anchor.insertLink(text)\n return true\n}\nfunction isUrl(s: string): boolean {\n let url\n try {\n url = new URL(s)\n } catch (_) {\n return false\n }\n return (\n url.protocol === \"http:\" ||\n url.protocol === \"https:\" ||\n url.protocol === \"mailto:\"\n )\n}\n","import { Editor, Node, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"../../sink\"\nimport { AnchorElement } from \"..\"\n\nexport function editLink(\n editor: Editor,\n { href, title, text }: { href: string; title?: string; text?: string },\n { at }: { at?: BetterAt }\n) {\n const link = findElementUp(editor, \"anchor\", { at })\n if (!link) return false\n\n const [element, path] = link\n\n // Update href and title\n Transforms.setNodes<AnchorElement>(editor, { href, title }, { at: path })\n\n // Update text if provided and different from current\n if (text !== undefined) {\n const currentText = Node.string(element)\n if (text !== currentText) {\n // Remove all children and insert new text\n Editor.withoutNormalizing(editor, () => {\n const childCount = element.children.length\n for (let i = childCount - 1; i >= 0; i--) {\n Transforms.removeNodes(editor, { at: [...path, i] })\n }\n Transforms.insertNodes(editor, { text }, { at: [...path, 0] })\n })\n }\n }\n\n return true\n}\n","import { Editor, Range, Text, Transforms } from \"slate\"\n\nexport function insertLink(\n editor: Editor,\n href: string,\n text: string = href,\n { select = true, title }: { select?: boolean; title?: string } = {}\n) {\n /**\n * If there is no selection, we default by inserting at the start of document.\n */\n const selection = editor.selection || {\n anchor: Editor.start(editor, [0]),\n focus: Editor.start(editor, [0]),\n }\n if (Range.isCollapsed(selection)) {\n /**\n * Insert the node and select it if select is true\n */\n Transforms.insertNodes(\n editor,\n {\n type: \"anchor\",\n href,\n title,\n children: [{ text }],\n },\n { select, at: selection }\n )\n /**\n * If select is true then select the inserted link\n */\n if (select && editor.selection) {\n const entry = Editor.node(editor, editor.selection)\n Transforms.select(editor, entry[1])\n }\n } else {\n /**\n * If there is a selection, we wrap the selection with our anchor.\n */\n Transforms.wrapNodes(\n editor,\n { type: \"anchor\", href, title, children: [] },\n {\n split: true,\n match: (node) => Text.isText(node) || Editor.isInline(editor, node),\n }\n )\n }\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"../../sink\"\n\nexport function removeLink(editor: Editor, { at }: { at?: BetterAt }) {\n const link = findElementUp(editor, \"anchor\", { at })\n if (!link) return false\n Transforms.unwrapNodes(editor, { at: link[1] })\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport { editLink } from \"./editLink\"\nimport { insertLink } from \"./insertLink\"\nimport { removeLink } from \"./removeLink\"\n\nexport function createAnchorMethods(editor: Editor) {\n return {\n insertLink: curryOne(insertLink, editor),\n removeLink: curryOne(removeLink, editor),\n editLink: curryOne(editLink, editor),\n }\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\n/**\n * If there is an anchor node inside an anchor node, unwrap the inner anchor\n * node as that is not allowed.\n *\n * Another approach would be to lift the nodes but I think unwrapping the\n * inner one makes more sense. Consider these two scenarios (keeping in mind\n * that they will likely be rare):\n *\n * - User selects text that includes a link. Then user links it. The user would\n * have a strong expectation that the link just applied would override the\n * link on the inside.\n *\n * - The opposite: User select text inside an existing link then tries to link\n * it. That's unusual and while the user may expect that inner selection to\n * get linked, I think this is a rare enough case whereas the prior one seems\n * like a slightly more natural one.\n *\n * We could, of course, solve both of these by adding more code paths at the\n * time the link is inserted. That won't change this normalization code and\n * not sure if it is worth the extra complexity.\n */\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n if (!Element.isElement(entry[0])) return false\n if (entry[0].type !== \"anchor\") return false\n const children = entry[0].children\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (!Element.isElement(child) || child.type !== \"anchor\") continue\n Transforms.unwrapNodes(editor, { at: [...entry[1], i] })\n return true\n }\n return false\n}\n","import { clsx } from \"clsx\"\nimport React from \"react\"\nimport { useEffect, useRef } from \"react\"\nimport { useSelected, useSlate } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { useLayer } from \"../../use-layer\"\nimport { AnchorElement } from \"../index\"\nimport { $Anchor, $Edge } from \"../styles\"\nimport { AnchorDialog } from \"./AnchorDialog\"\n\nexport function Anchor({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<AnchorElement>) {\n const startEdgeRef = useRef<HTMLSpanElement>(null)\n const anchorRef = useRef<HTMLAnchorElement>(null)\n const selected = useSelected()\n const editor = useSlate()\n const dialog = useLayer(\"dialog\")\n\n /**\n * TODO:\n *\n * Finish implementing the anchor dialog.\n *\n * Stopped partway through because the entire document is being re-rendered\n * on every keypress.\n */\n\n useEffect(() => {\n const anchor = anchorRef.current\n const startEdge = startEdgeRef.current\n if (!anchor || !startEdge) return\n /**\n * NOTE: Do not use `focused && selected` here because when we click or\n * focus on the pop up dialogs themselves, this will cause the dialogs to\n * close.\n *\n * TODO: Figure out how to make the dialogs not close when clicking on them.\n *\n * It has to support these use cases:\n *\n * - Closes when user clicks somewhere in the document outside the link\n * - Stays open when user clicks on the dialog\n * - Stays open when user is in an input in the dialog\n * - Closes when the editor loses focus but stays open when the editor loses\n * focus to the anchor dialog or the anchor edit dialog\n */\n // Only show dialog when the link is precisely selected (not part of a larger selection)\n const hasSelection = editor.selection &&\n editor.selection.anchor.offset !== editor.selection.focus.offset;\n\n if (selected && !hasSelection) {\n /**\n * The setTimeout delay is necessary when first clicking into the browser\n * and when switching from one link to another. Without it, the dialog\n * will not open.\n */\n setTimeout(() => {\n dialog.open(() => (\n <AnchorDialog\n destAnchor={anchor}\n destStartEdge={startEdge}\n element={element}\n />\n ))\n })\n } else {\n dialog.close()\n }\n }, [selected, element])\n\n return (\n <$Anchor\n className={clsx({ \"--selected\": selected })}\n href={element.href}\n target={element.target}\n {...attributes}\n ref={anchorRef}\n >\n {/* Edge allow Chrome to differentiate in/out of the link */}\n <$Edge ref={startEdgeRef} contentEditable={false} />\n <span>{children}</span>\n {/* Edge allow Chrome to differentiate in/out of the link */}\n <$Edge contentEditable={false} />\n </$Anchor>\n )\n}\n","import { createContext, useState } from \"react\"\n\nimport { Portal } from \"./portal\"\nimport { Layer, LayersContextValue, LayersRecord } from \"./types\"\n\n/**\n * Wrap this around the Component in which you want to have the ability to\n * display one or more layers at once.\n */\nexport const LayersContext = createContext<LayersContextValue>(\n /**\n * This is set to an invalid value and then typecast as the correct type.\n *\n * This is okay though because in `LayersProvider` we set the value to the\n * proper type before they are used for the first time.\n */\n {} as LayersContextValue\n)\n\nexport const LayerContext = createContext<Layer>({} as Layer)\n\n/**\n * The `Layers` Component should be wrapped around the Component or Components\n * which you want to have layer support.\n *\n * The `useLayer` hook must be called inside a `Layers` Component.\n *\n * It provides these necessary functions:\n *\n * - Makes available the resources necessary to open and close layers.\n *\n * - Renders the currently open layers to the DOM at the top level of the\n * DOM. We do this to simplify positioning as we can position everything\n * relative to the full window which is what is returned by\n * `getBoundingClientRect`\n *\n * NOTE:\n *\n * As a design decision, we wrap many components with the Layer instead of\n * having a Layer per component. This design decision is important because\n * we may want to open multiple layers of the same type and if we open another\n * layer of the same type, we want any other layers to close.\n *\n * For example, consider a Dialog. If we open a differnet Dialog, we want the\n * first one to close. This can only be done when a single component knows\n * about the existence of both.\n */\nexport function Layers({ children }: { children: React.ReactNode }) {\n const [layers, setLayers] = useState<LayersRecord>({})\n\n /**\n * Open a layer of the given type\n */\n function openLayer(layer: Layer) {\n setLayers((layers) => {\n return {\n ...layers,\n [layer.type]: layer,\n }\n })\n }\n\n /**\n * Close a layer of the given type\n */\n function closeLayer(layerType: string) {\n setLayers((layers) => {\n const nextLayers = { ...layers }\n delete nextLayers[layerType]\n return nextLayers\n })\n }\n\n /**\n * - provide the layers context\n * - render the layers at the top of the DOM using a Portal\n */\n return (\n <LayersContext.Provider\n value={{ layers, setLayers, openLayer, closeLayer }}\n >\n {children}\n {Object.entries(layers).map(([, layer]) => {\n return (\n <Portal key={layer.type}>\n <LayerContext.Provider value={layer}>\n <layer.Component />\n </LayerContext.Provider>\n </Portal>\n )\n })}\n </LayersContext.Provider>\n )\n}\n","import { createPortal } from \"react-dom\"\n\n/**\n * Portal to `document.body`\n *\n * NOTE:\n * Consider creating a version of Portal with a Reset in it.\n *\n * The reason is that when showing a portal, it will carry the baggage of\n * any styling from `<html>` and `<body>` element.\n */\nexport function Portal({ children }: { children: React.ReactNode }) {\n return createPortal(children, document.body)\n}\n","import { FunctionComponent, useContext } from \"react\"\n\nimport { LayersContext } from \"./layers\"\nimport { Layer } from \"./types\"\n\n/**\n * `useLayer` may only be called when it is inside a Component that is itself\n * nested under the `Layers` component. This is necessary because `useLayer`\n * uses a React Context which is set up in the `Layers` component.\n *\n * Using the `useLayer` hook returns a layer object that has an `open` and\n * `close` method. You can use it something like this:\n *\n * ```typescript\n * function MyComponent() {\n *\n * const tooltip = useLayer('tooltip')\n *\n * const openTootlip = () => {\n * tooltip.open(() => <Tooltip title=\"Hey Dudes\" />)\n * }\n *\n * return <div\n * onMouseEnter={openTooltip}\n * onMouseLeave={tooltip.close}\n * >Thing that needs a tooltip</div>\n * }\n * ```\n *\n * In this scenario, it opens a `Tooltip` component when the mouse enters the\n * div and closes it when the mouse leave it.\n *\n * This library is simple but flexible enough to be used to handle different\n * kinds of components that pop up in the DOM.\n *\n * - tooltips\n * - dialog boxes positioned where a button is clicked\n * - dialog boxes positioned in the center of a viewport\n * - notifications\n *\n * `useLayer` is designed to handle just the opening and closing of the layers\n * that overlays on top of all the other components at the top of the DOM.\n *\n * It also ensures only one of each kind of layer is open at a time. So when\n * a second tooltip is opened, the first is closed.\n *\n * The positioning of the tooltips, dialogs and notifications, especially when\n * the position is relative to another element like a button that was clicked\n * it the domain of the `useReposition` micro library.\n *\n * These libraries are not tied together in any way (there is nothing\n * opinionated that ties them toegher); however they were designed and built\n * at the same time and work together well to solve all the issues related to\n * popup windows/dialogs/tooltips of any kind.\n */\nexport function useLayer(type: string) {\n const { openLayer, closeLayer, layers } = useContext(LayersContext)\n\n /**\n * Call this method to open a layer that contains the Component at the given\n * layer type.\n *\n * Opening a layer of this type will close any other layers of this type.\n * For example, if a `tooltip` layer was currently open, opening a new\n * tooltip would close the previously open one.\n *\n * When opening a layer, we pass in a function (that takes no arguments) and\n * returns our rendered Component something like:\n *\n * ```ts\n * const dialog = useLayer('dialog')\n *\n * const openDialog = () => {\n * dialog.open(() => <MyDialog title=\"My Title\" />)\n * }\n * ```\n *\n * If you are getting TypeScript issues, especially when passing props as\n * properties of some other object, the easiest way to fix these issues are\n * to assign those values to a `const` first. This can happen when the\n * values on the object could potentially be `undefined` or change during\n * a re-render.\n *\n * For example, this could give typing issues:\n *\n * ```ts\n * type Item = {\n * title?: string\n * }\n *\n * const dialog = useLayer('dialog')\n *\n * const openDialog = () => {\n * if (item.title === undefined) return\n * dialog.open(() => <MyDialog title={item.title} />)\n * }\n * ```\n *\n * It's a little non-obvious because it looks like we did a check to make\n * sure that `item.title` is defined. But remember that it could change\n * during a re-render.\n *\n * Here's how to fix this.\n *\n * ```ts\n * type Item = {\n * title?: string\n * }\n *\n * const dialog = useLayer('dialog')\n *\n * const openDialog = () => {\n * if (item.title === undefined) return\n * const title = item.title\n * dialog.open(() => <MyDialog title={title} />)\n * }\n * ```\n *\n * Now `title` is of type `string` because we already asserted that\n * `item.title` was a string. We assigned it to a `const` meaning that it\n * won't change, even if re-rendered later.\n */\n function open(Component: FunctionComponent<Record<string, never>>) {\n const layer: Layer = { type, Component }\n openLayer(layer)\n }\n\n /**\n * Call this method to close the current layer of the given layer type.\n */\n function close() {\n closeLayer(type)\n }\n\n return {\n open,\n close,\n layer: layers[type],\n type,\n }\n}\n","import styled from \"@emotion/styled\"\n\nexport const $Anchor = styled(\"a\")`\n /**\n * Link colors\n */\n color: var(--link-color, blue);\n &:hover {\n color: var(--link-hover-color, blue);\n }\n /**\n * When the cursor is in the anchor and not outside the anchor, we style the\n * anchor with a very light shade. This is enough to subtly intuit to the user\n * that when they type, it will appear inside the link. When the shade is\n * not present, they intuit they are just outside the link.\n */\n border-radius: 0.125em;\n transition: background-color 250ms;\n &.--selected {\n background: var(--blue-50);\n }\n`\n/**\n * This edge piece that are at the edge of the inside of the anchor are visibly\n * designed to be 1px wide. A <span> can't be given a width so we fake this by\n * creating an empty span with 1px of width.\n */\nexport const $Edge = styled(\"span\")`\n display: inline;\n padding: 0 1px 0 0;\n`\n\n/**\n * Shows progress bar of an uploading attachment. This part is the outline.\n */\nexport const $ProgressBar = styled(\"span\")`\n position: fixed;\n width: 100px;\n background: var(--shade-50);\n height: 8px;\n border-radius: 7px;\n border: 1px solid var(--shade-400);\n overflow: hidden;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n`\n\n/**\n * Show the fill part of the progress bar.\n */\nexport const $ProgressBarFill = styled(\"span\")`\n position: absolute;\n left: 0;\n top: 0;\n height: 14px;\n background: var(--blue-400);\n transition: width 100ms linear;\n`\n","import styled from \"@emotion/styled\"\nimport { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { $Panel } from \"../../shared-overlays\"\nimport { useLayer } from \"../../use-layer\"\nimport { useAbsoluteReposition } from \"../../use-reposition\"\nimport { useTooltip } from \"../../use-tooltip\"\nimport { AnchorElement } from \"../index\"\nimport { AnchorEditDialog } from \"./AnchorEditDialog\"\nimport { ExternalLinkIcon, LinkOffIcon, PencilIcon } from \"./icons\"\n\nconst $AnchorDialog = styled($Panel)`\n position: absolute;\n display: flex;\n width: 20em;\n z-index: 10;\n padding: 1em;\n color: var(--shade-400);\n\n .--icons {\n display: flex;\n overflow: hidden;\n flex: 0 0 6em;\n }\n\n .--link {\n text-decoration: none;\n display: flex;\n flex: 0 0 14em;\n overflow: hidden;\n color: var(--shade-400);\n &:hover {\n color: var(--blue-600);\n }\n transition: all 200ms;\n }\n\n .--url {\n margin-left: 0.5em;\n .--hostname {\n font-size: 0.875em;\n width: 14em;\n line-height: 1.5em;\n color: var(--blue-600);\n overflow-wrap: break-word;\n /* width: 13.5em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis; */\n }\n .--pathname {\n margin-top: 0.125em;\n font-size: 0.75em;\n width: 16.25em;\n line-height: 1.5em;\n overflow-wrap: break-word;\n }\n .--tooltip {\n box-sizing: border-box;\n position: relative;\n margin-top: 1em;\n font-size: 0.875em;\n width: 14em;\n line-height: 1.5em;\n background: var(--shade-200);\n border-radius: 0.5em;\n padding: 0.5em 0.75em;\n color: var(--shade-600);\n overflow-wrap: break-word;\n }\n .--tooltip::before {\n content: \"\";\n position: absolute;\n top: -0.5em; /* Height of the triangle */\n left: 0.5em; /* Position it on the left side */\n border-left: 0.5em solid transparent; /* Half the width of the triangle */\n border-right: 0.5em solid transparent; /* Half the width of the triangle */\n border-bottom: 0.5em solid var(--shade-200); /* Height and color of the triangle */\n }\n }\n\n .--icon {\n cursor: pointer;\n margin-left: 0.5em;\n &:hover {\n color: var(--blue-600);\n }\n }\n\n svg {\n flex: 0 0 auto;\n width: 1.25em;\n height: 1.25em;\n stroke-width: 1.5;\n }\n`\n\nfunction parseUrl(s: string): { hostname: string; pathname: string } {\n try {\n const url = new URL(s)\n return { hostname: url.hostname, pathname: url.pathname }\n } catch {\n return { hostname: \"\", pathname: \"\" }\n }\n}\n\nexport function AnchorDialog({\n destAnchor,\n destStartEdge,\n element,\n}: {\n destAnchor: HTMLAnchorElement\n destStartEdge: HTMLSpanElement\n element: AnchorElement\n}) {\n const dialog = useLayer(\"dialog\")\n const editor = useSlateStatic()\n const url = parseUrl(element.href)\n const style = useAbsoluteReposition(\n { destAnchor, destStartEdge },\n ({ destAnchor, destStartEdge }) => {\n return {\n left: destStartEdge.left,\n top: destAnchor.top + destAnchor.height,\n }\n }\n )\n\n const removeTooltip = useTooltip({ title: \"リンクを削除\" })\n const editTooltip = useTooltip({ title: \"リンクを編集\" })\n\n const removeLink = useCallback(() => {\n editor.anchor.removeLink({ at: element })\n // Close the dialog after removing the link\n dialog.close()\n }, [editor, dialog])\n\n const openEditDialog = useCallback(() => {\n /**\n * Force close the tooltip otherwise it will stay open because the\n * `onMouseLeave` never gets called. Technically, the mouse never leaves\n * the icon through a mouse movement. The edit icon simply disappears.\n */\n editTooltip.onMouseLeave()\n dialog.open(() => {\n return (\n <AnchorEditDialog\n destAnchor={destAnchor}\n destStartEdge={destStartEdge}\n element={element}\n />\n )\n })\n }, [destAnchor, destStartEdge, element])\n\n return (\n <$AnchorDialog contentEditable={false} style={style}>\n <a\n className=\"--link\"\n href={element.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <ExternalLinkIcon />\n <div className=\"--url\">\n <div className=\"--hostname\">{url.hostname}</div>\n {url.pathname === \"\" || url.pathname === \"/\" ? null : (\n <div className=\"--pathname\">{url.pathname}</div>\n )}\n {element.title == null || element.title === \"\" ? null : (\n <div className=\"--tooltip\">{element.title}</div>\n )}\n </div>\n </a>\n <span className=\"--icons\">\n <span\n className=\"--icon\"\n onClick={removeLink}\n onMouseEnter={removeTooltip.onMouseEnter}\n onMouseLeave={removeTooltip.onMouseLeave}\n >\n <LinkOffIcon />\n </span>\n <span\n className=\"--icon\"\n onMouseEnter={editTooltip.onMouseEnter}\n onMouseLeave={editTooltip.onMouseLeave}\n onClick={openEditDialog}\n >\n <PencilIcon />\n </span>\n </span>\n </$AnchorDialog>\n )\n}\n","import React, { useRef } from \"react\"\n\nimport { $CloseMask } from \"../../styles/$CloseMask\"\n\n/**\n * Add this `CloseMask` before the Component you want this `CloseMask` to be\n * the background for.\n *\n * When users click on the `CloseMask`, it will close the layer.\n */\nexport function CloseMask({ close }: { close: () => void }) {\n const ref = useRef<HTMLDivElement>(null)\n return <$CloseMask ref={ref} onClick={close} />\n}\n","import styled from \"@emotion/styled\"\n\nexport const $CloseMask = styled(\"div\")`\n position: fixed;\n user-select: none;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow-y: auto;\n background: rgba(0, 0, 0, 0.01);\n`\n","import { isMac } from \"~/src/sink\"\n\n/**\n * Character Reference\n *\n * Ctrl+P Ctrl+Shift+P Ctrl+Alt+P\n * ⌘P ⇧⌘P ⌥⌘P\n */\n\nexport const key = {\n cmd: \"\\u2318\",\n ctrl: \"\\u2303\",\n shift: \"⇧\",\n opt: \"⌥\",\n enter: \"⏎\",\n}\n\nconst MAC_KEYS = {\n shift: key.shift,\n opt: key.opt,\n alt: key.opt,\n ctrl: key.ctrl,\n mod: key.cmd,\n cmd: key.cmd,\n enter: key.enter,\n super: `${key.opt}${key.cmd}`,\n}\n\nconst PC_KEYS = {\n alt: \"ALT\",\n ctrl: \"CTRL\",\n opt: \"ALT\",\n shift: \"SHIFT\",\n mod: \"CTRL\",\n cmd: \"CTRL\",\n enter: key.enter,\n super: \"CTRL+SHIFT\",\n}\n\nfunction pull<T>(arr: T[], value: T): void {\n const index: number = arr.findIndex((el: T) => el === value)\n if (index !== -1) {\n arr.splice(index, 1)\n }\n}\n\nfunction formatMac(segments: string[]) {\n const result = []\n Object.entries(MAC_KEYS).forEach(([key, symbol]) => {\n if (segments.includes(key)) {\n result.push(symbol)\n pull(segments, key)\n }\n })\n result.push(...segments.map((s) => s.toUpperCase()))\n return result.join(\"\")\n}\n\nfunction formatPC(segments: string[]) {\n const result = []\n Object.entries(PC_KEYS).forEach(([key, symbol]) => {\n if (segments.includes(key)) {\n result.push(symbol)\n pull(segments, key)\n }\n })\n result.push(...segments.map((s) => s.toUpperCase()))\n return result.join(\"+\")\n}\n\nexport function formatHotkey(shortcut: string) {\n const segments = shortcut.toLowerCase().split(\"+\")\n if (isMac()) {\n return formatMac(segments)\n } else {\n return formatPC(segments)\n }\n}\n","import { useRef } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { useAbsoluteReposition } from \"~/src/use-reposition\"\n\nimport { $Menu, $MenuDivider } from \"../../../toolbar-plugin/styles\"\nimport { MenuItemData } from \"../../types\"\nimport { CloseMask } from \"../CloseMask\"\nimport { MenuItem } from \"./MenuItem\"\n\nexport function Menu({\n dest,\n items,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n items: MenuItemData[]\n}) {\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(null)\n const style = useAbsoluteReposition({ src: ref, dest }, ({ dest }) => {\n return { left: dest.left - 8, top: dest.top + dest.height }\n })\n\n return (\n <>\n <CloseMask close={close} />\n <$Menu ref={ref} style={style}>\n {items.map((item, index) => {\n if (item === \"divider\") {\n return <$MenuDivider key={index} />\n } else if (item.show && !item.show(editor)) {\n return null\n } else {\n return (\n <MenuItem\n key={index}\n editor={editor}\n item={item}\n close={close}\n dest={dest}\n />\n )\n }\n })}\n </$Menu>\n </>\n )\n}\n","import { Rect } from \"../types\"\n\n/**\n * Returns a `Rect` representing the `fixed` positioning coordinates of\n * the `HTMLElement`\n */\nexport function getFixedRect(domElement: HTMLElement): Rect {\n const bounds = domElement.getBoundingClientRect()\n return {\n top: bounds.top,\n right: bounds.right,\n bottom: bounds.bottom,\n left: bounds.left,\n width: bounds.width,\n height: bounds.height,\n }\n}\n","import { Rect } from \"../types\"\nimport { getFixedRect } from \"./get-fixed-rect\"\n\n/**\n * Returns a `Rect` representing the `absolute` positioning coordinates of\n * the `HTMLElement`\n *\n * NOTE: we add `window.scrollY` to get the `absolute` position.\n */\nexport function getAbsoluteRect(domElement: HTMLElement): Rect {\n const rect = getFixedRect(domElement)\n const { scrollY } = window\n return Object.assign(rect, {\n top: rect.top + scrollY,\n bottom: rect.bottom + scrollY,\n })\n}\n","import { Rect } from \"../types\"\n\n/**\n * Returns a `Rect` representing the `fixed` positioning coordinates of\n * the window viewport.\n */\nexport function getFixedViewport(): Rect {\n /**\n * Get the width of the viewport not including the scrollbar\n *\n * https://stackoverflow.com/a/25298418\n */\n const width =\n document.documentElement.clientWidth || document.body.clientWidth\n return {\n top: 0,\n right: width,\n bottom: window.innerHeight,\n left: 0,\n width: width,\n height: window.innerHeight,\n }\n}\n","import { Rect } from \"../types\"\nimport { getFixedViewport } from \"./get-fixed-viewport\"\n\n/**\n * Returns a `Rect` representing the `absolute` positioning coordinates of\n * the window viewport.\n *\n * NOTE: we add `window.scrollY` to get the `absolute` position.\n */\nexport function getAbsoluteViewport(): Rect {\n const rect = getFixedViewport()\n return Object.assign(rect, {\n top: window.scrollY,\n bottom: window.scrollY + rect.height,\n })\n}\n","var objectMapValues = map;\n\n/*\n // returns a new object with the predicate applied to each value\n // like just-map-object, but (value, key, object) are passed to the predicate\n map({a: 3, b: 5, c: 9}, (value) => value + 1); // {a: 4, b: 6, c: 10}\n map({a: 3, b: 5, c: 9}, (value, key) => value + key); // {a: 3a, b: 5b, c: 9c}\n map({a: 3, b: 5, c: 9}, (value, key, object) => object.b); // {a: 5, b: 5, c: 5}\n*/\n\nfunction map(obj, predicate) {\n var result = {};\n var keys = Object.keys(obj);\n var len = keys.length;\n for (var i = 0; i < len; i++) {\n var key = keys[i];\n result[key] = predicate(obj[key], key, obj);\n }\n return result;\n}\n\nexport {objectMapValues as default};\n","import mapValues from \"just-map-values\"\nimport { RefObject } from \"react\"\n\nimport { MapHTMLElementLikeRecordToRectRecord, Rect } from \"./types\"\n\n/**\n * Tries to convert an `HTMLElement` to a `Rect` using the supplied\n * `convertElementToRect` method.\n *\n * The input Record can have as its values either an `HTMLElement` or a\n * `RefObject<HTMLElement>`. When it is a `RefObject` then it may or may not\n * refer to an `HTMLElement` so...\n *\n * - If the value is an `HTMLElement` we convert it to a `Rect`\n * - If the value is a `RefObject<HTMLElement>` we convert it to a\n * `Rect | null` depending on whether the `RefObject` contains the\n * `HTMLElement`.\n */\nexport function mapHTMLElementLikeRecordToRectRecord<\n T extends Record<string, HTMLElement | RefObject<HTMLElement>>\n>(\n elementLikeRecord: T,\n converElementToRect: (element: HTMLElement) => Rect\n): MapHTMLElementLikeRecordToRectRecord<T> {\n const rectRecord = mapValues(elementLikeRecord, (value) => {\n const maybeHTMLElement =\n value instanceof HTMLElement ? value : value.current\n const nextValue = maybeHTMLElement\n ? converElementToRect(maybeHTMLElement)\n : null\n return nextValue\n }) as MapHTMLElementLikeRecordToRectRecord<T>\n return rectRecord\n}\n","import { useEffect } from \"react\"\n\nimport {\n useThrottledRefresh,\n UseThrottledRefreshReturnType,\n} from \"./use-throttled-refresh\"\n\n/**\n * Refreshes the Component whenever the page is resized or the window is\n * scrolled. This is because these are usually the only two events that cause\n * the elements on a page to be repositioned.\n *\n * If there are yet other events that can cause the elements to be repositioned\n * or resized, you can also call the returned `refresh` method. This will\n * update the components while still respected the fact that the updates will\n * be throttled so as not to overload the browser.\n */\nexport function useReposition(): UseThrottledRefreshReturnType {\n /**\n * Create a throttled `refresh` method.\n */\n const refresh = useThrottledRefresh()\n\n /**\n * refresh on page resize or scroll (throttled)\n */\n useEffect(() => {\n refresh()\n window.addEventListener(\"resize\", refresh)\n window.addEventListener(\"scroll\", refresh)\n return () => {\n window.removeEventListener(\"resize\", refresh)\n window.removeEventListener(\"scroll\", refresh)\n }\n }, [])\n\n return refresh\n}\n","/**\n * NOTE:\n *\n * We have a preference for `just` packages like `just-throttle` since they\n * tend to be micro, but `just-throttle` has a bug. It does not execute\n * on the trailing edge even when told to do so.\n *\n * We ran a test where we logged the call to `refresh` and when the refresh was\n * executed and there were leftover `refresh` calls without a trailing\n * execution.\n */\nimport throttle from \"lodash.throttle\"\nimport { useState } from \"react\"\n\nexport type UseThrottledRefreshReturnType = ReturnType<typeof throttle> & {\n counter: number\n}\n\n/**\n * Creates a hook that rerenders a component when the returned `refresh`\n * method is called; however, it throttles the refresh based on the\n * `intervalInMs` argument passed in.\n *\n * This is a useful component used when throttling reposition updates.\n */\nexport function useThrottledRefresh(\n intervalInMs = 100\n): UseThrottledRefreshReturnType {\n const [counter, setState] = useState(0)\n\n const refresh = throttle(\n () => {\n setState((counter) => counter + 1)\n },\n intervalInMs,\n { trailing: true }\n )\n\n return Object.assign(refresh, { counter })\n}\n","import { RefObject } from \"react\"\n\nimport { getAbsoluteRect } from \"../get-methods/get-absolute-rect\"\nimport { getAbsoluteViewport } from \"../get-methods/get-absolute-viewport\"\nimport { MapHTMLElementLikeRecordToRectRecord, Rect } from \"../types\"\nimport { mapHTMLElementLikeRecordToRectRecord } from \"../utils\"\nimport { useReposition } from \"./use-reposition\"\n\n/**\n * For `absolute` positioning.\n *\n * For `fixed` positioning see `useFixedReposition`\n *\n * An all-in-one hook that helps you position elements relative to other\n * elements and to the viewport.\n *\n * It automatically refreshes when the user scrolls or the window is resized.\n *\n * The method takes as its first argument an object where the values can be\n * either an `HTMLElement` or a ref to an `HTMLElement` created using\n * `useRef(null)`.\n *\n * As the second argument, it takes a function that you use to process\n * everything and return a value you can use to position the element. It's\n * typical to return this in the form of a `style` Object but it doesn't have\n * to be.\n *\n * That function you pass in can take these arguments:\n *\n * - The first argument is in the same shape as the object of `HTMLElement` or\n * `ref` to `HTMLElement`; however, instead, its values are `Rect` or\n * if the original value was a `ref`, a `Rect | null`. The value can be\n * `null` because a `ref` can potentially contain no value and hence we can't\n * find a `Rect` for it.\n * - The second argument is a `Rect` representing the viewport of the `window`.\n * - The third argument is a `refresh` method you can call to force a\n * refresh. The refresh is throttled in sync with the ot\n */\nexport function useAbsoluteReposition<\n T extends Record<string, HTMLElement | RefObject<HTMLElement>>,\n NV\n>(\n elementLikeRecord: T,\n fn: (\n elementRecord: MapHTMLElementLikeRecordToRectRecord<T>,\n viewport: Rect,\n refresh: () => void\n ) => NV\n) {\n const refresh = useReposition()\n const rectRecord = mapHTMLElementLikeRecordToRectRecord(\n elementLikeRecord,\n (element) => getAbsoluteRect(element)\n )\n return fn(rectRecord, getAbsoluteViewport(), refresh)\n}\n","import { Rect } from \"../types\"\n\n/**\n * Takes a source Rect of the Element you are trying to position and makes\n * sure it is inside the container Rect.\n *\n * The source Rect can be `null` (e.g. when the `ref` hasn't been set yet) and\n * while it is, the item is positioned far off to the left of the screen.\n *\n * Can specify an optional `margin` as well.\n */\nexport function positionInside(\n src: Rect | null,\n container: Rect,\n pos: { left: number; top: number },\n { margin = 0 }: { margin?: number } = {}\n) {\n if (src == null) return { ...pos, left: -1024 }\n const right = pos.left + src.width\n if (right <= container.right - margin) return pos\n return { ...pos, left: container.right - src.width - margin }\n}\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays/styles/$Panel\"\n\nexport const $AnchorDialog = styled($Panel)`\n padding: 1em;\n width: 24em;\n`\nexport const $AnchorDialogInputLine = styled(\"div\")`\n display: flex;\n gap: 0.5em;\n`\n\nexport const $AnchorDialogInput = styled(\"input\")`\n flex: 1 1 auto;\n padding: 0.5em 0.75em;\n border-radius: 0.25em;\n color: var(--shade-700);\n border: 1px solid var(--shade-300);\n font-size: 0.9375em;\n &:focus {\n outline: 2px solid var(--blue-200);\n }\n`\n","import styled from \"@emotion/styled\"\n\nimport { SinkReset } from \"~/src/sink/editable\"\n\n/**\n * $Panel is a nice box that goes around a Drop Down menu or a Dialog Box.\n *\n * We don't use $Panel directly and instead we extend it.\n *\n * The $Panel itself extends the `SinkReset` and we do this because the\n * Component appears at the root. So any styling, for example like from\n * Bootstrap or Material UI will affect what's in the Panel.\n */\nexport const $Panel = styled(SinkReset)`\n position: absolute;\n z-index: 1000;\n border: 1px solid var(--table-border-color);\n border-radius: 0.5em;\n overflow: clip;\n filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07))\n drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));\n background: white;\n /**\n * If you are tempted to add the transitions back in, here's why we left\n * them off:\n *\n * - When we initially unhide the panel (by setting a negative 'left' pos)\n * the panel slides in very quickly. So we'd need to fix this first which\n * adds complexity.\n *\n * - Even if we fixed it, the browser window updates the scrolls and resizes\n * in a stepped manner (i.e. like frames in an animation). Keeping the\n * smooth animations makes the panel step in sync with the page refreshes\n * and so actually looks better.\n *\n * In other words, there's a technical issue we'd still need to solve but\n * even if we did, it looks better this way.\n */\n /* transition: left 100ms, top 100ms; */\n`\n","import styled from \"@emotion/styled\"\n\nimport { $Container } from \"../../shared-layout\"\n\nexport const $Editable = styled(\"div\")`\n padding: 2em;\n`\n\nexport const $OuterContainer = styled($Container)`\n /**\n * We use this to make sure the top of the container is rounded even though\n * the toolbar inside is square. We keep the toolbar square so that as the\n * toolbar hits the top when scrolling, it can become sticky. We can try to\n * round the toolbar, but it causes an issue where the part under the\n * rounded part is still visible (i.e. the edge of the container). We can\n * then try to put an absolutely positioned background on it with an opaque\n * color, but that doesn't work unless we know the color of the background\n * so... ultimately, it's not a good solution.\n *\n * NOTE:\n *\n * Using \"overflow: hidden;\" will break the \"position: sticky;\" and it will\n * not work. \"overflow: clip;\" does work though.\n *\n * https://stackoverflow.com/a/73051006\n */\n overflow-y: clip;\n display: flex;\n flex-direction: column;\n`\n","import styled from \"@emotion/styled\"\n\nimport { SinkReset } from \"../sink/editable\"\n\n/**\n * NOTE:\n *\n * This $Container should be extended and the following should be\n * added to it:\n *\n * - padding: We add this separately because if there is a toolbar, there\n * should be no padding on the container but there should be\n * padding on the actual editable. If it is the basic layout, we can add\n * the padding on the $Container but also use the $Container styling\n * directly on the Editable Component.\n */\nexport const $Container = styled(SinkReset)`\n border: 1px solid var(--shade-300); /* shade-300 */\n border-radius: 0.5em;\n color: rgb(39 39 42); /* shade-800 */\n line-height: 1.5;\n /**\n * !important is required because of role=\"textbox\" I think\n */\n outline: 2px solid transparent !important;\n transition: all 250ms;\n &.--focused {\n /**\n * !important is required because of role=\"textbox\" I think\n */\n outline: 2px solid var(--select-editor-color) !important;\n }\n`\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays/styles/$Panel\"\n\n/**\n * Drop Down Menu\n */\nexport const $Menu = styled($Panel)`\n position: absolute;\n padding-top: 0.5em;\n padding-bottom: 0.5em;\n transition: all 200ms;\n /**\n * Prevent clicks from stealing focus from the editor\n */\n user-select: none;\n`\n\n/**\n * Individual items in Drop Down Menu\n */\nexport const $MenuItem = styled(\"div\")`\n display: flex;\n z-index: 10;\n padding: 0 1em 0 1.5em;\n height: 2em;\n align-items: center;\n /**\n * Normally we don't do it this way but since each part of the MenuItem\n * is tightly related to the display: flex, this seemed the easiest way\n * to set this up.\n */\n .--icon {\n flex: 0 0;\n display: block;\n font-size: 1.25em;\n height: 1em;\n padding-right: 0.75em;\n color: var(--shade-400);\n svg {\n position: relative;\n stroke-width: 1.5px;\n }\n }\n .--title {\n flex: 1 0;\n font-size: 0.875em;\n color: var(--shade-800);\n }\n .--hotkey {\n flex: 0 0;\n font-size: 0.75em;\n padding-left: 1.5em;\n color: var(--shade-500);\n }\n background: white;\n cursor: pointer;\n &:hover {\n background: var(--blue-50);\n }\n`\n\nexport const $MenuDivider = styled(\"div\")`\n height: 1px;\n background: var(--shade-200);\n margin-top: 0.25em;\n margin-bottom: 0.25em;\n`\n","import styled from \"@emotion/styled\"\n\nexport const $ToolbarContainer = styled(\"div\")`\n /**\n * This flex rule applies to the \"display: flex;\" of the parent container.\n * Ensures the toolbar does not shrink or grow vertically.\n */\n flex: 0 0 auto;\n /**\n * If \"position: sticky;\" is not working, check the ancestor for \"overflow:\n * hidden;\" of any kind. This will stop sticky from working. A good workaround\n * is to use \"overflow: clip;\" instead.\n *\n * https://stackoverflow.com/a/73051006\n */\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--shade-50);\n /* font-size: 0.875em; */\n font-size: 0.9375em;\n padding: 0 0.5em;\n border-bottom: 1px solid var(--shade-300);\n /**\n * Prevent clicks from stealing focus from the editor\n */\n user-select: none;\n /**\n * Extreme attention to detail. When the sticky is ending and the toolbar\n * is stuck to the bottom of the editor, setting margin-bottom to -1px will\n * fix the 2px bottom border and make it the proper 1px.\n */\n margin-bottom: -1px;\n\n /**\n * NOTE: The space in the equation is significant\n */\n height: calc(\n 3em + 1px\n ); // $ToolbarDivider height + border-bottom of 1px above\n overflow: hidden;\n`\n\nexport const $Toolbar = styled(\"div\")`\n display: inline-block;\n height: calc(\n 3em + 1px\n ); // $ToolbarDivider height + border-bottom of 1px above\n`\n\nexport const $ToolbarDividerContainer = styled(\"div\")`\n display: inline-block;\n height: 3em;\n padding: 0 0.375em;\n`\n\nexport const $ToolbarDivider = styled(\"div\")`\n display: inline-block;\n background: var(--shade-300);\n opacity: 50%;\n width: 1px;\n height: 3em;\n`\n\nexport const $ToolbarButton = styled(\"div\")`\n box-sizing: border-box;\n position: relative;\n display: inline-block;\n vertical-align: top;\n font-size: 1.25em;\n margin-top: 0.25em;\n height: 2em;\n padding: 0.375em 0.375em;\n border-radius: 0.25em;\n text-align: center;\n color: var(--shade-500);\n transition: all 100ms;\n cursor: pointer;\n border: 1px solid rgba(0, 0, 0, 0);\n &.--disabled {\n opacity: 0.3;\n cursor: default;\n pointer-events: none;\n }\n &.--active {\n color: var(--shade-700);\n background: rgba(0, 0, 0, 0.05);\n svg {\n /* stroke-width: 2px; */\n }\n }\n svg {\n stroke-width: 1.5px;\n }\n @media (hover: hover) {\n &:not(.--disabled):hover {\n color: var(--shade-700);\n background: var(--blue-100);\n svg {\n /* stroke-width: 2px; */\n }\n }\n }\n\n &.--more {\n padding: 0.375em 0.5em;\n }\n .--more-icon {\n position: absolute;\n bottom: -0.2em;\n left: 50%;\n margin-left: -0.25em;\n opacity: 0.375;\n }\n`\n","import { useCallback } from \"react\"\nimport { Editor } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { $MenuItem } from \"../../../toolbar-plugin/styles\"\nimport { useLayer } from \"../../../use-layer\"\nimport { MenuItemData } from \"../../types\"\nimport { formatHotkey } from \"./formatHotkey\"\n\nexport function MenuItem({\n editor,\n item,\n close,\n dest,\n}: {\n editor: Editor\n item: Exclude<MenuItemData, \"divider\">\n close: () => void\n dest: HTMLElement\n}) {\n const menuLayer = useLayer(\"menu\")\n\n const onClick = useCallback(() => {\n if (item.Component) {\n const Component = item.Component\n menuLayer.open(() => <Component dest={dest} close={menuLayer.close} />)\n } else if (item.action) {\n item.action(editor)\n ReactEditor.focus(editor)\n close()\n }\n }, [editor, item])\n return (\n <>\n <$MenuItem onClick={onClick}>\n <div className=\"--icon\">\n <item.icon />\n </div>\n <div className=\"--title\">{item.title}</div>\n <div className=\"--hotkey\">\n {item.hotkey ? formatHotkey(item.hotkey) : undefined}\n </div>\n </$MenuItem>\n </>\n )\n}\n","import { MouseEvent, useCallback } from \"react\"\n\nimport { useLayer } from \"~/src/use-layer\"\n\nimport { Tooltip } from \"./tooltip\"\nimport { Triangle } from \"./triangle\"\n\n/**\n * Takes a title and a hotkey and renders it as a tooltip.\n *\n * You'll notice that hotkey can be a function and the reason is very specific\n * to our needs which is that we don't know what the hotkey should look like\n * until we are in the browser (i.e. not the server) because it checks the user\n * agent to see if we are on a Mac or on Windows.\n *\n * We can defer this request until the tooltip is displayed.\n *\n * The editor currently has no need to display this hotkey shortcuts except in\n * things like tooltips so this isn't a problem for us. Potentially, we may need\n * to figure out a way to render this on the server or figure out a way to\n * render on the server without the hotkey and then fill it in when we are in\n * the browser.\n *\n * If we ever fix this requirement that hotkeys can only be shown in the browser\n * (i.e. we get server side rendering of hotkeys working) then `useTooltip` can\n * be simplified to not take a function.\n */\nexport function useTooltip(\n {\n title,\n hotkey,\n }: {\n title: string\n hotkey?: string | (() => string | undefined)\n },\n deps: React.DependencyList = []\n) {\n const label = useLayer(\"tooltip-label\")\n const triangle = useLayer(\"tooltip-triangle\")\n\n /**\n * On hover over\n */\n const onMouseEnter = useCallback((e: MouseEvent<HTMLElement>) => {\n const dest = e.currentTarget\n /**\n * Open tooltip\n */\n if (title !== undefined) {\n label.open(() => (\n <Tooltip\n title={title}\n hotkey={typeof hotkey === \"function\" ? hotkey() : hotkey}\n dest={dest}\n />\n ))\n triangle.open(() => <Triangle dest={dest} />)\n }\n }, deps)\n\n /**\n * On hover out\n */\n const onMouseLeave = useCallback(() => {\n label.close()\n triangle.close()\n }, deps)\n return { onMouseEnter, onMouseLeave }\n}\n","import styled from \"@emotion/styled\"\n\nexport function useRect(dest: HTMLElement): DOMRect {\n return dest.getBoundingClientRect()\n}\n\nconst $Tooltip = styled(\"div\")`\n position: fixed;\n z-index: 10;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-size: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;\n color: white;\n font-size: 0.875em;\n line-height: 1.5em;\n padding: 0 0.5em;\n color: var(--shade-300);\n background: var(--shade-700);\n border-radius: 0.25em;\n white-space: nowrap;\n`\n\nconst $Hotkey = styled(\"span\")`\n margin-left: 0.75em;\n font-size: 0.875em;\n font-weight: 500;\n color: var(--shade-400);\n`\n\nexport function Tooltip({\n title,\n hotkey,\n dest,\n}: {\n title: string\n hotkey?: string\n dest: HTMLElement\n}) {\n const rect = useRect(dest)\n return (\n <$Tooltip\n style={{\n left: rect.left,\n top: `calc(${rect.top}px - 2em)`,\n }}\n >\n {title}\n\n {hotkey ? <$Hotkey>{hotkey}</$Hotkey> : null}\n </$Tooltip>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { useRect } from \"./tooltip\"\n\nconst $Triangle = styled(\"span\")`\n position: fixed;\n z-index: 10;\n width: 0;\n height: 0;\n border-left: 0.375em solid transparent;\n border-right: 0.375em solid transparent;\n border-top: 0.375em solid var(--shade-700);\n`\n\nexport function Triangle({ dest }: { dest: HTMLElement }) {\n const rect = useRect(dest)\n return (\n <$Triangle\n style={{\n left: `calc(${rect.left + rect.width / 2}px - 0.375em)`,\n top: `calc(${rect.top}px - 0.5em)`,\n }}\n />\n )\n}\n","import styled from \"@emotion/styled\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { Node } from \"slate\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { $Panel } from \"../../shared-overlays\"\nimport { t } from \"../../utils/translations\"\nimport {\n $CancelButton,\n $FormCaption,\n $FormGroup,\n $FormHint,\n $Input,\n $PrimaryButton,\n} from \"../../shared-styles\"\nimport { useLayer } from \"../../use-layer\"\nimport { useAbsoluteReposition } from \"../../use-reposition\"\nimport { AnchorElement } from \"../index\"\nimport { AnchorDialog } from \"./AnchorDialog\"\n\nconst $AnchorEditDialog = styled($Panel)`\n position: absolute;\n width: 20em;\n padding: 1em;\n`\n\nexport function AnchorEditDialog({\n destAnchor,\n destStartEdge,\n element,\n}: {\n destAnchor: HTMLAnchorElement\n destStartEdge: HTMLSpanElement\n element: AnchorElement\n}) {\n const dialog = useLayer(\"dialog\")\n const style = useAbsoluteReposition(\n { destAnchor, destStartEdge },\n ({ destAnchor, destStartEdge }) => {\n return {\n left: destStartEdge.left,\n top: destAnchor.top + destAnchor.height,\n }\n }\n )\n\n const editor = useSlateStatic()\n\n const [href, setHref] = useState<string>(element.href)\n const [text, setText] = useState<string>(Node.string(element))\n const [title, setTitle] = useState<string>(element.title || \"\")\n\n const formRef = useRef({ href, text, title })\n formRef.current = { href, text, title }\n\n const handleHrefChange = useCallback<\n React.ChangeEventHandler<HTMLInputElement>\n >((e) => {\n setHref(e.target.value)\n }, [])\n\n const handleTextChange = useCallback<\n React.ChangeEventHandler<HTMLInputElement>\n >((e) => {\n setText(e.target.value)\n }, [])\n\n const handleTitleChange = useCallback<\n React.ChangeEventHandler<HTMLInputElement>\n >((e) => {\n setTitle(e.target.value)\n }, [])\n\n const openAnchorDialog = useCallback(() => {\n dialog.open(() => (\n <AnchorDialog\n destAnchor={destAnchor}\n destStartEdge={destStartEdge}\n element={element}\n />\n ))\n }, [destAnchor, destStartEdge, element])\n\n const handleSubmit = useCallback(() => {\n const { href, text, title } = formRef.current\n editor.anchor.editLink({ href, text, title }, { at: element })\n openAnchorDialog()\n }, [openAnchorDialog])\n\n return (\n <$AnchorEditDialog contentEditable={false} style={style}>\n <$FormGroup>\n <$FormCaption>{t(\"linkUrl\")}</$FormCaption>\n <$Input type=\"text\" value={href} onChange={handleHrefChange} />\n </$FormGroup>\n <$FormGroup>\n <$FormCaption>{t(\"linkText\")}</$FormCaption>\n <$Input type=\"text\" value={text} onChange={handleTextChange} />\n <$FormHint>{t(\"linkTextHint\")}</$FormHint>\n </$FormGroup>\n <$FormGroup>\n <$FormCaption>{t(\"tooltipText\")}</$FormCaption>\n <$Input type=\"text\" value={title} onChange={handleTitleChange} />\n <$FormHint>{t(\"tooltipHint\")}</$FormHint>\n </$FormGroup>\n <$FormGroup>\n <$PrimaryButton onClick={handleSubmit}>{t(\"apply\")}</$PrimaryButton>\n </$FormGroup>\n <$FormGroup>\n <$CancelButton onClick={openAnchorDialog}>{t(\"cancel\")}</$CancelButton>\n </$FormGroup>\n </$AnchorEditDialog>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $FormGroup = styled(\"div\")`\n margin: 0.5em 0;\n &:first-of-type {\n margin-top: 0;\n }\n &:last-of-type {\n margin-bottom: 0;\n }\n`\n\nexport const $FormCaption = styled(\"div\")`\n font-size: 0.9375em;\n margin-bottom: 0.25em;\n color: var(--shade-700);\n`\n\nexport const $FormHint = styled(\"div\")`\n font-size: 0.875em;\n margin-top: 0.25em;\n color: var(--shade-500);\n`\n\nexport const $Textarea = styled(\"input\")`\n box-sizing: border-box;\n width: 100%;\n height: 6em;\n padding: 0.5em 0.75em;\n border-radius: 0.25em;\n color: var(--shade-700);\n font-family: inherit;\n border: 1px solid var(--shade-300);\n font-size: 0.9375em;\n &:focus {\n outline: 2px solid var(--blue-200);\n }\n`\n\nexport const $Input = styled(\"input\")`\n box-sizing: border-box;\n width: 100%;\n padding: 0.5em 0.75em;\n border-radius: 0.25em;\n color: var(--shade-700);\n border: 1px solid var(--shade-300);\n font-size: 0.9375em;\n &:focus {\n outline: 2px solid var(--blue-200);\n }\n`\n\nexport const $BaseButton = styled(\"div\")`\n /* Center vertically and horizontally */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n padding: 0.25em 0.75em;\n text-align: center;\n transition: all 100ms;\n border-radius: 0.25em;\n svg {\n font-size: 1.25em;\n stroke-width: 2px;\n }\n`\n\nexport const $PrimaryButton = styled($BaseButton)`\n color: var(--blue-50);\n background: var(--blue-500);\n outline: 0px solid white;\n &:hover {\n color: white;\n background: var(--blue-600);\n outline: 2px solid var(--blue-200);\n }\n svg {\n color: var(--blue-200);\n }\n`\n\nexport const $CancelButton = styled($BaseButton)`\n color: var(--shade-500);\n background: var(--shade-200);\n outline: 0px solid white;\n &:hover {\n color: var(--shade-600);\n background: var(--shade-300);\n outline: 2px solid var(--shade-200);\n }\n svg {\n color: var(--shade-400);\n }\n`\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"~/src/sink\"\n\nexport const ExternalLinkIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"M12 6H6a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6M11 13l9-9M15 4h5v5\" />\n </TablerIcon>\n)\n\nexport const LinkOffIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"m9 15 3-3m2-2 1-1M11 6l.463-.536a5 5 0 0 1 7.071 7.072L18 13M3 3l18 18M13 18l-.397.534a5.068 5.068 0 0 1-7.127 0 4.972 4.972 0 0 1 0-7.071L6 11\" />\n </TablerIcon>\n)\n\nexport const PencilIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"M4 20h4L18.5 9.5a1.5 1.5 0 0 0-4-4L4 16v4M13.5 6.5l4 4\" />\n </TablerIcon>\n)\n","import { Descendant } from \"slate\"\n\nimport { createPlugin, curryOne } from \"~/src/sink\"\n\nimport { TypedPlugin } from \"../sink/types/plugin/plugin\"\nimport { onPaste } from \"./editable/on-paste\"\nimport { createAnchorMethods } from \"./methods\"\nimport { normalizeNode } from \"./normalize-node\"\nimport { Anchor } from \"./render-element/anchor\"\n\ntype AnchorMethods = ReturnType<typeof createAnchorMethods>\n\nexport type AnchorEditor = {\n anchor: AnchorMethods\n}\n\nexport type AnchorElement = {\n type: \"anchor\"\n href: string\n target?: string\n title?: string\n children: Descendant[]\n}\n\nexport type AnchorPluginCustomTypes = {\n Name: \"anchor\"\n Editor: AnchorEditor\n Element: AnchorElement\n}\n\nexport const AnchorPlugin = createPlugin<AnchorPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.anchor = createAnchorMethods(editor)\n return createPolicy({\n name: \"anchor\",\n editor: {\n isInline(element) {\n if (element.type === \"anchor\") return true\n },\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n onPaste: curryOne(onPaste, editor),\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"anchor\") {\n return (\n <Anchor element={element} attributes={attributes}>\n {children}\n </Anchor>\n )\n }\n },\n },\n })\n }\n) as TypedPlugin<AnchorPluginCustomTypes>\n","import { Editor, Transforms } from \"slate\"\n\nimport { createPlugin, TypedPlugin } from \"~/src/sink\"\n\nimport { isSafeDelete } from \"./is-safe-delete\"\n\ntype AtomicDeleteEditor = {\n atomicDelete: true\n}\n\nexport type AtomicDeletePluginCustomTypes = {\n Name: \"atomic-delete\"\n Editor: AtomicDeleteEditor\n}\n\n/**\n * The Atomic Delete plugin protects master/slave related elements from being\n * put into a bad state after a delete.\n *\n * This can happen because Slate's default delete behavior does not take into\n * account the relationship between master/slave elements.\n *\n * Specifically, atomic delete protects against the following situations:\n *\n * - User forward deletes from just before a table. The first cell in the\n * table is deleted leaving a first row with one less cell than the rest\n * of the table.\n *\n * - User forward deletes at the end of a code block. Text from outside the\n * code block is pulled into the code block.\n *\n * - User backward deletes from just after a code block. Text from outside the\n * code block is pulled into the code block.\n *\n * - User backward deletes at the start of a code block. Text from inside the\n * code block is pulled outside the code block.\n */\nexport const AtomicDeletePlugin = createPlugin<AtomicDeletePluginCustomTypes>(\n (editor) => {\n editor.atomicDelete = true\n return {\n name: \"atomic-delete\",\n editor: {\n deleteBackward() {\n if (editor.selection == null) return false\n const entry = Editor.node(editor, editor.selection)\n const prevEntry = Editor.previous(editor, { mode: \"lowest\" })\n if (isSafeDelete(editor, entry, prevEntry)) return false\n Transforms.move(editor, { unit: \"character\", reverse: true })\n return true\n },\n deleteForward() {\n if (editor.selection == null) return false\n const entry = Editor.node(editor, editor.selection)\n const nextEntry = Editor.next(editor, { mode: \"lowest\" })\n if (isSafeDelete(editor, entry, nextEntry)) return false\n Transforms.move(editor, { unit: \"character\" })\n return true\n },\n },\n }\n }\n) as TypedPlugin<AtomicDeletePluginCustomTypes>\n","import { Editor, Element, NodeEntry, Path } from \"slate\"\n\nimport { findElementUp } from \"~/src/sink\"\n\nexport function isSafeDelete(\n editor: Editor,\n a: NodeEntry | undefined,\n b: NodeEntry | undefined\n) {\n if (!a || !b) return true\n /**\n * If the current Node and the next Node are the same, short circuit\n * and leave early. Good for performance.\n */\n if (Path.equals(a[1], b[1])) return true\n const masterEntryA = findElementUp(\n editor,\n (el) => Element.isElement(el) && editor.isMaster(el),\n { at: a[1] }\n )\n const masterEntryB = findElementUp(\n editor,\n (el) => {\n return Element.isElement(el) && editor.isMaster(el)\n },\n { at: b[1] }\n )\n /**\n * If neither have a master, then don't worry about it.\n */\n if (!masterEntryA && !masterEntryB) return true\n /**\n * If they both have a master but it's the same master, then don't\n * worry about it.\n */\n if (\n masterEntryA &&\n masterEntryB &&\n Path.equals(masterEntryA[1], masterEntryB[1])\n )\n return true\n return false\n}\n","import { Editor, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { createPlugin, curryOne, TypedPlugin } from \"~/src/sink\"\n\nimport { createImageMethods } from \"./methods\"\nimport { normalizeNode } from \"./normalize-node\"\nimport { renderElement } from \"./render-element\"\nimport { ImagePluginConfig, ImagePluginCustomTypes } from \"./types\"\n\n/**\n * Handle drop events for image files\n */\nfunction createOnDrop(editor: Editor) {\n return (event: React.DragEvent<HTMLDivElement>): boolean => {\n const { dataTransfer } = event\n\n // Check if there are files being dropped\n if (!dataTransfer.files || dataTransfer.files.length === 0) {\n return false\n }\n\n // Check if any of the files are images\n const imageFiles = Array.from(dataTransfer.files).filter((file) =>\n file.type.startsWith(\"image/\")\n )\n\n if (imageFiles.length === 0) {\n return false\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n // Get the drop position and move cursor there\n const range = ReactEditor.findEventRange(editor, event)\n if (range) {\n Transforms.select(editor, range)\n }\n\n // Get the onImageChange handler from the editor\n const onImageChange = editor.wysimark?.onImageChange\n\n // Process each image file\n for (const file of imageFiles) {\n if (onImageChange) {\n onImageChange(file)\n .then((url) => {\n if (url) {\n editor.image.insertImageFromUrl(url, file.name, \"\")\n }\n })\n .catch(() => {\n // Failed to upload image - silently ignore\n })\n } else {\n // If no onImageChange handler, create a data URL\n const reader = new FileReader()\n reader.onload = () => {\n const dataUrl = reader.result as string\n editor.image.insertImageFromUrl(dataUrl, file.name, \"\")\n }\n reader.readAsDataURL(file)\n }\n }\n\n return true\n }\n}\n\nconst DEFAULT_OPTIONS: ImagePluginConfig = {\n maxInitialInlineImageSize: { width: 64, height: 64 },\n maxInitialImageSize: { width: 320, height: 320 },\n maxImageSize: { width: 1024, height: 1024 },\n imageBlockPresets: [\n /**\n * Pixel Presets\n */\n { name: \"S\", title: \"Small\", type: \"bounds\", width: 160, height: 160 },\n { name: \"M\", title: \"Medium\", type: \"bounds\", width: 320, height: 320 },\n { name: \"L\", title: \"Large\", type: \"bounds\", width: 640, height: 640 },\n /**\n * Scale Presets\n */\n { name: \"⅓\", title: \"1/3 scale\", type: \"scale\", scale: 1 / 3 },\n { name: \"½\", title: \"1/2 scale\", type: \"scale\", scale: 0.5 },\n { name: \"Full\", title: \"Full size\", type: \"scale\", scale: 1 },\n ],\n imageInlinePresets: [\n /**\n * Pixel Presets\n */\n {\n name: \"16\",\n title: \"16 pixels\",\n type: \"bounds\",\n width: 16,\n height: 16,\n },\n {\n name: \"24\",\n title: \"24 pixels\",\n type: \"bounds\",\n width: 24,\n height: 24,\n },\n {\n name: \"32\",\n title: \"32 pixels\",\n type: \"bounds\",\n width: 32,\n height: 32,\n },\n /**\n * Scale Presets\n */\n { name: \"⅓\", title: \"1/3 scale\", type: \"scale\", scale: 1 / 3 },\n { name: \"½\", title: \"1/2 scale\", type: \"scale\", scale: 0.5 },\n { name: \"Full\", title: \"Full size\", type: \"scale\", scale: 1 },\n ],\n}\n\nexport const ImagePlugin = //({\n createPlugin<ImagePluginCustomTypes>(\n (editor, sinkOptions, { createPolicy }) => {\n const options: ImagePluginConfig = {\n ...DEFAULT_OPTIONS,\n ...sinkOptions.image,\n }\n editor.image = {\n ...createImageMethods(editor),\n maxInitialInlineImageSize: options.maxInitialInlineImageSize,\n maxInitialImageSize: options.maxInitialImageSize,\n maxImageSize: options.maxImageSize,\n imageBlockPresets: options.imageBlockPresets,\n imageInlinePresets: options.imageInlinePresets,\n }\n\n return createPolicy({\n name: \"image\",\n editor: {\n isVoid: (element) => {\n if ([\"image-block\", \"image-inline\"].includes(element.type)) {\n return true\n }\n },\n isInline: (element) => {\n if (element.type === \"image-inline\") return true\n },\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n renderElement,\n onDrop: createOnDrop(editor),\n },\n })\n }\n ) as TypedPlugin<ImagePluginCustomTypes>\n","import { Editor, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { curryOne } from \"~/src/sink\"\nimport { ImageBlockElement} from \"../types\"\n\nfunction noop(editor: Editor) {\n editor\n}\n\nfunction insertImageFromUrl(\n editor: Editor,\n url: string,\n alt?: string,\n title?: string,\n) {\n const { selection } = editor\n \n Transforms.insertNodes(editor, {\n type: \"image-block\",\n url,\n alt: alt || \"\",\n title: title || \"\",\n width: 320,\n height: 240,\n children: [{ text: \"\" }],\n } as ImageBlockElement)\n\n /**\n * If there is no selection the element is inserted at the bottom of the\n * editor. When this happens, the insertion point may not be visible and\n * so this code scrolls to the bottom of the editor. We don't do this if\n * there is a selection because if the user made a selection, it is\n * likely already in view.\n */\n if (!selection) {\n const lastPos = Editor.end(editor, [])\n Transforms.select(editor, lastPos)\n ReactEditor.focus(editor)\n }\n}\n\nexport function createImageMethods(editor: Editor) {\n return {\n noop: curryOne(noop, editor),\n insertImageFromUrl: curryOne(insertImageFromUrl, editor),\n }\n}\n","import { Editor, Node, NodeEntry } from \"slate\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n editor\n entry\n return false\n}\n","import { useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { $ImageBlock } from \"../styles/image-block-styles\"\nimport { ImageBlockElement } from \"../types\"\nimport { ImageWithControls } from \"./image-with-controls\"\n\nexport function ImageBlock({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ImageBlockElement>) {\n const editor = useSlateStatic()\n return (\n <div {...attributes}>\n <$ImageBlock contentEditable={false}>\n <ImageWithControls\n element={element}\n presets={editor.image.imageBlockPresets}\n />\n </$ImageBlock>\n {children}\n </div>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageBlock = styled(\"div\")`\n display: block;\n margin: 1em 0;\n`\n","import { clsx } from \"clsx\"\nimport React, { useState } from \"react\"\nimport { useSelected } from \"slate-react\"\n\nimport {\n $Image,\n $ImageContainer,\n} from \"../../styles/image-with-controls-styles/image-with-controls-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSizePreset,\n} from \"../../types\"\nimport { ImageResizeControl } from \"./image-resize-controls/image-resize-control\"\nimport { ImageSizeStatus } from \"./image-size-status/image-size-status\"\nimport { ImageToolbar } from \"./image-toolbar/image-toolbar\"\n\n/**\n * The `Image` Component is responsible for:\n *\n * - rendering the image\n * - displaying the UI for the image including\n * - resize controls\n * - current width/height\n * - image preset size controls\n *\n * It's outer $ImageContainer is represented as an `inline-block` and is\n * placed inside a `block` element for the `image-block` and a `span` element\n * for `image-inline`.\n */\nexport function ImageWithControls({\n element,\n presets,\n}: {\n element: ImageBlockElement | ImageInlineElement\n presets: ImageSizePreset[]\n}) {\n const url = element.url\n const selected = useSelected()\n const [isDragging, setIsDragging] = useState(false)\n const [size, setSize] = useState(\n element.srcWidth && element.srcHeight && element.width && element.height\n ? { width: element.width, height: element.height }\n : null\n )\n\n /**\n * Creates a `srcSize` object if there is both a srcWidth and a srcHeight.\n * This also acts as an indicator that the image can be resized. If there is\n * a `srcSize` present we know that the image can be resized.\n */\n const srcSize =\n element.srcWidth && element.srcHeight\n ? { width: element.srcWidth, height: element.srcHeight }\n : null\n\n /**\n * Show resize controls if the element is selected, it has a `size` and\n * it has a `srcSize`\n */\n const showControls = selected && size && srcSize\n\n /**\n * Add classes for different states.\n */\n const className = clsx({\n \"--selected\": selected,\n \"--dragging\": isDragging,\n \"--small\": size && (size.width <= 64 || size.height <= 64),\n })\n\n /**\n * The purpose of the surrounding $ImageContainer is simply to surround the\n * image tightly so that we can place the other control elements relative\n * to the image.\n *\n * In order to do this, the $ImageContainer must be an `inline-block` or else\n * space gets added on the inside of the container.\n *\n * NOTE:\n *\n * Everything inside the $ImageContainer must be safe to insert into a\n * `<p>` tag which means `<div>` tags are not allowed. Use `<span>` tags\n * instead, even if they are blocks. This is because we get some invalid\n * nested warning otherwise as `<div>` tags are not supposed to be children\n * of `<p>` tags.\n */\n return (\n <$ImageContainer className={className}>\n <$Image src={url} width={size?.width} height={size?.height} />\n {showControls ? (\n <ImageToolbar\n element={element}\n size={size}\n setSize={setSize}\n srcSize={srcSize}\n presets={presets}\n />\n ) : null}\n {/**\n * Show the size status bar only when the user is dragging to resize the\n * image.\n */}\n {isDragging && size ? <ImageSizeStatus size={size} /> : null}\n {showControls ? (\n <ImageResizeControl\n element={element}\n srcSize={srcSize}\n isDragging={isDragging}\n setIsDragging={setIsDragging}\n size={size}\n setSize={setSize}\n />\n ) : null}\n </$ImageContainer>\n )\n}\n","import styled from \"@emotion/styled\"\n\n/**\n * Wrap the image with a container so we can accurately place UI elements\n * around it.\n */\nexport const $ImageContainer = styled(\"span\")`\n /**\n * In order for this container to wrap tightly (without space), it needs to be\n * an \"inline-block\". If it's just an \"inline\" we end up with spacing\n * artificats related to how spacing is placed around text.\n */\n display: inline-block;\n /**\n * This wrapper's primary purpose (why we don't use the image by itself) is\n * so that we can place UI controls for the image in and around the image.\n */\n position: relative;\n`\n\nexport const $Image = styled(\"img\")`\n /**\n * TODO:\n *\n * This is a bit of a hack but is a better experience than not anything.\n *\n * Constrains the maximum resize width of an image to 100% of the space\n * available. This prevents the image from stepping outside its boundaries.\n *\n * Problem:\n *\n * - The \"height\" is set to \"auto\" which likely conflicts with the height\n * provided as an image attribute of \"height\" set by the application.\n * Effectively, this means that the \"height\" is ignored which is fine\n * except when the image hasn't been loaded yet, I think it's possible\n * and perhaps likely that there may be a reflow that happens before/after\n * the image is loaded.\n */\n max-width: 100%;\n height: auto;\n\n /**\n * Rounded borders are pretty and also help the selection outline look\n * pretty.\n */\n transition: border-radius 250ms;\n border-radius: 0.5em;\n .--small > & {\n border-radius: 1px;\n }\n display: block;\n\n /**\n * Selection border. We leave a space between the outline and the image so\n * that an image that is the same color as the selection border will still\n * look selected.\n */\n .--selected > & {\n outline: 2px solid var(--select-color);\n outline-offset: 1px;\n }\n /**\n * If the image isn't loaded yet, we want to have some color filling the space\n * that the image will eventually load into. This helps indicates to the user\n * the space that the image will fill into.\n *\n * Once the image is finished loading, we want to respect transparency so at\n * that point we hide the background shading.\n */\n .--loading > & {\n background: var(--shade-100);\n }\n\n /**\n * When we change the image via a preset, we want to animate the change;\n * however, when we are dragging to resize, a transition adds a janky delay\n * to the resize so we remove the transition during drag resizing.\n */\n transition: width 100ms, height 100ms;\n .--dragging > & {\n transition: border-radius 250ms;\n }\n`\n","import { clsx } from \"clsx\"\nimport { Dispatch, SetStateAction, useCallback } from \"react\"\nimport { Editor, Transforms } from \"slate\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { stopEvent } from \"~/src/sink\"\nimport { useResizeBrowser } from \"~/src/use-reposition/hooks\"\n\nimport {\n $ImageResizeHandle,\n $ImageResizeInvisibleHandle,\n} from \"../../../styles/image-with-controls-styles/image-resize-handle-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n} from \"../../../types\"\nimport { getEditorWidth, minMax, resizeToWidth } from \"../../../utils\"\n\n/**\n * Helper function finds the `img` inside the current Slate `Element`.\n *\n * The `Element` in the DOM points to the surrounding container, so we search\n * inside of it for the `img` tag which know there is only one of.\n *\n * We then get the client rect from it.\n */\nfunction getImageBoundsFromSlateElement(\n editor: Editor,\n element: ImageBlockElement | ImageInlineElement\n): DOMRect {\n const imageContainerDOMNode = ReactEditor.toDOMNode(editor, element)\n const imgDOMNode = imageContainerDOMNode.querySelector(\"img\")\n if (!imgDOMNode)\n throw new Error(`Image Element could not be found but should exist`)\n return imgDOMNode.getBoundingClientRect()\n}\n\nexport function ImageResizeControl({\n element,\n srcSize,\n size,\n setSize,\n isDragging,\n setIsDragging,\n}: {\n element: ImageBlockElement | ImageInlineElement\n srcSize: ImageSize\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n isDragging: boolean\n setIsDragging: Dispatch<SetStateAction<boolean>>\n}) {\n const editor = useSlateStatic()\n\n /**\n * Refreshes the rendering of the resize handle if the browser width is\n * changed. This is useful, for example, if the browser is resized, making\n * the editable area smaller, which in some cases shoudl cause the resize\n * handle to indicate that the image can only be resized smaller.\n */\n useResizeBrowser()\n\n /**\n * Retrieve the inner (usable) width of the editor.\n */\n const editorWidth = getEditorWidth(editor)\n\n /**\n * Create some convenience constants that we use a lot below\n */\n const width = size.width\n const maxWidth = Math.min(srcSize.width, editorWidth)\n const minWidth = Math.min(12, srcSize.width)\n\n /**\n * Start dragging\n */\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n stopEvent(e)\n setIsDragging(true)\n\n /**\n * Position of mouse pointer when mouse down is pressed\n */\n const startX = e.clientX\n\n /**\n * The initial image size for the visual image (i.e. the image we are\n * seeing on the screen) can vary from the image width as stored in the\n * Document value.\n *\n * This is because if the document image width value is larger than the\n * screen width, we have constrained the image so that it fits.\n *\n * When we start a resize, we want the resize to start at the visual\n * image width though or the drag may appear broken. For example, if you\n * start resizing smaller, if the image is larger than the width of the\n * screen, the resize will take no effect.\n *\n * For this reason, we start with the visual screen width.\n */\n const bounds = getImageBoundsFromSlateElement(editor, element)\n const startWidth = bounds.width\n\n let nextSize = { ...size }\n\n /**\n * Watch mouse movement during dragging\n */\n const onDocumentMouseMove = (e: MouseEvent) => {\n const nextWidth = minMax({\n value: startWidth + e.clientX - startX,\n min: minWidth,\n max: maxWidth,\n })\n nextSize = resizeToWidth(nextWidth, srcSize)\n\n setSize(nextSize)\n }\n\n /**\n * Remove dragging event listeners when releasing mouse button\n */\n const onDocumentMouseUp = () => {\n document.removeEventListener(\"mousemove\", onDocumentMouseMove)\n document.removeEventListener(\"mouseup\", onDocumentMouseUp)\n const path = ReactEditor.findPath(editor, element)\n /**\n * When we save the image to the document, at the moment, we have\n * decided to save the image at the actual resize width, as stored\n * in the resize state. This is different than using the visual\n * image width which is constrained to the width of the screen.\n *\n * Not sure if this is the right approach, but it does allow for a\n * manual workaround if desired where the content is being edited in\n * a smaller screen than the output window and the user wants to have\n * the image display at a larger size.\n *\n * Note that this is already possible (to save at a larger size than\n * the screen width) when using presets so it's not entirely out of\n * character for our editor either.\n */\n const size = {\n width: nextSize.width,\n height: nextSize.height,\n }\n /**\n * It's not, at the moment, strictly necessary to set the size because\n * the size is set during mouse move; however, I'm keeping this here\n * as (a) a sanity check to ensure this is always correct and (b) if\n * we ever decide to modify the size before saving (see the comment\n * above when setting size) then we don't end up in a bad state. This\n * is something that already occurred once during experimenting.\n */\n setSize(size)\n Transforms.setNodes(editor, size, { at: path })\n setIsDragging(false)\n }\n\n /**\n * Attach event listeners directly to document\n */\n document.addEventListener(\"mousemove\", onDocumentMouseMove)\n document.addEventListener(\"mouseup\", onDocumentMouseUp)\n },\n [srcSize.width, srcSize.height, size.width, element]\n )\n\n /**\n * FIXME:\n *\n * This can be refactored so that it shares more code with `onMouseDown`\n * above. They are nearly identical except:\n *\n * - the event listeners that are added/removed\n * - the way way in which clientX is retrieved\n */\n const onTouchStart = useCallback(\n (e: React.TouchEvent) => {\n stopEvent(e)\n setIsDragging(true)\n const startX = e.changedTouches[0].clientX\n const startWidth = size.width\n\n let nextSize = { ...size }\n\n const onDocumentTouchMove = (te: TouchEvent) => {\n // stopEvent(te)\n const e = te.changedTouches[0]\n\n const nextWidth = minMax({\n value: startWidth + e.clientX - startX,\n min: minWidth,\n max: maxWidth,\n })\n nextSize = resizeToWidth(nextWidth, srcSize)\n\n setSize(nextSize)\n }\n const onDocumentTouchEnd = () => {\n document.removeEventListener(\"touchmove\", onDocumentTouchMove)\n document.removeEventListener(\"touchend\", onDocumentTouchEnd)\n const path = ReactEditor.findPath(editor, element)\n Transforms.setNodes(\n editor,\n { width: nextSize.width, height: nextSize.height },\n { at: path }\n )\n setIsDragging(false)\n }\n\n document.addEventListener(\"touchmove\", onDocumentTouchMove)\n document.addEventListener(\"touchend\", onDocumentTouchEnd)\n },\n [srcSize.width, srcSize.height, size.width, element]\n )\n\n /**\n * Add special classNames to modify appearance of resize controls\n */\n const className = clsx({\n \"--center\": width < maxWidth && width > minWidth,\n \"--left\": width >= maxWidth && width > minWidth,\n \"--right\": width <= minWidth && width < maxWidth,\n \"--dragging\": isDragging,\n \"--small\": width <= 64 || size.height <= 64,\n })\n\n return (\n <>\n {/**\n * The invisible handle is not visible but gives a larger drag handle\n * target for the mouse and touch events\n */}\n <$ImageResizeInvisibleHandle\n className={className}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n >\n <$ImageResizeHandle>\n <span className=\"--bar --bar-left\" />\n <span className=\"--bar --bar-center\" />\n <span className=\"--bar --bar-right\" />\n </$ImageResizeHandle>\n </$ImageResizeInvisibleHandle>\n </>\n )\n}\n","import { useEffect } from \"react\"\n\nimport { useThrottledRefresh } from \"./use-throttled-refresh\"\n\n/**\n * Refreshes the Component whenever the page is resized or the window is\n * scrolled. This is because these are usually the only two events that cause\n * the elements on a page to be repositioned.\n *\n * If there are yet other events that can cause the elements to be repositioned\n * or resized, you can also call the returned `refresh` method. This will\n * update the components while still respected the fact that the updates will\n * be throttled so as not to overload the browser.\n */\nexport function useResizeBrowser() {\n /**\n * Create a throttled `refresh` method.\n */\n const refresh = useThrottledRefresh()\n\n /**\n * refresh on page resize or scroll (throttled)\n */\n useEffect(() => {\n refresh()\n window.addEventListener(\"resize\", refresh)\n return () => {\n window.removeEventListener(\"resize\", refresh)\n }\n }, [])\n\n return refresh\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageResizeInvisibleHandle = styled(\"span\")`\n position: absolute;\n display: block;\n /**\n * Prevent touch dragging from exhibiting a kind of scroll bounce behavior\n * when we just want the image to resize.\n */\n touch-action: none;\n background: rgba(127, 127, 127, 0.001);\n top: 0;\n right: calc(-1em - 2px);\n width: 2em;\n bottom: 0;\n &.--left {\n cursor: w-resize;\n }\n &.--center {\n cursor: ew-resize;\n }\n &.--right {\n cursor: e-resize;\n }\n &.--small {\n right: calc(-1.25em);\n /* background: green; */\n width: 1.25em;\n }\n`\nexport const $ImageResizeHandle = styled(\"span\")`\n position: absolute;\n display: block;\n background: var(--select-color);\n top: 50%;\n margin-top: -1em;\n width: 1em;\n height: 2em;\n outline: 1px solid white;\n transition: all 250ms;\n /**\n * The handle is 3 visible states depending on whether the image is at\n * maximum size or minimum size.\n *\n * There are three indicators that let the user know which directions are\n * available (left, right or both) that the user can drag:\n *\n * - rounded corners on the side that are available to drag towards\n * - on larger size image, the handle is on the inside, middle or outside\n * of the outline\n * - the cursor pointer indicates the direction available for resizing.\n */\n .--center > & {\n left: 0.5em;\n border-radius: 0.375em;\n }\n .--left > & {\n border-radius: 0.5em 0 0 0.5em;\n left: 1px;\n }\n .--right > & {\n border-radius: 0 0.5em 0.5em 0;\n left: calc(50% - 1px);\n }\n .--bar {\n position: absolute;\n background: var(--blue-200);\n width: 1px;\n top: 0.5em;\n bottom: 0.5em;\n }\n /**\n * Each of 3 bars is 1px wide and 3px apart\n */\n .--bar-left {\n left: calc(50% - 3.5px);\n }\n .--bar-center {\n left: calc(50% - 0.5px);\n }\n .--bar-right {\n left: calc(50% + 2.5px);\n }\n /**\n * When the image is small, we reduce the size of the handler and place it\n * outside the image. The reasons we do this:\n * \n * - If the handle is not outside the image at small sizes, the handle\n * obscures the image too much. At larger sizes, it works okay and the\n * inside handle placement makes the available direction of the drags more\n * intuitive.\n *\n * - Also, at small sizes, a large handle can overwhelm the image. That is,\n * the handle can be twice as tall as the image itself which looks poor.\n * It's still possible for the handle to be larger than the image at small\n * sizes, but this is okay in that we don't want the handle to become so\n * small that it is hard to see and hard to click.\n */\n .--small > & {\n /**\n * We opt to mainly adjust the size of the handle at smaller sizes by\n * adjusting the font-size. This is more efficient than changing all the\n * border-sizes because changing the font-size automatically changes the\n * size of the border, but we don't have to redo the different combinations\n * border-size and the corner that they need to display on.\n */\n font-size: 0.5em;\n width: 1.5em;\n left: 0.5em;\n margin-top: -1em;\n }\n /**\n * Each of 2 bars is 1px wide and 3px apart\n */\n .--small > & > .--bar-left {\n left: calc(50% - 2px);\n }\n .--small > & > .--bar-center {\n display: none;\n }\n .--small > & > .--bar-right {\n left: calc(50% + 1px);\n }\n`\n","/**\n * A more intuitive of ensuring a value is within a min/max range.\n */\n\nexport function minMax({\n value,\n min,\n max,\n}: {\n value: number\n min: number\n max: number\n}): number {\n if (!(max >= min)) throw new Error(`Expected max >= min but is not`)\n return Math.max(min, Math.min(max, value))\n}\n","import { Editor } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { ImageSize, ImageSizePreset } from \"../types\"\n\n/**\n * Takes a src image and resizes it to the exact width while preserving the\n * aspect ratio.\n *\n * NOTE: This is resizing to exact width, and not to inside width.\n */\nexport function resizeToWidth(width: number, srcSize: ImageSize): ImageSize {\n width = Math.round(width)\n const aspect = srcSize.width / srcSize.height\n return { width, height: Math.round(width / aspect) }\n}\n\n/**\n * Takes a src image and resizes it to the exact height while preserving the\n * aspect ratio.\n *\n * NOTE: This is resizing to exact height, and not to inside height.\n */\nexport function resizeToHeight(height: number, srcSize: ImageSize): ImageSize {\n height = Math.round(height)\n const aspect = srcSize.width / srcSize.height\n return { width: Math.round(height * aspect), height }\n}\n\n/**\n * Intuitive way of taking a size and a bounds and shrinking the size within\n * the given bounds if necessary.\n */\nexport function resizeInBounds(size: ImageSize, bounds: ImageSize): ImageSize {\n const aspect = size.width / size.height\n const boundsAspect = bounds.width / bounds.height\n if (aspect >= boundsAspect) {\n if (size.width > bounds.width) {\n return resizeToWidth(bounds.width, size)\n }\n } else {\n if (size.height > bounds.width) {\n return resizeToHeight(bounds.height, size)\n }\n }\n return size\n}\n\n/**\n * Takes an image size and an image resize preset and calculates the size of\n * the image when the preset is applied.\n *\n * Notably, there are two `preset` algorithms.\n *\n * - `bounds` which sets a maximum width/height and we find the maximum image\n * size that fits within those bounds.\n *\n * - `scale` which multiples the width/height by a given scale. Note that by\n * convention that scale should be 1 or less.\n */\nexport function resizeInPreset(\n size: ImageSize,\n srcSize: ImageSize,\n preset: ImageSizePreset\n): ImageSize {\n switch (preset.type) {\n case \"bounds\":\n return resizeInBounds(srcSize, preset)\n case \"scale\":\n return {\n width: Math.round(srcSize.width * preset.scale),\n height: Math.round(srcSize.height * preset.scale),\n }\n }\n}\n\n/**\n * Takes an editor object and returns the maximum width that elements inside of\n * the editor can be rendered at without overflowing.\n *\n * We get the `clientWidth` which is the \"box\" without the border but including\n * the padding. We then subtract the padding to get the value we want.\n */\nexport function getEditorWidth(editor: Editor) {\n const element = ReactEditor.toDOMNode(editor, editor)\n const computed = getComputedStyle(element)\n const padding =\n parseInt(computed.paddingLeft) + parseInt(computed.paddingRight)\n return element.clientWidth - padding\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageSizeStatus = styled(\"span\")`\n position: absolute;\n /**\n * The status appears with a 1px gap from the outline.\n *\n * - 1px for gap from image to outline\n * - 2px for outline width\n * - 1px more for the space to the status\n */\n bottom: calc(-2em - 4px);\n left: 0;\n font-size: 0.625em; /* 10px tiny */\n line-height: 2em;\n padding: 0 0.5em;\n color: var(--shade-100);\n background: var(--shade-600);\n outline: 1px solid rgba(255, 255, 255, 0.5);\n border-radius: 0.5em;\n white-space: nowrap;\n\n /* force numbers to be monospaced for better alignment */\n font-variant-numeric: tabular-nums;\n`\n","import { $ImageSizeStatus } from \"../../../styles/image-with-controls-styles/image-size-status-styles\"\nimport { ImageSize } from \"../../../types\"\n\nexport function ImageSizeStatus({ size }: { size: ImageSize }) {\n return (\n <$ImageSizeStatus>\n {size.width} × {size.height}\n </$ImageSizeStatus>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageToolbar = styled(\"span\")`\n position: absolute;\n /**\n * On top of the image +1 for space inside outline, +2 for outline,\n * +2 for space outside outline.\n *\n * DO NOT MOVE TO BOTTOM:\n *\n * This is a reminder not to move the preset to the bottom. Visually, it is\n * less obtrusive at the bottom; however, an issue is that when switching\n * between different presets, the preset UI moves up/down making it difficult\n * to switch between different presets. When kept at the top, the preset\n * UI doesn't move.\n */\n top: calc(-1.5em - 5px);\n /**\n * Align left to the outline: +1 for space inside outline, +2 for outline\n * width\n */\n left: -3px;\n /**\n * When we're resizing, the controls aren't usable and just add to visual\n * clutter so we hide it. The transition lets us do it smoothly and less\n * obtrusively.\n */\n transition: opacity 200ms;\n .--dragging & {\n opacity: 0;\n }\n display: flex;\n gap: 0.25em;\n`\n","import styled from \"@emotion/styled\"\n\n/**\n * Styling for a collection of buttons in the $ImageButtonsContainer at the top\n * of the image.\n */\nexport const $ImageButtonGroup = styled(\"span\")`\n /* font-size: 0.75em; */\n border-radius: 0.5em;\n display: flex;\n /**\n * So that inner Preset design shows within the rounded corners.\n */\n overflow: clip;\n /**\n * Let's the menu pop a little over other content. Without it, may be able to\n * see the border of the buttons.\n */\n outline: 1px solid white;\n`\n\nexport const $ImageButton = styled(\"span\")`\n font-size: 0.75em;\n line-height: 2em;\n padding: 0 0.625em;\n &:last-child {\n border-right: none;\n }\n cursor: pointer;\n\n /**\n * We don't want it to wrap\n */\n white-space: nowrap;\n\n /**\n * Preset default colors\n */\n color: var(--shade-600);\n background: var(--shade-200);\n border-right: 1px solid var(--shade-100);\n /**\n * When preset is disabled, it is lighter in color and with elss contrast.\n */\n &.--disabled {\n cursor: default;\n color: var(--shade-300);\n background: var(--shade-100);\n &:hover {\n color: var(--shade-300);\n background: var(--shade-100);\n }\n }\n &.--selected {\n cursor: default;\n color: var(--blue-700);\n background: var(--blue-200);\n &:hover {\n color: var(--blue-700);\n background: var(--blue-200);\n }\n }\n /**\n * On hover, it is dark, and with higher contrast.\n */\n &:hover {\n color: var(--shade-700);\n background: var(--shade-300);\n }\n svg {\n position: relative;\n top: 0.25em;\n font-size: 1.33em;\n line-height: 1em;\n }\n`\n","import { clsx } from \"clsx\"\nimport { Dispatch, SetStateAction, useCallback } from \"react\"\nimport { Transforms } from \"slate\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { useTooltip } from \"~/src/use-tooltip\"\n\nimport { $ImageButton } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n ImageSizePreset,\n} from \"../../../../types\"\nimport { resizeInPreset } from \"../../../../utils\"\n\n/**\n * Shows a single preset image sizes as defined by the `Preset` type.\n *\n * If the srcSize is smaller than the preset, clicking the preset would do\n * nothing except show the image at its full size. For this reason, the\n * preset is disabled if the srcSize is smaller than the preset.\n */\nexport function ImagePresetButton({\n element,\n preset,\n size,\n setSize,\n srcSize,\n}: {\n element: ImageBlockElement | ImageInlineElement\n preset: ImageSizePreset\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n srcSize: ImageSize\n}) {\n const editor = useSlateStatic()\n const presetSize = resizeInPreset(size, srcSize, preset)\n const tooltip = useTooltip({\n title: preset.title,\n hotkey: `${presetSize.width}x${presetSize.height}`,\n })\n\n const onClick = useCallback(() => {\n const path = ReactEditor.findPath(editor, element)\n const nextSize = resizeInPreset(size, srcSize, preset)\n setSize(nextSize)\n Transforms.setNodes(editor, nextSize, { at: path })\n }, [element, preset, size, srcSize])\n\n const isEnabled =\n preset.type === \"scale\"\n ? true\n : preset.width <= srcSize.width || preset.height <= srcSize.height\n\n const isDisabled = !isEnabled\n\n const isSelected =\n size.width === presetSize.width && size.height === presetSize.height\n\n const className = clsx({\n \"--disabled\": isDisabled,\n \"--selected\": !isDisabled && isSelected,\n })\n\n return (\n <$ImageButton\n className={className}\n onClick={isDisabled ? undefined : onClick}\n onMouseEnter={tooltip.onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n >\n {preset.name}\n </$ImageButton>\n )\n}\n","import { Dispatch, SetStateAction } from \"react\"\n\nimport { $ImageButtonGroup } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n ImageSizePreset,\n} from \"../../../../types\"\nimport { ImagePresetButton } from \"./image-preset-button\"\n\nexport function ImagePresetButtonGroup({\n element,\n size,\n setSize,\n srcSize,\n presets,\n}: {\n element: ImageBlockElement | ImageInlineElement\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n\n srcSize: ImageSize\n presets: ImageSizePreset[]\n}) {\n return (\n <$ImageButtonGroup>\n {presets.map((preset, i) => {\n return (\n <ImagePresetButton\n element={element}\n key={i}\n preset={preset}\n size={size}\n setSize={setSize}\n srcSize={srcSize}\n />\n )\n })}\n </$ImageButtonGroup>\n )\n}\n","import { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { useTooltip } from \"~/src/use-tooltip\"\n\nimport { $ImageButton } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport { ImageBlockElement, ImageInlineElement } from \"../../../../types\"\nimport { InlineIcon } from \"../../../icons\"\nimport { convertToInlineImage } from \"./convert-to-inline-image\"\n\nexport function BlockImageTypeButton({\n element,\n}: {\n element: ImageBlockElement | ImageInlineElement\n}) {\n const editor = useSlateStatic()\n const tooltip = useTooltip({\n title: \"Inline Image\",\n hotkey: \"In a line with text\",\n })\n\n const onClickInline = useCallback(() => {\n if (element.type !== \"image-block\") return\n convertToInlineImage(editor, element)\n }, [editor, element])\n return (\n <$ImageButton\n className={element.type === \"image-inline\" ? \"--selected\" : \"\"}\n onClick={element.type === \"image-inline\" ? undefined : onClickInline}\n onMouseEnter={tooltip.onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n >\n <InlineIcon />\n </$ImageButton>\n )\n}\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"~/src/sink\"\n\nexport const ResizeIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"m7 8-4 4 4 4M17 8l4 4-4 4M3 12h18\" />\n </TablerIcon>\n)\n\nexport const BlockIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <rect width={6} height={6} x={4} y={5} rx={1} />\n <path d=\"M4 15h16M4 19h16\" />\n </TablerIcon>\n)\n\nexport const InlineIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <rect width={6} height={6} x={9} y={5} rx={1} />\n <path d=\"M4 7h1M4 11h1M19 7h1M19 11h1M4 15h16M4 19h16\" />\n </TablerIcon>\n)\n","import { Editor, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { ImageBlockElement } from \"../../../../types\"\nimport { resizeInPreset } from \"../../../../utils\"\n\nexport function convertToInlineImage(\n editor: Editor,\n element: ImageBlockElement\n) {\n /**\n * TODO:\n *\n * This should be handled or thought about better. Like maybe if these\n * values don't exist, we still change the type.\n */\n if (\n !element.width ||\n !element.height ||\n !element.srcWidth ||\n !element.srcHeight\n )\n return\n const size = { width: element.width, height: element.height }\n const srcSize = { width: element.srcWidth, height: element.srcHeight }\n const path = ReactEditor.findPath(editor, element)\n Editor.withoutNormalizing(editor, () => {\n /**\n * TODO:\n *\n * `resizeInPreset` should probably be renamed to something like\n * `resizeIn` which can be used more generically. Perhaps it takes the\n * `type`, `width` and `height` as an Interface making it compatible with\n * a Preset which would extend it.\n */\n const nextSize = resizeInPreset(size, srcSize, {\n name: \"initial-inline-image\",\n title: \"\",\n type: \"bounds\",\n width: 24,\n height: 24,\n })\n Transforms.setNodes(\n editor,\n { type: \"image-inline\", ...nextSize },\n { at: path }\n )\n Transforms.wrapNodes(\n editor,\n { type: \"paragraph\", children: [] },\n { at: path }\n )\n })\n}\n","import { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { useTooltip } from \"~/src/use-tooltip\"\n\nimport { $ImageButton } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport { ImageBlockElement, ImageInlineElement } from \"../../../../types\"\nimport { BlockIcon } from \"../../../icons\"\nimport { convertToBlockImage } from \"./convert-to-block-image\"\n\nexport function InlineImageTypeButton({\n element,\n}: {\n element: ImageBlockElement | ImageInlineElement\n}) {\n const editor = useSlateStatic()\n const tooltip = useTooltip({\n title: \"Block Image\",\n hotkey: \"On a line by itself\",\n })\n\n const onClickBlock = useCallback(() => {\n if (element.type !== \"image-inline\") return\n convertToBlockImage(editor, element)\n }, [editor, element])\n\n return (\n <$ImageButton\n className={element.type === \"image-block\" ? \"--selected\" : \"\"}\n onClick={element.type === \"image-block\" ? undefined : onClickBlock}\n onMouseEnter={tooltip.onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n >\n <BlockIcon />\n </$ImageButton>\n )\n}\n","import { Editor, Text, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { findElementUp } from \"../../../../../sink\"\nimport { ImageInlineElement } from \"../../../../types\"\nimport { resizeInPreset } from \"../../../../utils\"\n\nexport function convertToBlockImage(\n editor: Editor,\n element: ImageInlineElement\n) {\n /**\n * TODO:\n *\n * This should be handled or thought about better. Like maybe if these\n * values don't exist, we still change the type.\n */\n if (\n !element.width ||\n !element.height ||\n !element.srcWidth ||\n !element.srcHeight\n )\n return\n const size = { width: element.width, height: element.height }\n const srcSize = { width: element.srcWidth, height: element.srcHeight }\n const path = ReactEditor.findPath(editor, element)\n\n Editor.withoutNormalizing(editor, () => {\n /**\n * TODO:\n *\n * `resizeInPreset` should probably be renamed to something like\n * `resizeIn` which can be used more generically. Perhaps it takes the\n * `type`, `width` and `height` as an Interface making it compatible with\n * a Preset which would extend it.\n */\n const nextSize = resizeInPreset(size, srcSize, {\n name: \"initial-block-image\",\n title: \"\",\n type: \"bounds\",\n width: 320,\n height: 320,\n })\n /**\n * Convert the inline image to a block image.\n *\n * When we make this change, it causes the normalization rules to change\n * from the rules of an inline to the rules of a block. Inlines can only\n * co-exist with Text and other Inline elments. They must also always be\n * followed by and preceded by a Text nod.\n *\n * Some of the code below help to fix the inconsistencies caused by this\n * change.\n */\n Transforms.setNodes(\n editor,\n { type: \"image-block\", ...nextSize },\n { at: path }\n )\n /**\n * Here we find the enclosing parent block for the inline.\n *\n * Note that there should always be a parent block for an inline. If there\n * isn't, something isn't working properly because the Slate normalization\n * rules require a block parent to an inline.\n */\n const parentEntry = findElementUp(\n editor,\n (node) => Editor.isBlock(editor, node) && node.type !== \"image-block\"\n )\n if (!parentEntry) throw new Error(\"This shouldn't happen\")\n const [parentElement, parentPath] = parentEntry\n const siblings = parentElement.children\n const siblingCount = parentElement.children.length\n const index = path.slice(-1)[0]\n\n /**\n * Before we lift the inline node, we want to remove **empty** Text blocks\n * at the beginning of the block when the inline node is the second item\n * and at the end of the block when the inline is the second to last item.\n *\n * We do this because Slate adds empty text nodes always at the beginning\n * and end of a line if the node next to it is an inline. This behavior\n * works fine in most cases, but when we want to lift the inline element\n * up, Slate sees that there is content next to it and when the element is\n * lifted up, the block is split into 3 pieces, including a piece with an\n * empty Text node.\n *\n * From a user expectation point of view though, we don't want these extra\n * blocks inserted. If the inline image is at the end of the line, we want\n * it converted to a block image with a block of stuff before it. There is\n * no use for the extra block at the end with no content in it.\n */\n /**\n * Remove the last sibling if it's empty and next to the inline image\n */\n const lastSibling = siblings[siblingCount - 1]\n if (\n index === siblingCount - 2 &&\n Text.isText(lastSibling) &&\n lastSibling.text === \"\"\n ) {\n Transforms.removeNodes(editor, {\n at: [...parentPath, siblingCount - 1],\n })\n }\n /**\n * Remove the first sibling if it's empty and next to the inline image\n */\n const firstSibling = siblings[0]\n const removeFirstSibling =\n index === 1 && Text.isText(firstSibling) && firstSibling.text === \"\"\n if (removeFirstSibling) {\n Transforms.removeNodes(editor, { at: [...parentPath, 0] })\n }\n /**\n * Now lift the node, but if the first sibling was removed, we need to account fo rthe fact that the index of the image changed.\n */\n Transforms.liftNodes(editor, {\n at: [...parentPath, removeFirstSibling ? index - 1 : index],\n })\n })\n}\n","import { $ImageButtonGroup } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport { ImageBlockElement, ImageInlineElement } from \"../../../../types\"\nimport { BlockImageTypeButton } from \"./block-image-type-button\"\nimport { InlineImageTypeButton } from \"./inline-image-type-button\"\n\nexport function ImageTypeButtonGroup({\n element,\n}: {\n element: ImageBlockElement | ImageInlineElement\n}) {\n return (\n <$ImageButtonGroup>\n <InlineImageTypeButton element={element} />\n <BlockImageTypeButton element={element} />\n </$ImageButtonGroup>\n )\n}\n","import React, { Dispatch, SetStateAction } from \"react\"\n\nimport { $ImageToolbar } from \"../../../styles/image-with-controls-styles/image-toolbar-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n ImageSizePreset,\n} from \"../../../types\"\nimport { ImagePresetButtonGroup } from \"./image-preset-buttons/image-preset-button-group\"\nimport { ImageTypeButtonGroup } from \"./image-type-buttons/image-type-button-group\"\n\n/**\n * The ImageToolbar appears above an image when the image is selected.\n *\n * It includes:\n *\n * - A set of image resize presets when clicked resizes the image to the preset\n * - Buttons to toggle between a block image and an inline image\n */\nexport function ImageToolbar({\n element,\n size,\n setSize,\n srcSize,\n presets,\n}: {\n element: ImageBlockElement | ImageInlineElement\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n srcSize: ImageSize\n presets: ImageSizePreset[]\n}) {\n return (\n <$ImageToolbar>\n <ImageTypeButtonGroup element={element} />\n <ImagePresetButtonGroup\n element={element}\n size={size}\n setSize={setSize}\n srcSize={srcSize}\n presets={presets}\n />\n </$ImageToolbar>\n )\n}\n","import { useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { $ImageInline } from \"../styles/image-inline-styles\"\nimport { ImageInlineElement } from \"../types\"\nimport { ImageWithControls } from \"./image-with-controls\"\n\nexport function ImageInline({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ImageInlineElement>) {\n const editor = useSlateStatic()\n return (\n <span {...attributes} style={{ display: \"inline-block\" }}>\n <$ImageInline contentEditable={false}>\n <ImageWithControls\n element={element}\n presets={editor.image.imageInlinePresets}\n />\n </$ImageInline>\n {children}\n </span>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageInline = styled(\"span\")`\n display: inline;\n`\n","import { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { ImageBlockElement, ImageInlineElement } from \"../types\"\nimport { ImageBlock } from \"./image-block\"\nimport { ImageInline } from \"./image-inline\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ImageBlockElement | ImageInlineElement>) {\n switch (element.type) {\n case \"image-block\":\n return (\n <ImageBlock element={element} attributes={attributes}>\n {children}\n </ImageBlock>\n )\n case \"image-inline\":\n return (\n <ImageInline element={element} attributes={attributes}>\n {children}\n </ImageInline>\n )\n }\n}\n","import { Descendant, Editor, Element, Node, Transforms } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n normalizeSiblings,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { $BlockQuote } from \"./styles\"\n\nexport type BlockQuoteEditor = {\n supportsBlockQuote: true\n blockQuotePlugin: {\n indent: () => void\n outdent: () => void\n isActive: () => boolean\n increaseDepth: () => void\n decreaseDepth: () => void\n canIncreaseDepth: () => boolean\n canDecreaseDepth: () => boolean\n }\n}\n\nexport type BlockQuoteElement = {\n type: \"block-quote\"\n children: Descendant[]\n}\n\nexport type BlockQuotePluginCustomTypes = {\n Name: \"block-quote\"\n Editor: BlockQuoteEditor\n Element: BlockQuoteElement\n}\n\nfunction matchBlockQuoteSafe(node: Node) {\n return (\n Element.isElement(node) &&\n /**\n * TODO:\n *\n * This is probably:\n * Element.isElement(node) && !Element.isInline(node) &&\n * !Element.isDependant(node)\n */\n (node.type === \"paragraph\" ||\n node.type === \"code-block\" ||\n node.type === \"table\" ||\n node.type === \"horizontal-rule\" ||\n node.type === \"task-list-item\" ||\n node.type === \"unordered-list-item\" ||\n node.type === \"ordered-list-item\" ||\n node.type === \"heading\")\n )\n}\n\nconst MAX_DEPTH = 2\n\nexport const BlockQuotePlugin = createPlugin<BlockQuotePluginCustomTypes>(\n (editor) => {\n editor.supportsBlockQuote = true\n editor.blockQuotePlugin = {\n indent: () => {\n Transforms.wrapNodes(\n editor,\n { type: \"block-quote\", children: [] },\n { match: matchBlockQuoteSafe }\n )\n },\n outdent: () => {\n Transforms.liftNodes(editor, {\n match: (node, path) => matchBlockQuoteSafe(node) && path.length > 1,\n })\n },\n isActive: () => {\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n return !!match\n },\n increaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return\n\n // Check if we're already at max depth\n if (!editor.blockQuotePlugin.canIncreaseDepth()) return\n\n const [, path] = match\n\n // Select all content inside the block-quote\n Transforms.select(editor, path)\n\n // Create a new block-quote wrapping the selected content\n Transforms.wrapNodes(\n editor,\n { type: \"block-quote\", children: [] },\n { at: path, split: false }\n )\n },\n decreaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return\n\n // Check if we can decrease depth\n if (!editor.blockQuotePlugin.canDecreaseDepth()) return\n\n const [node, path] = match\n\n // Get the children of the block-quote\n const children = (node as Element).children\n\n // Check if the first child is a block-quote\n if (\n children.length === 1 &&\n Element.isElement(children[0]) &&\n (children[0] as Element).type === \"block-quote\"\n ) {\n // Unwrap the nested block-quote\n Transforms.unwrapNodes(editor, {\n at: [...path, 0], // Path to the nested block-quote\n match: (n) => Element.isElement(n) && n.type === \"block-quote\",\n })\n }\n },\n canIncreaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return false\n\n const [node] = match\n\n // Calculate the current depth\n let depth = 0\n let current = node\n\n while (\n (current as Element).children.length === 1 &&\n Element.isElement((current as Element).children[0]) &&\n (current as Element).children[0] &&\n (current as Element).children[0] &&\n ((current as Element).children[0] as Element).type === \"block-quote\"\n ) {\n depth++\n current = (current as Element).children[0]\n }\n\n return depth < MAX_DEPTH\n },\n canDecreaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return false\n\n const [node] = match\n\n // Check if the first child is a block-quote\n return (\n (node as Element).children.length === 1 &&\n Element.isElement((node as Element).children[0]) &&\n (node as Element).children[0] &&\n ((node as Element).children[0] as Element).type === \"block-quote\"\n )\n },\n }\n return {\n name: \"block-quote\",\n editor: {\n normalizeNode(entry) {\n const [node, path] = entry\n if (!Element.isElement(node)) return false\n if (node.type !== \"block-quote\") return false\n return normalizeSiblings<Element>(editor, [node, path], (a, b) => {\n if (\n Element.isElement(a[0]) &&\n Element.isElement(b[0]) &&\n a[0].type === \"block-quote\" &&\n b[0].type === \"block-quote\"\n ) {\n Transforms.mergeNodes(editor, { at: b[1] })\n }\n return true\n })\n },\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"block-quote\") {\n return <$BlockQuote {...attributes}>{children}</$BlockQuote>\n }\n },\n onKeyDown: createHotkeyHandler({\n \"super+.\": editor.blockQuotePlugin.indent,\n \"super+,\": editor.blockQuotePlugin.outdent,\n }),\n },\n }\n }\n) as TypedPlugin<BlockQuotePluginCustomTypes>\n","import styled from \"@emotion/styled\"\n\nexport const $BlockQuote = styled(\"blockquote\")`\n position: relative;\n margin-top: 1em;\n margin-bottom: 1em;\n margin-left: 0;\n border-left: 0.25em solid rgba(0, 0, 0, 0.075);\n padding-left: 1.5em;\n`\n","import { Editor, Element, Transforms } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n curryOne,\n findElementUp,\n isCollapsed,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { decorate } from \"./decorate\"\nimport { createCodeBlockMethods } from \"./methods\"\nimport { tokenStyles } from \"./prism-theme\"\nimport { CodeBlockPluginCustomTypes } from \"./types\"\nexport * from \"./decorate\"\nexport * from \"./types\"\n\nimport { normalizeNode } from \"./normalizeNode\"\nimport { renderElement } from \"./render-element\"\n\nexport const CodeBlockPlugin = createPlugin<CodeBlockPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.codeBlock = createCodeBlockMethods(editor)\n\n function onDelete(): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const codeBlockEntry = findElementUp(editor, \"code-block\")\n if (codeBlockEntry == null) return false\n const codeBlockText = Editor.string(editor, codeBlockEntry[1])\n if (codeBlockText === \"\") {\n Transforms.removeNodes(editor, { at: codeBlockEntry[1] })\n return true\n }\n return false\n }\n\n return createPolicy({\n name: \"code-block\",\n editor: {\n deleteBackward: onDelete,\n deleteForward: onDelete,\n isInline(element) {\n if (\n element.type === \"code-block\" ||\n element.type === \"code-block-line\"\n )\n return false\n },\n isVoid(element) {\n if (\n element.type === \"code-block\" ||\n element.type == \"code-block-line\"\n )\n return false\n },\n isMaster(element) {\n if (element.type === \"code-block\") return true\n },\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n decorate,\n onKeyDown: createHotkeyHandler({\n \"super+`\": () =>\n editor.codeBlock.createCodeBlock({ language: \"text\" }),\n \"mod+a\": () => {\n /**\n * When selection is in code-block and the user pressed mod+a,\n * select the code-block instead of the full document.\n */\n const entry = findElementUp(\n editor,\n (el) => Element.isElement(el) && el.type === \"code-block\"\n )\n if (!entry) return false\n Transforms.select(editor, entry[1])\n return true\n },\n }),\n renderElement,\n renderLeaf: ({ leaf, children }) => {\n const style = leaf.prismToken\n ? tokenStyles[leaf.prismToken] || null\n : null\n if (style === null) {\n return children\n } else {\n return <span style={style}>{children}</span>\n }\n },\n },\n })\n }\n) as TypedPlugin<CodeBlockPluginCustomTypes>\n","import Prism from \"prismjs\"\nconst { languages, tokenize } = Prism\nimport { Element, Node, Path, Range } from \"slate\"\n\nimport { CodeBlockElement, CodeBlockLineElement } from \"./types\"\n\n/**\n * Decorate Overview:\n *\n * We decorate the entire `code-block` at once because if we do it by line,\n * code that continues through multiple lines is not higlighted correctly.\n *\n * In order to higlight the entire `code-block` at once, we need to add a\n * newline to the end of each `code-line`. We cannot use `Node.string` on the\n * entire `code-block`.\n *\n * Once we receive the Prism tokens back, we need to create the ranges.\n *\n * The important part is that we track the offsets from the start. With the\n * offsets, we need to map those back to a `path` and `offset` of each\n * `code-line`. We also need to take into consideration that we have added\n * newlines to the end of each line so the algorithm needs to account for that.\n */\n\n/**\n * Takes an array of text lines and returns an array with the offset\n * in characters of the start of each line.\n */\n\nfunction getLineOffsets(lines: string[]) {\n let offset = 0\n const lineOffsets: number[] = []\n for (const line of lines) {\n lineOffsets.push(offset)\n offset = offset + line.length\n }\n return lineOffsets\n}\n\n/**\n * `decorate` method passed to `Editable`\n */\n\nexport function decorate(\n nodeEntry: [CodeBlockElement | CodeBlockLineElement, Path]\n): Range[] {\n const [node, path] = nodeEntry\n\n if (!Element.isElement(node)) return []\n if (node.type !== \"code-block\") return []\n\n const lang: Prism.Grammar | undefined = languages[node.language]\n\n if (lang === undefined) return []\n\n /**\n * To decorate a code-block, we need to look at all the code in a code-block.\n *\n * We can't `Node.string` the entire block because it will join lines\n * together without newlines.\n *\n * For this reason, we create an array of `textLines` which is the text of\n * each codeLine plus a newline on the end of it.\n *\n * Then we join all of those together to get the text that was pass into\n * Prism.\n *\n * We need to keep `textLines` around so that we can extract the\n * `linePositions`\n */\n\n const codeLineElements = node.children\n\n const textLines = codeLineElements.map((node) => `${Node.string(node)}\\n`)\n\n const text = textLines.join(\"\")\n\n const lineOffsets: number[] = getLineOffsets(textLines)\n\n /**\n * Takes a character offset from the beginning of the `code-block` and\n * returns the `path` to the `code-line` and the `offset` within the\n * `code-line` which Slate needs to make the decoration.\n */\n\n function getPointFromOffset(offset: number) {\n for (let i = lineOffsets.length; i >= 0; i--) {\n const lineOffset = lineOffsets[i]\n if (lineOffset <= offset) {\n return {\n path: [...path, i],\n offset: offset - lineOffset,\n }\n }\n }\n throw new Error(\"This shouldn't happen and indicates a bug in the logic\")\n }\n\n const ranges: (Range & { prismToken: string })[] = []\n\n const tokens = tokenize(text, lang)\n\n /**\n * Track current character offset from beginning of `textLines` joined\n * together.\n */\n\n let offset = 0\n\n /**\n * Tokens are either:\n *\n * - string: which means it is not syntax highlighted\n * - { type: string, content: string, length: number }: the highlight and content\n */\n for (const token of tokens) {\n if (typeof token === \"string\") {\n offset += token.length\n } else {\n const anchor = getPointFromOffset(offset)\n const focus = getPointFromOffset(offset + token.length)\n ranges.push({\n anchor,\n focus,\n prismToken: token.type,\n })\n offset += token.length\n }\n }\n\n return ranges\n}\n","import { Editor } from \"slate\"\n\nimport { insertRootElement } from \"~/src/sink\"\n\nimport { BuiltInLanguage } from \"../types\"\n\nexport function createCodeBlock(\n editor: Editor,\n { language }: { language: BuiltInLanguage }\n) {\n insertRootElement(editor, {\n type: \"code-block\",\n language,\n children: [{ type: \"code-block-line\", children: [{ text: \"\" }] }],\n })\n}\n","import { Editor, Element, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"~/src/sink\"\n\nimport { BuiltInLanguage } from \"../types\"\n\n/**\n * Set the current CodeBlock's language if the selection is currently in a\n * CodeBlock. Returns true if the language was set, false otherwise.\n */\nexport function setCodeBlockLanguage(\n editor: Editor,\n language: BuiltInLanguage,\n options: { at?: BetterAt } = {}\n): boolean {\n const entry = findElementUp(\n editor,\n (el) => Element.isElement(el) && el.type === \"code-block\",\n { at: options.at }\n )\n if (!entry) return false\n Transforms.setNodes(editor, { language }, { at: entry[1] })\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport { createCodeBlock } from \"./createCodeBlock\"\nimport { setCodeBlockLanguage } from \"./setCodeBlockLanguage\"\n\nexport function createCodeBlockMethods(editor: Editor) {\n return {\n createCodeBlock: curryOne(createCodeBlock, editor),\n setCodeBlockLanguage: curryOne(setCodeBlockLanguage, editor),\n }\n}\n","/**\n * Styles from\n * https://github.com/PrismJS/prism-themes/blob/master/themes/prism-ghcolors.css\n */\n\nimport { CSSProperties } from \"react\"\n\nconst commentStyle = { color: \"#999988\", fontStyle: \"italic\" }\nconst dimStyle = { opacity: \"0.7\" }\nconst stringStyle = { color: \"#e3116c\" }\nconst operatorStyle = { color: \"#393a34\" }\nconst valueStyle = { color: \"#36acaa\" }\nconst keywordStyle = { color: \"#00a4db\" }\nconst functionStyle = { color: \"#9a050f\" }\nconst tagStyle = { color: \"#00009f\" }\nconst boldStyle = { fontWeight: \"bold\" }\nconst italicStyle = { fontStyle: \"italic\" }\n\ntype TokenStyles = Record<string, CSSProperties>\n\nexport const tokenStyles: TokenStyles = {\n comment: commentStyle,\n prolog: commentStyle,\n doctype: commentStyle,\n cdata: commentStyle,\n namespace: dimStyle,\n string: stringStyle,\n \"attr-value\": stringStyle,\n puncutation: operatorStyle,\n operator: operatorStyle,\n entity: valueStyle,\n url: valueStyle,\n symbol: valueStyle,\n number: valueStyle,\n boolean: valueStyle,\n variable: valueStyle,\n constant: valueStyle,\n property: valueStyle,\n regex: valueStyle,\n insert: valueStyle,\n atrule: keywordStyle,\n keyword: keywordStyle,\n \"attr-name\": keywordStyle,\n function: { ...functionStyle, ...boldStyle },\n delete: functionStyle,\n tag: tagStyle,\n selector: tagStyle,\n important: boldStyle,\n bold: boldStyle,\n italic: italicStyle,\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n if (!Element.isElement(entry[0])) return false\n /**\n * Code lines should only contain plain text.\n *\n * - If they contain void elements like images, remove them\n * - If they contain non-void elements, unwrap them\n *\n * TODO:\n *\n * Convert pasted in elements to Markdown code\n */\n if (entry[0].type === \"code-block-line\") {\n for (const [child, path] of Node.children(editor, entry[1])) {\n if (!Element.isElement(child)) continue\n if (editor.isVoid(child)) {\n Transforms.removeNodes(editor, { at: path })\n return true\n } else {\n Transforms.unwrapNodes(editor, { at: path })\n return true\n }\n }\n }\n /**\n * Code blocks should only contain code lines.\n *\n * - If they contain void blocks like images, remove them\n * - If they contain non-void blocks, then convert them to code lines\n *\n * TODO:\n *\n * Convert pasted in elements to Markdown code\n */\n if (entry[0].type === \"code-block\") {\n for (const [child, path] of Node.children(editor, entry[1])) {\n if (!Element.isElement(child)) continue\n if (child.type === \"code-block-line\") continue\n if (child.type === \"code-block\") {\n /**\n * When pasting two or more lines of `code-block-line`, Slate will paste\n * it as a `code-block` which will create a `code-block` in a\n * `code-block`. The following code removes the lower `code-block`.\n */\n Transforms.unwrapNodes(editor, { at: path })\n return true\n } else if (editor.isVoid(child)) {\n Transforms.removeNodes(editor, { at: path })\n return true\n } else {\n Transforms.removeNodes(editor, { at: path })\n Transforms.insertNodes(editor, {\n type: \"code-block-line\",\n children: [{ text: Node.string(child) }],\n })\n return true\n }\n }\n }\n return false\n}\n","import { useCallback, useState } from \"react\"\nimport { useSelected, useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\nimport { $CodeBlock, $CodeBlockLanguage, $CodeBlockScroller } from \"../styles\"\nimport { CodeBlockElement } from \"../types\"\n\nexport function CodeBlock({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<CodeBlockElement>) {\n const editor = useSlateStatic()\n const selected = useSelected()\n const [isEditing, setIsEditing] = useState(false)\n const [inputValue, setInputValue] = useState(element.language)\n\n const handleClick = useCallback(() => {\n setInputValue(element.language)\n setIsEditing(true)\n }, [element.language])\n\n const handleBlur = useCallback(() => {\n setIsEditing(false)\n if (inputValue !== element.language) {\n editor.codeBlock.setCodeBlockLanguage(inputValue || \"text\", { at: element })\n }\n }, [editor, element, inputValue])\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault()\n ;(e.target as HTMLInputElement).blur()\n } else if (e.key === \"Escape\") {\n setInputValue(element.language)\n setIsEditing(false)\n }\n }, [element.language])\n\n return (\n <$CodeBlock className={selected ? \"--selected\" : \"\"} {...attributes}>\n <$CodeBlockLanguage contentEditable={false}>\n {isEditing ? (\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n autoFocus\n style={{\n width: \"100%\",\n border: \"none\",\n background: \"transparent\",\n font: \"inherit\",\n color: \"inherit\",\n padding: 0,\n outline: \"none\",\n textAlign: \"right\",\n }}\n />\n ) : (\n <span onClick={handleClick} style={{ cursor: \"pointer\", width: \"100%\" }}>\n {element.language || \"text\"}\n </span>\n )}\n </$CodeBlockLanguage>\n <$CodeBlockScroller>{children}</$CodeBlockScroller>\n </$CodeBlock>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $CodeBlock = styled(\"div\")`\n position: relative;\n background: var(--code-block-bgcolor);\n margin: 1em 0;\n border-radius: 0.5em;\n border: 1px solid var(--code-block-border-color);\n /**\n * DO NOT REMOVE: Code for adding line numbering if enabled. See $CodeBlockLine\n * for more details.\n * counter-reset: line;\n */\n &.--selected {\n outline: 2px solid var(--select-color);\n }\n /**\n * NOTE: Required to make the border radius work on the first and last lines.\n * Otherwise they will be square.\n */\n overflow-x: hidden;\n`\n\nexport const $CodeBlockScroller = styled(\"div\")`\n padding: 2.25em 1em 1.5em 1em;\n border-radius: 0.5em;\n overflow-x: auto;\n`\n\nexport const $CodeBlockLanguage = styled(\"span\")`\n cursor: pointer;\n position: absolute;\n top: 0.25em;\n right: 0.25em;\n width: 8em;\n display: flex;\n font-size: 0.75em;\n color: var(--shade-700);\n background: var(--shade-200);\n padding: 0.25em 0.5em;\n border-radius: 0.5em;\n align-items: center;\n gap: 0.25em;\n span {\n text-align: right;\n flex: 1 1 auto;\n }\n svg {\n flex: 0 0 auto;\n position: relative;\n }\n &:hover {\n color: var(--shade-800);\n background: var(--shade-300);\n }\n`\n\nexport const $CodeBlockLine = styled(\"div\")`\n white-space: pre;\n line-height: 1.5em;\n counter-increment: line;\n font-family: \"andale mono\", AndaleMono, monospace;\n font-size: 0.875em;\n &.--selected {\n background-color: var(--shade-100);\n }\n /*\n DO NOT REMOVE: Code for adding line numbering.\n TODO: Make optional in future.\n */\n /* &:before {\n content: counter(line);\n color: rgba(0, 0, 0, 0.25);\n border-right: 1px solid rgba(0, 0, 0, 0.05);\n margin-right: 1em;\n padding: 0em 1em 0 0;\n text-align: right;\n display: inline-block;\n width: 2em;\n } */\n`\n","import { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\nimport { $CodeBlockLine } from \"../styles\"\nimport { CodeBlockLineElement } from \"../types\"\n\nexport function CodeBlockLine({\n attributes,\n children,\n}: ConstrainedRenderElementProps<CodeBlockLineElement>) {\n const selected = useSelected()\n return (\n <$CodeBlockLine\n className={selected ? \"--selected\" : \"\"}\n {...attributes}\n spellCheck=\"false\"\n >\n {children}\n </$CodeBlockLine>\n )\n}\n","import { ConstrainedRenderElementProps } from \"../../sink\"\nimport { CodeBlockElement, CodeBlockLineElement } from \"../types\"\nimport { CodeBlock } from \"./CodeBlock\"\nimport { CodeBlockLine } from \"./CodeBlockLine\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<CodeBlockElement | CodeBlockLineElement>) {\n if (element.type === \"code-block\") {\n return (\n <CodeBlock element={element} attributes={attributes}>\n {children}\n </CodeBlock>\n )\n } else if (element.type === \"code-block-line\") {\n return (\n <CodeBlockLine element={element} attributes={attributes}>\n {children}\n </CodeBlockLine>\n )\n }\n}\n","import { Transforms } from \"slate\"\n\nimport { createPlugin, findElementUp, isCollapsed, TypedPlugin } from \"~/src/sink\"\n\nimport { HtmlBlockPluginCustomTypes } from \"./types\"\nimport { HtmlBlock } from \"./render-element\"\nexport * from \"./types\"\n\nexport const HtmlBlockPlugin = createPlugin<HtmlBlockPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n function onDelete(): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const htmlBlockEntry = findElementUp(editor, \"html-block\")\n if (htmlBlockEntry == null) return false\n Transforms.removeNodes(editor, { at: htmlBlockEntry[1] })\n return true\n }\n\n return createPolicy({\n name: \"html-block\",\n editor: {\n deleteBackward: onDelete,\n deleteForward: onDelete,\n isInline(element) {\n if (element.type === \"html-block\") return false\n },\n isVoid(element) {\n if (element.type === \"html-block\") return true\n },\n isMaster(element) {\n if (element.type === \"html-block\") return true\n },\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"html-block\") {\n return (\n <HtmlBlock element={element} attributes={attributes}>\n {children}\n </HtmlBlock>\n )\n }\n },\n },\n })\n }\n) as TypedPlugin<HtmlBlockPluginCustomTypes>\n","import styled from \"@emotion/styled\"\n\nexport const $HtmlBlock = styled(\"div\")`\n position: relative;\n background-color: var(--shade-100);\n border: 1px solid var(--shade-300);\n border-radius: 0.5em;\n padding: 2em 1em 1em 1em;\n margin: 1em 0;\n font-family: \"andale mono\", AndaleMono, monospace;\n font-size: 0.875em;\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--shade-700);\n overflow-x: auto;\n\n &.--selected {\n outline: 2px solid var(--select-color);\n }\n`\n\nexport const $HtmlBlockLabel = styled(\"span\")`\n position: absolute;\n top: 0.25em;\n right: 0.5em;\n font-size: 0.625em;\n color: var(--shade-500);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n`\n","import { RenderElementProps } from \"slate-react\"\nimport { HtmlBlockElement } from \"./types\"\nimport { $HtmlBlock, $HtmlBlockLabel } from \"./styles\"\nimport { unescapeUrlSlashes } from \"~/src/convert/utils\"\n\ntype HtmlBlockRenderElementProps = RenderElementProps & {\n element: HtmlBlockElement\n}\n\nexport function HtmlBlock({\n attributes,\n children,\n element,\n}: HtmlBlockRenderElementProps) {\n return (\n <$HtmlBlock {...attributes} contentEditable={false}>\n <$HtmlBlockLabel>HTML</$HtmlBlockLabel>\n <div>{unescapeUrlSlashes(element.html)}</div>\n {children}\n </$HtmlBlock>\n )\n}\n","import { Descendant, Editor } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n curryOne,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { normalizeNode } from \"./normalize-node\"\nimport { Paragraph } from \"./render-element/paragraph\"\n\nexport type CollapsibleParagraphEditor = {\n collapsibleParagraph: {\n convertParagraph: () => void\n }\n}\n\nexport type ParagraphElement = {\n type: \"paragraph\"\n __collapsible?: true\n children: Descendant[]\n}\n\nexport type CollapsibleParagraphPluginCustomTypes = {\n Name: \"collapsible-paragraph\"\n Editor: CollapsibleParagraphEditor\n Element: ParagraphElement\n}\n\nexport const CollapsibleParagraphPlugin =\n createPlugin<CollapsibleParagraphPluginCustomTypes>((editor) => {\n const { insertBreak } = editor\n editor.insertBreak = () => {\n const { selection } = editor\n if (selection && selection.anchor.path[0] === selection.focus.path[0]) {\n // Get text from start of block to cursor position\n const blockPath = [selection.anchor.path[0]]\n const blockStart = Editor.start(editor, blockPath)\n const textBeforeCursor = Editor.string(editor, {\n anchor: blockStart,\n focus: selection.anchor,\n })\n\n // Check if cursor is right after a newline (creating empty line / paragraph break)\n if (textBeforeCursor.endsWith('\\n')) {\n // Create a new paragraph\n insertBreak()\n } else {\n // Insert a single line break\n editor.insertText('\\n')\n }\n } else {\n // Otherwise fall back to default behavior\n insertBreak()\n }\n }\n\n editor.convertElement.addConvertElementType(\"paragraph\")\n editor.collapsibleParagraph = {\n convertParagraph: () => {\n editor.convertElement.convertElements<ParagraphElement>(\n () => false,\n {\n type: \"paragraph\",\n },\n false\n )\n },\n }\n if (!editor.normalizeAfterDelete) {\n throw new Error(\n `The collapsible-paragraph-plugin has a dependency on the normalize-after-delete plugin. Please add that plugin before this one.`\n )\n }\n\n return {\n name: \"collapsible-paragraph\",\n editor: {\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n switch (element.type) {\n case \"paragraph\": {\n return (\n <Paragraph element={element} attributes={attributes}>\n {children}\n </Paragraph>\n )\n }\n }\n },\n onKeyDown: createHotkeyHandler({\n \"super+0\": editor.collapsibleParagraph.convertParagraph,\n }),\n },\n }\n }) as TypedPlugin<CollapsibleParagraphPluginCustomTypes>\n","import { Editor, Element, Node, NodeEntry } from \"slate\"\n\nimport { normalizeSiblingParagraphs } from \"./normalize-sibling-paragraphs\"\nimport { normalizeSiblingWalls } from \"./normalize-sibling-walls\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n const [node, path] = entry\n if (!Element.isElement(node)) return false\n if (normalizeSiblingWalls(editor, [node, path])) return true\n if (normalizeSiblingParagraphs(editor, [node, path])) return true\n return false\n}\n","import { Editor, Element, NodeEntry, Transforms } from \"slate\"\n\nimport { normalizeSiblings } from \"~/src/sink\"\n\nimport { ParagraphElement } from \"..\"\n\nfunction isParagraph(node: Element): node is ParagraphElement {\n return Element.isElement(node) && node.type === \"paragraph\"\n}\n/**\n * If there are two sibling paragraphs next to each other and they are both\n * marked as `__collapsible`, this indicates to us that some kind of wall\n * Element was removed.\n *\n * These two collapsible paragraphs should then be merged into one.\n */\nexport function normalizeSiblingParagraphs(\n editor: Editor,\n entry: NodeEntry<Element>\n): boolean {\n return normalizeSiblings(editor, entry, (a, b) => {\n if (!isParagraph(a[0]) || !isParagraph(b[0])) return false\n if (a[0].__collapsible && b[0].__collapsible) {\n Transforms.removeNodes(editor, { at: a[1] })\n return true\n }\n return false\n })\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\nimport { normalizeSiblings } from \"~/src/sink\"\n\nfunction isWall(editor: Editor, node: Node) {\n if (!Element.isElement(node)) return false\n return editor.isVoid(node) || editor.isMaster(node)\n}\n/**\n * We want to create collapsible paragraphs in places where we can't easily\n * create them. For example, between two images.\n *\n * Currently, we look for elements that are\n *\n * - `isVoid` like images or\n * - `isMaster` like `table` and `code-block`.\n *\n * If there is nothing between them, we insert a collapsible paragraph.\n */\n\nexport function normalizeSiblingWalls(\n editor: Editor,\n entry: NodeEntry<Element>\n): boolean {\n if (!isWall(editor, entry[0])) return false\n return normalizeSiblings(editor, entry, (a, b) => {\n if (!isWall(editor, a[0]) || !isWall(editor, b[0])) return false\n Transforms.insertNodes(\n editor,\n {\n type: \"paragraph\",\n __collapsible: true,\n children: [{ text: \"\" }],\n },\n { at: b[1] }\n )\n return true\n })\n}\n","import { clsx } from \"clsx\"\nimport { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { ParagraphElement } from \"..\"\nimport { $Paragraph } from \"./styles\"\nimport { getIsEmpty } from \"./utils\"\n\nexport function Paragraph({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ParagraphElement>) {\n const selected = useSelected()\n const isEmpty = getIsEmpty(element)\n return (\n <$Paragraph\n {...attributes}\n className={clsx({\n \"--selected\": selected,\n \"--empty\": isEmpty,\n \"--collapsible\": !!element.__collapsible,\n })}\n >\n {children}\n </$Paragraph>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $Paragraph = styled(\"p\")`\n padding: 0;\n margin: 0;\n &:first-child {\n margin-top: 0;\n }\n\n transition: background-color 200ms, margin-top 200ms, padding-top 200ms,\n margin-bottom 200ms, padding-bottom 200ms, font-size 200ms;\n\n &.--collapsible&.--empty {\n font-size: 0.25em; /* font-size is collapsed to 1/4 of regular em */\n margin: -0.4em 0;\n padding: 0.1em 0; /* this is kind of eye-balling it */\n border-radius: 1em;\n &:hover {\n background: rgba(0, 127, 255, 0.1);\n cursor: pointer;\n }\n }\n &.--collapsible&.--empty&.--selected {\n font-size: 1em;\n padding: 0;\n margin: 0;\n &:hover {\n background: none;\n cursor: default;\n }\n border-radius: 8px;\n }\n`\n","import { Element, Node } from \"slate\"\n\n/**\n * We check for empty by checking for one node that contains a text that is\n * empty. If there is an inline element, this will introduce at a minimum\n * 3 nodes based on the way Slate normalizes to always have text nodes at\n * the end which is why this check works.\n */\nexport function getIsEmpty(element: Element) {\n return (\n element.children.length === 1 &&\n Node.string(element.children[0]).length === 0\n )\n}\n","import { Editor, Element } from \"slate\"\n\n/**\n * This method lets other plugins register specific elements by their `type`\n * being able to be toggled with a paragraph.\n *\n * In order for an Element to be toggle compatible, generally it should be a\n * non-void block Element whose direct descendants are `Text` or inline elements\n * like:\n *\n * - headings\n * - list items\n */\nexport function addConvertElementType(\n editor: Editor,\n type: Element[\"type\"] | Array<Element[\"type\"]>\n): void {\n if (Array.isArray(type)) {\n editor.convertElement.convertElementTypes.push(...type)\n } else {\n editor.convertElement.convertElementTypes.push(type)\n }\n}\n","import { Editor, Element, Node, Path, Point, Range, Transforms } from \"slate\"\n\nimport { rewrapElement, TargetElement } from \"~/src/sink\"\n\n/**\n * Calculates the character offset of a point within an element.\n * Returns -1 if the point is not within the element.\n */\nfunction getOffsetInElement(\n editor: Editor,\n point: Point,\n elementPath: Path\n): number {\n try {\n const elementStart = Editor.start(editor, elementPath)\n const elementEnd = Editor.end(editor, elementPath)\n\n // Check if point is within element\n if (Point.isBefore(point, elementStart) || Point.isAfter(point, elementEnd)) {\n return -1\n }\n\n // Calculate offset from element start to point\n const range = { anchor: elementStart, focus: point }\n return Editor.string(editor, range).length\n } catch {\n return -1\n }\n}\n\n/**\n * Restores the selection to a specific offset within an element.\n */\nfunction restoreSelectionInElement(\n editor: Editor,\n elementPath: Path,\n offset: number\n): void {\n try {\n const element = Node.get(editor, elementPath)\n if (!Element.isElement(element)) return\n\n const text = Node.string(element)\n const safeOffset = Math.min(offset, text.length)\n\n // Find the exact point at the offset\n const elementStart = Editor.start(editor, elementPath)\n let currentOffset = 0\n let targetPath = elementStart.path\n let targetOffset = 0\n\n // Traverse through text nodes to find the correct position\n for (const [node, path] of Node.texts(element)) {\n const nodeLength = node.text.length\n if (currentOffset + nodeLength >= safeOffset) {\n // path is already relative to element, so just concat with elementPath\n targetPath = [...elementPath, ...path]\n targetOffset = safeOffset - currentOffset\n break\n }\n currentOffset += nodeLength\n }\n\n const point: Point = { path: targetPath, offset: targetOffset }\n Transforms.select(editor, { anchor: point, focus: point })\n } catch {\n // If restoration fails, don't crash\n }\n}\n\n/**\n * A type with generic for `convertElements` (below) to be used with the curry\n * method. TypeScript, unfortunately, cannot automatically curry generics for\n * us so we have to do it manually.\n */\nexport type CurriedConvertElements = <T extends Element = Element>(\n matchForToggle: (element: Element) => boolean,\n targetElement: TargetElement<T>,\n allowToggle: boolean\n) => void\n\n/**\n * Checks if an element contains newline characters in its text content\n */\nfunction elementContainsNewlines(element: Element): boolean {\n const text = Node.string(element)\n return text.includes(\"\\n\")\n}\n\n/**\n * Given a selection range and an element, determines which line indices are selected.\n * Returns an object with startLineIndex and endLineIndex.\n */\nfunction getSelectedLineIndices(\n editor: Editor,\n element: Element,\n elementPath: Path,\n selection: Range\n): { startLineIndex: number; endLineIndex: number } {\n const text = Node.string(element)\n const lines = text.split(\"\\n\")\n\n // Get the start and end points relative to this element\n const elementStart = Editor.start(editor, elementPath)\n const elementEnd = Editor.end(editor, elementPath)\n\n // Clamp selection to element boundaries\n const start = Point.isBefore(selection.anchor, elementStart)\n ? elementStart\n : Point.isAfter(selection.anchor, elementEnd)\n ? elementEnd\n : selection.anchor\n const end = Point.isBefore(selection.focus, elementStart)\n ? elementStart\n : Point.isAfter(selection.focus, elementEnd)\n ? elementEnd\n : selection.focus\n\n // Calculate offsets from element start\n const startOffset = Math.min(\n Editor.string(editor, { anchor: elementStart, focus: start }).length,\n text.length\n )\n const endOffset = Math.min(\n Editor.string(editor, { anchor: elementStart, focus: end }).length,\n text.length\n )\n\n const minOffset = Math.min(startOffset, endOffset)\n const maxOffset = Math.max(startOffset, endOffset)\n\n // Find which lines contain these offsets\n let currentOffset = 0\n let startLineIndex = 0\n let endLineIndex = lines.length - 1\n\n for (let i = 0; i < lines.length; i++) {\n const lineEnd = currentOffset + lines[i].length\n if (currentOffset <= minOffset && minOffset <= lineEnd) {\n startLineIndex = i\n }\n if (currentOffset <= maxOffset && maxOffset <= lineEnd) {\n endLineIndex = i\n break\n }\n currentOffset = lineEnd + 1 // +1 for newline\n }\n\n return { startLineIndex, endLineIndex }\n}\n\n/**\n * Splits an element at cursor/selection line boundaries.\n * Only splits out the lines that are selected, keeping other lines in original element.\n * Returns the path of the selected line(s) block.\n */\nfunction splitElementAtSelectedLines(\n editor: Editor,\n element: Element,\n path: Path,\n selection: Range\n): Path {\n const text = Node.string(element)\n if (!text.includes(\"\\n\")) {\n return path\n }\n\n const lines = text.split(\"\\n\")\n if (lines.length <= 1) {\n return path\n }\n\n const { startLineIndex, endLineIndex } = getSelectedLineIndices(\n editor,\n element,\n path,\n selection\n )\n\n // Lines before selection, selected lines, and lines after selection\n const beforeLines = lines.slice(0, startLineIndex)\n const selectedLines = lines.slice(startLineIndex, endLineIndex + 1)\n const afterLines = lines.slice(endLineIndex + 1)\n\n // If all lines are selected, no need to split\n if (beforeLines.length === 0 && afterLines.length === 0) {\n return path\n }\n\n Editor.withoutNormalizing(editor, () => {\n const basePath = path.slice(0, -1)\n const baseIndex = path[path.length - 1]\n\n // Insert after lines as new element (if any) - do this first as it goes after\n if (afterLines.length > 0) {\n const afterText = afterLines.join(\"\\n\")\n const afterElement: Element = {\n ...element,\n children: [{ text: afterText }],\n } as Element\n Transforms.insertNodes(editor, afterElement, {\n at: [...basePath, baseIndex + 1],\n })\n }\n\n // Update original element to contain only before lines + selected lines\n const childrenCount = element.children.length\n for (let j = childrenCount - 1; j >= 0; j--) {\n Transforms.removeNodes(editor, { at: [...path, j] })\n }\n\n if (beforeLines.length > 0) {\n // Original element keeps before lines\n Transforms.insertNodes(\n editor,\n { text: beforeLines.join(\"\\n\") },\n { at: [...path, 0] }\n )\n\n // Insert selected lines as new element after before lines\n const selectedText = selectedLines.join(\"\\n\")\n const selectedElement: Element = {\n type: \"paragraph\",\n children: [{ text: selectedText }],\n }\n Transforms.insertNodes(editor, selectedElement, {\n at: [...basePath, baseIndex + 1],\n })\n } else {\n // No before lines, original element becomes selected lines\n Transforms.insertNodes(\n editor,\n { text: selectedLines.join(\"\\n\") },\n { at: [...path, 0] }\n )\n }\n })\n\n // Return the path of the selected lines block\n if (beforeLines.length > 0) {\n return [...path.slice(0, -1), path[path.length - 1] + 1]\n }\n return path\n}\n\n/**\n * The `convertElements` takes a Block Element that has been identified as being\n * convertible and converts it into another type of Element.\n *\n * For example:\n *\n * - headings\n * - list items\n *\n * It also allows for toggling. In this scenario, if all the convertible\n * elements are already in the target state (e.g. we are converting to a heading\n * 2 and all the convertible elemtns are already a heading 2) then the elements\n * will convert back to a `paragraph` element.\n *\n * NOTE:\n *\n * Why is there an unusual signature?\n *\n * This method has a somewhat unusual and not-DRY signature which is in the form\n * of having a `matchForToggle` (which allows us to specify when an Element is\n * already matching the `targetElement`) and also an `allowToggle`; however, we\n * could make `matchForToggle` optional and only `allowToggle` if it is\n * specified.\n *\n * That being said, the signature is set up this way to reduce friction when\n * creating a specific convert function like `convertHeading`. In this scenario,\n * we can have the created `convertHeading` pass through the argument to\n * `allowToggle` and pass it through to this `convertElements` function making\n * that code easier to understand.\n */\nexport function convertElements<T extends Element = Element>(\n editor: Editor,\n matchForToggle: (element: Element) => boolean,\n targetElement: TargetElement<T>,\n allowToggle: boolean\n): boolean {\n const { selection } = editor\n if (!selection) return false\n\n /**\n * Find convertible elements\n */\n const entries = Array.from(\n Editor.nodes<Element>(editor, {\n match: (node) =>\n Element.isElement(node) &&\n editor.convertElement.isConvertibleElement(node),\n })\n )\n /**\n * If there aren't any convertible elements, there's nothing to do\n */\n if (entries.length === 0) return false\n\n /**\n * Save the cursor position (anchor offset) within the first convertible element\n * so we can restore it after conversion\n */\n let savedAnchorOffset = -1\n let savedFocusOffset = -1\n let isCollapsed = Range.isCollapsed(selection)\n\n /**\n * Save cursor offset relative to the first entry before any transformations\n */\n if (entries.length > 0) {\n const [, firstPath] = entries[0]\n savedAnchorOffset = getOffsetInElement(editor, selection.anchor, firstPath)\n savedFocusOffset = getOffsetInElement(editor, selection.focus, firstPath)\n }\n\n /**\n * Split elements that contain newlines at selected line boundaries\n * Process in reverse order to maintain path validity\n */\n const allPaths: Path[] = []\n Editor.withoutNormalizing(editor, () => {\n for (let i = entries.length - 1; i >= 0; i--) {\n const [element, path] = entries[i]\n if (elementContainsNewlines(element)) {\n const splitPath = splitElementAtSelectedLines(\n editor,\n element,\n path,\n selection\n )\n allPaths.unshift(splitPath)\n } else {\n allPaths.unshift(path)\n }\n }\n })\n\n /**\n * Re-fetch all elements at the updated paths\n */\n const updatedEntries: [Element, Path][] = allPaths\n .map((path) => {\n try {\n const node = Node.get(editor, path)\n if (Element.isElement(node)) {\n return [node, path] as [Element, Path]\n }\n return null\n } catch {\n return null\n }\n })\n .filter((entry): entry is [Element, Path] => entry !== null)\n\n if (updatedEntries.length === 0) return false\n\n /**\n * If `allowToggle` is `true` and all of the convertible elements match the\n * `matchForToggle` (for example, if converting to a heading level 2, if all\n * the matching convertible elements are heading level 2) then we want to\n * toggle back to a paragraph.\n */\n const shouldToggle =\n allowToggle && updatedEntries.every((entry) => matchForToggle(entry[0]))\n\n if (shouldToggle) {\n /**\n * If all of the entries are already the target type, then revert them to\n * a paragraph\n */\n Editor.withoutNormalizing(editor, () => {\n for (const entry of updatedEntries) {\n rewrapElement(editor, { type: \"paragraph\" }, entry[1])\n }\n })\n } else {\n /**\n * If any of the entries aren't the target type, then convert them to the\n * target type.\n */\n Editor.withoutNormalizing(editor, () => {\n for (const entry of updatedEntries) {\n rewrapElement(editor, targetElement, entry[1])\n }\n })\n }\n\n /**\n * Restore cursor position after conversion.\n * Use the first updated entry's path to restore the cursor at the saved offset.\n */\n if (updatedEntries.length > 0 && savedAnchorOffset >= 0) {\n const [, firstPath] = updatedEntries[0]\n if (isCollapsed) {\n // For collapsed selection (cursor), just restore anchor position\n restoreSelectionInElement(editor, firstPath, savedAnchorOffset)\n } else if (savedFocusOffset >= 0) {\n // For expanded selection, restore both anchor and focus\n try {\n const element = Node.get(editor, firstPath)\n if (Element.isElement(element)) {\n const text = Node.string(element)\n const safeAnchorOffset = Math.min(savedAnchorOffset, text.length)\n const safeFocusOffset = Math.min(savedFocusOffset, text.length)\n\n const elementStart = Editor.start(editor, firstPath)\n\n // Calculate anchor point\n let anchorPath = elementStart.path\n let anchorOffset = safeAnchorOffset\n let currentOffset = 0\n for (const [node, path] of Node.texts(element)) {\n const nodeLength = node.text.length\n if (currentOffset + nodeLength >= safeAnchorOffset) {\n // path is already relative to element, so just concat with firstPath\n anchorPath = [...firstPath, ...path]\n anchorOffset = safeAnchorOffset - currentOffset\n break\n }\n currentOffset += nodeLength\n }\n\n // Calculate focus point\n let focusPath = elementStart.path\n let focusOffset = safeFocusOffset\n currentOffset = 0\n for (const [node, path] of Node.texts(element)) {\n const nodeLength = node.text.length\n if (currentOffset + nodeLength >= safeFocusOffset) {\n // path is already relative to element, so just concat with firstPath\n focusPath = [...firstPath, ...path]\n focusOffset = safeFocusOffset - currentOffset\n break\n }\n currentOffset += nodeLength\n }\n\n Transforms.select(editor, {\n anchor: { path: anchorPath, offset: anchorOffset },\n focus: { path: focusPath, offset: focusOffset },\n })\n }\n } catch {\n // Fall back to collapsed selection at anchor\n restoreSelectionInElement(editor, firstPath, savedAnchorOffset)\n }\n }\n }\n\n return true\n}\n","import { Editor, Element } from \"slate\"\n\n/**\n * Returns true if the passed in `element` object is an element type that has\n * previously been registered as a convertible element using the\n * `editor.convertElement.addConvertElementType` method.\n */\nexport function isConvertElement(editor: Editor, element: Element): boolean {\n return editor.convertElement.convertElementTypes.includes(element.type)\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport { addConvertElementType } from \"./add-convert-element-type\"\nimport { convertElements, CurriedConvertElements } from \"./convert-elements\"\nimport { isConvertElement } from \"./is-convert-element\"\n\nexport function createConvertElementMethods(editor: Editor) {\n return {\n convertElementTypes: [] as string[],\n addConvertElementType: curryOne(addConvertElementType, editor),\n isConvertibleElement: curryOne(isConvertElement, editor),\n convertElements: curryOne(\n convertElements,\n editor\n ) as CurriedConvertElements,\n }\n}\n","import { createPlugin, TypedPlugin } from \"~/src/sink\"\n\nimport { createConvertElementMethods } from \"./methods\"\n\nexport type ConvertElementEditor = {\n convertElement: ReturnType<typeof createConvertElementMethods>\n}\n\nexport type ConvertElementPluginCustomTypes = {\n Name: \"convert-element\"\n Editor: ConvertElementEditor\n}\n\nexport const ConvertElementPlugin =\n createPlugin<ConvertElementPluginCustomTypes>((editor) => {\n editor.convertElement = createConvertElementMethods(editor)\n return {\n name: \"convert-element\",\n }\n }) as TypedPlugin<ConvertElementPluginCustomTypes>\n","import { Editor, Path, Range, Transforms } from \"slate\"\n\nimport { findElementUp } from \"../sink\"\nimport { HeadingElement } from \"./types\"\n\nexport function insertBreak(editor: Editor) {\n const entry = findElementUp<HeadingElement>(editor, \"heading\")\n if (!entry) return false\n if (!editor.selection) return false\n if (Range.isExpanded(editor.selection)) return false\n if (!Editor.isEnd(editor, editor.selection.anchor, entry[1])) return false\n const nextPath = Path.next(entry[1])\n Transforms.insertNodes(\n editor,\n { type: \"paragraph\", children: [{ text: \"\" }] },\n { at: nextPath }\n )\n Transforms.select(editor, {\n anchor: Editor.start(editor, nextPath),\n focus: Editor.start(editor, nextPath),\n })\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport { HeadingElement } from \"../types\"\n\nfunction convertHeading(\n editor: Editor,\n level: 1 | 2 | 3 | 4 | 5 | 6,\n allowToggle: boolean\n) {\n editor.convertElement.convertElements<HeadingElement>(\n (element) => element.type === \"heading\" && element.level == level,\n { type: \"heading\", level },\n allowToggle\n )\n}\n\nfunction isHeadingActive(editor: Editor, level: 1 | 2 | 3 | 4 | 5 | 6) {\n const [match] = Editor.nodes(editor, {\n match: n => {\n return (\n 'type' in n &&\n 'level' in n &&\n n.type === 'heading' &&\n n.level === level\n )\n },\n })\n return !!match\n}\n\nexport function createHeadingMethods(editor: Editor) {\n return {\n convertHeading: curryOne(convertHeading, editor),\n isHeadingActive: curryOne(isHeadingActive, editor),\n }\n}\n","import { css } from \"@emotion/react\"\nimport styled from \"@emotion/styled\"\n\nconst headingStyles = css`\n margin-top: 1em;\n &:first-child {\n margin-top: 0;\n }\n font-weight: bold;\n`\n\nexport const $H1 = styled(\"h1\")`\n ${headingStyles}\n font-size: 2.25em;\n letter-spacing: -0.01em;\n`\n\nexport const $H2 = styled(\"h2\")`\n ${headingStyles}\n font-size: 1.5em;\n`\n\nexport const $H3 = styled(\"h3\")`\n ${headingStyles}\n font-size: 1.25em;\n`\n\nexport const $H4 = styled(\"h4\")`\n ${headingStyles}\n font-size: 1em;\n`\n\nexport const $H5 = styled(\"h5\")`\n ${headingStyles}\n font-size: 1em;\n`\n\nexport const $H6 = styled(\"h6\")`\n ${headingStyles}\n font-size: 1em;\n`\n","export * from \"./types\"\n\nimport {\n createAutocompleteSpaceHandler,\n createHotkeyHandler,\n createPlugin,\n curryOne,\n curryTwo,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { insertBreak } from \"./insert-break\"\nimport { createHeadingMethods } from \"./methods\"\nimport { $H1, $H2, $H3, $H4, $H5, $H6 } from \"./styles\"\nimport { HeadingPluginCustomTypes } from \"./types\"\n\nexport const HeadingPlugin = createPlugin<HeadingPluginCustomTypes>(\n (editor) => {\n editor.convertElement.addConvertElementType(\"heading\")\n editor.heading = createHeadingMethods(editor)\n const hotkeyHandler = createHotkeyHandler({\n \"super+1\": curryTwo(editor.heading.convertHeading, 1, true),\n \"super+2\": curryTwo(editor.heading.convertHeading, 2, true),\n \"super+3\": curryTwo(editor.heading.convertHeading, 3, true),\n \"super+4\": curryTwo(editor.heading.convertHeading, 4, true),\n \"super+5\": curryTwo(editor.heading.convertHeading, 5, true),\n \"super+6\": curryTwo(editor.heading.convertHeading, 6, true),\n })\n const autocompleteHandler = createAutocompleteSpaceHandler(editor, {\n \"#\": curryTwo(editor.heading.convertHeading, 1, false),\n \"##\": curryTwo(editor.heading.convertHeading, 2, false),\n \"###\": curryTwo(editor.heading.convertHeading, 3, false),\n \"####\": curryTwo(editor.heading.convertHeading, 4, false),\n \"#####\": curryTwo(editor.heading.convertHeading, 5, false),\n \"######\": curryTwo(editor.heading.convertHeading, 6, false),\n })\n return {\n name: \"heading\",\n editor: {\n insertBreak: curryOne(insertBreak, editor),\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"heading\") {\n switch (element.level) {\n case 1:\n return <$H1 {...attributes}>{children}</$H1>\n case 2:\n return <$H2 {...attributes}>{children}</$H2>\n case 3:\n return <$H3 {...attributes}>{children}</$H3>\n case 4:\n return <$H4 {...attributes}>{children}</$H4>\n case 5:\n return <$H5 {...attributes}>{children}</$H5>\n case 6:\n return <$H6 {...attributes}>{children}</$H6>\n default: {\n const exhaustiveCheck: never = element.level\n throw new Error(\n `Expected element.level to be 1-6 but got ${exhaustiveCheck as number}`\n )\n }\n }\n }\n },\n onKeyDown: (e) => {\n if (hotkeyHandler(e)) return true\n if (autocompleteHandler(e)) return true\n return false\n },\n },\n }\n }\n) as TypedPlugin<HeadingPluginCustomTypes>\n","import { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { HorizontalRuleElement } from \".\"\nimport { $HorizontalRule } from \"./styles\"\n\nexport function HorizontalRule({\n attributes,\n children,\n}: ConstrainedRenderElementProps<HorizontalRuleElement>) {\n const selected = useSelected()\n return (\n <div {...attributes} draggable>\n {children}\n <div contentEditable={false}>\n <$HorizontalRule className={selected ? \"--selected\" : \"\"} />\n </div>\n </div>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $HorizontalRule = styled(\"hr\")`\n position: relative;\n height: 1em;\n /* background-color: var(--hr-color); */\n margin: 1em 0;\n &::before {\n position: absolute;\n content: \"\";\n left: 0.125em;\n right: 0.125em;\n top: 50%;\n height: 1px;\n background-color: var(--hr-color);\n border-radius: 1px;\n }\n border-radius: 0.25em;\n cursor: pointer;\n border: none;\n &:hover {\n background-color: rgba(0, 127, 255, 0.1);\n /* &::before {\n outline: 2px solid var(--hover-color);\n } */\n }\n &.--selected {\n background: none;\n &::before {\n outline: 2px solid var(--select-color, blue);\n }\n }\n`\n","import { Editor } from \"slate\"\n\nimport { curryOne, insertRootElement } from \"~/src/sink\"\n\nfunction insertHorizontalRule(editor: Editor) {\n return insertRootElement(editor, {\n type: \"horizontal-rule\",\n children: [{ text: \"\" }],\n })\n}\n\nexport function createHorizontalRuleMethods(editor: Editor) {\n return {\n insertHorizontalRule: curryOne(insertHorizontalRule, editor),\n }\n}\n","import { createHotkeyHandler, createPlugin, TypedPlugin } from \"~/src/sink\"\n\nimport { HorizontalRule } from \"./horizontal-rule\"\nimport { createHorizontalRuleMethods } from \"./methods\"\nimport { HorizontalRulePluginCustomTypes } from \"./types\"\nexport * from \"./types\"\n\nexport const HorizontalRulePlugin =\n createPlugin<HorizontalRulePluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.horizontalRule = createHorizontalRuleMethods(editor)\n return createPolicy({\n name: \"horizontal-rule\",\n editor: {\n isVoid(element) {\n if (element.type === \"horizontal-rule\") return true\n },\n },\n editableProps: {\n renderElement: (props) => {\n if (props.element.type === \"horizontal-rule\") {\n return <HorizontalRule {...props} />\n }\n },\n onKeyDown: createHotkeyHandler({\n \"super+-\": editor.horizontalRule.insertHorizontalRule,\n }),\n },\n })\n }\n ) as TypedPlugin<HorizontalRulePluginCustomTypes>\n","import styled from \"@emotion/styled\"\n\nexport const $InlineCode = styled(\"code\")`\n color: var(--shade-600);\n background-color: var(--inline-code-bgcolor);\n border: 1px solid var(--inline-code-border-color);\n border-radius: 0.25em;\n padding: 0.1375em 0.125em;\n /**\n * Font Stack from\n * https://qwtel.com/posts/software/the-monospaced-system-ui-css-font-stack/\n */\n font-family: ui-monospace, Menlo, Monaco, \"Cascadia Mono\", \"Segoe UI Mono\",\n \"Roboto Mono\", \"Oxygen Mono\", \"Ubuntu Monospace\", \"Source Code Pro\",\n \"Fira Mono\", \"Droid Sans Mono\", \"Courier New\", monospace;\n /**\n * This font size may seem smaller but any larger (including 0.875) means that\n * it messes up the line height of the normal text. Not sure why this happens\n * with the monospace font but seems to happen on both the default 'monospace'\n * font as well as the font stack above.\n */\n font-size: 0.75em;\n vertical-align: baseline;\n`\n\n/**\n * These invisible spans fix a bug in Chrome which doesn't allow the cursor to\n * sit on both the \"inside\" and \"outside\" of the inline-code span. By placing\n * this 1px wide span just inside of the inline code, we are able to workaround\n * this limitation.\n */\nexport const $InvisibleSpan = styled(\"span\")`\n display: inline-block;\n opacity: 0;\n width: 1px;\n overflow: hidden;\n`\n","import { createHotkeyHandler, createPlugin, TypedPlugin } from \"~/src/sink\"\n\nimport { $InlineCode, $InvisibleSpan } from \"./styles\"\nimport { InlineCodePluginCustomTypes } from \"./types\"\nexport * from \"./styles\"\nexport * from \"./types\"\n\nexport const InlineCodePlugin = createPlugin<InlineCodePluginCustomTypes>(\n (editor) => {\n if (!editor.marksPlugin)\n throw new Error(\n \"InlineCodePlugin has a dependency on the MarksPlugin but the MarksPlugin has not been added or is added after the InlineCodePlugin\"\n )\n editor.inlineCode = {\n toggleInlineCode: () => editor.marksPlugin.toggleMark(\"code\"),\n }\n return {\n name: \"inline-code\",\n editableProps: {\n renderLeaf: ({ leaf, children }) => {\n if (leaf.code) {\n return (\n /**\n * Disable spellCheck because it's computer code usually.\n */\n <$InlineCode spellCheck={false}>\n {/* These invisible spans are necessary. See comments for $InvisibleSpan. */}\n <$InvisibleSpan contentEditable={false}>|</$InvisibleSpan>\n {children}\n {/* These invisible spans are necessary. See comments for $InvisibleSpan. */}\n <$InvisibleSpan contentEditable={false}>|</$InvisibleSpan>\n </$InlineCode>\n )\n } else {\n return children\n }\n },\n onKeyDown: createHotkeyHandler({\n \"mod+j\": () => editor.inlineCode.toggleInlineCode(),\n }),\n },\n }\n }\n) as TypedPlugin<InlineCodePluginCustomTypes>\n","import { Editor, Path } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createIsElementType,\n createPlugin,\n curryOne,\n findElementUp,\n isStartOfElement,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { createListMethods } from \"./methods\"\nimport { normalizeNode } from \"./normalize-node\"\nimport { renderElement } from \"./render-element\"\nimport { ListItemElement, ListPluginCustomTypes } from \"./types\"\n\nexport * from \"./types\"\n\nexport const LIST_ITEM_TYPES: ListItemElement[\"type\"][] = [\n \"unordered-list-item\",\n \"ordered-list-item\",\n \"task-list-item\",\n]\n\nexport const isListItem = createIsElementType<ListItemElement>(LIST_ITEM_TYPES)\n\nexport const ListPlugin = createPlugin<ListPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.convertElement.addConvertElementType(LIST_ITEM_TYPES)\n const list = (editor.list = createListMethods(editor))\n const hotkeyHandler = createHotkeyHandler({\n tab: list.indent,\n \"shift+tab\": list.outdent,\n \"super+7\": curryOne(list.convertOrderedList, true),\n \"super+8\": curryOne(list.convertUnorderedList, true),\n \"super+9\": curryOne(list.convertTaskList, true),\n })\n\n return createPolicy({\n name: \"list\",\n editor: {\n normalizeNode: (entry) => normalizeNode(editor, entry),\n insertBreak: list.insertBreak,\n deleteBackward: (unit) => {\n /**\n * This handles the logic where if the cursor is at the start of a\n * list item, and the user presses backspace, then the list item\n * should be converted to a paragraph if there are no list items\n * before it. If there is a list item before it, then the normal\n * delete behavior which would merge the list items together will\n * occur.\n */\n if (unit !== \"character\") return false\n if (!isStartOfElement(editor, isListItem)) return false\n const listItem = findElementUp<ListItemElement>(editor, isListItem)\n if (!listItem) return false\n const listItemPath = listItem[1]\n /**\n * If the current list item is the first element in the document,\n * convert it to a paragraph.\n */\n if (!Path.hasPrevious(listItemPath)) {\n editor.collapsibleParagraph.convertParagraph()\n return true\n }\n const prevElementPath = Path.previous(listItemPath)\n const prevElementEntry = Editor.node(editor, prevElementPath)\n if (isListItem(prevElementEntry[0])) return false\n /**\n * If the previous element is not a list item, then convert the\n * current list item to a paragraph.\n */\n editor.collapsibleParagraph.convertParagraph()\n return true\n },\n },\n editableProps: {\n renderElement,\n onKeyDown(e) {\n if (!Editor.nodes(editor, { match: isListItem })) return false\n return hotkeyHandler(e)\n },\n },\n })\n }\n) as TypedPlugin<ListPluginCustomTypes>\n","import { Editor } from \"slate\"\n\nimport {\n OrderedListItemElement,\n TaskListItemElement,\n UnorderedListItemElement,\n} from \"..\"\n\nexport function convertOrderedList(editor: Editor, allowToggle: boolean) {\n return editor.convertElement.convertElements<OrderedListItemElement>(\n (element) => element.type === \"ordered-list-item\",\n (element) => {\n return {\n type: \"ordered-list-item\",\n depth: \"depth\" in element ? element.depth : 0,\n }\n },\n allowToggle\n )\n}\n\nexport function convertTaskList(editor: Editor, allowToggle: boolean) {\n return editor.convertElement.convertElements<TaskListItemElement>(\n (element) => element.type === \"task-list-item\",\n (element) => {\n return {\n type: \"task-list-item\",\n checked: \"checked\" in element ? element.checked : false,\n depth: \"depth\" in element ? element.depth : 0,\n }\n },\n allowToggle\n )\n}\n\nexport function convertUnorderedList(editor: Editor, allowToggle: boolean) {\n return editor.convertElement.convertElements<UnorderedListItemElement>(\n (element) => element.type === \"unordered-list-item\",\n (element) => {\n return {\n type: \"unordered-list-item\",\n depth: \"depth\" in element ? element.depth : 0,\n }\n },\n allowToggle\n )\n}\n","import { Editor, Element } from \"slate\"\nimport { findElementUp, isStartOfElement } from \"~/src/sink\"\nimport { isListItem } from \"..\"\nimport { ListItemElement } from \"../types\"\n\nconst MAX_DEPTH = 2\n\nexport function getListDepth(editor: Editor): number {\n const listItem = findElementUp<ListItemElement>(editor, isListItem)\n if (!listItem) return 0\n return listItem[0].depth\n}\n\nexport function canIncreaseDepth(editor: Editor): boolean {\n if (!isStartOfElement(editor, isListItem)) return false\n const depth = getListDepth(editor)\n return depth < MAX_DEPTH\n}\n\nexport function canDecreaseDepth(editor: Editor): boolean {\n if (!isStartOfElement(editor, isListItem)) return false\n const depth = getListDepth(editor)\n return depth > 0\n}\n\nexport function increaseDepth(editor: Editor): void {\n if (!canIncreaseDepth(editor)) return\n editor.list.indent()\n}\n\nexport function decreaseDepth(editor: Editor): void {\n if (!canDecreaseDepth(editor)) return\n editor.list.outdent()\n}\n","import { Editor } from \"slate\"\n\nimport { setNodesDynamic } from \"~/src/sink\"\n\nimport { isListItem, ListItemElement } from \"..\"\n\nexport function indent(editor: Editor) {\n return setNodesDynamic<ListItemElement>(\n editor,\n (node) => ({ depth: node.depth + 1 }),\n {\n match: isListItem,\n }\n )\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { findElementUp, rewrapElement } from \"~/src/sink\"\n\nimport { isListItem } from \"..\"\nimport { ListItemElement } from \"../types\"\n\nexport function insertBreak(editor: Editor): boolean {\n const entry = findElementUp<ListItemElement>(editor, isListItem)\n if (!entry) return false\n const [element, path] = entry\n\n /**\n * If we're in an empty list\n */\n if (Editor.isEmpty(editor, element)) {\n if (element.depth > 0) {\n /**\n * If it's indented, then unindent it\n */\n Transforms.setNodes(editor, { depth: element.depth - 1 }, { at: path })\n return true\n } else {\n /**\n * If it's fully unindented, turn it into a paragraph\n */\n rewrapElement(editor, { type: \"paragraph\" }, path)\n return true\n }\n }\n /**\n * Otherwise perform default insertBreak transform\n */\n Transforms.splitNodes(editor, { always: true })\n /**\n * Then find the list item we are now in\n */\n const nextEntry = findElementUp<ListItemElement>(editor, isListItem)\n if (!nextEntry) return true\n /**\n * And if it's a checked task list that is checked, we want to uncheck it.\n * New list items are by default always unchecked.\n */\n if (nextEntry[0].type === \"task-list-item\" && nextEntry[0].checked === true) {\n Transforms.setNodes(editor, { checked: false }, { at: nextEntry[1] })\n }\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { setNodesDynamic } from \"~/src/sink\"\n\nimport { isListItem, ListItemElement } from \"..\"\n\nexport function outdent(editor: Editor): boolean {\n const entries = Array.from(\n Editor.nodes<ListItemElement>(editor, {\n match: isListItem,\n })\n )\n /**\n * Don't allow `shift+tab` if any of the list items are already at a\n * depth of `0`\n */\n for (const entry of entries) {\n if (entry[0].depth === 0) return true\n }\n return setNodesDynamic<ListItemElement>(\n editor,\n (node) => ({ depth: Math.max(0, node.depth - 1) }),\n {\n match: isListItem,\n }\n )\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"~/src/sink\"\n\nimport { TaskListItemElement } from \"../types\"\n\nexport function toggleTaskListItem(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const taskListItem = findElementUp<TaskListItemElement>(\n editor,\n \"task-list-item\",\n { at }\n )\n if (!taskListItem) return false\n const nextChecked = !taskListItem[0].checked\n Transforms.setNodes<TaskListItemElement>(\n editor,\n { checked: nextChecked },\n { at: taskListItem[1] }\n )\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport {\n convertOrderedList,\n convertTaskList,\n convertUnorderedList,\n} from \"./convert-list-item\"\nimport {\n getListDepth,\n canIncreaseDepth,\n canDecreaseDepth,\n increaseDepth,\n decreaseDepth,\n} from \"./depth\"\nimport { indent } from \"./indent\"\nimport { insertBreak } from \"./insert-break\"\nimport { outdent } from \"./outdent\"\nimport { toggleTaskListItem } from \"./toggleTaskListItem\"\n\nexport function createListMethods(editor: Editor) {\n return {\n indent: curryOne(indent, editor),\n outdent: curryOne(outdent, editor),\n convertUnorderedList: curryOne(convertUnorderedList, editor),\n convertOrderedList: curryOne(convertOrderedList, editor),\n convertTaskList: curryOne(convertTaskList, editor),\n insertBreak: curryOne(insertBreak, editor),\n toggleTaskListItem: curryOne(toggleTaskListItem, editor),\n getListDepth: curryOne(getListDepth, editor),\n canIncreaseDepth: curryOne(canIncreaseDepth, editor),\n canDecreaseDepth: curryOne(canDecreaseDepth, editor),\n increaseDepth: curryOne(increaseDepth, editor),\n decreaseDepth: curryOne(decreaseDepth, editor),\n }\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\nimport { createIsElementType, normalizeSiblings } from \"~/src/sink\"\n\nimport { isListItem, OrderedListItemElement } from \"..\"\n\nconst isOrderedListItem = createIsElementType<OrderedListItemElement>([\n \"ordered-list-item\",\n])\n\n/**\n * Makes sure that when a list item is deeper than a preceding one, that we\n * reset the counter.\n *\n * How it works:\n *\n * If we have any two list item siblings where the second sibling is an\n * `ordered-list-item`, then the second sibling should have the property\n * `_firstOfType` be `true` if the depth of the second sibling is higher or\n * the previous sibling is not an ordered list item (e.g. a paragraph or a\n * bullet)\n *\n * Why we need it:\n *\n * We need to do this manually because our implementation of lists does not\n * actually nest lists within lists. We took the approach because the cost\n * of actually nesting lists is very high in terms of added complexity. It is\n * much easier to manually reset the counters than it is to implement\n * everything to W3C specifications, especially given that from a UI\n * perspective, users expect lists to behave similar to paragraphs and\n * headings.\n */\n\nexport function normalizeOrderedFirstAtDepth(\n editor: Editor,\n entry: NodeEntry<Node>\n): boolean {\n const [node, path] = entry\n if (!Element.isElement(node)) return false\n return normalizeSiblings<Element>(editor, [node, path], (a, b) => {\n /**\n * If the second item (the item we are actually looking at) is not an\n * ordered list item, then we aren't interested.\n */\n if (!isOrderedListItem(b[0])) return false\n /**\n * The second item is an ordered-list-item. If the item before it is not\n * or the second item is deeper than the first, then we want to set\n * `__firstAtDepth` to `true`.\n */\n // For non-list items, treat them as depth 0\n const __firstAtDepth = isOrderedListItem(a[0]) ? b[0].depth > a[0].depth : isListItem(a[0]) ? b[0].depth > a[0].depth : true\n /**\n * Check if the setting is already correct.\n */\n if (b[0].__firstAtDepth !== __firstAtDepth) {\n Transforms.setNodes(editor, { __firstAtDepth }, { at: b[1] })\n return true\n }\n return false\n })\n}\n","import { Editor, Node, NodeEntry } from \"slate\"\n\nimport { isListItem } from \"..\"\nimport { normalizeOrderedFirstAtDepth } from \"./normalize-ordered-first-at-depth\"\nexport * from \"./normalize-ordered-first-at-depth\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n const [node] = entry\n /**\n * Short circuit return if current entry isn't any type of list item element.\n */\n if (!isListItem(node)) return false\n return normalizeOrderedFirstAtDepth(editor, entry)\n}\n","import { clsx } from \"clsx\"\nimport { useEffect } from \"react\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { normalizeOrderedFirstAtDepth } from \"../normalize-node\"\nimport { OrderedListItemElement as OrderedListItemElement } from \"../types\"\nimport { $OrderedListItem } from \"./styles\"\n\nexport function OrderedListItem({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<OrderedListItemElement>) {\n const editor = useSlateStatic()\n useEffect(() => {\n const path = ReactEditor.findPath(editor, element)\n normalizeOrderedFirstAtDepth(editor, [element, path])\n }, [])\n const style = {\n marginLeft: `${2 + element.depth * 2}em`,\n \"--list-item-var\": `list-item-depth-${element.depth}`,\n } as React.CSSProperties\n const className = clsx({ \"--first-at-depth\": element.__firstAtDepth })\n return (\n <$OrderedListItem {...attributes} className={className} style={style}>\n {children}\n </$OrderedListItem>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { isDebug } from \"~/src/sink\"\n\nconst $ListItem = styled(\"li\")`\n margin-top: 0.5em;\n margin-bottom: 0.5em;\n list-style-position: outside;\n`\n\nexport const $UnorderedListItem = styled($ListItem)`\n position: relative;\n list-style-type: none;\n .--list-item-icon {\n position: absolute;\n top: 0.25em;\n left: -1.375em;\n line-height: 1.5em;\n color: var(--shade-600);\n }\n`\n\nexport const $OrderedListItem = styled($ListItem)`\n position: relative;\n list-style-type: none;\n counter-increment: var(--list-item-var);\n\n &.--first-at-depth {\n counter-reset: var(--list-item-var);\n /**\n * if isDebug is true, then show a highlight on list items that are marked\n * as the first at a given depth.\n */\n background: ${isDebug ? \"rgba(0, 255, 0, 0.2)\" : \"inherit\"};\n }\n\n &:before {\n position: absolute;\n content: counter(var(--list-item-var)) \".\";\n top: 0;\n left: -2em;\n width: 1.5em;\n text-align: right;\n color: var(--shade-500);\n /* force numbers to be monospaced for better alignment */\n font-variant-numeric: tabular-nums;\n }\n`\n\nexport const $TaskListItem = styled($ListItem)`\n position: relative;\n list-style-type: none;\n .--list-item-icon {\n position: absolute;\n top: 0.25em;\n left: -1.5em;\n line-height: 1.5em;\n color: var(--shade-300);\n .--checkmark {\n color: green;\n stroke-width: 3px;\n }\n }\n`\n","import { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { TaskListItemElement } from \"../types\"\nimport { CheckedIcon, UncheckedIcon } from \"./list-icons\"\nimport { $TaskListItem } from \"./styles\"\n\nexport function TaskListItem({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<TaskListItemElement>) {\n const editor = useSlateStatic()\n const toggle = useCallback(() => {\n editor.list.toggleTaskListItem({ at: element })\n }, [editor, element])\n\n const marginLeft = `${2 + element.depth * 2}em`\n return (\n <$TaskListItem {...attributes} style={{ marginLeft }}>\n <div className=\"--list-item-icon\" contentEditable={false}>\n {element.checked ? (\n <CheckedIcon onClick={toggle} style={{ cursor: \"pointer\" }} />\n ) : (\n <UncheckedIcon onClick={toggle} style={{ cursor: \"pointer\" }} />\n )}\n </div>\n {children}\n </$TaskListItem>\n )\n}\n","import * as React from \"react\"\nimport { SVGProps } from \"react\"\n\n/**\n * https://tabler-icons.io/\n */\nexport const UncheckedIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n strokeWidth={2}\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 24 24\"\n {...props}\n >\n <path d=\"M0 0h24v24H0z\" stroke=\"none\" />\n <rect x={4} y={4} width={16} height={16} rx={2} />\n </svg>\n)\n\n/**\n * https://tabler-icons.io/\n */\nexport const CheckedIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"icon icon-tabler icon-tabler-checkbox\"\n width=\"1em\"\n height=\"1em\"\n strokeWidth={2}\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 24 24\"\n {...props}\n >\n <path d=\"M0 0h24v24H0z\" stroke=\"none\" />\n <path d=\"m9 11 3 3 8-8\" className=\"--checkmark\" />\n <path d=\"M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h9\" />\n </svg>\n)\n\n/**\n * Modified viewfinder-circle from https://heroicons.com/\n */\nexport const BulletIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n {...props}\n >\n <path d=\"M12 8.25a3.75 3.75 0 1 0 0 7.5 3.75 3.75 0 0 0 0-7.5z\" />\n </svg>\n)\n","import { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { UnorderedListItemElement } from \"../types\"\nimport { BulletIcon } from \"./list-icons\"\nimport { $UnorderedListItem } from \"./styles\"\n\nexport function UnorderedListItem({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<UnorderedListItemElement>) {\n const marginLeft = `${2 + element.depth * 2}em`\n return (\n <$UnorderedListItem {...attributes} style={{ marginLeft }}>\n <div className=\"--list-item-icon\" contentEditable={false}>\n <BulletIcon />\n </div>\n {children}\n </$UnorderedListItem>\n )\n}\n","import { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { ListItemElement } from \"../types\"\nimport { OrderedListItem } from \"./ordered-list-item\"\nimport { TaskListItem } from \"./task-list-item\"\nimport { UnorderedListItem } from \"./unordered-list-item\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ListItemElement>) {\n switch (element.type) {\n case \"ordered-list-item\":\n return (\n <OrderedListItem element={element} attributes={attributes}>\n {children}\n </OrderedListItem>\n )\n case \"unordered-list-item\":\n return (\n <UnorderedListItem element={element} attributes={attributes}>\n {children}\n </UnorderedListItem>\n )\n case \"task-list-item\":\n return (\n <TaskListItem element={element} attributes={attributes}>\n {children}\n </TaskListItem>\n )\n }\n}\n","import { clsx } from \"clsx\"\nimport { Editor, Point, Range } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { createMarksMethods } from \"./methods\"\nimport { $MarksSpan } from \"./styles\"\n\nexport type MarksEditor = {\n /**\n * IMPORTANT:\n *\n * This cannot be named `marks` because it conflicts with the `editor.marks`\n * built into the BaseEditor.j\n */\n marksPlugin: ReturnType<typeof createMarksMethods>\n activeMarks?: {\n bold?: boolean\n italic?: boolean\n underline?: boolean\n strike?: boolean\n }\n}\n\nexport type MarksText = {\n text: string\n bold?: true\n italic?: true\n underline?: true\n strike?: true\n highlight?: true\n}\n\nexport type MarksPluginCustomTypes = {\n Name: \"marks\"\n Editor: MarksEditor\n Text: MarksText\n}\n\nexport const MarksPlugin = createPlugin<MarksPluginCustomTypes>((editor) => {\n editor.marksPlugin = createMarksMethods(editor)\n editor.activeMarks = {}\n const hotkeyHandler = createHotkeyHandler({\n \"mod+b\": editor.marksPlugin.toggleBold,\n \"mod+i\": editor.marksPlugin.toggleItalic,\n \"mod+u\": editor.marksPlugin.toggleUnderline,\n \"super+0\": editor.marksPlugin.removeMarks,\n \"super+k\": editor.marksPlugin.toggleStrike,\n })\n // Override insertText to apply active marks\n const { insertText: defaultInsertText } = editor\n editor.insertText = (text) => {\n if (editor.activeMarks && Object.keys(editor.activeMarks).length > 0) {\n const { activeMarks } = editor\n // Apply marks before inserting text\n Object.entries(activeMarks).forEach(([mark, isActive]) => {\n if (isActive) {\n editor.addMark(mark, true)\n }\n })\n }\n defaultInsertText(text)\n }\n\n // Override removeMarks to clear activeMarks at line end\n const { removeMarks } = editor.marksPlugin\n editor.marksPlugin.removeMarks = () => {\n removeMarks()\n if (editor.selection) {\n const point = Range.isRange(editor.selection as any) ? (editor.selection as Range).focus : editor.selection\n if (Point.isPoint(point)) {\n const isAtLineEnd = Editor.after(editor, point) === null ||\n Editor.isEnd(editor, point, Editor.end(editor, []))\n if (isAtLineEnd) {\n editor.activeMarks = {}\n }\n }\n }\n }\n\n return {\n name: \"marks\",\n editableProps: {\n renderLeaf: ({ leaf, children }) => {\n return (\n <$MarksSpan\n className={clsx({\n \"--bold\": leaf.bold,\n \"--italic\": leaf.italic,\n \"--underline\": leaf.underline,\n \"--strike\": leaf.strike,\n \"--highlight\": leaf.highlight,\n })}\n >\n {children}\n </$MarksSpan>\n )\n },\n onKeyDown: (e) => {\n if (hotkeyHandler(e)) return true\n // if (\n // autocompleteMarker(editor, e, {\n // triggerMarker: \"`\",\n // regexp: /([`])(\\S.*?)([`])$/,\n // mark: \"code\",\n // })\n // ) {\n // return true\n // }\n // if (\n // autocompleteMarker(editor, e, {\n // triggerMarker: \"*\",\n // regexp: /([*])(.+?)([*])$/,\n // mark: \"italic\",\n // })\n // ) {\n // return true\n // }\n return false\n },\n },\n }\n}) as TypedPlugin<MarksPluginCustomTypes>\n\n// function autocompleteMarker(\n// editor: Editor,\n// e: React.KeyboardEvent<HTMLDivElement>,\n// {\n// triggerMarker,\n// regexp,\n// mark,\n// }: { triggerMarker: string; regexp: RegExp; mark: keyof Text }\n// ): boolean {\n// /**\n// * Make sure theere is a selection and it's collapsed\n// */\n// console.log(\n// { triggerMarker, mark },\n// e.key,\n// e.which,\n// toKeyCode(\"*\"),\n// toKeyName(\"*\"),\n// isHotkey(\"*\", { byKey: true })(e.nativeEvent)\n// )\n// if (editor.selection === null) return false\n// if (Range.isExpanded(editor.selection)) return false\n// /**\n// * WHAT I'M WORKING ON:\n// *\n// * So, basically, `is-hotkey` doesn't work with an asterisk. We need to find\n// * an alternate way of testing but it's a little tricky and there are a few\n// * approaches we can take:\n// *\n// * - The first approach is to write our own key checker, but be careful\n// * because we want to make sure we aren't interception hotkeys with modifier\n// * keys for example. Like CMD+OPTION+8 should not trigger the `*` trigger.\n// *\n// * - NOTE: tested and paste does not trigger insertText. The second approach\n// * is to tie into `insertText` instead. This may be a more reliable method\n// * but we also need to at least think about whether insertText gets\n// * triggered during a paste event, for example, and if it does, that would\n// * be weird to have that suddenly bold some text.\n// *\n// */\n// // if (isHotkey(triggerMarker, e.nativeEvent)) {\n// if (isHotkey(triggerMarker, e.nativeEvent)) {\n// console.log(\"triggered\")\n// stopEvent(e)\n// const markerText = triggerMarker\n// Transforms.insertText(editor, markerText)\n// const { selection } = editor\n\n// /**\n// * Make sure we are in a block that is not void.\n// */\n// const blockEntry = findElementUp(\n// editor,\n// (node) =>\n// Element.isElement(node) &&\n// !Editor.isVoid(editor, node) &&\n// Editor.isBlock(editor, node)\n// )\n// if (blockEntry == null) return true\n\n// /**\n// * Grab all the text from the beginning of the block until now\n// */\n// const range = {\n// anchor: Editor.start(editor, blockEntry[1]),\n// focus: selection.focus,\n// }\n// const text = Editor.string(editor, range)\n\n// /**\n// * See if the text matches our pattern\n// */\n// const match = text.match(regexp)\n// if (match == null) return true\n// if (match.length !== 4)\n// throw new Error(\n// `Expected the RegExp to have 3 grouped subexpressions but returned ${\n// match.length - 1\n// }`\n// )\n\n// /**\n// * Delete the closing markers\n// */\n// const closingMarkersRange = getRangeBackwards(\n// editor,\n// editor.selection.focus,\n// match[3].length\n// )\n// Transforms.delete(editor, { at: closingMarkersRange })\n\n// /**\n// * Delete the opening markers\n// */\n// const openingMarkersRange = getRangeBackwards(\n// editor,\n// editor.selection.focus,\n// match[2].length + match[3].length,\n// match[2].length\n// )\n// Transforms.delete(editor, { at: openingMarkersRange })\n\n// /**\n// * Create a range that represents the selected text\n// */\n// const matchRange = getRangeBackwards(\n// editor,\n// editor.selection.focus,\n// match[2].length\n// )\n\n// /**\n// * Feels like `withoutMerging` should work but if we undo twice after this,\n// * causes a crash.\n// *\n// * This looks like a good solution that isn't in main\n// * https://github.com/ianstormtaylor/slate/issues/3874\n// *\n// * NOTE:\n// *\n// * Manually calling `editor.onChange()` won't work\n// *\n// * An appropriate starting point for searching more in issues\n// * https://github.com/ianstormtaylor/slate/issues?q=is%3Aissue+withoutMerging+is%3Aclosed\n// */\n// editor.marksPlugin.toggleMark(mark, undefined, { at: matchRange })\n\n// return true\n// }\n// return false\n// }\n\n// function getRangeBackwards(\n// editor: Editor,\n// point: Point,\n// startDistance: number,\n// endDistance?: number\n// ) {\n// const startPoint = Editor.before(editor, point, {\n// unit: \"character\",\n// distance: startDistance,\n// })\n// const endPoint =\n// endDistance === undefined\n// ? point\n// : Editor.before(editor, point, {\n// unit: \"character\",\n// distance: endDistance,\n// })\n// if (!startPoint)\n// throw new Error(\n// `startPoint not found. The distance backward from the point may be invalid.`\n// )\n// if (!endPoint)\n// throw new Error(\n// `endPoint not found. The distance backward from the point may be invalid.`\n// )\n// return {\n// anchor: startPoint,\n// focus: endPoint,\n// }\n// }\n","import { Editor, Location, Text, Transforms } from \"slate\"\n\n/**\n * Toggles a mark.\n *\n * Certain marks may not be able to co-exist with another mark. For example,\n * superscript and subscript cannot be applied at the same time. In these\n * cases, you can provide a final argument of `unsetKey` that when the mark\n * is toggled on, the `unsetKey` mark is toggled off automatically. When the\n * mark is toggled off, it will ignore the `unsetKey`\n */\n\nexport function removeMarks(\n editor: Editor,\n { at = editor.selection }: { at?: Location | null } = {}\n) {\n if (at == null) return\n const nodeEntries = [\n ...Editor.nodes(editor, {\n match: (n) => Text.isText(n),\n at,\n }),\n ]\n const setter: Record<string, null> = {}\n for (const [node] of nodeEntries) {\n for (const key of Object.keys(node)) {\n if (key === \"text\") continue\n setter[key] = null\n }\n }\n Transforms.setNodes(editor, setter, {\n match: (n) => Text.isText(n),\n split: true,\n at,\n })\n}\n","import { Editor, Location, Point, Range, Text, Transforms } from \"slate\"\n\n/**\n * Toggles a mark.\n *\n * Certain marks may not be able to co-exist with another mark. For example,\n * superscript and subscript cannot be applied at the same time. In these\n * cases, you can provide a final argument of `unsetKey` that when the mark\n * is toggled on, the `unsetKey` mark is toggled off automatically. When the\n * mark is toggled off, it will ignore the `unsetKey`\n */\n\nexport function toggleMark(\n editor: Editor,\n markKey: keyof Text,\n unsetKey?: keyof Text,\n { at = editor.selection }: { at?: Location | null } = {}\n) {\n if (at == null) return\n\n // Check if selection is at end of line\n const point = Range.isRange(at as any) ? (at as Range).focus : at\n const isAtLineEnd = Point.isPoint(point) && (\n Editor.after(editor, point) === null || \n Editor.isEnd(editor, point, Editor.end(editor, []))\n )\n\n const validMarkKey = markKey as 'bold' | 'italic' | 'underline' | 'strike'\n const marks = Editor.marks(editor) || {}\n const isActive = marks[validMarkKey] === true\n\n // Store mark state for next insert if at line end\n if (isAtLineEnd) {\n if (!isActive) {\n // Turning mark on\n editor.activeMarks = {\n ...editor.activeMarks,\n [validMarkKey]: true\n }\n } else {\n // Turning mark off\n const { [validMarkKey]: _, ...remainingMarks } = editor.activeMarks || {}\n editor.activeMarks = remainingMarks\n }\n }\n\n // Toggle mark in current selection\n if (isActive) {\n Editor.removeMark(editor, validMarkKey)\n } else {\n Editor.addMark(editor, validMarkKey, true)\n }\n\n // Handle unset key if provided\n if (typeof unsetKey === \"string\") {\n Editor.removeMark(editor, unsetKey)\n }\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport { removeMarks } from \"./removeMarks\"\nimport { toggleMark } from \"./toggle-mark\"\n\nexport function createMarksMethods(editor: Editor) {\n return {\n removeMarks: curryOne(removeMarks, editor),\n toggleMark: curryOne(toggleMark, editor),\n toggleBold: () => toggleMark(editor, \"bold\"),\n toggleItalic: () => toggleMark(editor, \"italic\"),\n toggleUnderline: () => toggleMark(editor, \"underline\"),\n toggleStrike: () => toggleMark(editor, \"strike\"),\n toggleHighlight: () => toggleMark(editor, \"highlight\"),\n }\n}\n","import styled from \"@emotion/styled\"\n\nexport const $MarksSpan = styled(\"span\")`\n &.--bold {\n font-weight: bold;\n }\n &.--italic {\n font-style: italic;\n }\n &.--underline {\n text-decoration: underline;\n }\n &.--strike {\n text-decoration: line-through;\n }\n /**\n * Text decorations don't merge automatically so we make a special one\n * when there is both an underline and a strike through.\n */\n &.--underline.--strike {\n text-decoration: underline line-through;\n }\n &.--highlight {\n background-color: #ffeb3b;\n }\n`\n","import { Editor, Point } from \"slate\"\n\nimport { createPlugin, forceNormalizePath, TypedPlugin } from \"~/src/sink\"\n\nexport type NormalizeAfterDeleteEditor = {\n normalizeAfterDelete: true\n}\n\nexport type NormalizeAfterDeletePluginCustomTypes = {\n Name: \"normalize-after-delete\"\n Editor: NormalizeAfterDeleteEditor\n}\n\nfunction forceNormalizeNearestElement(editor: Editor) {\n if (!editor.selection) return\n const entry = Editor.parent(editor, editor.selection)\n forceNormalizePath(editor, entry[1])\n}\n\n/**\n * The purpose of this plugin is to have the Slate normalizer execute when an\n * Element is deleted. When text is deleted, the normalizer executes properly\n * but if an entire element is deleted, Slate behaves as if no normalization\n * is required.\n *\n * This fails us in a few normalization scenarios:\n *\n * - The normalizer needs to run when a sibling (previous or next) changes.\n * - The normalizer needs to run when a child is removed\n *\n * The plugin takes a few steps to make things more efficient. Namely, it only\n * executes a normalization if we are deleting backwards and we are at the\n * start of an element, or deleting forwards and we are at the end of an\n * Element. If neither of these are true, the delete will cause a normalzation\n * on its own because the text will have changed.\n */\nexport const NormalizeAfterDeletePlugin =\n createPlugin<NormalizeAfterDeletePluginCustomTypes>((editor) => {\n editor.normalizeAfterDelete = true\n return {\n name: \"normalize-after-delete\",\n editor: {\n deleteBackward() {\n if (!editor.selection) return false\n const entry = Editor.parent(editor, editor.selection)\n const isStart = Point.equals(\n Editor.start(editor, entry[1]),\n editor.selection.anchor\n )\n if (!isStart) return false\n return function () {\n forceNormalizeNearestElement(editor)\n }\n },\n deleteForward() {\n if (!editor.selection) return false\n const entry = Editor.parent(editor, editor.selection)\n const isEnd = Point.equals(\n Editor.end(editor, entry[1]),\n editor.selection.anchor\n )\n if (!isEnd) return false\n return function () {\n forceNormalizeNearestElement(editor)\n }\n },\n },\n editableProps: {},\n }\n }) as TypedPlugin<NormalizeAfterDeletePluginCustomTypes>\n","import { Element, NodeEntry } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n findElementUp,\n isEndOfElement,\n isStartOfElement,\n TypedPlugin,\n} from \"~/src/sink\"\n\nimport { deleteFragmentWithProtectedTypes } from \"./delete-fragment\"\nimport { createTableMethods } from \"./methods\"\nimport { normalizeTableIndexes } from \"./normalize/normalize-table\"\nimport { normalizeTableCell } from \"./normalize/normalize-table-cell\"\nimport { renderElement } from \"./render-element\"\nimport {\n TableCellElement,\n TableContentElement,\n TableElement,\n TableRowElement,\n} from \"./types\"\n\nexport * from \"./types\"\n\nexport type TableEditor = {\n supportsTable: true\n tablePlugin: ReturnType<typeof createTableMethods>\n}\n\nexport type TablePluginCustomTypes = {\n Name: \"table\"\n Editor: TableEditor\n Element:\n | TableElement\n | TableRowElement\n | TableCellElement\n | TableContentElement\n}\n\nexport const TablePlugin = createPlugin<TablePluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.supportsTable = true\n editor.tablePlugin = createTableMethods(editor)\n return createPolicy({\n name: \"table\",\n editor: {\n deleteBackward: () => {\n /**\n * If we're at start of a cell, disable delete backward because we\n * don't want the cell to be deleted.\n */\n return isStartOfElement(editor, \"table-cell\")\n },\n deleteForward: () => {\n /**\n * If we're at end of a cell, disable delete forward because we don't\n * want the cell to be deleted.\n */\n return isEndOfElement(editor, \"table-cell\")\n },\n deleteFragment: () =>\n deleteFragmentWithProtectedTypes(editor, [\"table-cell\"]),\n insertBreak: () => {\n /**\n * IF we're anywhere in a table cell, insert a soft break instead\n */\n const entry = findElementUp(editor, \"table-cell\")\n if (entry) {\n editor.insertText(\"\\n\")\n return true\n }\n return false\n },\n isMaster(element) {\n if (element.type === \"table\") return true\n },\n normalizeNode: (entry): boolean => {\n const [node] = entry\n if (!Element.isElement(node)) return false\n switch (node.type) {\n case \"table\":\n return normalizeTableIndexes(\n editor,\n entry as NodeEntry<TableElement>\n )\n case \"table-cell\": {\n return normalizeTableCell(\n editor,\n entry as NodeEntry<TableCellElement>\n )\n }\n }\n return false\n },\n },\n editableProps: {\n renderElement,\n onKeyDown: createHotkeyHandler({\n /**\n * navigation\n */\n tab: editor.tablePlugin.tabForward,\n \"shift+tab\": editor.tablePlugin.tabBackward,\n \"shift+enter\": editor.tablePlugin.shiftEnterForward,\n down: editor.tablePlugin.down,\n up: editor.tablePlugin.up,\n /**\n * selection\n */\n \"mod+a\": editor.tablePlugin.selectCell,\n /**\n * insert\n */\n \"super+t\": () => editor.tablePlugin.insertTable(3, 2),\n \"mod+shift+enter\": () => editor.tablePlugin.insertRow({ offset: 0 }),\n \"mod+enter\": () => editor.tablePlugin.insertRow({ offset: 1 }),\n \"super+[\": () => editor.tablePlugin.insertColumn({ offset: 0 }),\n \"super+]\": () => editor.tablePlugin.insertColumn({ offset: 1 }),\n /**\n * remove\n */\n \"super+backspace\": editor.tablePlugin.removeTable,\n \"mod+backspace\": editor.tablePlugin.removeRow,\n \"mod+shift+backspace\": editor.tablePlugin.removeColumn,\n }),\n },\n })\n }\n) as TypedPlugin<TablePluginCustomTypes>\n","import { Editor, Path, Transforms } from \"slate\"\n\nimport { findElementUpPath } from \"~/src/sink\"\n\nimport { getReversedDeleteSafeRanges } from \"./get-reversed-delete-safe-ranges\"\n\n/**\n * This is a special version of deleteFragment that respects elements of the\n * given `protectedTypes` so that they aren't deleted whole and only their\n * children are deleted.\n *\n * This is used in cases like a `table-cell` where we want to protect the\n * shape of the `table`.\n *\n * If the start or end of the deletion range isn't in a protectedType, we don't\n * need to anything special so we let the default delete handle it.\n *\n * If the start or end of the deletion range is in a protectedType but it is\n * the same Element, then the default handler works fine too.\n *\n * In other cases, we break down the full deletion range into multiple ranges.\n * Each range won't go across a protectedType. In effect, this means that we\n * only delete the content of protectedTypes and we do the regular deletes\n * across everything else.\n */\nexport function deleteFragmentWithProtectedTypes(\n editor: Editor,\n protectedTypes: string[]\n) {\n if (editor.selection == null) return false\n const [start, end] = Editor.edges(editor, editor.selection)\n const startProtectedPath = findElementUpPath(editor, protectedTypes, {\n at: start,\n })\n const endProtectedPath = findElementUpPath(editor, protectedTypes, {\n at: end,\n })\n /**\n * If the start or the end of the selection isn't in a protectedType element\n * then just do a normal delete so we return `false`.\n */\n if (!startProtectedPath && !endProtectedPath) {\n return false\n }\n\n /**\n * If the start and end are in the same protectedType element, then the\n * default handler works fine so return `false`\n */\n if (\n startProtectedPath &&\n endProtectedPath &&\n Path.equals(startProtectedPath, endProtectedPath)\n ) {\n return false\n }\n\n /**\n * Breaks the range to delete into chunks of ranges that are safe to delete.\n * We do this by not allowing a deletion across one of the `protectedTypes`\n */\n const reversedRanges = getReversedDeleteSafeRanges(\n editor,\n editor.selection,\n protectedTypes\n )\n\n /**\n * We iterate through the ranges backwards deleting each delete safe range.\n * At the end, we collapse the originally selected deletion range to the\n * front.\n *\n * NOTE:\n *\n * Ideally, we'd actually collapse this to the start or end depending on the\n * direction of the delete; however, that information is not presently\n * provided to us. Might be a small improvement in the future that requires\n * us to update Slate.\n */\n Editor.withoutNormalizing(editor, () => {\n for (const range of reversedRanges) {\n Transforms.delete(editor, { at: range })\n }\n Transforms.collapse(editor, { edge: \"start\" })\n })\n\n return true\n}\n","import { BasePoint, Editor, Path, Range } from \"slate\"\n\nimport { findElementUpPath } from \"~/src/sink\"\n\nexport function getReversedDeleteSafeRanges(\n editor: Editor,\n deleteRange: Range,\n protectedTypes: string[]\n): Range[] {\n /**\n * Editor.positions returns a bunch of positions which essentially represent\n * the start and end of Nodes with the exception of the start of the passed\n * in Range and the end of the passed in Range.\n */\n const positions = [...Editor.positions(editor, { at: deleteRange })]\n\n /**\n * We create our own set of deleteSafeRanges here\n */\n const deleteSafeRanges: Range[] = []\n\n let startPos: BasePoint, prevPos: BasePoint, startTdPath: Path | undefined\n startPos = prevPos = positions[0]\n startTdPath = findElementUpPath(editor, protectedTypes, {\n at: startPos,\n })\n\n for (const pos of positions) {\n const tdPath = findElementUpPath(editor, protectedTypes, {\n at: pos,\n })\n /**\n * What we're looking for is that if we search for a protectedType from\n * this point, and the protectedType is the same as the prvious point we\n * looked at, then keep going.\n *\n * We keep track of the `prevPos` though because when we are in a different\n * protectedType (or switch to not being in one) then we need the `prevPos`\n */\n if (\n (startTdPath && tdPath && Path.equals(startTdPath, tdPath)) ||\n (startTdPath == undefined && tdPath == undefined)\n ) {\n prevPos = pos\n } else {\n /**\n * Once we see a difference (i.e. a new protectedType or we switch to\n * being or not being in a protectedType) then we create a Range and\n * add it to `deleteSafeRanges`.\n *\n * We also reset some of our variables that we are tracking.\n */\n const range = { anchor: startPos, focus: prevPos }\n deleteSafeRanges.push(range)\n startPos = prevPos = pos\n startTdPath = tdPath\n }\n }\n const range = { anchor: startPos, focus: prevPos }\n deleteSafeRanges.push(range)\n deleteSafeRanges.reverse()\n return deleteSafeRanges\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt, curryOne } from \"~/src/sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { insertColumn } from \"./insert-column\"\nimport { insertRow } from \"./insert-row\"\nimport { insertTable } from \"./insert-table\"\nimport { down, up } from \"./navigation\"\nimport { removeColumn } from \"./remove-column\"\nimport { removeRow } from \"./remove-row\"\nimport { removeTable } from \"./remove-table\"\nimport { setTableColumnAlign } from \"./setTableColumnAlign\"\nimport { shiftEnterForward, tabBackward, tabForward } from \"./tab\"\n\nexport function createTableMethods(editor: Editor) {\n return {\n getTableInfo: curryOne(getTableInfo, editor),\n insertTable: curryOne(insertTable, editor),\n insertColumn: curryOne(insertColumn, editor),\n insertRow: curryOne(insertRow, editor),\n removeTable: curryOne(removeTable, editor),\n removeColumn: curryOne(removeColumn, editor),\n removeRow: curryOne(removeRow, editor),\n tabForward: curryOne(tabForward, editor),\n tabBackward: curryOne(tabBackward, editor),\n shiftEnterForward: curryOne(shiftEnterForward, editor),\n selectCell: curryOne(selectCell, editor),\n down: curryOne(down, editor),\n up: curryOne(up, editor),\n setTableColumnAlign: curryOne(setTableColumnAlign, editor),\n }\n}\n\nfunction selectCell(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const t = getTableInfo(editor, { at })\n if (t === undefined) return false\n const { cellPath } = t\n Transforms.select(editor, cellPath)\n return true\n}\n","import { Editor, Element, Location, Path } from \"slate\"\n\nimport { findElementUp } from \"~/src/sink\"\n\nimport {\n TableCellElement,\n TableColumn,\n TableElement,\n TableRowElement,\n} from \"../types\"\n\n/**\n * The TableInfo object that includes quick access information starting from a\n * cell in a table including information about the row and the table.\n *\n * NOTE:\n *\n * This is flat and not nested because it makes destructuring easier, for\n * example, in the table methods.\n */\nexport type TableInfo = {\n tableElement: TableElement\n tablePath: Path\n tableColumns: TableColumn[]\n rowElement: TableRowElement\n rowPath: Path\n rowIndex: number\n rowCount: number\n cellElement: TableCellElement\n cellPath: Path\n cellIndex: number\n cellCount: number\n}\n\n/**\n * get table info\n */\n\nexport function getTableInfo(\n editor: Editor,\n { at = editor.selection }: { at?: Location | Element | null } = {}\n): TableInfo | undefined {\n if (at == null) return undefined\n const cellMatch = findElementUp<TableCellElement>(editor, \"table-cell\", {\n at,\n })\n if (!cellMatch) return undefined\n const rowMatch = findElementUp<TableRowElement>(editor, \"table-row\", {\n at,\n })\n if (!rowMatch) return undefined\n const tableMatch = findElementUp<TableElement>(editor, \"table\", { at })\n if (!tableMatch) return undefined\n const [tableElement, tablePath] = tableMatch\n const [rowElement, rowPath] = rowMatch\n const [cellElement, cellPath] = cellMatch\n return {\n tableElement,\n tablePath,\n tableColumns: tableElement.columns,\n rowElement,\n rowPath,\n rowIndex: rowPath.slice(-1)[0],\n rowCount: tableElement.children.length,\n cellElement,\n cellPath,\n cellIndex: cellPath.slice(-1)[0],\n cellCount: rowElement.children.length,\n }\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"~/src/sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { createCell } from \"./utils\"\n\nexport function insertColumn(\n editor: Editor,\n { offset = 0, at = editor.selection }: { offset?: 0 | 1; at?: BetterAt } = {}\n): boolean {\n const t = getTableInfo(editor, { at })\n if (t === undefined) return false\n const { tableElement, tablePath, cellIndex } = t\n const nextCellIndex = cellIndex + offset\n Editor.withoutNormalizing(editor, () => {\n const { columns } = tableElement\n const nextColumns = [...columns]\n /**\n * Insert a Column into `TableElement.columns` which is the same as the\n * value of the current column. This is the `alignment` of the column.\n */\n nextColumns.splice(nextCellIndex, 0, columns[nextCellIndex])\n Transforms.setNodes(editor, { columns: nextColumns }, { at: tablePath })\n\n /**\n * Insert a `TableCell` at the correct spot.\n */\n tableElement.children.forEach((rowElement, i) => {\n Transforms.insertNodes(editor, createCell(nextCellIndex), {\n at: [...tablePath, i, nextCellIndex],\n })\n })\n })\n return true\n}\n\n// export function insertColumnLeft(\n// editor: Editor,\n// { at }: { at?: MatchAt } = {}\n// ) {\n// return insertColumn(editor, { at })\n// }\n\n// export function insertColumnRight(\n// editor: Editor,\n// { at }: { at?: MatchAt } = {}\n// ) {\n// return insertColumn(editor, { at, offset: 1 })\n// }\n","import { TableCellElement, TableContentElement } from \"../types\"\n\nexport function createCell(\n index: number,\n children: TableContentElement[] = [\n {\n type: \"table-content\",\n children: [{ text: \"\" }],\n },\n ]\n): TableCellElement {\n return {\n type: \"table-cell\",\n children,\n }\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"~/src/sink\"\n\nimport { TableRowElement } from \"../types\"\nimport { getTableInfo } from \"./get-table-info\"\nimport { createCell } from \"./utils\"\n\nfunction createRow(columnCount: number): TableRowElement {\n return {\n type: \"table-row\",\n children: [...Array(columnCount).keys()].map((index) => createCell(index)),\n }\n}\n\n/**\n * Used internally for `insertRowAbove` and `insertRowBelow` to do an insert\n * with an offset to improve code reused.\n */\nexport function insertRow(\n editor: Editor,\n { at = editor.selection, offset = 0 }: { at?: BetterAt; offset?: 0 | 1 } = {}\n): boolean {\n const t = getTableInfo(editor, { at })\n if (!t) return false\n const nextRowElement = createRow(t.tableElement.columns.length)\n Transforms.insertNodes(editor, nextRowElement, {\n at: [...t.tablePath, t.rowIndex + offset],\n })\n return true\n}\n\n/**\n * Insert row above current selection\n */\nexport function insertRowAbove(\n editor: Editor,\n { at }: { at?: BetterAt } = {}\n): boolean {\n return insertRow(editor, { at })\n}\n\n/**\n * Insert row below current selection\n */\nexport function insertRowBelow(\n editor: Editor,\n { at }: { at?: BetterAt } = {}\n): boolean {\n return insertRow(editor, { at, offset: 1 })\n}\n","import { Editor, Element, Location, Path, Transforms } from \"slate\"\n\nimport { findElementUp } from \"~/src/sink\"\n\nimport { TableColumn, TableElement, TableRowElement } from \"../types\"\nimport { createCell } from \"./utils\"\n\nfunction createRange(size: number): number[] {\n return [...Array(size).keys()]\n}\n\nfunction createColumns(columnCount: number): TableColumn[] {\n return createRange(columnCount).map(() => ({ align: \"left\" }))\n}\n\nfunction createTable(columnCount: number, rowCount: number): TableElement {\n return {\n type: \"table\",\n columns: createColumns(columnCount),\n children: createRange(rowCount).map(() => createRow(columnCount)),\n }\n}\n\nfunction createRow(columnCount: number): TableRowElement {\n return {\n type: \"table-row\",\n children: [...Array(columnCount).keys()].map((index) => createCell(index)),\n }\n}\n\n/**\n * Used internally for `insertRowAbove` and `insertRowBelow` to do an insert\n * with an offset to improve code reused.\n */\nexport function insertTable(\n editor: Editor,\n columnCount: number,\n rowCount: number,\n { at = editor.selection }: { at?: Location | null } = {}\n): boolean {\n const table = createTable(columnCount, rowCount)\n return insertRootElement(editor, table, { at })\n}\n\nexport function insertRootElement(\n editor: Editor,\n element: Element,\n { at = editor.selection }: { at?: Location | null } = {}\n) {\n if (at == null) return false\n const entry = findElementUp(\n editor,\n (node) => Element.isElement(node) && editor.isMaster(node)\n )\n if (entry == null) {\n const selection = editor.selection\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at })\n if (selection) {\n Transforms.select(editor, selection)\n Transforms.move(editor)\n }\n })\n } else {\n const nextPath = Path.next(entry[1])\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at: nextPath })\n Transforms.select(editor, Editor.start(editor, nextPath))\n })\n }\n return true\n}\n","import { Editor, Path } from \"slate\"\n\nimport { selectEndOfElement, selectStartOfElement } from \"~/src/sink\"\n\nimport { TableInfo } from \"../get-table-info\"\n\nexport function selectElementBelow(editor: Editor, t: TableInfo) {\n const { cellIndex, rowIndex, rowCount, tablePath } = t\n /**\n * if we aren't in the last row of a table, move down a row\n */\n if (rowIndex < rowCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, cellIndex])\n return true\n }\n /**\n * If we are in the last row of a table, move to the start of the Element\n * after the table\n */\n try {\n selectStartOfElement(editor, Path.next(tablePath))\n return true\n } catch (e) {\n return false\n }\n}\n\nexport function selectElementAbove(editor: Editor, t: TableInfo) {\n const { cellIndex, rowIndex, tablePath } = t\n /**\n * if we aren't in the first row of a table, move up a row\n */\n if (rowIndex > 0) {\n selectStartOfElement(editor, [...tablePath, rowIndex - 1, cellIndex])\n return true\n }\n /**\n * If we are in the first row of a table, move to the end of the Element\n * before the table\n */\n try {\n selectEndOfElement(editor, Path.previous(tablePath))\n return true\n } catch (e) {\n return false\n }\n}\n","import { Descendant, Editor, Element } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\n/**\n * This is named with `...Unreliable...` because at the beginning of a line\n * (e.g. the second line of a paragraph) the DOMRect returned will be for a\n * position at the end of the previous line.\n *\n * So why have an unreliable version? Because, there actually is no reliable\n * version and the unreliable one works in most cases. It's better than not\n * having an unreliable selection rect.\n *\n * So it's useful, but we need to handle the case where it's on the end of the\n * previous line instead of the beginning of the line.\n *\n * NOTE:\n *\n * Inserting a `span` and removing it does not work. We can kind of getting it\n * to work by inserting a span with some with (like has the letter \"A\") inside.\n * It will then sometimes switch the problem so that the DOMRect return is on\n * the next line instead of the previous; however, makes the cursor move into\n * the wrong position when cursoring down the right side and this is worse than\n * the problem is solves.\n */\nexport function getUnreliableSelectionRect(): DOMRect | null {\n const s = window.getSelection()\n if (!s) return null\n const range = s.getRangeAt(0)\n return range.getBoundingClientRect()\n}\n\n/**\n * Takes a Slate Element and returns a DOMRect representing the Element as\n * it is in the DOM.\n */\nfunction getElementRect(editor: Editor, element: Descendant) {\n return ReactEditor.toDOMNode(editor, element).getBoundingClientRect()\n}\n\nexport function checkIsInElement(editor: Editor, element: Element): boolean {\n /**\n * Get the unreliable selection rect. If there is no selection, we consider\n * that the selection is not in the last line which will usually indicates\n * default behavior.\n */\n const selectionRect = getUnreliableSelectionRect()\n if (!selectionRect) return false\n const elementRect = getElementRect(editor, element)\n return (\n selectionRect.right < elementRect.right &&\n selectionRect.left > elementRect.left &&\n selectionRect.bottom < elementRect.bottom &&\n selectionRect.top > elementRect.top\n )\n}\n","import { Editor } from \"slate\"\n\nimport { getTableInfo } from \"../get-table-info\"\nimport { selectElementAbove, selectElementBelow } from \"./select-element\"\nimport { checkIsInElement } from \"./utils\"\n\n/**\n * arrow down\n */\nexport function down(editor: Editor): boolean {\n const t = getTableInfo(editor)\n /**\n * don't handle if we're not in a table\n */\n if (!t) return false\n setTimeout(() => {\n if (!checkIsInElement(editor, t.cellElement)) {\n selectElementBelow(editor, t)\n }\n })\n return false\n}\n\n/**\n * arrow up\n */\nexport function up(editor: Editor): boolean {\n const t = getTableInfo(editor)\n /**\n * don't handle if we're not in a table\n */\n if (!t) return false\n setTimeout(() => {\n if (!checkIsInElement(editor, t.cellElement)) {\n selectElementAbove(editor, t)\n }\n })\n return false\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"~/src/sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { removeTable } from \"./remove-table\"\n\nexport function removeColumn(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const t = getTableInfo(editor, { at })\n if (!t) return false\n\n const { tableElement, tablePath, rowIndex, cellIndex, cellCount } = t\n if (cellCount === 1) {\n return removeTable(editor)\n }\n Editor.withoutNormalizing(editor, () => {\n // Set the new `align` value based on the current `td` column (not the position\n // to insert at)\n const columns = [...tableElement.columns]\n columns.splice(cellIndex, 1)\n Transforms.setNodes(editor, { columns }, { at: tablePath })\n tableElement.children.forEach((rowElement, rowIndex) => {\n Transforms.removeNodes(editor, {\n at: [...tablePath, rowIndex, cellIndex],\n })\n })\n const selection = Editor.start(editor, [\n ...tablePath,\n rowIndex,\n Math.min(cellIndex, cellCount - 2),\n ])\n Transforms.select(editor, selection)\n })\n}\n","import { Editor, Transforms } from \"slate\"\n\nexport function removeTable(editor: Editor): boolean {\n const t = editor.tablePlugin.getTableInfo()\n if (t === undefined) return false\n Transforms.removeNodes(editor, { at: t.tablePath })\n return true\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"~/src/sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { removeTable } from \"./remove-table\"\n\nexport function removeRow(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const t = getTableInfo(editor, { at })\n if (t === undefined) return false\n if (t.rowCount === 1) {\n removeTable(editor)\n return true\n }\n Editor.withoutNormalizing(editor, () => {\n Transforms.removeNodes(editor, { at: t.rowPath })\n Transforms.select(\n editor,\n Editor.start(editor, [\n ...t.tablePath,\n Math.min(t.rowIndex, t.rowCount - 2),\n t.cellIndex,\n ])\n )\n })\n return true\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { getTableInfo } from \"./get-table-info\"\n\nexport function setTableColumnAlign(\n editor: Editor,\n options: { align: \"left\" | \"center\" | \"right\" }\n) {\n const t = getTableInfo(editor)\n if (t === undefined) return false\n const { tableElement, tablePath, cellIndex } = t\n const nextColumns = tableElement.columns.slice()\n nextColumns.splice(cellIndex, 1, { align: options.align })\n Transforms.setNodes(editor, { columns: nextColumns }, { at: tablePath })\n return true\n}\n","import { Editor, Path, Transforms } from \"slate\"\n\nimport { selectStartOfElement } from \"~/src/sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { insertRowBelow } from \"./insert-row\"\n\nexport function tabForward(editor: Editor) {\n const t = getTableInfo(editor)\n if (!t) return false\n\n const { cellIndex, cellCount, rowIndex, rowCount, tablePath } = t\n\n /**\n * If we aren't in the last cell of the row, then select the next cell\n */\n if (cellIndex < cellCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex, cellIndex + 1])\n return true\n }\n\n /**\n * If we are in the last cell of the row but we aren't in the last row of\n * the table, then select the first cell in the next row.\n */\n if (rowIndex < rowCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, 0])\n return true\n }\n\n /**\n * If we are in the last cell of the table, exit the table\n * by inserting a new paragraph after the table and selecting it.\n */\n const nextPath = Path.next(tablePath)\n Transforms.insertNodes(\n editor,\n { type: \"paragraph\", children: [{ text: \"\" }] },\n { at: nextPath }\n )\n selectStartOfElement(editor, nextPath)\n\n return true\n}\n\nexport function tabBackward(editor: Editor) {\n const t = getTableInfo(editor)\n if (!t) return false\n\n const { cellIndex, cellCount, rowIndex, tablePath } = t\n\n if (cellIndex > 0) {\n selectStartOfElement(editor, [...tablePath, rowIndex, cellIndex - 1])\n return true\n }\n\n if (rowIndex > 0) {\n selectStartOfElement(editor, [...tablePath, rowIndex - 1, cellCount - 1])\n return true\n }\n}\n\n/**\n * Shift+Enter: Move to next cell, or add new row at end of table\n */\nexport function shiftEnterForward(editor: Editor) {\n const t = getTableInfo(editor)\n if (!t) return false\n\n const { cellIndex, cellCount, rowIndex, rowCount, tablePath } = t\n\n /**\n * If we aren't in the last cell of the row, then select the next cell\n */\n if (cellIndex < cellCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex, cellIndex + 1])\n return true\n }\n\n /**\n * If we are in the last cell of the row but we aren't in the last row of\n * the table, then select the first cell in the next row.\n */\n if (rowIndex < rowCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, 0])\n return true\n }\n\n /**\n * If we are in the last cell of the table, insert a new row and then\n * select the first cell in the new row.\n */\n insertRowBelow(editor)\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, 0])\n\n return true\n}\n","import { Editor, NodeEntry, Transforms } from \"slate\"\n\nimport { TableElement } from \"../types\"\n\nexport function normalizeTableIndexes(\n editor: Editor,\n entry: NodeEntry<TableElement>\n): boolean {\n let isTransformed = false\n const rowElements = entry[0].children\n rowElements.forEach((rowElement, y) => {\n const cellElements = rowElement.children\n cellElements.forEach((cellElement, x) => {\n if (cellElement.x !== x || cellElement.y !== y) {\n Transforms.setNodes(editor, { x, y }, { at: [...entry[1], y, x] })\n isTransformed = true\n }\n })\n })\n return isTransformed\n}\n","import { Editor, NodeEntry, Transforms } from \"slate\"\n\nimport { TableCellElement } from \"../types\"\n\nexport function normalizeTableCell(\n editor: Editor,\n entry: NodeEntry<TableCellElement>\n): boolean {\n const [node, path] = entry\n if (node.children.length === 1 && node.children[0].type === \"table-content\") {\n return false\n }\n Editor.withoutNormalizing(editor, () => {\n /**\n * This ensures that the first child node of a `table-cell`\n * is a `table-content` node. It won't be if a user pastes\n * in the start of a `table-cell`.\n *\n * We want this because our algorithm will merge all following\n * nodes into this node. If we don't do this, we are merging\n * into a potentially non `table-content` cell and might end up\n * with some other `Element` like a `code-block`.\n *\n * NOTE:\n *\n * In order to make sure this doesn't turn into a noop, we add\n * some text here. It is arbitrarily an `X`.\n */\n Transforms.insertNodes(\n editor,\n {\n type: \"table-content\",\n children: [{ text: \"X\" }],\n },\n { at: [...entry[1], 0] }\n )\n /**\n * We then iterate from the back of the children to the front\n * and merging left. Because we inserted an extra node, the\n * for loop looks a little unusual in that `i` starts at\n * `node.children.length` instead of `node.children.length - 1`.\n */\n for (let i = node.children.length; i >= 0; i--) {\n Transforms.mergeNodes(editor, { at: [...path, i] })\n }\n /**\n * When we're done, we remove the `X`.\n *\n * There might be a cleaner way to do this whout adding and\n * removing the `X` and when we find it, we can improve this\n * code.\n *\n * IMPORTANT:\n *\n * Whatever a replacement is, remember that we need to execute\n * the commands such that it preserves the cursor position.\n */\n Transforms.delete(editor, {\n at: { path: [...path, 0, 0], offset: 0 },\n unit: \"character\",\n })\n })\n return true\n}\n","import { useEffect } from \"react\"\nimport { ReactEditor, useSelected, useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { normalizeTableIndexes } from \"../normalize/normalize-table\"\nimport { TableElement } from \"../types\"\nimport { $Table } from \"./styles\"\nimport { TableContext } from \"./table-context\"\n\nexport function Table({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableElement>) {\n const editor = useSlateStatic()\n const isSelected = useSelected()\n /**\n * The first time we render a table, we make sure it is normalized.\n * When it comes out of an `initialValue` it's not guaranteed to include\n * `x` and `y` properties as they are optional.\n *\n * This mainly helps us not have to manually add these values when the\n * `x` and `y` are purely an internal requirement for rendering.\n */\n useEffect(() => {\n const path = ReactEditor.findPath(editor, element)\n normalizeTableIndexes(editor, [element, path])\n }, [])\n return (\n <TableContext.Provider value={{ isSelected }}>\n <$Table {...attributes} columns={element.columns}>\n <tbody>{children}</tbody>\n </$Table>\n </TableContext.Provider>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { TableColumn } from \"../../types\"\nexport * from \"./table-menu-styles\"\n\n/**\n * Table\n */\nexport const $Table = styled(\"table\")<{ columns: TableColumn[] }>`\n border-collapse: collapse;\n margin: 1em 0;\n ${({ columns }) =>\n columns\n .map(\n (column, index) =>\n `td:nth-of-type(${index + 1}) { text-align: ${column.align}; }`\n )\n .join(\"\\n\")}\n`\n\n/**\n * Table Row\n */\nexport const $TableRow = styled(\"tr\")`\n position: relative;\n &:first-of-type {\n background: var(--table-head-bgcolor);\n }\n`\n\n/**\n * Table Cell\n *\n * - `--selected` indicates selected cell\n */\nexport const $TableCell = styled(\"td\")`\n position: relative;\n border-width: 1px;\n border-style: solid;\n border-color: rgba(0, 0, 0, 0.2) rgba(0, 0, 0, 0.05);\n border-color: var(--table-row-border-color) var(--table-column-border-color);\n padding: 0.75em 1em;\n min-width: 2em;\n &.--selected {\n outline: 2px solid var(--select-color, blue);\n }\n /**\n * Stronger borders on the left and right edge\n */\n &:first-of-type {\n border-left-color: var(--table-border-color);\n }\n &:last-of-type {\n border-right-color: var(--table-border-color);\n }\n`\n\n/**\n * Table Content (inside Table Cell)\n */\nexport const $TableContent = styled(\"div\")`\n /**\n * Smaller font inside a table than outside of it\n */\n font-size: 0.9375em; /* 15px */\n /**\n * Even smaller font and dimmer for the heading row\n */\n tr:first-of-type & {\n color: rgba(0, 0, 0, 0.6);\n font-size: 0.875em; /* 14px */\n }\n`\n","import styled from \"@emotion/styled\"\n\n/**\n * Table Menu\n */\n\nconst $BaseMenu = styled(\"div\")`\n position: absolute;\n /**\n * very slightly shaded\n */\n background: rgba(0, 0, 0, 0.001);\n\n /**\n * hover \n */\n &:hover {\n /**\n * needs to pop up so that it doesn't jump back and forth with neighbor\n * below\n */\n z-index: 1000;\n /**\n * Makes the visible tile get darker on hover over any part of the\n * menu including the invisible part\n */\n .--tile {\n background: rgba(0, 0, 0, 0.15);\n }\n }\n`\n\nexport const $ColumnMenu = styled($BaseMenu)`\n cursor: pointer;\n /**\n * hangs out on top\n */\n left: -1px;\n right: -1px;\n right: 0;\n height: 3em;\n top: -3em;\n`\n\nexport const $RowMenu = styled($BaseMenu)`\n /**\n * hangs out on left\n */\n top: -1px;\n bottom: -1px;\n width: 3em;\n left: -3em;\n`\n\n/**\n * Menu Tile\n */\n\nconst $MenuTile = styled(\"div\")`\n position: absolute;\n background: rgba(0, 0, 0, 0.05);\n border: 1px solid rgba(0, 0, 0, 0.05);\n transition: all 200ms;\n /**\n * NOTE: One of these should be overridden\n */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n`\n\n/**\n * The `$RowMenuTile` is the visible part of the `$RowMenu` and is the right\n * half of the `$RowMenu`.\n */\nexport const $ColumnMenuTile = styled($MenuTile)`\n top: 50%;\n border-bottom: none;\n border-right: none;\n bottom: 1px;\n td:first-of-type & {\n border-top-left-radius: 0.5em;\n }\n td:last-of-type & {\n border-top-right-radius: 0.5em;\n border-right: 1px solid rgba(0, 0, 0, 0.05);\n right: -1px;\n }\n svg {\n position: absolute;\n top: 0.1875em;\n left: 50%;\n margin-left: -0.5em;\n color: rgba(0, 0, 0, 0.2);\n }\n &:hover svg {\n color: rgba(0, 0, 0, 0.5);\n }\n\n /* border-top-left-radius: 0.5em;\n border-top-right-radius: 0.5em; */\n`\n\n/**\n * The `$RowMenuTile` is the visible part of the `$RowMenu` and is the right\n * half of the `$RowMenu`.\n */\nexport const $RowMenuTile = styled($MenuTile)`\n left: 50%;\n border-right: none;\n border-bottom: none;\n right: 1px;\n tr:first-of-type & {\n border-top-left-radius: 0.5em;\n }\n tr:last-of-type & {\n border-bottom-left-radius: 0.5em;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n bottom: 0;\n }\n svg {\n position: absolute;\n left: 0.25em;\n top: 50%;\n margin-top: -0.5em;\n color: rgba(0, 0, 0, 0.2);\n }\n &:hover svg {\n color: rgba(0, 0, 0, 0.5);\n }\n\n /* border-top-left-radius: 0.5em;\n border-bottom-left-radius: 0.5em; */\n`\n\n/**\n * Menu Button\n */\n\nconst $MenuButton = styled(\"div\")`\n position: absolute;\n font-size: 1.5em;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n svg {\n display: block;\n }\n`\n\nexport const $AddMenuButton = styled($MenuButton)`\n color: #c0c0c0;\n &:hover {\n color: royalblue;\n }\n`\n\nexport const $RemoveMenuButton = styled($MenuButton)`\n color: #c0c0c0;\n &:hover {\n color: firebrick;\n }\n`\n","import { createContext } from \"react\"\n\nexport const TableContext = createContext<{ isSelected: boolean }>({\n isSelected: false,\n})\n","import { useContext } from \"react\"\nimport { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { TableCellElement } from \"../../types\"\nimport { $TableCell } from \"../styles\"\nimport { TableContext } from \"../table-context\"\nimport { ColumnMenu } from \"./column-menu\"\nimport { RowMenu } from \"./row-menu\"\nimport { TableMenu } from \"./table-menu\"\n\nexport function TableCell({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableCellElement>) {\n const tableContext = useContext(TableContext)\n const selected = useSelected()\n /**\n * table has slection and we are in the top left cell\n */\n const showTableMenu =\n tableContext.isSelected && element.x === 0 && element.y === 0\n /**\n * table has selection and we are in the left columns\n */\n const showRowMenu = tableContext.isSelected && element.x === 0\n /**\n * table has selection and we are in the top row\n */\n const showColumnMenu = tableContext.isSelected && element.y === 0\n return (\n <$TableCell\n className={selected ? \"--selected\" : \"\"}\n {...attributes}\n data-x={element.x}\n data-y={element.y}\n >\n {children}\n {showTableMenu ? <TableMenu /> : null}\n {showRowMenu ? <RowMenu cellElement={element} /> : null}\n {showColumnMenu ? <ColumnMenu cellElement={element} /> : null}\n </$TableCell>\n )\n}\n","import React, { useCallback, useRef, useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { Menu, MenuItemData } from \"~/src/shared-overlays\"\nimport { useLayer } from \"~/src/use-layer\"\n\nimport {\n AlignCenter,\n AlignLeft,\n AlignRight,\n BarsIcon,\n MinusIcon,\n PlusIcon,\n} from \"../../../icons\"\nimport { TableCellElement } from \"../../../types\"\nimport {\n $AddMenuButton,\n $ColumnMenu,\n $ColumnMenuTile,\n $RemoveMenuButton,\n} from \"../../styles\"\n\nexport function ColumnMenu({ cellElement }: { cellElement: TableCellElement }) {\n const editor = useSlateStatic()\n const menu = useLayer(\"column-menu\")\n const buttonRef = useRef<HTMLDivElement>(null)\n const [hover, setHover] = useState(false)\n\n const onMouseEnter = useCallback(() => {\n setHover(true)\n }, [])\n\n const onMouseLeave = useCallback(() => {\n setHover(false)\n }, [])\n\n const onClick = useCallback(() => {\n if (menu.layer) menu.close()\n const dest = buttonRef.current\n if (dest === null) return\n const items: MenuItemData[] = [\n {\n icon: AlignLeft,\n title: \"左揃え\",\n action: () => {\n editor.tablePlugin.setTableColumnAlign({ align: \"left\" })\n },\n },\n {\n icon: AlignCenter,\n title: \"中央揃え\",\n action: () => {\n editor.tablePlugin.setTableColumnAlign({ align: \"center\" })\n },\n },\n {\n icon: AlignRight,\n title: \"右揃え\",\n action: () => {\n editor.tablePlugin.setTableColumnAlign({ align: \"right\" })\n },\n },\n ]\n // Menu\n menu.open(() => <Menu dest={dest} items={items} close={menu.close} />)\n }, [])\n\n return (\n <$ColumnMenu\n ref={buttonRef}\n contentEditable={false}\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <$ColumnMenuTile className=\"--tile\">\n <BarsIcon />\n </$ColumnMenuTile>\n {hover ? (\n <>\n <$RemoveMenuButton\n style={{\n top: 0,\n left: \"50%\",\n marginLeft: \"-0.5em\",\n }}\n onMouseDown={() =>\n editor.tablePlugin.removeColumn({ at: cellElement })\n }\n >\n <MinusIcon />\n </$RemoveMenuButton>\n\n <$AddMenuButton\n style={{ left: \"-0.5em\", top: 0 }}\n onMouseDown={() =>\n editor.tablePlugin.insertColumn({ at: cellElement })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n <$AddMenuButton\n style={{ right: \"-0.5em\", top: 0 }}\n onMouseDown={() =>\n editor.tablePlugin.insertColumn({ at: cellElement, offset: 1 })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n </>\n ) : null}\n </$ColumnMenu>\n )\n}\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"../sink\"\n\nexport const PlusIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm.75-11.25a.75.75 0 0 0-1.5 0v2.5h-2.5a.75.75 0 0 0 0 1.5h2.5v2.5a.75.75 0 0 0 1.5 0v-2.5h2.5a.75.75 0 0 0 0-1.5h-2.5v-2.5z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\n\nexport const MinusIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM6.75 9.25a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-6.5z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\n\nexport const BarsIcon = () => (\n <TablerIcon>\n <path d=\"M4 6h16M4 12h16M4 18h16\" />\n </TablerIcon>\n)\n\nexport const AlignLeft = () => (\n <TablerIcon>\n <path d=\"M4 6h16M4 12h10M4 18h14\" />\n </TablerIcon>\n)\n\nexport const AlignCenter = () => (\n <TablerIcon>\n <path d=\"M4 6h16M8 12h8M6 18h12\" />\n </TablerIcon>\n)\n\nexport const AlignRight = () => (\n <TablerIcon>\n <path d=\"M4 6h16M10 12h10M6 18h14\" />\n </TablerIcon>\n)\n","import React, { useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { BarsIcon, MinusIcon, PlusIcon } from \"../../../icons\"\nimport { TableCellElement } from \"../../../types\"\nimport {\n $AddMenuButton,\n $RemoveMenuButton,\n $RowMenu,\n $RowMenuTile,\n} from \"../../styles\"\n\nexport function RowMenu({ cellElement }: { cellElement: TableCellElement }) {\n const editor = useSlateStatic()\n const [hover, setHover] = useState(false)\n\n return (\n <$RowMenu\n contentEditable={false}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n >\n <$RowMenuTile className=\"--tile\">\n <BarsIcon />\n </$RowMenuTile>\n {hover ? (\n <>\n <$RemoveMenuButton\n style={{\n top: \"50%\",\n left: \"0.5em\",\n marginTop: \"-0.5em\",\n }}\n onMouseDown={() =>\n editor.tablePlugin.removeRow({ at: cellElement })\n }\n >\n <MinusIcon />\n </$RemoveMenuButton>\n <$AddMenuButton\n style={{ top: \"-0.5em\", left: \"0.5em\" }}\n onMouseDown={() =>\n editor.tablePlugin.insertRow({ at: cellElement })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n <$AddMenuButton\n style={{ bottom: \"-0.5em\", left: \"0.5em\" }}\n onMouseDown={() =>\n editor.tablePlugin.insertRow({ at: cellElement, offset: 1 })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n </>\n ) : null}\n </$RowMenu>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $TableMenu = styled(\"div\")`\n position: absolute;\n /**\n * very slightly shaded\n */\n background: rgba(0, 0, 0, 0.001);\n\n /**\n * hangs out on left\n */\n top: -1.5em;\n left: -4em;\n height: 2.5em;\n width: 2.5em;\n\n /**\n * hover \n */\n &:hover {\n /**\n * needs to pop up so that it doesn't jump back and forth with neighbor\n * below\n */\n z-index: 1000;\n /**\n * Makes the visible tile get darker on hover over any part of the\n * menu including the invisible part\n */\n .--row-menu-tile {\n background: rgba(0, 0, 0, 0.15);\n }\n }\n`\n\n/**\n * The `$RowMenuTile` is the visible part of the `$RowMenu` and is the right\n * half of the `$RowMenu`.\n */\nexport const $TableMenuTile = styled(\"div\")`\n position: absolute;\n left: 0;\n top: 0;\n width: 1.5em;\n height: 1.5em;\n background: rgba(0, 0, 0, 0.05);\n border-radius: 50%;\n`\n","import { $TableMenu, $TableMenuTile } from \"./$table-menu\"\n\nexport function TableMenu() {\n return (\n <$TableMenu contentEditable={false}>\n <$TableMenuTile className=\"--table-menu-tile\" />\n </$TableMenu>\n )\n}\n","import { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { TableContentElement } from \"../types\"\nimport { $TableContent } from \"./styles\"\n\nexport function TableContent({\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableContentElement>) {\n return <$TableContent {...attributes}>{children}</$TableContent>\n}\n","import { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport { TableRowElement } from \"../types\"\nimport { $TableRow } from \"./styles\"\n\nexport function TableRow({\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableRowElement>) {\n return <$TableRow {...attributes}>{children}</$TableRow>\n}\n","import { ConstrainedRenderElementProps } from \"~/src/sink\"\n\nimport {\n TableCellElement,\n TableContentElement,\n TableElement,\n TableRowElement,\n} from \"../types\"\nimport { Table } from \"./table\"\nimport { TableCell } from \"./table-cell\"\nimport { TableContent } from \"./table-content\"\nimport { TableRow } from \"./table-row\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<\n TableElement | TableRowElement | TableCellElement | TableContentElement\n>) {\n switch (element.type) {\n case \"table\":\n return (\n <Table element={element} attributes={attributes}>\n {children}\n </Table>\n )\n case \"table-row\":\n return (\n <TableRow element={element} attributes={attributes}>\n {children}\n </TableRow>\n )\n case \"table-cell\":\n return (\n <TableCell element={element} attributes={attributes}>\n {children}\n </TableCell>\n )\n case \"table-content\":\n return (\n <TableContent element={element} attributes={attributes}>\n {children}\n </TableContent>\n )\n }\n}\n","import { Global } from \"@emotion/react\"\n\nimport { createPlugin, TypedPlugin } from \"~/src/sink\"\n\nimport { globalStyles } from \"./global-styles\"\n\nexport type ThemeEditor = {\n theme: true\n}\n\nexport type ThemePluginCustomTypes = {\n Name: \"theme\"\n Editor: ThemeEditor\n}\n\nexport const ThemePlugin = createPlugin<ThemePluginCustomTypes>((editor) => {\n editor.theme = true\n return {\n name: \"theme\",\n editor: {},\n renderEditable: ({ attributes, Editable }) => {\n return (\n <>\n <Global styles={globalStyles} />\n <Editable {...attributes} />\n </>\n )\n },\n editableProps: {},\n }\n}) as TypedPlugin<ThemePluginCustomTypes>\n","import { css } from \"@emotion/react\"\n\nconst blue = `\n--blue-50: rgb(239 246 255);\n--blue-100: rgb(219 234 254);\n--blue-200: rgb(191 219 254);\n--blue-300: rgb(147 197 253);\n--blue-400: rgb(96 165 250);\n--blue-500: rgb(59 130 246);\n--blue-600: rgb(37 99 235);\n--blue-700: rgb(29 78 216);\n--blue-800: rgb(30 64 175);\n--blue-900: rgb(30 58 138);\n`\n\n// ignore because right now we're manually swapping them in/out\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst slateShades = `\n--shade-50: rgb(248 250 252);\n--shade-100: rgb(241 245 249);\n--shade-200: rgb(226 232 240);\n--shade-300: rgb(203 213 225);\n--shade-400: rgb(148 163 184);\n--shade-500: rgb(100 116 139);\n--shade-600: rgb(71 85 105);\n--shade-700: rgb(51 65 85);\n--shade-800: rgb(30 41 59);\n--shade-900: rgb(15 23 42);\n`\n\n// ignore because right now we're manually swapping them in/out\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst grayShades = `\n--shade-50: rgb(249 250 251);\n--shade-100: rgb(243 244 246);\n--shade-200: rgb(229 231 235);\n--shade-300: rgb(209 213 219);\n--shade-400: rgb(156 163 175);\n--shade-500: rgb(107 114 128);\n--shade-600: rgb(75 85 99);\n--shade-700: rgb(55 65 81);\n--shade-800: rgb(31 41 55);\n--shade-900: rgb(17 24 39);\n`\n\n// ignore because right now we're manually swapping them in/out\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst zincShades = `\n--shade-50: rgb(250 250 250);\n--shade-100: rgb(244 244 245);\n--shade-200: rgb(228 228 231);\n--shade-300: rgb(212 212 216);\n--shade-400: rgb(161 161 170);\n--shade-500: rgb(113 113 122);\n--shade-600: rgb(82 82 91);\n--shade-700: rgb(63 63 70);\n--shade-800: rgb(39 39 42);\n--shade-900: rgb(24 24 27);\n`\n\nexport const globalStyles = css`\n :root {\n /* Tailwind Colors */\n ${blue}\n ${zincShades}\n /* Select Colors */\n --select-color: var(--blue-400);\n --select-editor-color: var(--blue-200);\n --hover-color: var(--blue-200);\n /* Link Colors */\n --link-color: var(--blue-600);\n --link-hover-color: var(--blue-700);\n /* Code Block Colors */\n /* Inline Code Colors */\n --inline-code-bgcolor: var(--shade-100);\n --inline-code-border-color: var(--shade-200);\n /* Table Colors */\n --table-border-color: var(--shade-300);\n --table-row-border-color: var(--shade-300);\n --table-column-border-color: var(--shade-100);\n --table-head-bgcolor: var(--shade-50);\n --table-menu-bgcolor: var(--shade-100);\n --table-menu-hover-bgcolor: var(--shade-200);\n /* Horizontal Rule Colors */\n --hr-color: var(--shade-300);\n }\n`\n","import { clsx } from \"clsx\"\nimport { useCallback, useRef } from \"react\"\nimport { Editor, Transforms } from \"slate\"\nimport { ReactEditor, useFocused, useSlateStatic } from \"slate-react\"\n\nimport { RenderEditableProps } from \"~/src/sink\"\nimport { Layers } from \"~/src/use-layer\"\n\nimport { Toolbar } from \"../components\"\nimport { $Editable, $OuterContainer } from \"../styles\"\n\nexport function renderEditable({ attributes, Editable }: RenderEditableProps) {\n const outerContainerRef = useRef<HTMLDivElement>(null)\n\n const editor = useSlateStatic()\n const focused = useFocused()\n\n /**\n * When the user clicks inside the outer container but outside of the content\n * or the toolbar, we want the user to see the cursor inside the editable\n * region.\n */\n const onClickOuterContainer = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n /**\n * If the user clicked on the toolbar, we don't want to do anything.\n *\n * If the user clicked on the content, we don't want to do anything\n * because focus and selection will be handled by Slate.\n */\n if (e.target !== e.currentTarget) return\n /**\n * Select the last position in the editor\n */\n Transforms.select(editor, Editor.end(editor, []))\n ReactEditor.focus(editor)\n },\n [editor]\n )\n /**\n * The Toolbar works by rendering an $OuterContainer which is the border\n * around the entire editor.\n *\n * Inside the $OuterContainer, we have our actual Toolbar and the\n * actual Editable.\n *\n * TODO:\n *\n * We currently add `Layers` around everything in the Toolbar plugin but\n * we should consider adding this somewhere else because the layers inside\n * the Editor (like in the image toolbar) won't work unless we are using the\n * toolbar plugin.\n *\n * Conceivably, we could have a version of the editor without the Toolbar.\n *\n * We could consider adding a Layers plugin and make it a dependency of some\n * other thing or we could just add it outside of everything as part of\n * Sink itself since probably every version of the editor will require at\n * least one layer somewhere.\n */\n return (\n <Layers>\n <$OuterContainer\n ref={outerContainerRef}\n className={clsx({ \"--focused\": focused })}\n style={{\n height: editor.toolbar.height,\n minHeight: editor.toolbar.minHeight,\n maxHeight: editor.toolbar.maxHeight,\n }}\n onClick={onClickOuterContainer}\n >\n <Toolbar />\n <Editable\n as={$Editable}\n {...attributes}\n style={{ overflowY: \"auto\" }}\n />\n </$OuterContainer>\n </Layers>\n )\n}\n","import { clsx } from \"clsx\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { CloseMask } from \"~/src/shared-overlays\"\nimport { useAbsoluteReposition } from \"~/src/use-reposition\"\n\nimport {\n $TableDialog,\n $TableDialogGrid,\n $TableDialogGridCell,\n} from \"../../styles/table-styles\"\n\nfunction createRange(size: number): number[] {\n return [...Array(size).keys()]\n}\n\nexport function TableDialog({\n dest,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n}) {\n const [hover, setHover] = useState({ x: 0, y: 0 })\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(null)\n const style = useAbsoluteReposition({ src: ref, dest }, ({ dest }) => {\n return { left: dest.left - 8, top: dest.top + dest.height }\n })\n const rows = createRange(5).map((i) => i + 1)\n const cols = createRange(5).map((i) => i + 1)\n\n const hoverCell = useCallback(\n (x: number, y: number) => {\n setHover({ x, y })\n },\n [setHover]\n )\n\n const createTable = useCallback(\n (x: number, y: number) => {\n editor.tablePlugin.insertTable(x, y)\n ReactEditor.focus(editor)\n close()\n },\n [editor]\n )\n\n return (\n <>\n <CloseMask close={close} />\n <$TableDialog ref={ref} style={style}>\n <$TableDialogGrid onMouseLeave={() => hoverCell(0, 0)}>\n {rows.map((y) => {\n return cols.map((x) => {\n const selected = x <= hover.x && y <= hover.y\n return (\n <$TableDialogGridCell\n className={clsx({ \"--selected\": selected })}\n key={`${x},${y}`}\n onMouseEnter={() => hoverCell(x, y)}\n onClick={() => createTable(x, y)}\n />\n )\n })\n })}\n </$TableDialogGrid>\n </$TableDialog>\n </>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays\"\n\nexport const $TableDialog = styled($Panel)`\n padding: 0.5em;\n`\nexport const $TableDialogGrid = styled(\"div\")`\n display: grid;\n grid-template-columns: repeat(5, 1.75em);\n grid-template-rows: 1.5em;\n /* grid-gap: 1px; */\n`\nexport const $TableDialogGridCell = styled(\"div\")`\n background: var(--shade-100);\n height: 1.5em;\n border-radius: 0.125em;\n border-right: 1px solid white;\n border-top: 1px solid white;\n cursor: pointer;\n &.--selected {\n background: var(--blue-100);\n }\n`\n","import throttle from \"lodash.throttle\"\nimport { useEffect, useRef, useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { MenuItemData } from \"../../../shared-overlays/types\"\nimport { initialItems, itemSets } from \"../../items\"\nimport {\n $Toolbar,\n $ToolbarContainer,\n $ToolbarDivider,\n $ToolbarDividerContainer,\n} from \"../../styles\"\nimport { ToolbarButton } from \"./toolbar-button\"\n\n/**\n * Render a toolbar item which is either a button or a divider.\n */\nfunction ToolbarItem({ item }: { item: MenuItemData }) {\n const editor = useSlateStatic()\n if (item === \"divider\") {\n return (\n <$ToolbarDividerContainer data-item-type=\"divider\">\n <$ToolbarDivider />\n </$ToolbarDividerContainer>\n )\n }\n const show = item.show === undefined ? true : item.show(editor)\n if (!show) return null\n return <ToolbarButton item={item} />\n}\n\n/**\n * Returns the width of the toolbar, the width of a button, and the width of a\n * divider.\n */\nfunction getWidths(toolbar: HTMLDivElement) {\n const button = toolbar.querySelector<HTMLDivElement>(\n \"[data-item-type=button]\"\n )\n const divider = toolbar.querySelector<HTMLDivElement>(\n \"[data-item-type=divider]\"\n )\n if (!button || !divider) throw new Error(\"Button or divider not found\")\n return {\n toolbar: toolbar.offsetWidth,\n button: button.offsetWidth,\n divider: divider.offsetWidth,\n }\n}\n\n/**\n * Takes an array of items representing a set of toolbar buttons and items and\n * returns the width of the set in pixels\n */\nfunction measureItemSetWidth(\n items: MenuItemData[],\n buttonWidth: number,\n dividerWidth: number\n): number {\n let width = 0\n for (const item of items) {\n width += item === \"divider\" ? dividerWidth : buttonWidth\n }\n return width\n}\n\n// Allow a little slack so we don't collapse the toolbar while there is still\n// plenty of visible space. This helps avoid early wrapping on wide screens.\nconst WIDTH_BUFFER_PX = 48\n\nexport function Toolbar() {\n const ref = useRef<HTMLDivElement>(null)\n const [items, setItems] = useState<MenuItemData[]>(initialItems)\n\n useEffect(() => {\n const refresh = throttle(\n () => {\n const toolbar = ref.current\n if (!toolbar) throw new Error(\"Toolbar not found\")\n const widths = getWidths(toolbar)\n /**\n * Iterate through the item sets and find the first one that fits within\n * the toolbar width. If none fit, use the last item set.\n */\n for (let i = 0; i < itemSets.length - 1; i++) {\n const itemSetWidth = measureItemSetWidth(\n itemSets[i],\n widths.button,\n widths.divider\n )\n if (itemSetWidth < widths.toolbar - WIDTH_BUFFER_PX) {\n setItems(itemSets[i])\n return\n }\n }\n setItems(itemSets[itemSets.length - 1])\n },\n 100,\n { trailing: true }\n )\n // Delay initial refresh to ensure DOM is fully rendered\n const timeoutId = setTimeout(refresh, 0)\n window.addEventListener(\"resize\", refresh)\n return () => {\n clearTimeout(timeoutId)\n window.removeEventListener(\"resize\", refresh)\n }\n }, [])\n\n return (\n <$ToolbarContainer ref={ref}>\n <$Toolbar>\n {items.map((item, index) => (\n <ToolbarItem\n key={typeof item === \"string\" ? index : item.title}\n item={item}\n />\n ))}\n </$Toolbar>\n </$ToolbarContainer>\n )\n}\n","import { TablerIcon } from \"../sink\"\n\nexport const H = () => (\n <TablerIcon>\n <path d=\"M7 12h10M7 5v14M17 5v14M15 19h4M15 5h4M5 19h4M5 5h4\" />\n </TablerIcon>\n)\n\nexport const More = () => (\n <TablerIcon className=\"--more-icon\" width=\"0.5em\" viewBox=\"0 0 12 24\">\n <path d=\"m2 12 4 4 4-4\" />\n </TablerIcon>\n)\n\nexport const LinkPlus = () => (\n <TablerIcon width=\"0.5em\" viewBox=\"6 0 12 24\">\n <path d=\"M9 12h6M12 9v6\" />\n </TablerIcon>\n)\n\nexport const H1 = () => (\n <TablerIcon>\n <path d=\"M19 18v-8l-2 2M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H2 = () => (\n <TablerIcon>\n <path d=\"M17 12a2 2 0 1 1 4 0c0 .591-.417 1.318-.816 1.858L17 18.001h4M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H3 = () => (\n <TablerIcon>\n <path d=\"M19 14a2 2 0 1 0-2-2M17 16a2 2 0 1 0 2-2M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H4 = () => (\n <TablerIcon>\n <path d=\"M20 18v-8l-4 6h5M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H5 = () => (\n <TablerIcon>\n <path d=\"M17 18h2a2 2 0 1 0 0-4h-2v-4h4M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H6 = () => (\n <TablerIcon>\n <path d=\"M19 14a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\" />\n <path d=\"M21 12a2 2 0 1 0-4 0v4M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const Normal = () => (\n <TablerIcon>\n <path d=\"M8 18V6h2l6 9V6h2v12h-2l-6-9v9H8z\" />\n </TablerIcon>\n)\n\nexport const Bold = () => (\n <TablerIcon>\n {/* <path d=\"M0 0h24v24H0z\" stroke=\"none\" /> */}\n <path d=\"M7 5h6a3.5 3.5 0 0 1 0 7H7zM13 12h1a3.5 3.5 0 0 1 0 7H7v-7\" />\n </TablerIcon>\n)\n\nexport const Italic = () => (\n <TablerIcon>\n <path d=\"M11 5h6M7 19h6M14 5l-4 14\" />\n </TablerIcon>\n)\n\nexport const Style = () => (\n <TablerIcon>\n <path d=\"M4 20h3M14 20h7M6.9 15h6.9M10.2 6.3 16 20M5 20l6-16h2l7 16\" />\n </TablerIcon>\n)\n\nexport const Link = () => (\n <TablerIcon>\n <path d=\"M10 14a3.5 3.5 0 0 0 5 0l4-4a3.5 3.5 0 0 0-5-5l-.5.5\" />\n <path d=\"M14 10a3.5 3.5 0 0 0-5 0l-4 4a3.5 3.5 0 0 0 5 5l.5-.5\" />\n </TablerIcon>\n)\n\n/**\n * Block Quote\n */\n\nexport const Blockquote = () => (\n <TablerIcon>\n <path d=\"M6 15h15M21 19H6M15 11h6M21 7h-6M9 9h1a1 1 0 1 1-1 1V7.5a2 2 0 0 1 2-2M3 9h1a1 1 0 1 1-1 1V7.5a2 2 0 0 1 2-2\" />\n </TablerIcon>\n)\n\nexport const Quote = () => (\n <TablerIcon>\n <path d=\"M10 11H6a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v6c0 2.667-1.333 4.333-4 5M19 11h-4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v6c0 2.667-1.333 4.333-4 5\" />\n </TablerIcon>\n)\n\nexport const DoubleQuote = () => (\n <TablerIcon>\n <path d=\"M10 9l4 3-4 3\" />\n <path d=\"M16 9l4 3-4 3\" />\n </TablerIcon>\n)\n\nexport const QuoteOff = () => (\n <TablerIcon>\n <path d=\"M10 11H6a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1m4 4v3c0 2.667-1.333 4.333-4 5M19 11h-4m-1-1V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v6c0 .66-.082 1.26-.245 1.798m-1.653 2.29c-.571.4-1.272.704-2.102.912M3 3l18 18\" />\n </TablerIcon>\n)\n\n/**\n * List\n */\n\nexport const BulletList = () => (\n <TablerIcon>\n <path d=\"M9 6h11M9 12h11M9 18h11M5 6v.01M5 12v.01M5 18v.01\" />\n </TablerIcon>\n)\n\n/**\n * Table\n */\n\nexport const Table = () => (\n <TablerIcon>\n <rect x={4} y={4} width={16} height={16} rx={2} />\n <path d=\"M4 10h16M10 4v16\" />\n </TablerIcon>\n)\n\n/**\n * Code\n */\n\nexport const Code = () => (\n <TablerIcon>\n <path d=\"m7 8-4 4 4 4M17 8l4 4-4 4M14 4l-4 16\" />\n </TablerIcon>\n)\n\nexport const CodeBlock = () => (\n <TablerIcon>\n <path d=\"M9 8L5 12L9 16M15 8L19 12L15 16\" />\n </TablerIcon>\n)\n\n/**\n * Media and Files\n */\n\nexport const Image = () => (\n <TablerIcon>\n <path d=\"M15 8h.01\" />\n <rect x={4} y={4} width={16} height={16} rx={3} />\n <path d=\"m4 15 4-4a3 5 0 0 1 3 0l5 5\" />\n <path d=\"m14 14 1-1a3 5 0 0 1 3 0l2 2\" />\n </TablerIcon>\n)\n\nexport const Attachment = () => (\n <TablerIcon>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2zM12 11v6M9 14h6\" />\n </TablerIcon>\n)\n\nexport const FileUpload = () => (\n <TablerIcon>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2zM12 11v6\" />\n <path d=\"M9.5 13.5 12 11l2.5 2.5\" />\n </TablerIcon>\n)\n\nexport const PhotoUp = () => (\n <TablerIcon>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M15 8h.01M12.5 21H6a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v6.5\" />\n <path d=\"m3 16 5-5c.928-.893 2.072-.893 3 0l3.5 3.5\" />\n <path d=\"m14 14 1-1c.679-.653 1.473-.829 2.214-.526M19 22v-6M22 19l-3-3-3 3\" />\n </TablerIcon>\n)\n\n/**\n * Text Styles\n */\n\nexport const Plus = () => (\n <TablerIcon>\n <path d=\"M12 5v14M5 12h14\" />\n </TablerIcon>\n)\n\nexport const Strikethrough = () => (\n <TablerIcon>\n <path d=\"M5 12h14M16 6.5A4 2 0 0 0 12 5h-1a3.5 3.5 0 0 0 0 7h2a3.5 3.5 0 0 1 0 7h-1.5a4 2 0 0 1-4-1.5\" />\n </TablerIcon>\n)\n\nexport const Underline = () => (\n <TablerIcon>\n <path d=\"M7 5v5a5 5 0 0 0 10 0V5M5 19h14\" />\n </TablerIcon>\n)\n\nexport const RemoveStyles = () => (\n <TablerIcon>\n <path d=\"m14 6 7 7-2 2M10 10l-4.172 4.172a2.828 2.828 0 1 0 4 4L14 14\" />\n <path d=\"m16 12 4.414-4.414a2 2 0 0 0 0-2.829l-1.171-1.171a2 2 0 0 0-2.829 0L12 8M4 20l1.768-1.768M3 3l18 18\" />\n </TablerIcon>\n)\n\nexport const ListCheck = () => (\n <TablerIcon>\n <path d=\"m9 11 3 3 8-8\" />\n <path d=\"M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h9\" />\n </TablerIcon>\n)\n\nexport const ListNumbers = () => (\n <TablerIcon>\n <path d=\"M11 6h9M11 12h9M12 18h8M4 16a2 2 0 1 1 4 0c0 .591-.5 1-1 1.5L4 20h4M6 10V4L4 6\" />\n </TablerIcon>\n)\n\nexport const IncreaseDepth = () => (\n <TablerIcon>\n <path d=\"M4 6h16M8 12h12M12 18h8M7 12l-3-3M7 12l-3 3\" />\n </TablerIcon>\n)\n\nexport const DecreaseDepth = () => (\n <TablerIcon>\n <path d=\"M4 6h16M8 12h12M12 18h8M4 12l3-3M4 12l3 3\" />\n </TablerIcon>\n)\n\n/**\n * Markdown\n */\nexport const Markdown = () => (\n <TablerIcon>\n <path d=\"M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z\" />\n <path d=\"M7 15V9l2 2 2-2v6M14 9v6h4M14 13h2\" />\n </TablerIcon>\n)\n\n/**\n * Visual Editor\n */\nexport const VisualEditor = () => (\n <TablerIcon>\n <path d=\"M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z\" />\n <path d=\"M8 8h8M8 12h8M8 16h5\" />\n <path d=\"M16 16h1\" />\n </TablerIcon>\n)\n\nexport const Highlight = () => (\n <TablerIcon>\n <path d=\"M3 19h4L17.5 8.5a2.828 2.828 0 1 0-4-4L3 15v4\" />\n <path d=\"m12.5 5.5 4 4\" />\n <path d=\"M3 21h7\" />\n <path d=\"M18 19h3M19.5 17.5v3\" />\n </TablerIcon>\n)\n","import { MenuItemData } from \"~/src/shared-overlays/types\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"~/src/utils/translations\"\n\nconst listDepthItems: MenuItemData[] = [\n {\n icon: Icon.IncreaseDepth,\n title: t(\"increaseDepth\"),\n hotkey: \"tab\",\n action: (editor) => editor.list?.increaseDepth(),\n active: (editor) => editor.list?.canIncreaseDepth() ?? false,\n show: (editor) => !!editor.list,\n },\n {\n icon: Icon.DecreaseDepth,\n title: t(\"decreaseDepth\"),\n hotkey: \"shift+tab\",\n action: (editor) => editor.list?.decreaseDepth(),\n active: (editor) => editor.list?.canDecreaseDepth() ?? false,\n show: (editor) => !!editor.list,\n },\n]\n\nconst blockItems: MenuItemData[] = [\n {\n icon: Icon.Normal,\n title: t(\"normal\"),\n hotkey: \"super+0\",\n action: (editor) => {\n editor.collapsibleParagraph.convertParagraph()\n },\n },\n {\n icon: Icon.H1,\n title: t(\"heading1\"),\n hotkey: \"super+1\",\n action: (editor) => editor.heading.convertHeading(1, true),\n active: (editor) => editor.heading.isHeadingActive(1),\n },\n {\n icon: Icon.H2,\n title: t(\"heading2\"),\n hotkey: \"super+2\",\n action: (editor) => editor.heading.convertHeading(2, true),\n active: (editor) => editor.heading.isHeadingActive(2),\n },\n {\n icon: Icon.H3,\n title: t(\"heading3\"),\n hotkey: \"super+3\",\n action: (editor) => editor.heading.convertHeading(3, true),\n active: (editor) => editor.heading.isHeadingActive(3),\n },\n]\n\nexport const expandedBlockItems: MenuItemData[] = [...blockItems]\n\nexport const compactBlockItems: MenuItemData[] = [\n {\n icon: Icon.H,\n title: t(\"paragraphStyle\"),\n more: true,\n children: blockItems,\n }\n]\n\n// Export listDepthItems so they can be used in list-items.tsx\nexport { listDepthItems }\n","import { useState, useRef, CSSProperties, useEffect } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { CloseMask } from \"~/src/shared-overlays\"\nimport { positionInside, useAbsoluteReposition } from \"~/src/use-reposition\"\nimport { t } from \"~/src/utils/translations\"\n\nimport { $FileDialog } from \"../../styles/file-dialog-styles\"\n\ntype ImageSource = \"url\" | \"file\"\n\nexport function ImageUrlDialog({\n dest,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n}) {\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(undefined) as unknown as HTMLDivElement\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n // Persist dialog values in editor.wysimark so they survive dialog close/reopen\n const savedState = editor.wysimark?.imageDialogState\n const hasOnImageChange = !!editor.wysimark?.onImageChange\n\n const [url, setUrl] = useState(savedState?.url ?? \"\")\n const [alt, setAlt] = useState(savedState?.alt ?? \"\")\n const [title, setTitle] = useState(savedState?.title ?? \"\")\n const [imageSource, setImageSource] = useState<ImageSource>(savedState?.imageSource ?? (hasOnImageChange ? \"file\" : \"url\"))\n const [isUploading, setIsUploading] = useState(false)\n const [uploadedUrl, setUploadedUrl] = useState(savedState?.uploadedUrl ?? \"\")\n\n // Save state to editor when values change\n useEffect(() => {\n if (editor.wysimark) {\n editor.wysimark.imageDialogState = { url, alt, title, imageSource, uploadedUrl }\n }\n }, [url, alt, title, imageSource, uploadedUrl])\n\n // Clear state on successful submit or cancel\n const clearState = () => {\n if (editor.wysimark) {\n editor.wysimark.imageDialogState = undefined\n }\n }\n\n const style = useAbsoluteReposition(\n { src: ref, dest },\n ({ src, dest }) => {\n return positionInside(\n src,\n dest,\n {\n left: dest.left - 16,\n top: dest.top + dest.height,\n },\n { margin: 16 }\n )\n }\n ) as CSSProperties\n\n function handleSubmit(e: React.FormEvent) {\n e.preventDefault()\n const finalUrl = imageSource === \"file\" ? uploadedUrl : url\n if (finalUrl.trim() === \"\") return\n\n editor.image.insertImageFromUrl(finalUrl, alt, title)\n clearState()\n close()\n }\n\n function handleCancel() {\n clearState()\n close()\n }\n\n async function handleFileSelect(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0]\n if (!file || !editor.wysimark?.onImageChange) return\n\n setIsUploading(true)\n try {\n const resultUrl = await editor.wysimark.onImageChange(file)\n setUploadedUrl(resultUrl)\n } catch (error) {\n console.error(\"Failed to upload image:\", error)\n } finally {\n setIsUploading(false)\n }\n }\n\n function handleSelectFileClick() {\n fileInputRef.current?.click()\n }\n\n const isSubmitDisabled = imageSource === \"file\"\n ? uploadedUrl.trim() === \"\" || isUploading\n : url.trim() === \"\"\n\n return (\n <>\n <CloseMask close={close} />\n <$FileDialog ref={ref as unknown as React.RefObject<HTMLDivElement>} style={style}>\n <form onSubmit={handleSubmit} style={{ padding: \"8px\" }}>\n {hasOnImageChange && (\n <div style={{ marginBottom: \"12px\" }}>\n <label style={{ display: \"inline-flex\", alignItems: \"center\", marginRight: \"16px\", cursor: \"pointer\" }}>\n <input\n type=\"radio\"\n name=\"imageSource\"\n value=\"file\"\n checked={imageSource === \"file\"}\n onChange={() => setImageSource(\"file\")}\n style={{ marginRight: \"4px\" }}\n />\n {t(\"imageSourceFile\")}\n </label>\n <label style={{ display: \"inline-flex\", alignItems: \"center\", cursor: \"pointer\" }}>\n <input\n type=\"radio\"\n name=\"imageSource\"\n value=\"url\"\n checked={imageSource === \"url\"}\n onChange={() => setImageSource(\"url\")}\n style={{ marginRight: \"4px\" }}\n />\n {t(\"imageSourceUrl\")}\n </label>\n </div>\n )}\n\n {imageSource === \"url\" ? (\n <div style={{ marginBottom: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"imageUrlRequired\")}\n </label>\n <input\n type=\"text\"\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\"\n }}\n placeholder=\"https://example.com/image.jpg\"\n />\n </div>\n ) : (\n <div style={{ marginBottom: \"8px\" }}>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: \"none\" }}\n />\n <button\n type=\"button\"\n onClick={handleSelectFileClick}\n disabled={isUploading}\n style={{\n padding: \"8px 16px\",\n backgroundColor: isUploading ? \"#ccc\" : \"#f0f0f0\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n cursor: isUploading ? \"not-allowed\" : \"pointer\",\n marginBottom: \"8px\"\n }}\n >\n {isUploading ? t(\"uploading\") : t(\"selectFile\")}\n </button>\n {uploadedUrl && (\n <div style={{ marginTop: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"imageUrlRequired\")}\n </label>\n <input\n type=\"text\"\n value={uploadedUrl}\n disabled\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n backgroundColor: \"#f5f5f5\",\n color: \"#666\"\n }}\n />\n </div>\n )}\n </div>\n )}\n\n <div style={{ marginBottom: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"altText\")}\n </label>\n <input\n type=\"text\"\n value={alt}\n onChange={(e) => setAlt(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\"\n }}\n placeholder={t(\"imageDescription\")}\n />\n </div>\n\n <div style={{ marginBottom: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"title\")}\n </label>\n <input\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\"\n }}\n placeholder={t(\"imageTitle\")}\n />\n </div>\n\n <div style={{ display: \"flex\", gap: \"8px\" }}>\n <button\n type=\"submit\"\n disabled={isSubmitDisabled}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px 16px\",\n backgroundColor: isSubmitDisabled ? \"#ccc\" : \"#0078d4\",\n color: \"white\",\n border: \"none\",\n borderRadius: \"4px\",\n cursor: isSubmitDisabled ? \"not-allowed\" : \"pointer\",\n fontWeight: \"bold\"\n }}\n >\n {t(\"register\")}\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n style={{\n padding: \"8px 16px\",\n backgroundColor: \"#f0f0f0\",\n color: \"#333\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n cursor: \"pointer\"\n }}\n >\n {t(\"cancel\")}\n </button>\n </div>\n </form>\n </$FileDialog>\n </>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays/styles/$Panel\"\n\nexport const $FileDialog = styled($Panel)`\n padding: 1em;\n width: 18em;\n`\n","import { isHotkey } from \"is-hotkey\"\nimport {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\"\nimport { Editor, Range } from \"slate\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { positionInside, useAbsoluteReposition } from \"~/src/use-reposition\"\n\nimport { CloseMask } from \"../../../shared-overlays/components/CloseMask\"\nimport { t } from \"../../../utils/translations\"\nimport * as Icon from \"../../icons\"\nimport {\n $AnchorDialog,\n $AnchorDialogInput,\n $AnchorDialogInputLine,\n} from \"../../styles\"\nimport { $DialogButton, $DialogHint } from \"../../styles/dialog-shared-styles\"\n\nconst isEnter = isHotkey(\"enter\")\n\nexport function AnchorDialog({\n dest,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n}) {\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(null)\n const style = useAbsoluteReposition(\n { src: ref, dest },\n ({ src, dest }, viewport) => {\n return positionInside(\n src,\n viewport,\n {\n left: dest.left - 12,\n top: dest.top + dest.height,\n },\n { margin: 16 }\n )\n }\n )\n\n // Get selected text as initial value for link text\n const initialText = useMemo(() => {\n const { selection } = editor\n if (selection && !Range.isCollapsed(selection)) {\n return Editor.string(editor, selection)\n }\n return \"\"\n }, [])\n\n const [url, setUrl] = useState(\"\")\n const [text, setText] = useState(initialText)\n const [title, setTitle] = useState(initialText)\n const [titleManuallyEdited, setTitleManuallyEdited] = useState(false)\n\n const insertLink = () => {\n const linkText = text.trim() || url\n const linkTitle = title.trim() || undefined\n editor.anchor.insertLink(url, linkText, { select: true, title: linkTitle })\n ReactEditor.focus(editor)\n close()\n }\n\n const onChangeUrl = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setUrl(e.currentTarget.value)\n },\n [setUrl]\n )\n\n const onChangeText = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const newText = e.currentTarget.value\n setText(newText)\n // Sync title with text if title hasn't been manually edited\n if (!titleManuallyEdited) {\n setTitle(newText)\n }\n },\n [setText, setTitle, titleManuallyEdited]\n )\n\n const onChangeTitle = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setTitle(e.currentTarget.value)\n setTitleManuallyEdited(true)\n },\n [setTitle]\n )\n\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (!isEnter(e)) return\n e.preventDefault()\n e.stopPropagation()\n insertLink()\n }\n\n return (\n <>\n <CloseMask close={close} />\n <$AnchorDialog ref={ref} style={style}>\n <$AnchorDialogInputLine>\n <$AnchorDialogInput\n type=\"text\"\n value={url}\n autoFocus\n placeholder={t(\"linkUrl\")}\n onChange={onChangeUrl}\n onKeyDown={onKeyDown}\n />\n </$AnchorDialogInputLine>\n <$AnchorDialogInputLine style={{ marginTop: \"0.5em\" }}>\n <$AnchorDialogInput\n type=\"text\"\n value={text}\n placeholder={t(\"linkText\")}\n onChange={onChangeText}\n onKeyDown={onKeyDown}\n />\n </$AnchorDialogInputLine>\n <$AnchorDialogInputLine style={{ marginTop: \"0.5em\" }}>\n <$AnchorDialogInput\n type=\"text\"\n value={title}\n placeholder={t(\"tooltipText\")}\n onChange={onChangeTitle}\n onKeyDown={onKeyDown}\n />\n <$DialogButton onClick={insertLink}>\n <Icon.Link />\n <Icon.LinkPlus />\n </$DialogButton>\n </$AnchorDialogInputLine>\n <$DialogHint>{t(\"tooltipHint\")}</$DialogHint>\n </$AnchorDialog>\n </>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $DialogButton = styled(\"div\")`\n /* Center vertically and horizontally */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n /* font-size: 1.25em; */\n padding: 0.25em 0.75em;\n text-align: center;\n color: var(--blue-100);\n color: white;\n background: var(--blue-500);\n transition: all 100ms;\n &:hover {\n color: var(--blue-50);\n background: var(--blue-600);\n outline: 2px solid var(--blue-200);\n }\n border-radius: 0.25em;\n svg {\n color: var(--blue-200);\n font-size: 1.25em;\n stroke-width: 2px;\n }\n`\n\nexport const $DialogHint = styled(\"div\")`\n font-size: 0.875em;\n margin-top: 0.5em;\n color: var(--shade-500);\n line-height: 1.375;\n`\n","import { MenuItemData } from \"~/src/shared-overlays\"\n\nimport { TableDialog } from \"../components\"\nimport { ImageUrlDialog } from \"../components/dialog/image-url-dialog\"\nimport { AnchorDialog } from \"../components/dialog/anchor-dialog\"\nimport * as Icon from \"../icons\"\nimport { t } from \"~/src/utils/translations\"\n\nexport const dialogItems: MenuItemData[] = [\n {\n icon: Icon.Link,\n title: t(\"insertLink\"),\n more: true,\n hotkey: \"mod+k\",\n Component: AnchorDialog,\n },\n {\n icon: Icon.Image,\n title: t(\"insertImageFromUrl\"),\n more: true,\n Component: ImageUrlDialog,\n },\n {\n icon: Icon.Table,\n title: t(\"insertTable\"),\n more: true,\n Component: TableDialog,\n },\n]\n\nexport const expandedDialogItems: MenuItemData[] = dialogItems\n\nexport const compactDialogItems: MenuItemData[] = dialogItems\n\nexport const smallDialogItems: MenuItemData[] = [\n {\n icon: Icon.Plus,\n title: t(\"insert\"),\n more: true,\n children: dialogItems,\n },\n]\n","import { Editor } from \"slate\"\nimport { MenuItemData } from \"~/src/shared-overlays\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"~/src/utils/translations\"\n\nfunction getMarks(editor: Editor) {\n const marks = Editor.marks(editor)\n return {\n bold: marks?.bold || false,\n italic: marks?.italic || false,\n strike: marks?.strike || false,\n code: marks?.code || false,\n underline: marks?.underline || false,\n highlight: marks?.highlight || false,\n }\n}\n\nconst primaryMarkItems: MenuItemData[] = [\n {\n icon: Icon.Bold,\n title: t(\"bold\"),\n hotkey: \"mod+b\",\n action: (editor) => editor.marksPlugin.toggleBold(),\n active: (editor) => getMarks(editor).bold,\n },\n {\n icon: Icon.Italic,\n title: t(\"italic\"),\n hotkey: \"mod+i\",\n action: (editor) => editor.marksPlugin.toggleItalic(),\n active: (editor) => getMarks(editor).italic,\n },\n {\n icon: Icon.Strikethrough,\n title: t(\"strike\"),\n hotkey: \"super+k\",\n action: (editor) => editor.marksPlugin.toggleStrike(),\n active: (editor) => getMarks(editor).strike,\n },\n {\n icon: Icon.Code,\n title: t(\"inlineCode\"),\n hotkey: \"mod+j\",\n action: (editor) => editor.inlineCode.toggleInlineCode(),\n active: (editor) => getMarks(editor).code,\n },\n {\n icon: Icon.Underline,\n title: t(\"underline\"),\n hotkey: \"mod+u\",\n action: (editor) => editor.marksPlugin.toggleUnderline(),\n active: (editor) => getMarks(editor).underline,\n },\n {\n icon: Icon.Highlight,\n title: t(\"highlight\"),\n action: (editor) => editor.marksPlugin.toggleHighlight(),\n active: (editor) => getMarks(editor).highlight,\n show: (editor) => !editor.wysimark?.disableHighlight,\n },\n]\n\nexport const expandedMarkItems: MenuItemData[] = primaryMarkItems\nexport const compactMarkItems: MenuItemData[] = [\n {\n icon: Icon.Bold,\n title: t(\"format\"),\n more: true,\n children: primaryMarkItems,\n },\n]\n","import { MenuItemData } from \"~/src/shared-overlays\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"~/src/utils/translations\"\nimport { listDepthItems } from \"./block-items\"\n\nexport const listItems: MenuItemData[] = [\n {\n icon: Icon.BulletList,\n title: t(\"bulletList\"),\n hotkey: \"super+8\",\n action: (editor) => editor.list?.convertUnorderedList(true),\n show: (editor) => !!editor.list,\n },\n {\n icon: Icon.ListNumbers,\n title: t(\"numberedList\"),\n hotkey: \"super+7\",\n action: (editor) => editor.list?.convertOrderedList(true),\n show: (editor) => !!editor.list,\n },\n {\n icon: Icon.ListCheck,\n title: t(\"checkList\"),\n hotkey: \"super+9\",\n action: (editor) => editor.list?.convertTaskList(true),\n show: (editor) => !!editor.list && !editor.wysimark?.disableTaskList,\n },\n]\n\nexport const expandedListItems: MenuItemData[] = [...listItems, \"divider\", ...listDepthItems]\n\nexport const compactListItems: MenuItemData[] = [\n {\n icon: Icon.ListNumbers,\n title: t(\"list\"),\n more: true,\n children: [...listItems, \"divider\", ...listDepthItems],\n show: (editor) => !!editor.list,\n },\n]\n","import { MenuItemData } from \"~/src/shared-overlays\"\nimport { Editor, Transforms } from \"slate\"\nimport { findElementUp } from \"~/src/sink\"\nimport * as Icon from \"../icons\"\nimport { t } from \"~/src/utils/translations\"\n\nconst quoteItemsList: MenuItemData[] = [\n {\n icon: Icon.Quote,\n title: t(\"quote\"),\n hotkey: \"super+.\",\n action: (editor) => {\n if (editor.blockQuotePlugin.isActive()) {\n editor.blockQuotePlugin.outdent()\n } else {\n editor.blockQuotePlugin.indent()\n }\n },\n active: (editor) => editor.blockQuotePlugin.isActive(),\n },\n {\n icon: Icon.DoubleQuote,\n title: t(\"increaseQuoteDepth\"),\n action: (editor) => editor.blockQuotePlugin.increaseDepth(),\n active: (editor) => editor.blockQuotePlugin.canIncreaseDepth(),\n },\n {\n icon: Icon.CodeBlock,\n title: t(\"codeBlock\"),\n action: (editor) => {\n const { selection } = editor;\n const codeBlockEntry = findElementUp(editor, \"code-block\");\n\n // Case 1: If a code block is already active, convert it to a paragraph\n if (codeBlockEntry) {\n const [codeBlock, path] = codeBlockEntry;\n\n // Extract text content from the code block\n const textContent = Editor.string(editor, path);\n\n // Remove the code block\n Transforms.removeNodes(editor, { at: path });\n\n // Insert a paragraph with the extracted text\n Transforms.insertNodes(\n editor,\n {\n type: \"paragraph\",\n children: [{ text: textContent }]\n },\n { at: path }\n );\n return;\n }\n\n // Case 2: If text is selected, convert it to a code block\n if (selection && JSON.stringify(selection.anchor.path) !== JSON.stringify(selection.focus.path)) {\n // Handle multi-paragraph selection\n // This is more complex and would require custom handling\n // For simplicity, we'll just create a code block with default behavior\n editor.codeBlock?.createCodeBlock({ language: \"text\" });\n return;\n }\n\n if (selection && (selection.anchor.offset !== selection.focus.offset ||\n JSON.stringify(selection.anchor.path) !== JSON.stringify(selection.focus.path))) {\n // Get the selected text\n const selectedText = Editor.string(editor, selection);\n\n // Delete the selected text\n Transforms.delete(editor);\n\n // Insert a code block with the selected text\n Transforms.insertNodes(\n editor,\n {\n type: \"code-block\",\n language: \"text\",\n children: [\n {\n type: \"code-block-line\",\n children: [{ text: selectedText }]\n }\n ]\n }\n );\n return;\n }\n\n // Case 3: Default case - create a new empty code block\n editor.codeBlock?.createCodeBlock({ language: \"text\" });\n },\n active: (editor) => !!findElementUp(editor, \"code-block\"),\n show: (editor) => !!editor.codeBlock && !editor.wysimark?.disableCodeBlock,\n },\n]\n\nexport const expandedQuoteItems: MenuItemData[] = quoteItemsList\n\nexport const compactQuoteItems: MenuItemData[] = [\n {\n icon: Icon.Quote,\n title: t(\"quote\"),\n more: true,\n children: quoteItemsList,\n },\n]\n\n// For backward compatibility\nexport const quoteItems = expandedQuoteItems\n","import { MenuItemData } from \"~/src/shared-overlays\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"~/src/utils/translations\"\n\nexport const rawModeItem: MenuItemData = {\n icon: Icon.Markdown,\n title: t(\"switchToRawMarkdown\"),\n action: (editor) => {\n // Call the toggleRawMode function if it exists on the editor\n if (editor.wysimark && typeof editor.wysimark.toggleRawMode === 'function') {\n editor.wysimark.toggleRawMode();\n }\n },\n // Only show in the toolbar when not in Raw mode and toggleRawMode is available\n show: (editor) => {\n return editor.wysimark && typeof editor.wysimark.toggleRawMode === 'function' && !editor.wysimark.isRawMode;\n },\n active: () => false, // Never show as active in the toolbar\n}\n\nexport const visualModeItem: MenuItemData = {\n icon: Icon.VisualEditor,\n title: t(\"switchToVisualEditor\"),\n action: (editor) => {\n // Call the toggleRawMode function if it exists on the editor\n if (editor.wysimark && typeof editor.wysimark.toggleRawMode === 'function') {\n editor.wysimark.toggleRawMode();\n }\n },\n // Only show in the toolbar when in Raw mode\n show: (editor) => {\n return !!(editor.wysimark && editor.wysimark.isRawMode);\n },\n active: () => false, // Never show as active in the toolbar\n}\n","import { MenuItemData } from \"~/src/shared-overlays\"\n\nimport { expandedBlockItems, compactBlockItems } from \"./block-items\"\nimport { compactDialogItems, expandedDialogItems, smallDialogItems } from \"./dialogItems\"\nimport { compactMarkItems, expandedMarkItems } from \"./mark-items\"\nimport { expandedListItems, compactListItems } from \"./list-items\"\nimport { expandedQuoteItems, compactQuoteItems } from \"./quote-items\"\nimport { rawModeItem, visualModeItem } from \"./raw-mode-item\"\n\n/**\n * A collection of `Item` objects that describe either\n *\n * - A Button in the toolbar\n * - A Menu Item in a drop down of the toolbar\n *\n * An `Item` is described in the same way whether it is a button or a menu\n * item making them interchangeable.\n */\n\nexport const largeItems: MenuItemData[] = [\n ...expandedBlockItems,\n \"divider\",\n ...expandedListItems,\n \"divider\",\n ...expandedMarkItems,\n \"divider\",\n ...expandedDialogItems,\n \"divider\",\n ...expandedQuoteItems,\n \"divider\",\n rawModeItem,\n visualModeItem,\n]\n\nexport const mediumItems: MenuItemData[] = [\n ...compactBlockItems,\n \"divider\",\n ...expandedListItems,\n \"divider\",\n ...expandedMarkItems,\n \"divider\",\n ...compactDialogItems,\n \"divider\",\n ...expandedQuoteItems,\n \"divider\",\n rawModeItem,\n visualModeItem,\n]\n\nexport const smallItems: MenuItemData[] = [\n ...compactBlockItems,\n \"divider\",\n ...compactListItems,\n \"divider\",\n ...compactMarkItems,\n \"divider\",\n ...smallDialogItems,\n \"divider\",\n ...compactQuoteItems,\n \"divider\",\n rawModeItem,\n visualModeItem,\n]\n\nexport const initialItems: MenuItemData[] = smallItems\n\nexport const items = mediumItems\n\nexport const itemSets: MenuItemData[][] = [largeItems, mediumItems, smallItems]\n","import { clsx } from \"clsx\"\nimport { MouseEvent, useCallback, useRef } from \"react\"\nimport { ReactEditor, useSlate, useSlateStatic } from \"slate-react\"\n\nimport { formatHotkey, Menu, MenuItemData } from \"~/src/shared-overlays\"\nimport { useLayer } from \"~/src/use-layer\"\nimport { useTooltip } from \"~/src/use-tooltip\"\nimport { r } from \"~/src/utils/translations\"\n\nimport * as Icon from \"../../icons\"\nimport { $ToolbarButton } from \"../../styles\"\n\nexport function ToolbarButton({\n item,\n}: {\n item: Exclude<MenuItemData, \"divider\">\n}) {\n const staticEditor = useSlateStatic()\n const editor = useSlate() // エディタの状態変更を検知\n const isActive = item.active ? item.active(editor) : false\n const ref = useRef<HTMLDivElement>(null)\n const tooltip = useTooltip({\n title: item.title,\n hotkey: () => (item.hotkey ? formatHotkey(item.hotkey) : undefined),\n })\n const menuLayer = useLayer(\"menu\")\n\n const openMenu = useCallback(() => {\n const dest = ref.current\n const items = item.children\n const Component = item.Component\n if (!dest) return\n if (items) {\n menuLayer.open(() => (\n <Menu dest={dest} items={items} close={menuLayer.close} />\n ))\n } else if (Component) {\n menuLayer.open(() => <Component dest={dest} close={menuLayer.close} />)\n }\n }, [item])\n\n const onClick = useCallback(() => {\n if (item.action) {\n item.action(staticEditor)\n ReactEditor.focus(staticEditor)\n return\n }\n if (menuLayer.layer) {\n menuLayer.close()\n } else {\n openMenu()\n }\n }, [menuLayer.layer, item])\n\n /**\n * On hover\n */\n const onMouseEnter = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n tooltip.onMouseEnter(e)\n /**\n * If any `menu` is already open, then we open up the currently hovered\n * `menu` automatically. This replicates behavior in menus in windowing\n * systems.\n */\n if (menuLayer.layer) openMenu()\n },\n [menuLayer.layer]\n )\n\n return (\n <$ToolbarButton\n data-item-type=\"button\"\n ref={ref}\n onMouseEnter={onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n onClick={onClick}\n className={clsx({\n \"--active\": isActive && !r(item?.title)?.includes('Depth'),\n \"--more\": item.more,\n \"--disabled\": !isActive && r(item?.title)?.includes('Depth')\n })}\n >\n <item.icon />\n {item.more ? <Icon.More /> : null}\n </$ToolbarButton>\n )\n}\n","import { createPlugin, TypedPlugin } from \"~/src/sink\"\n\nimport { renderEditable } from \"./render-editable\"\n\nexport type ToolbarEditor = {\n toolbar: {\n height?: string | number\n minHeight?: string | number\n maxHeight?: string | number\n showUploadButtons?: boolean\n }\n}\n\nexport type ToolbarOptions = {\n toolbar: {\n height?: string | number\n minHeight?: string | number\n maxHeight?: string | number\n showUploadButtons?: boolean\n }\n}\n\nexport type ToolbarPluginCustomTypes = {\n Name: \"toolbar\"\n Editor: ToolbarEditor\n Options: ToolbarOptions\n}\n\nexport const ToolbarPlugin = createPlugin<ToolbarPluginCustomTypes>(\n (editor, options) => {\n editor.toolbar = {\n height: options.toolbar?.height,\n minHeight: options.toolbar?.minHeight,\n maxHeight: options.toolbar?.maxHeight,\n showUploadButtons: options.toolbar?.showUploadButtons ?? true,\n }\n return {\n name: \"toolbar\",\n editor: {},\n renderEditable,\n editableProps: {},\n }\n }\n) as TypedPlugin<ToolbarPluginCustomTypes>\n","import { Editor, Element, Node, Path, Transforms } from \"slate\"\n\nimport { createPlugin, TypedPlugin } from \"~/src/sink\"\n\ntype TrailingBlockPluginCustomType = {\n Name: \"trailing-block\"\n Editor: { allowTrailingBlock: true }\n}\n\nexport const TrailingBlockPlugin = createPlugin<TrailingBlockPluginCustomType>(\n (editor) => {\n editor.allowTrailingBlock = true\n return {\n name: \"trailing-block\",\n editor: {\n normalizeNode: (entry) => {\n if (!Editor.isEditor(entry[0])) return false\n const lastPath = [editor.children.length - 1]\n /**\n * We expect the last node of the Editor to be an `Element` because\n * the children of an `Editor` are `Element` objects.\n */\n const lastElement = Node.child(\n editor,\n editor.children.length - 1\n ) as Element\n /**\n * We need to add a trailing block when it is not easy for us to\n * start typing at the end of the document. This happens in these\n * conditions:\n *\n * - The last Element is a `void` block that we can't type into\n * - The last Element is an Element that contains child elements\n * like a `table` or a nested `list`.\n */\n if (\n Editor.hasBlocks(editor, lastElement) ||\n Editor.isVoid(editor, lastElement)\n ) {\n Transforms.insertNodes(\n editor,\n { type: \"paragraph\", children: [{ text: \"\" }] },\n {\n at: Path.next(lastPath),\n }\n )\n }\n return true\n },\n },\n }\n }\n) as TypedPlugin<TrailingBlockPluginCustomType>\n","import { Editor, Transforms } from \"slate\"\n\nimport { curryOne } from \"~/src/sink\"\n\nimport { parse, escapeUrlSlashes } from \"../../convert\"\n\nfunction pasteMarkdown(editor: Editor, markdown: string) {\n // Escape forward slashes in URLs before parsing\n const escapedMarkdown = escapeUrlSlashes(markdown);\n const fragment = parse(escapedMarkdown)\n Transforms.insertNodes(editor, fragment)\n}\n\nexport function createPasteMarkdownMethods(editor: Editor) {\n return {\n pasteMarkdown: curryOne(pasteMarkdown, editor),\n }\n}\n","import { createPlugin, stopEvent, TypedPlugin } from \"~/src/sink\"\n\nimport { createPasteMarkdownMethods } from \"./methods\"\n\ntype PasteMarkdownMethods = ReturnType<typeof createPasteMarkdownMethods>\n\nexport type PasteMarkdownEditor = {\n pasteMarkdown: PasteMarkdownMethods\n}\n\nexport type PasteMarkdownPluginCustomTypes = {\n Name: \"paste-markdown\"\n Editor: PasteMarkdownEditor\n}\n\nexport const PasteMarkdownPlugin = createPlugin<PasteMarkdownPluginCustomTypes>(\n (editor) => {\n editor.pasteMarkdown = createPasteMarkdownMethods(editor)\n return {\n name: \"paste-markdown\",\n editor: {},\n editableProps: {\n onPaste(e) {\n const { types } = e.clipboardData\n if (types.length !== 1 || types[0] !== \"text/plain\") {\n return false\n }\n const markdown = e.clipboardData.getData(\"text/plain\")\n editor.pasteMarkdown.pasteMarkdown(markdown)\n stopEvent(e)\n return true\n },\n },\n }\n }\n) as TypedPlugin<PasteMarkdownPluginCustomTypes>\n","import { RenderPlaceholderProps } from \"slate-react\"\n\nimport { createPlugin, TypedPlugin } from \"~/src/sink\"\n\nexport type PlaceholderEditor = {\n placeholder: {}\n}\n\nexport type PlaceholderPluginCustomTypes = {\n Name: \"placeholder\"\n Editor: PlaceholderEditor\n}\n\n/**\n * To have the placeholder work properly, it cannot have `width: 100%` and\n * `max-width: 100%` set or it creates horizontal scrollbars.\n *\n * The default `renderPlaceholder` adds these styles so we override them.\n */\nfunction renderPlaceholder(props: RenderPlaceholderProps) {\n const nextAttributes: RenderPlaceholderProps[\"attributes\"] = {\n ...props.attributes,\n style: {\n ...props.attributes.style,\n width: undefined,\n maxWidth: undefined,\n },\n }\n return <span {...nextAttributes}>{props.children}</span>\n}\n\nexport const PlaceholderPlugin = createPlugin<PlaceholderPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.placeholder = {}\n return createPolicy({\n name: \"placeholder\",\n editableProps: {\n renderPlaceholder,\n },\n })\n }\n) as TypedPlugin<PlaceholderPluginCustomTypes>\n","import { BaseEditor, BaseText } from \"slate\"\nimport { HistoryEditor } from \"slate-history\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { AnchorPlugin } from \"~/src/anchor-plugin\"\nimport { AtomicDeletePlugin } from \"~/src/atomic-delete-plugin\"\nimport { ImagePlugin } from \"~/src/image-plugin\"\nimport { BlockQuotePlugin } from \"~/src/block-quote-plugin\"\nimport { CodeBlockPlugin } from \"~/src/code-block-plugin\"\nimport { HtmlBlockPlugin } from \"~/src/html-block-plugin\"\nimport { CollapsibleParagraphPlugin } from \"~/src/collapsible-paragraph-plugin\"\nimport { ConvertElementPlugin } from \"~/src/convert-element-plugin\"\nimport { HeadingPlugin } from \"~/src/heading-plugin\"\nimport { HorizontalRulePlugin } from \"~/src/horizontal-rule-plugin\"\nimport { InlineCodePlugin } from \"~/src/inline-code-plugin\"\nimport { ListPlugin } from \"~/src/list-plugin\"\nimport { MarksPlugin } from \"~/src/marks-plugin\"\nimport { NormalizeAfterDeletePlugin } from \"~/src/normalize-after-delete-plugin\"\nimport { ExtractCustomTypes } from \"~/src/sink\"\nimport { TablePlugin } from \"~/src/table-plugin\"\nimport { ThemePlugin } from \"~/src/theme-plugin\"\nimport { ToolbarPlugin } from \"~/src/toolbar-plugin\"\nimport { TrailingBlockPlugin } from \"~/src/trailing-block-plugin\"\nimport { PasteMarkdownPlugin } from \"../paste-markdown-plugin\"\nimport { PlaceholderPlugin } from \"../placeholder-plugin\"\nimport { WysimarkEditor } from \"./types\"\n\n/**\n * Default plugins array (all built-in plugins in correct order)\n */\nexport const defaultPlugins = [\n PasteMarkdownPlugin,\n ConvertElementPlugin,\n AnchorPlugin,\n HeadingPlugin,\n MarksPlugin,\n InlineCodePlugin,\n BlockQuotePlugin,\n CodeBlockPlugin,\n HtmlBlockPlugin,\n TablePlugin,\n HorizontalRulePlugin,\n TrailingBlockPlugin,\n ListPlugin,\n AtomicDeletePlugin,\n NormalizeAfterDeletePlugin,\n CollapsibleParagraphPlugin,\n ThemePlugin,\n ToolbarPlugin,\n ImagePlugin,\n PlaceholderPlugin,\n]\n\n/**\n * @deprecated Use defaultPlugins instead\n */\nexport const plugins = defaultPlugins\n\nexport type PluginTypes = ExtractCustomTypes<typeof plugins>\n\ntype CustomEditor = PluginTypes[\"Editor\"]\ntype CustomElement = PluginTypes[\"Element\"]\ntype CustomText = PluginTypes[\"Text\"]\n\nexport type OptionsType = PluginTypes[\"Options\"]\nexport type Element = CustomElement\nexport type Text = CustomText\n\ndeclare module \"slate\" {\n interface CustomTypes {\n Editor: BaseEditor &\n ReactEditor &\n HistoryEditor &\n CustomEditor &\n WysimarkEditor\n Element: CustomElement\n Text: BaseText & CustomText\n }\n}\n","import { createSink } from \"~/src/sink\"\n\nimport { defaultPlugins, PluginTypes } from \"./plugins\"\n\nconst { withSink, SinkEditable } = createSink<PluginTypes>(defaultPlugins)\n\nexport { SinkEditable, withSink }\n","import { useState } from \"react\"\nimport { createEditor, Editor, Transforms } from \"slate\"\nimport { withHistory } from \"slate-history\"\nimport { ReactEditor, withReact } from \"slate-react\"\n\nimport { parse, serialize, escapeUrlSlashes } from \"../convert\"\nimport { Element } from \"./plugins\"\nimport { withSink } from \"./SinkEditable\"\nimport { WysimarkEditor } from \"./types\"\n\nexport type UseEditorOptions = {\n authToken?: string\n height?: string | number\n minHeight?: string | number\n maxHeight?: string | number\n /**\n * Disable raw Markdown editing mode.\n * When true, the raw mode toggle button will be hidden from the toolbar.\n * Defaults to true (raw mode is disabled by default).\n *\n * @example\n * ```tsx\n * const editor = useEditor({\n * disableRawMode: false // Enable raw mode\n * })\n * ```\n */\n disableRawMode?: boolean\n /**\n * Disable task list (checklist) functionality.\n * When true, the task list button will be hidden from the toolbar\n * and task list creation will be disabled.\n *\n * @example\n * ```tsx\n * const editor = useEditor({\n * disableTaskList: true\n * })\n * ```\n */\n disableTaskList?: boolean\n /**\n * Disable code block functionality.\n * When true, the code block button will be hidden from the toolbar.\n *\n * @example\n * ```tsx\n * const editor = useEditor({\n * disableCodeBlock: true\n * })\n * ```\n */\n disableCodeBlock?: boolean\n /**\n * Disable highlight mark functionality.\n * When true, the highlight button will be hidden from the toolbar.\n * Highlight is serialized as <mark>text</mark> in markdown.\n * Defaults to true (highlight is disabled by default).\n *\n * @example\n * ```tsx\n * const editor = useEditor({\n * disableHighlight: false // Enable highlight\n * })\n * ```\n */\n disableHighlight?: boolean\n}\n\nexport function useEditor({\n authToken,\n height,\n minHeight,\n maxHeight,\n disableRawMode,\n disableTaskList,\n disableCodeBlock,\n disableHighlight,\n}: UseEditorOptions = {}): Editor & ReactEditor & WysimarkEditor {\n const [editor] = useState(() => {\n const editor = createEditor()\n const nextEditor = withSink(withReact(withHistory(editor)), {\n toolbar: {\n height,\n minHeight,\n maxHeight,\n /**\n * If `authToken` is provided then show upload buttons.\n */\n showUploadButtons: !!authToken,\n },\n image: {}\n })\n nextEditor.convertElement.addConvertElementType(\"paragraph\")\n editor.wysimark = {\n // Disable raw mode (defaults to true)\n disableRawMode: disableRawMode ?? true,\n // Disable task list if specified\n disableTaskList,\n // Disable code block if specified\n disableCodeBlock,\n // Disable highlight (defaults to true)\n disableHighlight: disableHighlight ?? true,\n }\n editor.getMarkdown = () => {\n return serialize(editor.children as Element[])\n }\n editor.setMarkdown = (markdown: string) => {\n // Escape forward slashes in URLs before parsing\n const escapedMarkdown = escapeUrlSlashes(markdown);\n const documentValue = parse(escapedMarkdown)\n editor.children = documentValue\n editor.selection = null\n Transforms.select(editor, Editor.start(editor, [0]))\n }\n return nextEditor\n })\n\n return editor\n}\n"],"mappings":"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","names":["useCallback","useRef","useState","throttle","useCallback","useRef","useState","Editor","Transforms","ReactEditor","Slate","SlateText","SlateText","s","SlateText","SlateText","SlateText","Element","Element","SlateText","SlateText","SlateText","indent","key","key","renderElement","jsx","withSink","Element","Editor","Element","Editor","jsx","Element","Element","Editor","Editor","Editor","Editor","Editor","Editor","SlateElement","Range","Range","SlateElement","Editor","isHotkey","isHotkey","Editor","Transforms","Editor","Editor","Transforms","Editor","Element","Path","Transforms","Element","Editor","Transforms","Path","Editor","Transforms","Editor","Transforms","Editor","Transforms","Editor","Node","Transforms","Transforms","Node","Editor","Editor","Range","Text","Transforms","Transforms","Transforms","Element","Transforms","useEffect","useRef","jsx","layers","styled","styled","useCallback","useSlateStatic","styled","jsx","key","useRef","useSlateStatic","key","useEffect","useState","counter","useEffect","styled","styled","styled","styled","styled","styled","styled","styled","styled","styled","styled","ReactEditor","jsx","jsxs","ReactEditor","Fragment","jsx","jsxs","useSlateStatic","useRef","dest","useCallback","styled","jsx","jsxs","styled","jsx","styled","jsx","useCallback","styled","useCallback","useRef","useState","Node","useSlateStatic","styled","jsx","jsxs","styled","destAnchor","destStartEdge","useSlateStatic","useState","Node","useRef","useCallback","href","text","title","jsx","jsx","jsxs","$AnchorDialog","styled","parseUrl","useSlateStatic","destAnchor","destStartEdge","removeLink","useCallback","jsx","jsxs","useRef","useEffect","jsx","Editor","Transforms","Element","Path","Path","Element","Editor","Transforms","Transforms","ReactEditor","Editor","Transforms","ReactEditor","Transforms","Editor","ReactEditor","normalizeNode","useSlateStatic","styled","clsx","useState","useSelected","styled","clsx","useCallback","Transforms","ReactEditor","useSlateStatic","useEffect","useEffect","styled","ReactEditor","Fragment","jsx","jsxs","ReactEditor","useSlateStatic","useCallback","e","size","Transforms","clsx","styled","jsxs","styled","styled","clsx","useCallback","Transforms","ReactEditor","useSlateStatic","jsx","useSlateStatic","useCallback","ReactEditor","Transforms","clsx","jsx","useCallback","useSlateStatic","jsx","jsxs","jsxs","jsx","Editor","Transforms","ReactEditor","ReactEditor","Editor","Transforms","jsx","useSlateStatic","useCallback","useCallback","useSlateStatic","Editor","Text","Transforms","ReactEditor","ReactEditor","Editor","Transforms","Text","jsx","useSlateStatic","useCallback","jsx","jsxs","jsx","jsxs","jsx","jsxs","useSelected","useState","clsx","jsx","jsxs","useSlateStatic","useSlateStatic","styled","jsx","jsxs","useSlateStatic","jsx","createOnDrop","ReactEditor","Transforms","normalizeNode","Editor","Element","Transforms","styled","jsx","Element","Transforms","Editor","Editor","Element","Transforms","Element","Node","node","offset","Element","Transforms","Element","Transforms","Element","Node","Transforms","normalizeNode","useCallback","useState","useSelected","useSlateStatic","styled","jsx","jsxs","useSlateStatic","useSelected","useState","useCallback","useSelected","jsx","useSelected","jsx","renderElement","jsx","Editor","Transforms","normalizeNode","Element","renderElement","Transforms","styled","jsx","jsxs","jsx","Transforms","Editor","Element","Element","Transforms","Element","Transforms","Element","Transforms","Element","Transforms","normalizeNode","Element","clsx","useSelected","styled","Node","jsx","useSelected","clsx","jsx","insertBreak","Editor","normalizeNode","Editor","Element","Node","Range","Transforms","Editor","Node","Element","Transforms","isCollapsed","Range","Editor","Path","Range","Transforms","Range","Editor","Path","Transforms","Editor","Editor","styled","jsx","useSelected","styled","jsx","jsxs","useSelected","jsx","styled","jsx","jsxs","Editor","Path","MAX_DEPTH","Editor","Transforms","insertBreak","Editor","Transforms","Editor","Editor","Transforms","Transforms","insertBreak","Element","Transforms","Element","Transforms","normalizeNode","clsx","useEffect","ReactEditor","useSlateStatic","styled","styled","jsx","useSlateStatic","useEffect","ReactEditor","clsx","useCallback","useSlateStatic","jsx","jsxs","jsx","jsxs","useSlateStatic","useCallback","jsx","jsxs","jsx","renderElement","normalizeNode","Path","Editor","renderElement","clsx","Editor","Point","Range","Editor","Text","Transforms","key","Editor","Point","Range","styled","jsx","removeMarks","Range","Point","Editor","clsx","Editor","Point","Editor","Point","Element","Editor","Path","Transforms","Editor","Path","Editor","Path","range","Editor","Path","Transforms","Transforms","Editor","Transforms","t","Editor","Transforms","Transforms","t","Transforms","Editor","Element","Path","Transforms","createRow","insertRootElement","Element","Editor","Transforms","Path","Path","t","Path","ReactEditor","t","Editor","Transforms","Transforms","t","t","Editor","Transforms","rowIndex","Editor","Transforms","t","Editor","Transforms","Transforms","t","Transforms","Path","Transforms","t","Path","Transforms","t","Transforms","Transforms","Editor","Transforms","useEffect","ReactEditor","useSelected","useSlateStatic","styled","styled","styled","createContext","jsx","useSlateStatic","useSelected","useEffect","ReactEditor","useContext","useSelected","useCallback","useRef","useState","useSlateStatic","jsx","Fragment","jsx","jsxs","useSlateStatic","useRef","useState","useCallback","useState","useSlateStatic","Fragment","jsx","jsxs","useSlateStatic","useState","styled","jsx","jsx","jsxs","useContext","useSelected","jsx","jsx","jsx","renderElement","Element","renderElement","css","css","Fragment","jsx","jsxs","Editable","clsx","useCallback","useRef","Editor","Transforms","ReactEditor","useSlateStatic","clsx","useCallback","useRef","useState","ReactEditor","useSlateStatic","styled","styled","Fragment","jsx","jsxs","createRange","useState","useSlateStatic","useRef","dest","useCallback","createTable","ReactEditor","clsx","throttle","useEffect","useRef","useState","useSlateStatic","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","Table","jsxs","CodeBlock","jsx","jsxs","jsx","useState","useRef","useEffect","useSlateStatic","styled","styled","Fragment","jsx","jsxs","useSlateStatic","useRef","useState","useEffect","dest","isHotkey","useCallback","useMemo","useRef","useState","Editor","Range","ReactEditor","useSlateStatic","styled","Fragment","jsx","jsxs","isHotkey","AnchorDialog","useSlateStatic","useRef","dest","useMemo","Range","Editor","useState","insertLink","ReactEditor","useCallback","AnchorDialog","Table","Editor","Editor","Editor","Transforms","CodeBlock","Editor","Transforms","clsx","useCallback","useRef","ReactEditor","useSlate","useSlateStatic","jsx","jsxs","useSlateStatic","useSlate","useRef","useCallback","ReactEditor","clsx","jsx","useSlateStatic","useRef","useState","useEffect","throttle","jsx","jsxs","Editable","useRef","useSlateStatic","useCallback","Transforms","Editor","ReactEditor","clsx","Editor","Node","Path","Transforms","Editor","Node","Transforms","Path","Transforms","Transforms","jsx","SinkEditable","useState","Editor","Transforms","useState","editor","Transforms","Editor","jsx","jsxs","jsx","Editable","useState","useRef","useCallback","throttle","Transforms","Editor","ReactEditor","jsxs","Slate","SinkEditable","jsx","useState","useRef","markdown","useCallback","jsx","Editable"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/entry/index.tsx","../src/convert/parse/index.ts","../node_modules/devlop/lib/default.js","../node_modules/mdast-util-gfm-table/lib/index.js","../src/convert/parse/custom-gfm.ts","../src/convert/utils.ts","../src/convert/parse/parse-blockquote.ts","../src/convert/parse/parse-code-block.ts","../src/convert/parse/parse-footnote-definition.ts","../src/convert/parse/parse-phrasing-content/normalize-segments.ts","../src/convert/parse/parse-phrasing-content/normalize-segment.ts","../src/convert/serialize/serialize-line/utils/is-utils.ts","../src/convert/serialize/serialize-line/utils/mark-utils/mark-convert-utils.ts","../src/convert/serialize/serialize-line/utils/mark-utils/mark-get-utils.ts","../src/convert/serialize/serialize-line/utils/mark-utils/mark-order-utils.ts","../src/convert/serialize/serialize-line/utils/text-utils.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-generic-image.ts","../src/convert/parseUrl.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-utils.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-portive-image.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/parse-uncommon-mark-image.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/image-parsers.ts","../src/convert/parse/parse-phrasing-content/parse-inline-image/index.ts","../src/convert/parse/parse-phrasing-content/parse-phrasing-content.ts","../src/convert/parse/parse-heading.ts","../src/convert/parse/parse-html.ts","../src/convert/parse/parse-list/parse-list-item-child.ts","../src/convert/parse/parse-list/parse-list-item.ts","../src/convert/parse/parse-list/parse-list.ts","../src/convert/parse/parse-paragraph.ts","../src/convert/parse/parse-table.ts","../src/convert/parse/parse-thematic-break.ts","../src/convert/parse/parse-content.ts","../src/convert/parse/transform-inline-links.ts","../src/convert/serialize/normalize/normalizeElementListDepths.ts","../src/convert/serialize/serialize-code-block/serialize-code-line.ts","../src/convert/serialize/serialize-code-block/index.ts","../src/convert/serialize/serialize-image-shared/serialize-generic-image-url.ts","../src/convert/serialize/serialize-image-shared/serialize-portive-image-url.ts","../src/convert/serialize/serialize-image-shared/serialize-uncommonmark-image-url.ts","../src/convert/serialize/serialize-image-shared/index.ts","../src/convert/serialize/serialize-image-block/index.ts","../src/convert/serialize/serialize-line/serialize-line.ts","../src/convert/serialize/serialize-line/diff-marks/find-marks-to-add.ts","../src/convert/serialize/serialize-line/diff-marks/find-marks-to-remove.ts","../src/convert/serialize/serialize-line/diff-marks/index.ts","../src/convert/serialize/serialize-line/normalize-line/index.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/merge-adjacent-spaces.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/move-spaces-out-of-anchors.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/must-have-one-text-child.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/slice-spaces-at-node-boundaries.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/trim-spaces-at-end-of-line.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/trim-spaces-at-start-of-line.ts","../src/convert/serialize/serialize-line/normalize-line/normalizers/index.ts","../src/convert/serialize/serialize-line/normalize-line/run-normalizers-on-node.ts","../src/convert/serialize/serialize-line/normalize-line/normalize-nodes.ts","../src/convert/serialize/serialize-line/segment/serialize-segment.ts","../src/convert/serialize/serialize-line/segment/serialize-code-text.ts","../src/convert/serialize/serialize-line/segment/serialize-anchor.ts","../src/convert/serialize/serialize-line/segment/serialize-non-code-text.ts","../src/convert/serialize/serialize-table/index.ts","../src/convert/serialize/serialize-element.ts","../src/convert/serialize/serialize-elements.ts","../src/convert/serialize/index.ts","../src/utils/translations.ts","../src/sink/create-plugin/index.ts","../src/sink/editable/index.tsx","../src/sink/editable/utils.ts","../src/sink/editable/create-decorate.ts","../src/sink/editable/create-editable.tsx","../src/sink/editable/create-handler.ts","../src/sink/editable/create-render-element.ts","../src/sink/editable/create-render-leaf.ts","../src/sink/editable/create-render-placeholder.tsx","../src/sink/editable/styles.tsx","../src/sink/editor/create-boolean-action.ts","../src/sink/editor/create-void-action.ts","../src/sink/editor/index.ts","../src/sink/create-sink/index.tsx","../src/sink/is-debug.ts","../src/sink/utils/core-utils/better-at.ts","../src/sink/utils/core-utils/curry.ts","../src/sink/utils/core-utils/is-mac.ts","../src/sink/utils/core-utils/stop-event.ts","../src/sink/utils/find-utils/find-element-up.ts","../src/sink/utils/standardize-utils/standardize-node-matcher.ts","../src/sink/utils/icon-utils/tabler-icon.tsx","../src/sink/utils/is-utils/is-collapsed.ts","../src/sink/utils/is-utils/is-element-type.ts","../src/sink/utils/is-utils/is-end-of-element.ts","../src/sink/utils/is-utils/is-in-empty-element.ts","../src/sink/utils/is-utils/is-start-of-element.ts","../src/sink/utils/key-utils/create-autocomplete-space-handler.tsx","../src/sink/utils/key-utils/is-better-hotkey.ts","../src/sink/utils/key-utils/create-hotkey-handler.ts","../src/sink/utils/normalize-utils/force-normalize-path.ts","../src/sink/utils/normalize-utils/normalize-siblings.ts","../src/sink/utils/select-utils/index.ts","../src/sink/utils/standardize-utils/target-element.ts","../src/sink/utils/transform-utils/insert-root-element.ts","../src/sink/utils/transform-utils/rewrap-element.ts","../src/sink/utils/transform-utils/set-nodes-dynamic.ts","../src/anchor-plugin/editable/on-paste.tsx","../src/anchor-plugin/methods/editLink.ts","../src/anchor-plugin/methods/insertLink.ts","../src/anchor-plugin/methods/removeLink.ts","../src/anchor-plugin/methods/index.ts","../src/anchor-plugin/normalize-node/index.ts","../src/anchor-plugin/render-element/anchor.tsx","../src/use-layer/layers.tsx","../src/use-layer/portal.tsx","../src/use-layer/use-layer.tsx","../src/anchor-plugin/styles.tsx","../src/anchor-plugin/render-element/AnchorDialog.tsx","../src/shared-overlays/components/CloseMask/index.tsx","../src/shared-overlays/styles/$CloseMask.tsx","../src/shared-overlays/components/Menu/formatHotkey.ts","../src/shared-overlays/components/Menu/Menu.tsx","../src/use-reposition/get-methods/get-fixed-rect.ts","../src/use-reposition/get-methods/get-absolute-rect.ts","../src/use-reposition/get-methods/get-fixed-viewport.ts","../src/use-reposition/get-methods/get-absolute-viewport.ts","../node_modules/just-map-values/index.mjs","../src/use-reposition/utils.ts","../src/use-reposition/hooks/use-reposition.tsx","../src/use-reposition/hooks/use-throttled-refresh.ts","../src/use-reposition/hooks/use-absolute-reposition.tsx","../src/use-reposition/position-methods/index.ts","../src/toolbar-plugin/styles/anchor-dialog-styles.ts","../src/shared-overlays/styles/$Panel.ts","../src/toolbar-plugin/styles/layout-styles.ts","../src/shared-layout/index.ts","../src/toolbar-plugin/styles/menu-styles.ts","../src/toolbar-plugin/styles/toolbar-styles.ts","../src/shared-overlays/components/Menu/MenuItem.tsx","../src/use-tooltip/index.tsx","../src/use-tooltip/tooltip.tsx","../src/use-tooltip/triangle.tsx","../src/anchor-plugin/render-element/AnchorEditDialog.tsx","../src/shared-styles/index.ts","../src/toolbar-plugin/components/dialog/DraggableHeader.tsx","../src/anchor-plugin/render-element/icons.tsx","../src/anchor-plugin/index.tsx","../src/atomic-delete-plugin/index.ts","../src/atomic-delete-plugin/is-safe-delete.ts","../src/image-plugin/index.tsx","../src/image-plugin/methods/index.ts","../src/image-plugin/normalize-node/index.ts","../src/image-plugin/render-element/image-block.tsx","../src/image-plugin/styles/image-block-styles.tsx","../src/image-plugin/render-element/image-with-controls/index.tsx","../src/image-plugin/styles/image-with-controls-styles/image-with-controls-styles.tsx","../src/image-plugin/render-element/image-with-controls/image-resize-controls/image-resize-control.tsx","../src/use-reposition/hooks/use-resize-browser.tsx","../src/image-plugin/styles/image-with-controls-styles/image-resize-handle-styles.tsx","../src/image-plugin/utils/min-max.ts","../src/image-plugin/utils/resize-utils.ts","../src/image-plugin/styles/image-with-controls-styles/image-size-status-styles.tsx","../src/image-plugin/render-element/image-with-controls/image-size-status/image-size-status.tsx","../src/image-plugin/styles/image-with-controls-styles/image-toolbar-styles.tsx","../src/image-plugin/styles/image-with-controls-styles/image-buttons-styles.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-preset-buttons/image-preset-button.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-preset-buttons/image-preset-button-group.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/block-image-type-button.tsx","../src/image-plugin/render-element/icons.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/convert-to-inline-image.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/inline-image-type-button.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/convert-to-block-image.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-type-buttons/image-type-button-group.tsx","../src/image-plugin/render-element/image-with-controls/image-toolbar/image-toolbar.tsx","../src/image-plugin/render-element/image-inline.tsx","../src/image-plugin/styles/image-inline-styles.tsx","../src/image-plugin/render-element/index.tsx","../src/block-quote-plugin/index.tsx","../src/block-quote-plugin/styles.tsx","../src/code-block-plugin/index.tsx","../src/code-block-plugin/decorate.tsx","../src/code-block-plugin/methods/createCodeBlock.ts","../src/code-block-plugin/methods/setCodeBlockLanguage.ts","../src/code-block-plugin/methods/index.ts","../src/code-block-plugin/prism-theme.ts","../src/code-block-plugin/types.tsx","../src/code-block-plugin/normalizeNode.tsx","../src/code-block-plugin/render-element/CodeBlock.tsx","../src/code-block-plugin/icons/ChevronDownIcon.tsx","../src/code-block-plugin/styles.ts","../src/code-block-plugin/render-element/CodeBlockLine.tsx","../src/code-block-plugin/render-element/index.tsx","../src/html-block-plugin/index.tsx","../src/html-block-plugin/styles.ts","../src/html-block-plugin/render-element.tsx","../src/collapsible-paragraph-plugin/index.tsx","../src/collapsible-paragraph-plugin/normalize-node/index.ts","../src/collapsible-paragraph-plugin/normalize-node/normalize-sibling-paragraphs.ts","../src/collapsible-paragraph-plugin/normalize-node/normalize-sibling-walls.ts","../src/collapsible-paragraph-plugin/render-element/paragraph.tsx","../src/collapsible-paragraph-plugin/render-element/styles.ts","../src/collapsible-paragraph-plugin/render-element/utils.ts","../src/convert-element-plugin/methods/add-convert-element-type.ts","../src/convert-element-plugin/methods/convert-elements.ts","../src/convert-element-plugin/methods/is-convert-element.ts","../src/convert-element-plugin/methods/index.ts","../src/convert-element-plugin/index.tsx","../src/heading-plugin/insert-break.ts","../src/heading-plugin/methods/index.ts","../src/heading-plugin/styles.ts","../src/heading-plugin/index.tsx","../src/horizontal-rule-plugin/horizontal-rule.tsx","../src/horizontal-rule-plugin/styles.tsx","../src/horizontal-rule-plugin/methods/index.ts","../src/horizontal-rule-plugin/index.tsx","../src/inline-code-plugin/styles.ts","../src/inline-code-plugin/index.tsx","../src/list-plugin/index.tsx","../src/list-plugin/methods/convert-list-item.ts","../src/list-plugin/methods/depth.ts","../src/list-plugin/methods/indent.ts","../src/list-plugin/methods/insert-break.ts","../src/list-plugin/methods/outdent.ts","../src/list-plugin/methods/toggleTaskListItem.ts","../src/list-plugin/methods/index.ts","../src/list-plugin/normalize-node/normalize-ordered-first-at-depth.ts","../src/list-plugin/normalize-node/index.ts","../src/list-plugin/render-element/ordered-list-item.tsx","../src/list-plugin/render-element/styles.ts","../src/list-plugin/render-element/task-list-item.tsx","../src/list-plugin/render-element/list-icons.tsx","../src/list-plugin/render-element/unordered-list-item.tsx","../src/list-plugin/render-element/index.tsx","../src/marks-plugin/index.tsx","../src/marks-plugin/methods/removeMarks.ts","../src/marks-plugin/methods/toggle-mark.ts","../src/marks-plugin/methods/index.ts","../src/marks-plugin/styles.tsx","../src/normalize-after-delete-plugin/index.tsx","../src/table-plugin/index.tsx","../src/table-plugin/delete-fragment/index.ts","../src/table-plugin/delete-fragment/get-reversed-delete-safe-ranges.ts","../src/table-plugin/methods/index.ts","../src/table-plugin/methods/get-table-info.ts","../src/table-plugin/methods/insert-column.ts","../src/table-plugin/methods/utils.ts","../src/table-plugin/methods/insert-row.ts","../src/table-plugin/methods/insert-table.ts","../src/table-plugin/methods/navigation/select-element.ts","../src/table-plugin/methods/navigation/utils.ts","../src/table-plugin/methods/navigation/index.ts","../src/table-plugin/methods/remove-column.ts","../src/table-plugin/methods/remove-table.ts","../src/table-plugin/methods/remove-row.ts","../src/table-plugin/methods/setTableColumnAlign.ts","../src/table-plugin/methods/tab.ts","../src/table-plugin/normalize/normalize-table.ts","../src/table-plugin/normalize/normalize-table-cell.ts","../src/table-plugin/render-element/table.tsx","../src/table-plugin/render-element/styles/index.ts","../src/table-plugin/render-element/styles/table-menu-styles.ts","../src/table-plugin/render-element/table-context.tsx","../src/table-plugin/render-element/table-cell/index.tsx","../src/table-plugin/render-element/table-cell/column-menu/index.tsx","../src/table-plugin/icons.tsx","../src/table-plugin/render-element/table-cell/row-menu/index.tsx","../src/table-plugin/render-element/table-cell/table-menu/$table-menu.tsx","../src/table-plugin/render-element/table-cell/table-menu/index.tsx","../src/table-plugin/render-element/table-content.tsx","../src/table-plugin/render-element/table-row.tsx","../src/table-plugin/render-element/index.tsx","../src/theme-plugin/index.tsx","../src/theme-plugin/global-styles.ts","../src/toolbar-plugin/render-editable/index.tsx","../src/toolbar-plugin/components/dialog/table-dialog.tsx","../src/toolbar-plugin/styles/table-styles.ts","../src/toolbar-plugin/components/toolbar/toolbar.tsx","../src/toolbar-plugin/icons.tsx","../src/toolbar-plugin/items/block-items.tsx","../src/toolbar-plugin/components/dialog/image-url-dialog.tsx","../src/toolbar-plugin/styles/file-dialog-styles.ts","../src/toolbar-plugin/components/dialog/anchor-dialog.tsx","../src/toolbar-plugin/styles/dialog-shared-styles.ts","../src/toolbar-plugin/items/dialogItems.tsx","../src/toolbar-plugin/items/mark-items.tsx","../src/toolbar-plugin/items/list-items.tsx","../src/toolbar-plugin/items/quote-items.tsx","../src/toolbar-plugin/items/index.tsx","../src/toolbar-plugin/components/toolbar/toolbar-button.tsx","../src/toolbar-plugin/index.tsx","../src/trailing-block-plugin/index.tsx","../src/paste-markdown-plugin/methods/index.ts","../src/paste-markdown-plugin/index.tsx","../src/placeholder-plugin/index.tsx","../src/entry/plugins.ts","../src/entry/SinkEditable.tsx","../src/entry/useEditor.tsx"],"sourcesContent":["// Ensure this package is treated as a client component (e.g. in Next.js App Router)\n'use client'\n\nimport {\n createRef,\n RefObject,\n useCallback,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\"\nimport { createRoot } from \"react-dom/client\"\nimport { Editable, useEditor, OnImageChangeHandler } from './entry/index'\nimport type { UseEditorOptions } from './entry/useEditor'\n\nexport { Editable, useEditor }\nexport type { OnImageChangeHandler, UseEditorOptions }\n\n/**\n * The options passed into the standalone version of Wysimark.\n */\ntype StandaloneOptions = Parameters<typeof useEditor>[0] & {\n onChange?: (markdown: string) => void\n placeholder?: string\n initialMarkdown?: string\n className?: string\n}\n\ntype StandaloneMethods = {\n getMarkdown: () => string\n setMarkdown: (markdown: string) => void\n}\n\n/**\n * The object returned by `createWysimark`\n */\nexport type Wysimark = {\n unmount: () => void\n getMarkdown: () => string\n setMarkdown: (markdown: string) => void\n}\n\nfunction StandaloneEditor({\n standaloneOptions: { onChange, placeholder, className, ...options },\n standaloneMethodsRef,\n}: {\n standaloneOptions: StandaloneOptions\n standaloneMethodsRef: RefObject<StandaloneMethods | null>\n}) {\n const [markdown, setMarkdown] = useState(options.initialMarkdown || \"\")\n const markdownRef = useRef(markdown)\n const editor = useEditor(options)\n\n markdownRef.current = markdown\n\n useImperativeHandle(\n standaloneMethodsRef,\n () => {\n return {\n getMarkdown() {\n return markdownRef.current\n },\n setMarkdown(markdown: string) {\n markdownRef.current = markdown\n setMarkdown(markdown)\n },\n }\n },\n [markdownRef, setMarkdown]\n )\n\n const onChangeEditable = useCallback(\n (markdown: string) => {\n /**\n * Setting the ref is important in the case where there is an attempt to\n * call the `getMarkdown` method from `onChange`. Otherwise the `ref`\n * doesn't get updated until the next render which happens sometime after\n * the `onChange` callback is called.\n */\n markdownRef.current = markdown\n setMarkdown(markdown)\n onChange?.(markdown)\n },\n [editor]\n )\n\n return (\n <Editable\n editor={editor}\n value={markdown}\n className={className || \"\"}\n onChange={onChangeEditable}\n placeholder={placeholder}\n />\n )\n}\n\n/**\n * The primary entry point for the standalone version of Wysimark.\n */\nexport function createWysimark(\n containerElement: HTMLElement,\n options: StandaloneOptions\n): Wysimark {\n const standaloneMethodsRef = createRef<StandaloneMethods | null>()\n\n const root = createRoot(containerElement)\n\n root.render(\n <StandaloneEditor\n standaloneMethodsRef={standaloneMethodsRef}\n standaloneOptions={options}\n />\n )\n\n return {\n unmount() {\n try {\n root.unmount()\n } catch {\n /* ignore */\n }\n },\n getMarkdown() {\n return standaloneMethodsRef.current?.getMarkdown() || \"\"\n // const markdown = editorRef.current?.getMarkdown()\n // return typeof markdown === \"string\"\n // ? markdown\n // : options.initialMarkdown || \"\"\n },\n setMarkdown(markdown: string) {\n standaloneMethodsRef.current?.setMarkdown(markdown)\n },\n }\n}\n","import throttle from \"lodash.throttle\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { Descendant, Editor, Element, Transforms } from \"slate\"\nimport { ReactEditor, RenderLeafProps, Slate } from \"slate-react\"\n\nimport { parse, serialize, escapeUrlSlashes, unescapeUrlSlashes } from \"../convert\"\nimport { t } from \"../utils/translations\"\nimport { SinkEditable } from \"./SinkEditable\"\nimport { useEditor } from \"./useEditor\"\n\nexport type { Element, Text } from \"./plugins\"\n\nexport { useEditor }\n\nfunction renderLeaf({ children, attributes }: RenderLeafProps) {\n return <span {...attributes}>{children}</span>\n}\n\nexport type OnImageChangeHandler = (file: File) => Promise<string>\n\nexport type EditableProps = {\n editor: Editor\n value: string\n onChange: (markdown: string) => void\n throttleInMs?: number\n placeholder?: string\n className?: string\n style?: React.CSSProperties\n onImageChange?: OnImageChangeHandler\n}\n\nexport function Editable({\n editor,\n value,\n onChange,\n throttleInMs = 1000,\n placeholder,\n className,\n style,\n onImageChange,\n}: EditableProps) {\n const [isRawMode, setIsRawMode] = useState(false)\n const [rawText, setRawText] = useState(value)\n const ignoreNextChangeRef = useRef<boolean>(false)\n const initialValueRef = useRef<Descendant[] | undefined>(undefined)\n const prevValueRef = useRef<Descendant[] | undefined>(undefined)\n // Store rawText to use when switching back to visual mode\n const pendingRawTextRef = useRef<string | null>(null)\n\n const onThrottledSlateChange = useCallback(\n throttle(\n () => {\n const markdown = serialize(editor.children as Element[])\n editor.wysimark.prevValue = {\n markdown,\n children: editor.children,\n }\n onChange(markdown)\n },\n throttleInMs,\n { leading: false, trailing: true }\n ),\n [editor, onChange, throttleInMs]\n )\n\n const onSlateChange = useCallback(() => {\n if (prevValueRef.current === editor.children) {\n return\n }\n prevValueRef.current = editor.children\n onThrottledSlateChange()\n }, [onThrottledSlateChange])\n\n // Skip parsing when in raw mode - only update when in visual mode\n if (!isRawMode) {\n // Use pendingRawText if we just switched from raw mode\n const markdownToUse = pendingRawTextRef.current ?? value\n if (pendingRawTextRef.current !== null) {\n pendingRawTextRef.current = null\n }\n\n if (editor.wysimark.prevValue == null || initialValueRef.current == null) {\n ignoreNextChangeRef.current = true\n const valueToProcess = escapeUrlSlashes(markdownToUse);\n const children = parse(valueToProcess)\n editor.children = children\n prevValueRef.current = initialValueRef.current = children\n editor.wysimark.prevValue = {\n markdown: markdownToUse,\n children,\n }\n } else {\n if (markdownToUse !== editor.wysimark.prevValue.markdown) {\n ignoreNextChangeRef.current = true\n const valueToProcess = escapeUrlSlashes(markdownToUse);\n const documentValue = parse(valueToProcess)\n editor.children = documentValue\n editor.selection = null\n Transforms.select(editor, Editor.start(editor, [0]))\n }\n }\n }\n\n const onSinkeEditableMouseDown = useCallback(() => {\n if (navigator.userAgent.toLowerCase().includes(\"firefox\")) {\n ReactEditor.focus(editor)\n }\n }, [editor])\n\n const onBlur = useCallback(() => {\n onThrottledSlateChange.flush()\n }, [onThrottledSlateChange])\n\n // Handle raw text change\n const handleRawTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newText = e.target.value;\n setRawText(newText);\n onChange(newText);\n }\n\n // When switching from visual mode to raw mode\n const updateRawTextFromEditor = useCallback(() => {\n const currentMarkdown = editor.getMarkdown();\n setRawText(currentMarkdown);\n }, [editor]);\n\n // Handle mode toggle\n const handleRawModeToggle = () => {\n if (isRawMode) {\n // Switching from raw mode to visual mode\n // Store rawText to use for initialization\n pendingRawTextRef.current = rawText\n // Reset initialization refs so the editor re-initializes\n editor.wysimark.prevValue = undefined\n initialValueRef.current = undefined\n prevValueRef.current = undefined\n } else {\n // Switching from visual mode to raw mode\n updateRawTextFromEditor();\n }\n setIsRawMode(!isRawMode);\n };\n\n editor.wysimark.onImageChange = onImageChange;\n editor.wysimark.onChange = onChange;\n\n // Check if raw mode is disabled\n const disableRawMode = editor.wysimark.disableRawMode\n\n return (\n <div style={{ position: 'relative' }}>\n {/* Raw mode toggle button - only show if not disabled */}\n {!disableRawMode && (\n <div style={{ position: 'absolute', top: '5px', right: '25px', zIndex: 10 }}>\n <div\n onClick={handleRawModeToggle}\n style={{\n background: 'none',\n border: isRawMode ? '1px solid #4a90e2' : '1px solid transparent',\n cursor: 'pointer',\n padding: '6px',\n borderRadius: '4px',\n backgroundColor: isRawMode ? 'rgba(74, 144, 226, 0.1)' : 'transparent',\n boxShadow: isRawMode ? '0 1px 3px rgba(0, 0, 0, 0.1)' : 'none',\n transition: 'all 0.2s ease-in-out',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center'\n }}\n title={isRawMode ? t(\"switchToVisualEditor\") : t(\"switchToRawMarkdown\")}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n handleRawModeToggle();\n e.preventDefault();\n }\n }}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect\n x=\"3\"\n y=\"3\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n stroke={isRawMode ? \"#4a90e2\" : \"currentColor\"}\n strokeWidth=\"1.5\"\n fill={isRawMode ? \"rgba(74, 144, 226, 0.05)\" : \"transparent\"}\n />\n <path\n d=\"M7 15V9L10 12L13 9V15\"\n stroke={isRawMode ? \"#4a90e2\" : \"currentColor\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M16 9H18V15\"\n stroke={isRawMode ? \"#4a90e2\" : \"currentColor\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M16 12H18\"\n stroke={isRawMode ? \"#4a90e2\" : \"currentColor\"}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n </div>\n )}\n\n {/* Raw mode textarea - always in DOM but hidden when not in raw mode */}\n <div style={{ display: isRawMode ? 'block' : 'none', textAlign: 'center' }}>\n <textarea\n value={unescapeUrlSlashes(rawText).replace(/ /g, '')}\n onChange={handleRawTextChange}\n placeholder={placeholder}\n className={className}\n style={{\n width: 'calc(100% - 60px)',\n margin: '0 auto',\n minHeight: '200px',\n padding: '20px',\n fontFamily: 'monospace',\n fontSize: '14px',\n color: '#333',\n lineHeight: '1.5',\n backgroundColor: '#fff',\n border: '1px solid #ddd',\n borderRadius: '4px',\n ...style\n }}\n />\n </div>\n\n {/* Visual editor - always in DOM but hidden when in raw mode */}\n <div style={{ display: isRawMode ? 'none' : 'block' }}>\n <Slate\n editor={editor}\n initialValue={initialValueRef.current as Descendant[]}\n onChange={onSlateChange}\n >\n <SinkEditable\n renderLeaf={renderLeaf}\n onMouseDown={onSinkeEditableMouseDown}\n onBlur={onBlur}\n placeholder={placeholder}\n className={className}\n style={style}\n />\n </Slate>\n </div>\n </div>\n )\n}\n","import type { Root, TopLevelContent } from \"mdast\"\nimport remarkParse from \"remark-parse\"\nimport { unified } from \"unified\"\n\nimport { Element } from \"../types\"\nimport { customRemarkGfm } from \"./custom-gfm\"\nimport { parseContents } from \"./parse-content\"\nimport { transformInlineLinks } from \"./transform-inline-links\"\n\n// @ts-expect-error - Ignore TypeScript errors for the unified plugin system\nconst parser = unified().use(remarkParse).use(customRemarkGfm())\n\nexport function parseToAst(markdown: string) {\n const ast = parser.parse(markdown) as Root\n /**\n * Takes linkReference and imageReference and turns them into link and image.\n */\n transformInlineLinks(ast)\n return ast\n}\n\n/**\n * Takes a Markdown string as input and returns a remarkParse AST\n */\nexport function parse(markdown: string): Element[] {\n const ast = parseToAst(markdown)\n /**\n * If there is no content, remark returns a root ast with no children (i.e.\n * no paragraphs) but for Slate, we need it to return an empty paragraph.\n *\n * So when this happens, we just generate an empty paragraph and return that\n * s he result.\n */\n if (ast.children.length === 0) {\n return [{ type: \"paragraph\", children: [{ text: \"\" }] }] as Element[]\n }\n\n return parseContents(ast.children as TopLevelContent[])\n}\n","export function deprecate(fn) {\n return fn\n}\n\nexport function equal() {}\n\nexport function ok() {}\n\nexport function unreachable() {}\n","/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('mdast').TableRow} TableRow\n *\n * @typedef {import('markdown-table').Options} MarkdownTableOptions\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').State} State\n * @typedef {import('mdast-util-to-markdown').Info} Info\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [tableCellPadding=true]\n * Whether to add a space of padding between delimiters and cells (default:\n * `true`).\n * @property {boolean | null | undefined} [tablePipeAlign=true]\n * Whether to align the delimiters (default: `true`).\n * @property {MarkdownTableOptions['stringLength'] | null | undefined} [stringLength]\n * Function to detect the length of table cell content, used when aligning\n * the delimiters between cells (optional).\n */\n\nimport {ok as assert} from 'devlop'\nimport {markdownTable} from 'markdown-table'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM tables in\n * markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM tables.\n */\nexport function gfmTableFromMarkdown() {\n return {\n enter: {\n table: enterTable,\n tableData: enterCell,\n tableHeader: enterCell,\n tableRow: enterRow\n },\n exit: {\n codeText: exitCodeText,\n table: exitTable,\n tableData: exit,\n tableHeader: exit,\n tableRow: exit\n }\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterTable(token) {\n const align = token._align\n assert(align, 'expected `_align` on table')\n this.enter(\n {\n type: 'table',\n align: align.map(function (d) {\n return d === 'none' ? null : d\n }),\n children: []\n },\n token\n )\n this.data.inTable = true\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitTable(token) {\n this.exit(token)\n this.data.inTable = undefined\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterRow(token) {\n this.enter({type: 'tableRow', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exit(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterCell(token) {\n this.enter({type: 'tableCell', children: []}, token)\n}\n\n// Overwrite the default code text data handler to unescape escaped pipes when\n// they are in tables.\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCodeText(token) {\n let value = this.resume()\n\n if (this.data.inTable) {\n value = value.replace(/\\\\([\\\\|])/g, replace)\n }\n\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'inlineCode')\n node.value = value\n this.exit(token)\n}\n\n/**\n * @param {string} $0\n * @param {string} $1\n * @returns {string}\n */\nfunction replace($0, $1) {\n // Pipes work, backslashes don’t (but can’t escape pipes).\n return $1 === '|' ? $1 : $0\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM tables in\n * markdown.\n *\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM tables.\n */\nexport function gfmTableToMarkdown(options) {\n const settings = options || {}\n const padding = settings.tableCellPadding\n const alignDelimiters = settings.tablePipeAlign\n const stringLength = settings.stringLength\n const around = padding ? ' ' : '|'\n\n return {\n unsafe: [\n {character: '\\r', inConstruct: 'tableCell'},\n {character: '\\n', inConstruct: 'tableCell'},\n // A pipe, when followed by a tab or space (padding), or a dash or colon\n // (unpadded delimiter row), could result in a table.\n {atBreak: true, character: '|', after: '[\\t :-]'},\n // A pipe in a cell must be encoded.\n {character: '|', inConstruct: 'tableCell'},\n // A colon must be followed by a dash, in which case it could start a\n // delimiter row.\n {atBreak: true, character: ':', after: '-'},\n // A delimiter row can also start with a dash, when followed by more\n // dashes, a colon, or a pipe.\n // This is a stricter version than the built in check for lists, thematic\n // breaks, and setex heading underlines though:\n // <https://github.com/syntax-tree/mdast-util-to-markdown/blob/51a2038/lib/unsafe.js#L57>\n {atBreak: true, character: '-', after: '[:|-]'}\n ],\n handlers: {\n inlineCode: inlineCodeWithTable,\n table: handleTable,\n tableCell: handleTableCell,\n tableRow: handleTableRow\n }\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {Table} node\n */\n function handleTable(node, _, state, info) {\n return serializeData(handleTableAsData(node, state, info), node.align)\n }\n\n /**\n * This function isn’t really used normally, because we handle rows at the\n * table level.\n * But, if someone passes in a table row, this ensures we make somewhat sense.\n *\n * @type {ToMarkdownHandle}\n * @param {TableRow} node\n */\n function handleTableRow(node, _, state, info) {\n const row = handleTableRowAsData(node, state, info)\n const value = serializeData([row])\n // `markdown-table` will always add an align row\n return value.slice(0, value.indexOf('\\n'))\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {TableCell} node\n */\n function handleTableCell(node, _, state, info) {\n const exit = state.enter('tableCell')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, {\n ...info,\n before: around,\n after: around\n })\n subexit()\n exit()\n return value\n }\n\n /**\n * @param {Array<Array<string>>} matrix\n * @param {Array<string | null | undefined> | null | undefined} [align]\n */\n function serializeData(matrix, align) {\n return markdownTable(matrix, {\n align,\n // @ts-expect-error: `markdown-table` types should support `null`.\n alignDelimiters,\n // @ts-expect-error: `markdown-table` types should support `null`.\n padding,\n // @ts-expect-error: `markdown-table` types should support `null`.\n stringLength\n })\n }\n\n /**\n * @param {Table} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<Array<string>>} */\n const result = []\n const subexit = state.enter('table')\n\n while (++index < children.length) {\n result[index] = handleTableRowAsData(children[index], state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @param {TableRow} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableRowAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<string>} */\n const result = []\n const subexit = state.enter('tableRow')\n\n while (++index < children.length) {\n // Note: the positional info as used here is incorrect.\n // Making it correct would be impossible due to aligning cells?\n // And it would need copy/pasting `markdown-table` into this project.\n result[index] = handleTableCell(children[index], node, state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {InlineCode} node\n */\n function inlineCodeWithTable(node, parent, state) {\n let value = defaultHandlers.inlineCode(node, parent, state)\n\n if (state.stack.includes('tableCell')) {\n value = value.replace(/\\|/g, '\\\\$&')\n }\n\n return value\n }\n}\n","import type { Plugin, Processor } from 'unified'\nimport { gfmTableFromMarkdown } from 'mdast-util-gfm-table'\nimport { gfm } from 'micromark-extension-gfm'\nimport { gfmToMarkdown } from 'mdast-util-gfm'\n\n// Internal type for unified processor data\ninterface ProcessorData {\n micromarkExtensions?: unknown[];\n fromMarkdownExtensions?: unknown[];\n toMarkdownExtensions?: unknown[];\n}\n\n/**\n * Helper function to wrap a handler to ensure this.data is initialized\n */\nfunction wrapHandler(originalHandler: Function | undefined) {\n if (!originalHandler) return undefined;\n return function(this: any, token: any) {\n if (!this.data) {\n this.data = {};\n }\n return originalHandler.call(this, token);\n };\n}\n\n/**\n * Custom wrapper around remark-gfm that ensures the data object is initialized\n * This fixes the \"Cannot read/set properties of undefined\" errors\n * that occur when parsing tables\n */\nexport function customRemarkGfm(): Plugin {\n // Return a plugin function that initializes the data object\n return function(this: Processor) {\n // Make sure 'this' exists\n if (!this) {\n return;\n }\n\n // Initialize the data object on the processor\n // Get the data object - unified processor's data() method returns the data object\n const data = this.data() as ProcessorData;\n\n // Initialize the extensions arrays if they don't exist\n const micromarkExtensions = data.micromarkExtensions || (data.micromarkExtensions = []);\n const fromMarkdownExtensions = data.fromMarkdownExtensions || (data.fromMarkdownExtensions = []);\n const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);\n\n // Add the GFM extensions\n // We're using the original extensions from remark-gfm\n micromarkExtensions.push(gfm());\n\n // Create a patched version of gfmTableFromMarkdown\n const patchedFromMarkdown = function() {\n const extension = gfmTableFromMarkdown();\n\n // Wrap all enter handlers to ensure this.data is initialized\n if (extension.enter) {\n for (const key of Object.keys(extension.enter)) {\n (extension.enter as any)[key] = wrapHandler((extension.enter as any)[key]);\n }\n }\n\n // Wrap all exit handlers to ensure this.data is initialized\n if (extension.exit) {\n for (const key of Object.keys(extension.exit)) {\n (extension.exit as any)[key] = wrapHandler((extension.exit as any)[key]);\n }\n }\n\n return extension;\n };\n\n // Add our patched extensions\n fromMarkdownExtensions.push(patchedFromMarkdown());\n toMarkdownExtensions.push(gfmToMarkdown());\n\n return undefined; // Return undefined as the plugin doesn't need to return anything\n }\n}\n","import { Element } from \"./types\"\n\n/**\n * Function to escape forward slashes in URLs, but only for plain text URLs (not in markdown links)\n * This is necessary because the markdown parser doesn't handle unescaped forward slashes in URLs correctly\n */\nexport function escapeUrlSlashes(text: string): string {\n // First, we need to identify markdown links to exclude them\n const markdownLinkPattern = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n\n // Store the markdown links to restore them later\n const links: string[] = [];\n let linkIndex = 0;\n\n // Replace markdown links with placeholders\n const textWithoutLinks = text.replace(markdownLinkPattern, (match) => {\n links.push(match);\n return `__MARKDOWN_LINK_${linkIndex++}__`;\n });\n\n // URL regex pattern to identify plain text URLs\n const urlPattern = /(https?:\\/\\/[^\\s]+)/g;\n\n // Escape forward slashes in plain text URLs\n const textWithEscapedUrls = textWithoutLinks.replace(urlPattern, (url) => {\n return url.replace(/\\//g, '\\\\/');\n });\n\n // Restore the markdown links\n let result = textWithEscapedUrls;\n for (let i = 0; i < links.length; i++) {\n result = result.replace(`__MARKDOWN_LINK_${i}__`, links[i]);\n }\n\n return result;\n}\n\n/**\n * Function to unescape forward slashes in URLs that were previously escaped\n * This is used when switching to raw mode to display the unescaped markdown\n */\nexport function unescapeUrlSlashes(text: string): string {\n // Unescape all escaped characters in the text\n return text.replace(/\\\\(.)/g, (match, char) => {\n return char;\n });\n}\n\nexport function assert(pass: boolean, message: string) {\n if (!pass) throw new Error(`${message}`)\n}\n\nexport function assertElementType(element: Element, type: Element[\"type\"]) {\n if (element.type !== type)\n throw new Error(\n `Expected element to be of type ${JSON.stringify(\n element\n )} but is ${JSON.stringify(element, null, 2)}`\n )\n}\n\nexport function assertUnreachable(x: never): never {\n throw new Error(\n `Didn't expect to get here with value ${JSON.stringify(x, null, 2)}`\n )\n}\n","import type { Blockquote } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { parseContents } from \"./parse-content\"\n\nexport function parseBlockquote(content: Blockquote): Element[] {\n return [{ type: \"block-quote\", children: parseContents(content.children) }]\n}\n","import type { Code } from \"mdast\"\n\nimport { Element } from \"../types\"\n\nexport function parseCodeBlock(content: Code): Element[] {\n const codeLines = content.value.split(\"\\n\")\n return [\n {\n type: \"code-block\",\n language: content.lang || \"text\",\n children: codeLines.map((codeLine) => ({\n type: \"code-block-line\",\n children: [{ text: codeLine }],\n })),\n },\n ]\n}\n","import type { FootnoteDefinition } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { parseContents } from \"./parse-content\"\n\n/**\n * GitHub Flavored Markdown does not support footnotes and therefore, at the\n * moment, Wysimark does not support footnotes.\n *\n * However, we do provide some compatibility. Remarks, by default, parses\n * Footnote Definitions and we convert them into a blockquote. We insert an\n * extra paragraph at the top that contains the footnote identifier in square\n * brackets like `[1]`\n */\nexport function parseFootnoteDefinition(\n footnote: FootnoteDefinition\n): Element[] {\n return [\n {\n type: \"block-quote\",\n children: [\n /**\n * Insert an initial paragraph with the footnote identifier in square\n * brackets.\n */\n { type: \"paragraph\", children: [{ text: `[${footnote.identifier}]` }] },\n /**\n * The rest of the children are parsed as is and supports the full range\n * of element types like headings, lists and nested block quotes.\n */\n ...parseContents(footnote.children),\n ],\n },\n ]\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { Segment } from \"../../types\"\nimport { normalizeSegment } from \"./normalize-segment\"\n\n/**\n * After generating segments by just pushing them onto an Array, we want to get\n * them into proper form for use in Slate.\n *\n * Slate expects its data structure to follow [certain\n * rules](https://docs.slatejs.org/concepts/11-normalizing) and we make sure\n * they are followed.\n *\n * These are the rules for segments (text/inline) that we enforce:\n *\n * - Rule 1: All Element nodes must contain at least one Text descendant\n * - Rule 2: Two adjacent texts with the same custom properties will be merged.\n * - Rule 4: Inline nodes cannot be the first or last child of a parent block,\n * nor can it be next to another inline node in the children array.\n *\n */\nexport function normalizeSegments(segments: Segment[]): Segment[] {\n const nextSegments: Segment[] = []\n\n /**\n * Rule 2:\n *\n * Build up the nextSegments. The `normalizeSegment` function called inside\n * does the work of checking to see if the segment before is a Text with the\n * exact same marks. If it is, then instead of pushing on another Text\n * segment, it merges the current segment Text into the previous Segment.\n *\n * Rule 4 (part 3):\n *\n * It also checks for two inline elements and inserts an empty Text node\n * between them by emitting a `{text: ''}` before the inline Element segment.\n */\n for (let i = 0; i < segments.length; i++) {\n /**\n * When we provide the `prevSegment` notice that is is actually the\n * `prevSegment` from our `nextSegments` and not `segments[i-1]`.\n *\n * This is important because `normalizeSegment` will mutate `prevSegment`\n */\n\n const mutablePrevSegment: Segment | undefined =\n nextSegments[nextSegments.length - 1]\n nextSegments.push(...normalizeSegment(segments[i], mutablePrevSegment))\n }\n\n /**\n * Rule 1:\n *\n * If there are no segments, we ensure there is at least one by inserting an\n * empty Text\n */\n if (nextSegments.length === 0) nextSegments.push({ text: \"\" })\n /**\n * Rule 4 (part 1 & part 2):\n *\n * If the first segment isn't Text, insert a Text\n */\n if (!SlateText.isText(nextSegments[0])) nextSegments.unshift({ text: \"\" })\n /**\n * Rule 4:\n *\n * If the last segment isn't Text, insert a Text\n */\n if (!SlateText.isText(nextSegments[nextSegments.length - 1]))\n nextSegments.push({ text: \"\" })\n return nextSegments\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { getMarksFromText } from \"../../serialize/serialize-line/utils\"\nimport { Segment, Text } from \"../../types\"\n\n/**\n * This is algorithm checks for equality of marks.\n */\nexport function areMarksEqual(a: Text, b: Text): boolean {\n const marksA = getMarksFromText(a)\n const marksB = getMarksFromText(b)\n /**\n *\n * WARNING:\n *\n * This algorithm is specific to our use case. a, b contain non-repeated\n * items. It will fail in other scenarios.\n *\n * > If you want to check if both arrays are equals, containing the same\n * > unsorted items (but not used multiple times)\n *\n * https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript#comment68674302_19746771\n */\n return (\n marksA.length == marksB.length && marksA.every((v) => marksB.includes(v))\n )\n}\n\n/**\n * Enforces Rule 2\n *\n * Two adjacent texts with the same custom properties will be merged.\n * https://docs.slatejs.org/concepts/11-normalizing\n *\n * normalizeSegment does most of the work for merging two segments with the same\n * marks together.\n *\n * Normally, this method emits the current `segment`; however, if the current\n * segment and the previous segment have the same marks, it instead emits an\n * empty array indicating not to add the current segment. Instead, it merges the\n * current segment text into the text of the previous segment.\n *\n * Enforce Rule 4 (part 3)\n *\n * \"Inline nodes cannot be the first or last child of a parent block, nor can it\n * be next to another inline node in the children array.\"\n *\n * Mainly, it's enforcing the part about the fact that there must be a Text node\n * between two inline Element nodes.\n */\nexport function normalizeSegment(\n segment: Segment,\n /**\n * Let's be explicit that we are doing something unusual here in that we are\n * mutating the previous segment by naming it as such.\n */\n mutablePrevSegment?: Segment\n): Segment[] {\n const segmentIsText = SlateText.isText(segment)\n const prevSegmentIsText = SlateText.isText(mutablePrevSegment)\n\n /**\n * Rule 4 (part 3):\n *\n * If there is a previous segment and the previous segment and the current\n * segment are both inline elements, we want to insert a space between them\n * which this does.\n *\n * It stops checking for merging two texts with each other since if they are\n * two inline elements, it doesn't need to check for text anymore.\n */\n if (mutablePrevSegment && !prevSegmentIsText && !segmentIsText) {\n return [{ text: \"\" }, segment]\n }\n\n /**\n * If the current segment is an Inline Element, then we can't merge it so we\n * return it as is\n */\n if (!segmentIsText) return [segment]\n /**\n * If the previous segment is an Inline Element or it's node defined, then we\n * can't merge into it so we return it as is\n */\n if (mutablePrevSegment === undefined || !prevSegmentIsText) return [segment]\n\n /**\n * If the two Text segments have the same marks, then merge them\n */\n const marksEqual = areMarksEqual(mutablePrevSegment, segment)\n if (marksEqual) {\n mutablePrevSegment.text = [mutablePrevSegment.text, segment.text].join(\"\")\n return []\n }\n\n return [segment]\n}\n","import * as Slate from \"slate\"\n\nimport { AnchorElement } from \"../../../../anchor-plugin\"\n\nimport { Segment, Text } from \"../../../types\"\nimport { LineElement, Node } from \"../normalize-line/types\"\n\n/**\n * Is this a Text Node\n */\nexport function isText(segment: Node | undefined): segment is Text {\n return Slate.Text.isText(segment)\n}\n\n/**\n * Is this an Element Node\n *\n * In the context of our normalizers, passing `isElement` means that it is\n * a `LineElement` or `AnchorElement`\n *\n * TODO:\n *\n * We should also add the following in the future:\n *\n * - `ImageInlineElement`\n * - `AttachmentElement`\n */\nexport function isElement(\n segment: Node\n): segment is LineElement | AnchorElement {\n return Slate.Element.isElement(segment)\n}\n\n/**\n * Identify this as a plain, non-code Text space. This is fairly specific\n * because we only want to manipulate non-code Text spaces. If the Text is\n * `code` then we can apply our marks next to it.\n *\n * - Does the passed in `Text` node made up of only one or more spaces\n * - The `Text` node must not be `code`\n */\nexport function isPlainSpace(segment: Segment): boolean {\n return (\n Slate.Text.isText(segment) && !!segment.text.match(/^\\s+$/) && !segment.code\n )\n}\n","import { MarkKey } from \"../../../../types\"\n\nexport const MARK_KEY_TO_OPEN_TOKEN = {\n bold: \"**\",\n italic: \"_\",\n // ins: \"++\",\n strike: \"~~\",\n highlight: \"<mark>\",\n /**\n * IMPORTANT!\n *\n * We noop `code` here.\n *\n * We accept the `code` mark so as not to throw an error if it is found. We do\n * this because we handle `code` text specially because of the way it needs to\n * be escaped.\n *\n * This is handled in the `serializeLine` code.\n */\n code: \"\",\n} as Record<MarkKey, string>\n\nexport const MARK_KEY_TO_CLOSE_TOKEN = {\n bold: \"**\",\n italic: \"_\",\n // ins: \"++\",\n strike: \"~~\",\n highlight: \"</mark>\",\n code: \"\",\n} as Record<MarkKey, string>\n\n/**\n * @deprecated Use MARK_KEY_TO_OPEN_TOKEN instead\n */\nexport const MARK_KEY_TO_TOKEN = MARK_KEY_TO_OPEN_TOKEN\n\n/**\n * Convert a single mark to its opening symbol/tag\n */\nfunction convertMarkToOpenSymbol(mark: MarkKey): string {\n if (mark in MARK_KEY_TO_OPEN_TOKEN) return MARK_KEY_TO_OPEN_TOKEN[mark]\n throw new Error(\n `Could not find mark ${JSON.stringify(mark)} in MARK_KEY_TO_OPEN_TOKEN lookup`\n )\n}\n\n/**\n * Convert a single mark to its closing symbol/tag\n */\nfunction convertMarkToCloseSymbol(mark: MarkKey): string {\n if (mark in MARK_KEY_TO_CLOSE_TOKEN) return MARK_KEY_TO_CLOSE_TOKEN[mark]\n throw new Error(\n `Could not find mark ${JSON.stringify(mark)} in MARK_KEY_TO_CLOSE_TOKEN lookup`\n )\n}\n\n/**\n * Convert an array of marks to opening symbols/tags\n */\nexport function convertMarksToOpenSymbols(marks: MarkKey[]) {\n return marks.map(convertMarkToOpenSymbol).join(\"\")\n}\n\n/**\n * Convert an array of marks to closing symbols/tags\n */\nexport function convertMarksToCloseSymbols(marks: MarkKey[]) {\n return marks.map(convertMarkToCloseSymbol).join(\"\")\n}\n\n/**\n * Convert an array of marks to a string\n * @deprecated Use convertMarksToOpenSymbols or convertMarksToCloseSymbols instead\n */\nexport function convertMarksToSymbolsExceptCode(marks: MarkKey[]) {\n return marks.map(convertMarkToOpenSymbol).join(\"\")\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { MarkKey, Segment, Text } from \"../../../../types\"\nimport { isPlainSpace, isText } from \"../is-utils\"\n\n/**\n * Gets all the marks in current `Text`\n */\nexport function getMarksFromText(text: Text): MarkKey[] {\n const { text: _textContent, ...marks } = text\n void _textContent\n return Object.keys(marks) as (keyof typeof marks)[]\n}\n\n/**\n * Gets all the marks from the current segment\n */\nexport function getMarksFromSegment(segment: Segment): MarkKey[] {\n if (SlateText.isText(segment)) {\n if (isPlainSpace(segment)) {\n throw new Error(\n `You probably didn't mean to do this. We should only be getting marks from segments that are not plain space segments.`\n )\n }\n return getMarksFromText(segment)\n } else if (segment.type === \"anchor\") {\n return getCommonAnchorMarks(segment.children as Segment[])\n } else {\n /**\n * TODO: Need to handle images still.\n */\n throw new Error(`Unhandled type ${segment.type}`)\n }\n}\n\nexport function getCommonAnchorMarks(segments: Segment[]): MarkKey[] {\n let commonMarks: MarkKey[] | undefined\n for (const segment of segments) {\n if (!isText(segment)) {\n /**\n * Use this to test for images in anchors\n *\n * [](http://jamstack.club)\n */\n if (segment.type === \"image-inline\") continue\n /**\n * TODO: This is not actually true. It can be an inline image which we\n * still need to add.\n */\n throw new Error(\n `Expected every segment in an anchor to be a Text segment`\n )\n }\n if (isPlainSpace(segment)) continue\n const currentMarks = getMarksFromText(segment)\n if (commonMarks === undefined) {\n commonMarks = currentMarks\n continue\n }\n commonMarks = commonMarks.filter((commonMark) =>\n currentMarks.includes(commonMark)\n )\n }\n if (commonMarks === undefined)\n throw new Error(\n `No text segments were found as children in this anchor which should not be possible`\n )\n return commonMarks\n}\n","import { MarkKey } from \"../../../../types\"\n\n/**\n * When adding back marks, this is the order in which we add them back.\n *\n * The order is determined by an educated guess about which marks are more\n * likely to be chaging inside other marks. For example, this is probably pretty\n * common:\n *\n * **This is x^2^**\n *\n * Having a superscript inside of a bold. But it's probably rare to have bold\n * switched on/off inside a superscript.\n */\nconst ORDERED_MARK_KEYS: MarkKey[] = [\n \"bold\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"highlight\",\n \"code\",\n]\n\n/**\n * Sort Algorithm\n *\n * https://stackoverflow.com/a/44063445\n */\nexport function sortMarks(marks: MarkKey[]): MarkKey[] {\n return marks\n .slice()\n .sort((a, b) => ORDERED_MARK_KEYS.indexOf(a) - ORDERED_MARK_KEYS.indexOf(b))\n}\n","const ESCAPES = [\n \"\\\\\", // escape\n \"`\", // code\n \"*\", // bold/italic/hr\n \"_\", // bold/italic/hr\n \"[\", // link/list\n \"]\", // link/list\n \"(\", // link\n \")\", // link\n \"#\", // headings\n \"+\", // list\n \"-\", // hr/list\n \".\", // numbered list\n \"!\", // image\n \"|\", // table\n \"^\", // sup\n \"~\", // sub/strikethrough\n \"<\", // link/html\n \">\", // link/html\n /**\n * Includes all the characters in the list of Backslash escapes in the example\n * for GitHub Flavored Markdown.\n *\n * https://github.github.com/gfm/#backslash-escapes\n */\n \"{\",\n \"}\",\n \"=\",\n \":\",\n \";\",\n \"$\",\n \"%\",\n \"&\",\n \"?\",\n '\"',\n \"'\",\n \",\",\n \"\\\\\",\n \"/\",\n \"@\",\n]\n\nconst ESCAPES_REGEXP = new RegExp(\n `(${ESCAPES.map((symbol) => `\\\\${symbol}`).join(\"|\")})`,\n \"g\"\n)\n\n/**\n * Escape text that could have an ambiguous meaning in markdown\n */\nexport function escapeText(s: string) {\n return s.replace(ESCAPES_REGEXP, (s: string) => `\\\\${s}`)\n // .replace(/\\n/g, \"<br>\")\n}\n","import type { Image } from \"mdast\"\n\nimport { ImageData } from \"./index\"\n\n/**\n * As a fallback, we don't\n */\nexport function parseGenericImage(image: Image): ImageData {\n return {\n url: image.url,\n title: image.title || undefined,\n alt: image.alt || undefined,\n }\n}\n","type ParsedUrl = {\n origin: string\n hostname: string\n pathname: string\n searchParams: URLSearchParams\n hash: string\n}\n\n/**\n * NOTE: As per the URL spec:\n *\n * - searchParams part does not include the \"?\"\n * - hash part includes the \"#\"\n */\nconst URL_REGEX = /^(\\/[^?#]*)(?:\\?([^#]*))?(#.*)?$/\n\nexport function parseUrl(url: string): ParsedUrl {\n try {\n const urlData = new URL(url)\n return {\n origin: urlData.origin,\n hostname: urlData.hostname,\n pathname: urlData.pathname,\n searchParams: urlData.searchParams,\n hash: urlData.hash,\n }\n } catch {\n const matchdata = url.match(URL_REGEX)\n if (matchdata === null)\n throw new Error(`Invalid format should not happen: ${url}`)\n const [, pathname, searchParams, hash] = [...matchdata]\n return {\n origin: \"\",\n hostname: \"\",\n pathname: pathname || \"\",\n searchParams: new URLSearchParams(searchParams),\n hash: hash || \"\",\n }\n }\n}\n","/**\n * Takes a `string` in the form `640x480` (i.e. number x number) and return an\n * ImageSize object with `width` and `height`.\n */\nexport function parseSize(\n s: string | null\n): { width: number; height: number } | null {\n if (typeof s !== \"string\") return null\n const sizeMatch = s.match(/^(\\d+)x(\\d+)$/)\n if (sizeMatch === null) return null\n return {\n width: parseInt(sizeMatch[1]),\n height: parseInt(sizeMatch[2]),\n }\n}\n","import type { Image } from \"mdast\"\n\nimport { parseUrl } from \"../../../parseUrl\"\nimport { ImageData } from \"./index\"\nimport { parseSize } from \"./parse-utils\"\n\nexport function parsePortiveImage(image: Image): ImageData | undefined {\n // const url = new URL(image.url)\n const url = parseUrl(image.url)\n /**\n * Only parse portive URL if it is a portive recognized domain\n */\n if (!url.hostname.match(/[.]portive[.]com$/i)) return\n /**\n * Should have a size param as part of the query string\n */\n const sizeParam = url.searchParams.get(\"size\")\n if (sizeParam === null) return\n /**\n * And the query string should parse properly as an ImageSize\n */\n const size = parseSize(sizeParam)\n if (size === null) return\n /**\n * The Portive image URL should end in something like `--640x480.jpg` which\n * identifies its width/height.\n */\n const srcSizeMatch = url.pathname.match(/[-][-](\\d+)x(\\d+)[.][a-zA-Z]+$/)\n if (srcSizeMatch === null) return\n /**\n * Return the `ImageData`\n */\n return {\n url: `${url.origin}${url.pathname}`,\n title: image.title || undefined,\n alt: image.alt || undefined,\n width: size.width,\n height: size.height,\n srcWidth: parseInt(srcSizeMatch[1]),\n srcHeight: parseInt(srcSizeMatch[2]),\n }\n}\n","import type { Image } from \"mdast\"\n\nimport { parseUrl } from \"../../../parseUrl\"\nimport { ImageData } from \"./index\"\nimport { parseSize } from \"./parse-utils\"\n\n/**\n * UncommonMark images are just regular images with some additional encoding in\n * the URL hash which allows us to embed extra information without affecting the\n * image that is rendered nor does it affect the `title` or `alt` attributes.\n */\nexport function parseUncommonMarkImage(image: Image): ImageData | undefined {\n const url = parseUrl(image.url)\n /**\n * If there's no hash, it's not UncommonMark\n */\n if (url.hash.length === 0) return\n /**\n * We use `URLSearchParams` to decode the size data after the `#` because it's\n * free (embedded in every browser without more code) and available (including\n * Node)!\n */\n const params = new URLSearchParams(url.hash.slice(1))\n const size = parseSize(params.get(\"size\"))\n const srcSize = parseSize(params.get(\"srcSize\"))\n if (!size || !srcSize) return\n /**\n * If we successfully parsed all the ImageSize info, then return the\n * `ImageData`\n */\n return {\n url: `${url.origin}${url.pathname}`,\n title: image.title || undefined,\n alt: image.alt || undefined,\n width: size.width,\n height: size.height,\n srcWidth: srcSize.width,\n srcHeight: srcSize.height,\n }\n}\n","import { parseGenericImage } from \"./parse-generic-image\"\nimport { parsePortiveImage } from \"./parse-portive-image\"\nimport { parseUncommonMarkImage } from \"./parse-uncommon-mark-image\"\n\nexport const imageParsers = [\n parsePortiveImage,\n parseUncommonMarkImage,\n parseGenericImage,\n]\n","import type { Image } from \"mdast\"\n\nimport { ImageSharedElement } from \"../../../../image-plugin/types\"\n\nimport { Segment } from \"../../../types\"\nimport { imageParsers } from \"./image-parsers\"\n\nexport type ImageData = Omit<ImageSharedElement, \"children\">\n\n/**\n * Iterate through all the image parsers utnil we find one that returns\n * `ImageData`. Combine that `ImageData` with the `type` and `children` and\n * return it as the `ImageInlineElement`\n */\nexport function parseInlineImage(image: Image): Segment[] {\n for (const imageParser of imageParsers) {\n const imageData = imageParser(image)\n if (!imageData) continue\n return [\n {\n type: \"image-inline\",\n ...imageData,\n children: [{ text: \"\" }],\n },\n ]\n }\n throw new Error(`Shouldn't get here because last parser always returns data`)\n}\n","import type { PhrasingContent } from \"mdast\"\n\nimport { MarkProps, Segment } from \"../../types\"\nimport { assertUnreachable } from \"../../utils\"\nimport { normalizeSegments } from \"./normalize-segments\"\nimport { parseInlineImage } from \"./parse-inline-image\"\nimport { Descendant } from \"slate\"\n\n/**\n * Parse inline HTML content, with special handling for <mark> tags\n */\nfunction parseInlineHtml(htmlValue: string, marks: MarkProps): Segment[] {\n // Check for <mark>...</mark> pattern\n const markMatch = htmlValue.match(/^<mark>(.+?)<\\/mark>$/s)\n if (markMatch) {\n return [{ text: markMatch[1], ...marks, highlight: true }]\n }\n // For other HTML, treat as code\n return [{ text: htmlValue, code: true }]\n}\n\nexport function parsePhrasingContents(\n phrasingContents: PhrasingContent[],\n marks: MarkProps = {}\n): Segment[] {\n const segments: Segment[] = []\n for (const phrasingContent of phrasingContents) {\n segments.push(...parsePhrasingContent(phrasingContent, marks))\n }\n const nextInlines = normalizeSegments(segments)\n return nextInlines\n}\n\nfunction parsePhrasingContent(\n phrasingContent: PhrasingContent,\n marks: MarkProps = {}\n): Segment[] {\n switch (phrasingContent.type) {\n case \"delete\":\n return parsePhrasingContents(phrasingContent.children, {\n ...marks,\n strike: true,\n })\n case \"emphasis\":\n return parsePhrasingContents(phrasingContent.children, {\n ...marks,\n italic: true,\n })\n case \"footnoteReference\":\n return [{ text: `[${phrasingContent.identifier}]` }]\n case \"html\":\n return parseInlineHtml(phrasingContent.value, marks)\n case \"image\":\n return parseInlineImage(phrasingContent)\n case \"inlineCode\": {\n return [{ text: phrasingContent.value, ...marks, code: true }]\n }\n case \"link\":\n return [\n {\n type: \"anchor\",\n href: phrasingContent.url,\n title:\n /**\n * Ensure that `title` is undefined if it's null.\n */\n phrasingContent.title == null ? undefined : phrasingContent.title,\n children: parsePhrasingContents(phrasingContent.children, marks) as Descendant[],\n },\n ]\n case \"strong\":\n return parsePhrasingContents(phrasingContent.children, {\n ...marks,\n bold: true,\n })\n case \"text\":\n return [{ text: phrasingContent.value, ...marks }]\n case \"linkReference\":\n case \"imageReference\":\n throw new Error(\n `linkReference and imageReference should be converted to link and image through our transformInlineLinks function`\n )\n case \"break\":\n /**\n * NOTE:\n *\n * I don't think this is doing anything at the moment as a \"\\n\" is being\n * read without being turned into a break. We can test this by doing a\n * console.log before the return below.\n */\n return [{ text: \"\\n\" }]\n case \"footnote\":\n /**\n * TODO: Support footnotes\n *\n * This is a footnote, and should be converte to a suitable alternative or\n * for us to explicitly support a Footnote type in the future. At the\n * moment, we don't explicitly support a footnote as it's (a) not part of\n * GFM and (b) not really that useful while (c) adding complexity to the\n * UI for something that's not used.\n */\n throw new Error(\"footnote is not supported yet\")\n }\n assertUnreachable(phrasingContent)\n}\n","import type { Heading } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { parsePhrasingContents } from \"./parse-phrasing-content/parse-phrasing-content\"\n\nexport function parseHeading(content: Heading): Element[] {\n return [\n {\n type: \"heading\",\n level: content.depth,\n children: parsePhrasingContents(content.children),\n },\n ]\n}\n","import type { HTML } from \"mdast\"\n\nimport { Element } from \"../types\"\n\nexport function parseHTML(content: HTML): Element[] {\n return [\n {\n type: \"html-block\",\n html: content.value,\n children: [{ text: \"\" }],\n },\n ]\n}\n","import type { ListItem } from \"mdast\"\n\nimport { Element } from \"../../types\"\nimport { parseContent } from \"../parse-content\"\nimport { parsePhrasingContents } from \"../parse-phrasing-content/parse-phrasing-content\"\nimport { parseList } from \"./parse-list\"\n\nexport function parseListItemChild(\n child: ListItem[\"children\"][number],\n {\n depth,\n ordered,\n checked,\n }: { depth: number; ordered: boolean; checked: boolean | null | undefined }\n): Element[] {\n switch (child.type) {\n case \"paragraph\":\n if (checked === true || checked === false) {\n return [\n {\n type: \"task-list-item\",\n depth,\n checked,\n children: parsePhrasingContents(child.children),\n },\n ]\n } else if (ordered) {\n return [\n {\n type: \"ordered-list-item\",\n depth,\n children: parsePhrasingContents(child.children),\n },\n ]\n } else {\n return [\n {\n type: \"unordered-list-item\",\n depth,\n children: parsePhrasingContents(child.children),\n },\n ]\n }\n case \"list\":\n return parseList(child, depth + 1)\n default:\n /**\n * NOTE:\n *\n * We break out of a list when the children of a list item are not more\n * lists/list items.\n *\n * This is one area where we don't strictly adhere to the Markdown\n * specification and it is intentional because adhering strictly to the\n * Markdown specification would create a harmful user experience.\n *\n * It appears that Markdown allows nesting other block types in lists\n * other than list items. For example, one can place a table, block\n * quote, heading or something else in a list item.\n *\n * There are a few problems with this from a user perspective:\n *\n * - It's unexpected. No other editors provide such a feature.\n * - If we were to adopt this as a feature, the user experience would be\n * terrible, namely because it would be unpredictable what commands do\n * toggle headings or list items should do if they were nested.\n *\n */\n return parseContent(child)\n }\n}\n","import type { ListItem } from \"mdast\"\n\nimport { Element } from \"../../types\"\nimport { parseListItemChild } from \"./parse-list-item-child\"\n\nexport function parseListItem(\n listItem: ListItem,\n options: { depth: number; ordered: boolean }\n): Element[] {\n const elements: Element[] = []\n for (const child of listItem.children) {\n elements.push(\n ...parseListItemChild(child, { ...options, checked: listItem.checked })\n )\n }\n return elements\n}\n","import type { List } from \"mdast\"\n\nimport { Element } from \"../../types\"\nimport { parseListItem } from \"./parse-list-item\"\n\nexport function parseList(list: List, depth = 0): Element[] {\n // console.log(JSON.stringify(list, null, 2))\n const elements: Element[] = []\n for (const listItem of list.children) {\n elements.push(\n ...parseListItem(listItem, { depth, ordered: !!list.ordered })\n )\n }\n return elements\n}\n","import type { Paragraph } from \"mdast\"\n\nimport { ImageBlockElement, ImageInlineElement } from \"../../image-plugin/types\"\n\nimport { Element, Segment } from \"../types\"\nimport { parsePhrasingContents } from \"./parse-phrasing-content/parse-phrasing-content\"\n\nfunction isImageBlock(segments: Segment[]): boolean {\n if (segments.length !== 3) return false\n if (!(\"text\" in segments[0]) || segments[0].text !== \"\") return false\n if (!(\"text\" in segments[2]) || segments[2].text !== \"\") return false\n if (!(\"type\" in segments[1]) || segments[1].type !== \"image-inline\")\n return false\n return true\n}\n\nconst NBSP = \"\\u00A0\"\n\nfunction isSingleNBSP(segments: Segment[]): boolean {\n if (segments.length !== 1) return false\n if (!(\"text\" in segments[0]) || segments[0].text !== NBSP) return false\n return true\n}\n\n/**\n * Parses to a Paragraph or an ImageBlock element.\n *\n * We need to do it this way because an ImageBlock is a Paragraph that happens\n * to have exactly one ImageInline child.\n */\nexport function parseParagraph(content: Paragraph): Element[] {\n const segments = parsePhrasingContents(content.children)\n if (isImageBlock(segments)) {\n const imageSegment = segments[1] as ImageInlineElement\n const imageBlockElement: ImageBlockElement = {\n ...imageSegment,\n type: \"image-block\",\n }\n return [imageBlockElement]\n }\n if (isSingleNBSP(segments)) {\n return [\n {\n type: \"paragraph\",\n children: [{ text: \"\" }],\n },\n ]\n }\n\n return [\n {\n type: \"paragraph\",\n children: segments,\n },\n ]\n}\n","import type { Table, TableCell, TableRow } from \"mdast\"\n\nimport {\n TableCellElement,\n TableElement,\n TableRowElement,\n} from \"../../table-plugin\"\n\nimport { parsePhrasingContents } from \"./parse-phrasing-content/parse-phrasing-content\"\n\nexport function parseTable(table: Table): [TableElement] {\n if (table.align == null)\n throw new Error(`Expected an array of AlignType for table.align`)\n return [\n {\n type: \"table\",\n columns: table.align.map((align) => ({\n align: align || \"left\",\n })),\n children: table.children.map(parseTableRow),\n },\n ]\n}\n\nfunction parseTableRow(row: TableRow): TableRowElement {\n if (row.type !== \"tableRow\") throw new Error(`Expected a tableRow`)\n return { type: \"table-row\", children: row.children.map(parseTableCell) }\n}\n\nfunction parseTableCell(cell: TableCell): TableCellElement {\n if (cell.type !== \"tableCell\") throw new Error(`Expected a tableCell`)\n return {\n type: \"table-cell\",\n children: [\n {\n type: \"table-content\",\n children: parsePhrasingContents(cell.children),\n },\n ],\n }\n}\n","import { Element } from \"../types\"\n\nexport function parseThematicBreak(): Element[] {\n return [\n {\n type: \"horizontal-rule\",\n children: [{ text: \"\" }],\n },\n ]\n}\n","import type { TopLevelContent } from \"mdast\"\n\nimport { Element } from \"../types\"\nimport { assertUnreachable } from \"../utils\"\nimport { parseBlockquote } from \"./parse-blockquote\"\nimport { parseCodeBlock } from \"./parse-code-block\"\nimport { parseFootnoteDefinition } from \"./parse-footnote-definition\"\nimport { parseHeading } from \"./parse-heading\"\nimport { parseHTML } from \"./parse-html\"\nimport { parseList } from \"./parse-list\"\nimport { parseParagraph } from \"./parse-paragraph\"\nimport { parseTable } from \"./parse-table\"\nimport { parseThematicBreak } from \"./parse-thematic-break\"\n\nexport function parseContents(contents: TopLevelContent[]): Element[] {\n const elements: Element[] = []\n for (const content of contents) {\n elements.push(...parseContent(content))\n }\n return elements\n}\n\nexport function parseContent(content: TopLevelContent): Element[] {\n switch (content.type) {\n case \"blockquote\":\n return parseBlockquote(content)\n case \"code\":\n return parseCodeBlock(content)\n case \"definition\":\n /**\n * A `definition` is used by a `linkRef` or `imageRef`; however, we inline\n * these with our `./remark-inline-links`\n */\n throw new Error(`The type \"definition\" should not exist. See comments`)\n case \"footnoteDefinition\":\n return parseFootnoteDefinition(content)\n case \"heading\":\n return parseHeading(content)\n case \"html\":\n return parseHTML(content)\n case \"list\":\n return parseList(content)\n case \"paragraph\":\n /**\n * Returns a `paragraph` or an `image-block` Element.\n */\n return parseParagraph(content)\n case \"table\":\n return parseTable(content)\n case \"thematicBreak\":\n return parseThematicBreak()\n case \"yaml\":\n /**\n * YAML FrontMatter is not used in Wysimark.\n */\n return []\n }\n assertUnreachable(content)\n}\n","import type { Content, Image, Link, Parent, Root } from \"mdast\"\nimport { definitions } from \"mdast-util-definitions\"\nimport type { Node } from \"unist\"\nimport { SKIP, visit } from \"unist-util-visit\"\n\n/**\n * Based on the code from `remark-inline-links` but rewritten here because, for\n * reasons unknown to me, the plugin doesn't seem to execute at all despite not\n * throwing an error. Looks like the function that `remarkInlineLinks` returns\n * is never executed. Not sure if this is due to a change in `unified` but I\n * can't seem to find any mention anywhere of this no longer working including\n * in discussion or issues and the list of plugins show that\n * `remark-inline-links` is currently working and compatible with the lateste\n * version.\n *\n * Never-the-less, pulling it out and working on the ast directly (this function\n * modifies the AST in place) seems to work.\n *\n * https://github.com/remarkjs/remark-inline-links\n */\nexport function transformInlineLinks(tree: Root): void {\n const definition = definitions(tree)\n\n visit<Node>(tree as Node, (n, index, p) => {\n const node = n as unknown as Content\n const parent = p as unknown as Parent | null\n if (\n node.type === \"definition\" &&\n parent !== null &&\n typeof index === \"number\"\n ) {\n parent.children.splice(index, 1)\n return [SKIP, index]\n }\n\n if (node.type === \"imageReference\" || node.type === \"linkReference\") {\n const identifier =\n \"identifier\" in node && typeof node.identifier === \"string\"\n ? node.identifier\n : \"\"\n const def = definition(identifier)\n\n if (def && parent !== null && typeof index === \"number\") {\n const replacement: Image | Link =\n node.type === \"imageReference\"\n ? { type: \"image\", url: def.url, title: def.title, alt: node.alt }\n : {\n type: \"link\",\n url: def.url,\n title: def.title,\n children: node.children,\n }\n\n parent.children[index] = replacement\n return [SKIP, index]\n }\n }\n })\n}\n","import { ListItemElement } from \"../../../list-plugin/types\"\n\nimport { Element } from \"../../types\"\n\n/**\n * Provides a type guard for `ListItemElement`.\n */\nfunction isListItemElement(element: Element): element is ListItemElement {\n return (\n element.type === \"ordered-list-item\" ||\n element.type === \"unordered-list-item\" ||\n element.type === \"task-list-item\"\n )\n}\n\nexport function normalizeElementListDepths(elements: Element[]) {\n const normalizedElements: Element[] = []\n\n /**\n * previousDepth of -1 indicates that the previous element was not a list\n * item.\n */\n let previousDepth = -1\n\n for (const element of elements) {\n /**\n * If it's not a list item, just reset previousDepth and add the element\n * to `normalizedElements`.\n */\n if (!isListItemElement(element)) {\n normalizedElements.push(element)\n previousDepth = -1\n continue\n }\n\n /**\n * If it is a list item, we need to make sure the depth never increases by\n * more than 1. This is important because if we skip the first depth (i.e.\n * we start at depth of 2) then we get the first list indented which makes\n * Markdown think it's a code block. After the first list item, we don't\n * want to indent by more than one depth level because Markdown will assume\n * that's still a single depth level. When we outdent a level, Markdown\n * could get confused.\n *\n * WARNING:\n *\n * This does create a situation where the list in Wysimark is not saved and\n * loaded to return the same document; however, the alternative is that we\n * prevent the editor from creating a list which skips a depth. This could\n * be perceived as broken UI by the user. This appraoch feels less obtrusive\n * to the user.\n */\n const nextDepth =\n element.depth > previousDepth + 1 ? previousDepth + 1 : element.depth\n normalizedElements.push({ ...element, depth: nextDepth })\n previousDepth = nextDepth\n }\n\n return normalizedElements\n}\n","import { CodeBlockLineElement } from \"../../../code-block-plugin\"\n\n/**\n * Serializing a code line is simple under the assumption that the normalizers\n * in Wysimark are working correctly. Technically, a code-line should have\n * exactly one child with one `Text` node with no marks in it.\n */\nexport function serializeCodeLine(codeLine: CodeBlockLineElement): string {\n /**\n * As a safety measure, we make sure that we are receiving a `codeLine`\n */\n if (codeLine.type !== \"code-block-line\")\n throw new Error(\n `Expected all children of code-block to be a codeline but is ${JSON.stringify(\n codeLine,\n null,\n 2\n )}`\n )\n /**\n * We are converting all segments under the assumption that they are text\n * segments.\n */\n return codeLine.children.map((segment) => segment.text).join(\"\")\n}\n","import { CodeBlockElement } from \"../../../code-block-plugin\"\n\nimport { serializeCodeLine } from \"./serialize-code-line\"\n\n/**\n * Serializing a code block is usually three backticks folloed by the language,\n * then the code is raw verbatim and then three backticks to close.\n *\n * However, we have to account for if any line in the code starts with three\n * backticks. In that case, we need to start our code block with 4 backticks.\n * And if there are 4 backticks in the code, then we need to start it with 5.\n *\n * We always need to start our code block with one more backtick than can be\n * found starting any line in the code block.\n */\nexport function serializeCodeBlock(codeBlock: CodeBlockElement): string {\n const lines: string[] = []\n /**\n * Start with the default number of backticks\n */\n let backticks = 3\n for (const codeLine of codeBlock.children) {\n /**\n * Grab a raw code line from it\n */\n const lineOfCode = serializeCodeLine(codeLine)\n /**\n * Check if it starts with any backticks and if it does, make our backticks\n * one larger than the largest one.\n */\n const match = lineOfCode.match(/^([`]+)/)\n if (match) backticks = Math.max(backticks, match[1].length + 1)\n /**\n * Add it to our lines\n */\n lines.push(lineOfCode)\n }\n /**\n * At the very end, when we know how many backticks we need, add our backticks\n * and language at the start and the closing backticks at the end.\n */\n lines.unshift(`${\"`\".repeat(backticks)}${codeBlock.language}`)\n lines.push(`${\"`\".repeat(backticks)}`)\n return `${lines.join(\"\\n\")}\\n\\n`\n}\n","import { ImageSharedElement } from \"../../../image-plugin/types\"\n\n/**\n * As a fallback, if there is no width/height or srcWidth/srcHeight info then\n * just save the image url and do not save with uncommonMark hints.\n */\nexport function serializeGenericImageUrl(image: ImageSharedElement): string {\n return image.url\n}\n","import { ImageSharedElement } from \"../../../image-plugin/types\"\n\nimport { parseUrl } from \"../../parseUrl\"\n\n/**\n * When an image is in the `.portive.com` subdomain like `files.portive.com` or\n * `staging.files.portive.com` and if the image has a `width` and `height` then\n * we encode the `width` and `height in the `url` as part of the query string.\n *\n * https://files.portive.com/f/abcdef--640x480.jpg?size=320x240\n *\n * Indicates a src image of 640x480 that will be resized and sent to the browser\n * at 320x240\n *\n * This does these things:\n *\n * - When parsing the image URL, we are able to pull the width/height out of the\n * URL and use it to populate those values in the editor.\n *\n * - The query string will also physically resize the image before delivering it\n * from Portive. This means that in regular Markdown that doesn't have any\n * special understanding of Portive's special querystring encodings, the image\n * is still returned in the correct size.\n */\nexport function serializePortiveImageUrl(\n image: ImageSharedElement\n): string | undefined {\n if (image.url.startsWith(\"$\")) return \"\"\n const { hostname } = parseUrl(image.url)\n /**\n * Only parse portive URL if it is a portive recognized domain\n */\n if (hostname.match(/[.]portive[.]com$/i) && image.width && image.height)\n return `${image.url}?size=${image.width}x${image.height}`\n}\n","import { ImageSharedElement } from \"../../../image-plugin/types\"\n\n/**\n * In UncommonMark, we provide hints after the hash `#` portion of the URL that\n * does not affect the URL of the image being delivered. It is usually used to\n * tell the browser to scroll to the given section in a linked document.\n *\n * https://imageservice.com/abcdefg.jpg#srcSize=1024x768&size=640x480\n */\nexport function serializeUncommonmarkImageUrl(\n image: ImageSharedElement\n): string | undefined {\n if (image.width && image.height && image.srcWidth && image.srcHeight)\n return `${image.url}#srcSize=${image.srcWidth}x${image.srcHeight}&size=${image.width}x${image.height}`\n}\n","import { ImageSharedElement } from \"../../../image-plugin/types\"\n\nimport { serializeGenericImageUrl } from \"./serialize-generic-image-url\"\nimport { serializePortiveImageUrl } from \"./serialize-portive-image-url\"\nimport { serializeUncommonmarkImageUrl } from \"./serialize-uncommonmark-image-url\"\n\nconst urlSerializers = [\n serializePortiveImageUrl,\n serializeUncommonmarkImageUrl,\n serializeGenericImageUrl,\n]\n\nexport function serializeImageShared(image: ImageSharedElement): string {\n for (const urlSerializer of urlSerializers) {\n const url = urlSerializer(image)\n if (typeof url === \"string\") {\n /**\n * Sometimes the serialized URL will return \"\" which means that the URL\n * hasn't returned yet. When this happens, we don't want the markdown for\n * the image to be added to the final value because the image would be\n * invalid. This happens when the image is uploading.\n */\n if (url === \"\") return \"\"\n return ``\n }\n }\n /**\n * Shouldn't get here because the last url seializer `serializeGenericUrl`\n * always returns a value.\n */\n throw new Error(`Shouldn't get here`)\n}\n","import { ImageBlockElement } from \"../../../image-plugin/types\"\n\nimport { serializeImageShared } from \"../serialize-image-shared\"\n\n/**\n * Serialize an image block element to markdown.\n *\n * Block-level images require trailing newlines (\\n\\n) to properly separate\n * them from subsequent content. Without these newlines, content immediately\n * following an image (like headings) would be parsed as part of the same\n * paragraph, breaking the markdown structure.\n *\n * Example:\n * Correct: \\n\\n# Heading\n * Incorrect: # Heading <- heading becomes plain text\n */\nexport function serializeImageBlock(element: ImageBlockElement): string {\n const imageMarkdown = serializeImageShared(element)\n return imageMarkdown ? `${imageMarkdown}\\n\\n` : \"\"\n}\n","import { Element as SlateElement, Text as SlateText } from \"slate\"\n\nimport { MarkKey, Segment } from \"../../types\"\nimport { diffMarks } from \"./diff-marks\"\nimport { normalizeLine } from \"./normalize-line\"\nimport { serializeSegment } from \"./segment/serialize-segment\"\nimport {\n convertMarksToOpenSymbols,\n convertMarksToCloseSymbols,\n getMarksFromSegment,\n isPlainSpace,\n} from \"./utils\"\n\n/**\n * Takes a line (an array of Segment) and turns it into markdown.\n *\n * The majority of this code deals with how we convert marks like `bold` and\n * `italic` into symbols and where to place them. There are several complicated\n * cases we need to handle like:\n *\n * - Symbols must always be placed on the inside of spaces next to the word like\n * \" **bold** \" and not \"** bold **\". We need to be aware of our placement of\n * symbols around spaces but spaces themselves can safely and actually must\n * ignore the actual marks on them. A bold space and a not-bold space are\n * considered the same in Markdown.\n * - Anchors must have common marks moved out of them\n * - Anchors must have not common marks set inside of them\n */\nexport function serializeLine(\n inputSegments: Segment[],\n leadingMarks: MarkKey[] = [],\n trailingMarks: MarkKey[] = []\n): string {\n /**\n * Normalize line does a lot of the work here to take any spaces that can be\n * found around the edges of segments and turns them into their own segments.\n * We don't need to do this in spaces on the inside of segments though.\n *\n * This is important because at the boundaries of segments, that's when marks\n * change (e.g. bold/italic) and it is at these points, we need to put spaces\n * into separate segments so that we can place the symbols for the marks\n * around them.\n */\n const segments = normalizeLine(inputSegments)\n const substrings: string[] = []\n\n /**\n * In order to seed the loop, we start by creating a `leadingDiff` going from\n * the `leadingMarks` provided to this method and the marks in the first\n * segment.\n *\n * The `leadingMarks` will always be `[]` at the beginning. When we get into a\n * nested `anchor` though, there may be some marks that had been previously\n * set outside of the anchor that need to be considered.\n */\n let leadingDiff = diffMarks(leadingMarks, getMarksFromSegment(segments[0]))\n\n /**\n * In each iteration, we want to serialize the following:\n *\n * - Symbols that represent all the marks to add to this segment\n * - The markdown for the segment itself (text, inline code, anchor, inline\n * image)\n * - Symbols that represent all the marks to remove from this segment\n */\n for (let i = 0; i < segments.length; i++) {\n /**\n * This is the current segment that we are looking at.\n */\n const segment = segments[i]\n\n /**\n * If it's plain space, add it to markdown and start at the top of the loop\n * again\n *\n * Basically, ignore the symbols we need to add when it's a space.\n *\n * The symbols get handled by the non-space segments.\n *\n * When we continue, we end up with the same `leadingDiff` from the last\n * segment which is what we want. This is because the `leadingDiff` actually\n * applies to the next Segment which should be either a not space Text or an\n * Element.\n */\n if (SlateText.isText(segment) && isPlainSpace(segment)) {\n substrings.push(segment.text)\n continue\n }\n\n /**\n * Here is where we add the serialization of the segment.\n *\n * First we start by adding the symbols needed to add the marks to this\n * segment.\n */\n substrings.push(convertMarksToOpenSymbols(leadingDiff.add))\n\n /**\n * Then we add the Text or the Anchor for the segment\n */\n substrings.push(serializeSegment(segment))\n\n /**\n * Now we are searching for the next segment which we want to grab the marks\n * from. Basically, any segment that isn't a space. For clarity, in this\n * algorithm, we should never have two `isPlainSpace` segments in a row\n * because this would have been normalized to one `isPlainSpace` segment in\n * the call to `normalizeLine`\n */\n const nextMarks = getNextMarks(segments, i, trailingMarks)\n const trailingDiff = diffMarks(leadingDiff.nextOrderedMarks, nextMarks)\n substrings.push(convertMarksToCloseSymbols(trailingDiff.remove))\n\n /**\n * The `trailingDiff` becomes the new `leadingDiff`\n */\n leadingDiff = trailingDiff\n }\n return substrings.join(\"\")\n}\n\n/**\n * Looks for the next set of valid marks by\n *\n * This method is local to `serialize-line` as it's intimiately tied with the\n * call to `getNextMarks` in `serializeLine`\n */\nfunction getNextMarks(\n segments: Segment[],\n index: number,\n trailingMarks: MarkKey[]\n): MarkKey[] {\n /**\n * Starting at the index `i` following the current index `index`\n *\n * If it's a plain space, skip it.\n *\n * If it isn't, get the marks for the segment.\n *\n * NOTE:\n *\n * If the segment is an `anchor` we the common marks for all the segments in\n * the anchor not including the plain spaces.\n */\n for (let i = index + 1; i < segments.length; i++) {\n const segment = segments[i]\n if (isPlainSpace(segment)) continue\n if (SlateElement.isElement(segment)) {\n const element = segment as { type?: string }\n if (element.type === \"image-inline\") continue\n }\n return getMarksFromSegment(segment)\n }\n return trailingMarks\n}\n","import { MarkKey } from \"../../../types\"\nimport { sortMarks } from \"../utils\"\n\n/**\n * Find the marks to add in ordere to get our orderedMarks to match the\n * `targetMarks`.\n *\n * We do this in a smart, but perhaps, imperfect way.\n *\n * When we need to add marks, we add them in an order that is more likely to\n * reduce the number of marks we add. See the comments under `MARK_KEY_ORDER` to\n * find out how.\n *\n * That said, we could probably choose a more complex algorithm that looks at\n * all the text to find out how to most efficiently place which marks as outer\n * or inner marks; however, there will still be situations in which the choice\n * will be arbitrary and this would likely greatly increase the complexity of\n * the code.\n *\n * This feels like a good trade-off and is likely to cause an unreadable\n * markdown representation. I suppose if for some reason a user had a bunch of\n * superscripted text which was intermittently styled with bold and italic, then\n * we'd have less than ideal markdown.\n */\nexport function findMarksToAdd(\n orderedMarks: MarkKey[],\n targetMarks: MarkKey[]\n) {\n const marksWeNeedToAdd = targetMarks.filter(\n (mark) => !orderedMarks.includes(mark)\n )\n const orderedMarksToAdd = sortMarks(marksWeNeedToAdd)\n return { orderedMarksToAdd }\n}\n","import { MarkKey } from \"../../../types\"\n\n/**\n * Takes a list of our current `orderedMarks` (i.e. what marks have been applied\n * to our text and in which order) and then gives us a list of `targetMarks`\n * which, for clarity, the order doesn't matter.\n *\n * We then create a list of `orderedMarksToRemove` which is a list of marks we\n * need to remove in the correct order, in order to satisfy that there aren't\n * any marks left that aren't also in the `targetMarks`.\n */\nexport function findMarksToRemove(\n orderedMarks: MarkKey[],\n targetMarks: MarkKey[]\n): { orderedMarksToRemove: MarkKey[]; nextOrderedMarks: MarkKey[] } {\n /**\n * As a good practice, don't manipulate the incoming argument (even though\n * technically it doesn't matter here)\n */\n const nextOrderedMarks = [...orderedMarks]\n\n /**\n * Find the marks that we need to remove.\n */\n const marksWeNeedToRemove = orderedMarks.filter(\n (mark) => !targetMarks.includes(mark)\n )\n\n /**\n * An ordered array of marks to remove\n */\n const orderedMarksToRemove: MarkKey[] = []\n\n /**\n * We iterate a maximum number of times with an upper limit of\n * `nextOrderedMarks.length` to prevent infinite loops.\n *\n * If we meet our condition of removing all the `marksWeNeedToRemove` we are\n * going to break out of this loop early which is common. Used a for loop\n * instead of counting the number of loops and throwing an error.\n */\n for (let i = 0; i < orderedMarks.length; i++) {\n /**\n * If we don't have any more marks we need to remove, we are done so leave\n * the loop.\n */\n if (marksWeNeedToRemove.length === 0) break\n /**\n * Remove the last mark\n */\n const markToRemove = nextOrderedMarks.pop()\n if (markToRemove === undefined) {\n throw new Error(\n `This shouldn't happen unless we made a mistake in the algorithm`\n )\n }\n /**\n * Add to our `orderedMarkToRemove` which is done in the correct order\n * because we are popping them off from the right.\n */\n orderedMarksToRemove.push(markToRemove)\n\n /**\n * Whatever we added to our list of `orderedMarksToRemove` we can now take\n * off our list of `marksWeNeedToRemove`. Sometimes we will be removed marks\n * that don't take anything off our list of `marksWeNeedToRemove` because of\n * the order in which we need to remove marks.\n *\n * For this reason, the check to see if the `mark` was in our list of\n * `marksWeNeedToRemove` is important.\n */\n const index = marksWeNeedToRemove.indexOf(markToRemove)\n if (index !== -1) {\n marksWeNeedToRemove.splice(index, 1)\n }\n }\n\n return { orderedMarksToRemove, nextOrderedMarks }\n}\n","import { MarkKey } from \"../../../types\"\nimport { findMarksToAdd } from \"./find-marks-to-add\"\nimport { findMarksToRemove } from \"./find-marks-to-remove\"\n\n/**\n * Takes a set of incoming marks and a set of target markets and returns what\n * marks need to be removed including the order in which they need to be removed\n * and what marks need to be added including the order in which they needed to\n * be added.\n *\n * The algorithm, collectively, is a little complex because we must always\n * remove an inner set of mark symbols before we can remove an outer set. This\n * means that sometimes when we want to remove a mark, we end up actually having\n * to add one. Like in this scenario:\n *\n * **_bold italic_** _italic_\n *\n * In order to go from bold and italic to just italic, we need to first remove\n * the inner italic, then remove the outer bold, and because the italic was\n * removed we need to add back the italic.\n *\n * Note that the algorithm is asymmetrical. It's just the way it has to be.\n */\nexport function diffMarks(orderedMarks: MarkKey[], targetMarks: MarkKey[]) {\n /**\n * First we remove the marks in order to arrive at our target marks.\n *\n * The algorithm basically just takes off the inner-most (right-most) marks\n * and adds them to `marsToRemove` until we don't have any marks that aren't\n * also in the `targetMarks`.\n *\n * Because we may be over-removing the marks, the method returns a\n * `nextOrderedMarks` or basically the `orderedMarks` after the remove has\n * happened. We then use this as the basis to add any marks we need back to\n * arrive at our `targetMarks`.\n */\n const { orderedMarksToRemove, nextOrderedMarks } = findMarksToRemove(\n orderedMarks,\n targetMarks\n )\n /**\n * We call out to a method that adds the necessary marks back in. The\n * algorithm here is pretty straightforward. Just add back the marks we need\n * and to achieve some level of consistency, add them back in a specific order\n * that feels nice and makes sense. For example, superscript/subscript is more\n * nested than bold because they are more likely to be toggled.\n */\n const { orderedMarksToAdd } = findMarksToAdd(nextOrderedMarks, targetMarks)\n return {\n remove: orderedMarksToRemove,\n add: orderedMarksToAdd,\n nextOrderedMarks: [...nextOrderedMarks, ...orderedMarksToAdd],\n }\n}\n","import { Element } from \"slate\"\n\nimport { Segment } from \"../../../types\"\nimport { normalizeNodes } from \"./normalize-nodes\"\nimport { LineElement } from \"./types\"\n\n/**\n * A very focused duplicate function that only duplicates the `children` of\n * `anchor` elements.\n *\n * It's designed this way to be fast and to avoid duplicating the entire tree\n * as only anchors have children that will be manipulated.\n */\nconst duplicateSegments = (segments: Segment[]): Segment[] => {\n return segments.map((segment) => {\n if (Element.isElement(segment) && segment.type === \"anchor\") {\n return {\n ...segment,\n children: duplicateSegments(segment.children as Segment[]),\n }\n } else {\n return segment\n }\n })\n}\n\n/**\n * Entry Point for normalizing\n */\nexport function normalizeLine(segments: Segment[]) {\n /**\n * We need to duplicate `segments` because `normalizeNodes` will manipulate the\n * array but the original array coming from Slate will be readOnly.\n */\n const line: LineElement = {\n type: \"line\",\n children: duplicateSegments(segments),\n }\n normalizeNodes([line], undefined)\n return line.children\n}\n","import { isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\n/**\n * If we ever find two spaces next to each other, merge them together.\n *\n * This can happen, for example, if there were spaces next to each other but\n * with different marks. It can also happen from other normalizers. For example,\n * there is a normalizer that moves spaces at the outer edges of an anchor\n * outside of the anchor.\n */\nexport function mergeAdjacentSpaces({\n node,\n nextNode,\n nodes: nodes,\n index,\n}: NormalizeOptions): boolean {\n if (!isText(node) || !isPlainSpace(node) || node.code) return false\n if (!isText(nextNode) || !isPlainSpace(nextNode) || node.code) return false\n nodes.splice(index, 2, { text: `${node.text}${nextNode.text}` })\n return true\n}\n","import { Segment } from \"../../../../types\"\nimport { isElement, isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function moveSpacesAtStartOfAnchor({\n node,\n nodes,\n prevNode,\n index,\n}: NormalizeOptions): boolean {\n if (!isElement(node)) return false\n if (node.type !== \"anchor\") return false\n const firstChild = node.children[0] as Segment\n if (isText(firstChild) && isPlainSpace(firstChild)) {\n // remove the first child from the anchor\n node.children.splice(0, 1)\n // add the first child\n if (isText(prevNode) && isPlainSpace(prevNode)) {\n prevNode.text = `${prevNode.text}${firstChild.text}`\n } else {\n nodes.splice(index, 0, { text: firstChild.text })\n }\n return true\n }\n return false\n}\n\nexport function moveSpacesAtEndOfAnchor({\n node,\n nodes,\n nextNode,\n index,\n}: NormalizeOptions): boolean {\n if (!isElement(node)) return false\n if (node.type !== \"anchor\") return false\n const lastChild = node.children[node.children.length - 1] as Segment\n if (isText(lastChild) && isPlainSpace(lastChild)) {\n // remove the first child from the anchor\n node.children.splice(node.children.length - 1, 1)\n // add the first child\n if (isText(nextNode) && isPlainSpace(nextNode)) {\n nextNode.text = `${lastChild.text}${nextNode.text}`\n } else {\n nodes.splice(index + 1, 0, { text: lastChild.text })\n }\n return true\n }\n return false\n}\n","import { isElement } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function mustHaveOneTextChild({ node }: NormalizeOptions): boolean {\n if (!isElement(node)) return false\n if (node.type !== \"line\") return false\n if (node.children.length > 0) return false\n node.children.push({ text: \"\" })\n return true\n}\n","import { Text } from \"../../../../types\"\nimport { isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\n/**\n * If a Text Node has spaces at the very start, or at the very end, we slice\n * those spaces into their own nodes.\n *\n * This is to help us later with the serialize process because we need spaces\n * to be isolated so that when we apple tokens like `**bold**` we are able\n * to place the tokens so that they are always against the non-space characters.\n *\n * For example, `** bold**` would not bold the text because the `**` is not\n * touching the word `bold` on the left.\n *\n * The algorithm here works by looking for a RegExp match on spaces on the\n * left or the right. If either are found, then it splits it into three parts\n * (left space, middle and right space) and then filteres out any zero length\n * spaces at the end. In this way, we handle left and right spaces in one\n * pass.\n */\nexport function sliceSpacesAtNodeBoundaries({\n node,\n nodes,\n index,\n}: NormalizeOptions): boolean {\n if (!isText(node)) return false\n if (isPlainSpace(node)) return false\n /**\n * The content of Inline Code is literal so don't move the spaces out of it.\n */\n if (node.code) return false\n const match = node.text.match(/^(\\s*)(.*?)(\\s*)$/)\n if (!match) return false\n if (match[1].length === 0 && match[3].length === 0) return false\n const nextSegments: Text[] = [\n { text: match[1] },\n { ...node, text: match[2] },\n { text: match[3] },\n ].filter((text) => text.text !== \"\")\n nodes.splice(index, 1, ...nextSegments)\n return true\n}\n","import { isElement, isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function trimSpaceAtEndOfLine({\n index,\n nodes,\n node,\n parent,\n}: NormalizeOptions): boolean {\n if (index !== nodes.length - 1) return false\n if (nodes.length <= 1) return false\n if (!isText(node)) return false\n if (!isPlainSpace(node)) return false\n if (parent && isElement(parent) && parent.type === \"line\") {\n nodes.splice(nodes.length - 1, 1)\n return true\n }\n return false\n}\n","import { isElement, isPlainSpace, isText } from \"../../utils\"\nimport { NormalizeOptions } from \"../types\"\n\nexport function trimSpaceAtStartOfLine({\n index,\n nodes,\n node,\n parent,\n}: NormalizeOptions): boolean {\n if (index !== 0) return false\n if (nodes.length === 0) return false\n if (!isText(node)) return false\n if (!isPlainSpace(node)) return false\n if (parent && isElement(parent) && parent.type === \"line\") {\n nodes.splice(0, 1)\n return true\n }\n return false\n}\n","import { NormalizeOptions } from \"../types\"\nimport { mergeAdjacentSpaces } from \"./merge-adjacent-spaces\"\nimport {\n moveSpacesAtEndOfAnchor,\n moveSpacesAtStartOfAnchor,\n} from \"./move-spaces-out-of-anchors\"\nimport { mustHaveOneTextChild } from \"./must-have-one-text-child\"\nimport { sliceSpacesAtNodeBoundaries } from \"./slice-spaces-at-node-boundaries\"\nimport { trimSpaceAtEndOfLine } from \"./trim-spaces-at-end-of-line\"\nimport { trimSpaceAtStartOfLine } from \"./trim-spaces-at-start-of-line\"\n\nexport const normalizers: Array<(options: NormalizeOptions) => boolean> = [\n sliceSpacesAtNodeBoundaries,\n moveSpacesAtStartOfAnchor,\n moveSpacesAtEndOfAnchor,\n mergeAdjacentSpaces,\n trimSpaceAtStartOfLine,\n trimSpaceAtEndOfLine,\n mustHaveOneTextChild,\n]\n","import { normalizers } from \"./normalizers\"\nimport { NormalizeOptions } from \"./types\"\n\n/**\n * Attempts to run all normalizers on the given Node one by one.\n *\n * If any normalizer makes an update, this function exits immediately and\n * returns a `true` value indicating that a normalizer has made an update.\n *\n * Because we don't know how that update modified the data structure, another\n * pass will be made at running all the normalizers.\n *\n * This is not the most efficient route, but there isn't a lot of processing\n * we need to do and this reduces the likelihood of bugs. Normalization is\n * similar to how it works in Slate but we don't keep track of dirty paths\n * and simply rerun the normalizations at the given level until it is clean.\n */\nexport function runNormalizersOnNode(normalizeOptions: NormalizeOptions) {\n for (const normalizer of normalizers) {\n const isHandled = normalizer(normalizeOptions)\n if (isHandled) {\n return true\n }\n }\n return false\n}\n","import { AnchorElement } from \"../../../../anchor-plugin\"\n\nimport { isElement } from \"../utils\"\nimport { runNormalizersOnNode } from \"./run-normalizers-on-node\"\nimport { LineElement, Node, NormalizeOptions } from \"./types\"\n\nconst MAX_RERUNS = 72\n\nexport function normalizeNodes(\n nodes: Node[],\n parent?: AnchorElement | LineElement\n): boolean {\n let isAnyUpdated = false\n let isUpdated\n let runs = 0\n const maxReruns = (nodes.length + 1) * MAX_RERUNS\n do {\n isUpdated = false\n runs = runs + 1\n if (runs > maxReruns)\n throw new Error(\n `There have been ${runs} normalization passes (72x the number of nodes at this level). This likely indicates a bug in the code.`\n )\n segmentLoop: for (let i = 0; i < nodes.length; i++) {\n const node: Node = nodes[i]\n /**\n * Normalize the children of the current Node before normalizing the\n * Node itself.\n */\n if (isElement(node)) {\n const isChildrenUpdated = normalizeNodes(\n node.children as Array<AnchorElement | LineElement>,\n node\n )\n if (isChildrenUpdated) {\n isUpdated = true\n isAnyUpdated = true\n break segmentLoop\n }\n }\n /**\n * Create the normalizeOptions\n */\n const prevNode: Node | undefined = nodes[i - 1]\n const nextNode: Node | undefined = nodes[i + 1]\n const options: NormalizeOptions = {\n parent,\n node,\n prevNode,\n nextNode,\n index: i,\n nodes,\n }\n\n /**\n * Run the normalizers on this node.\n */\n if (runNormalizersOnNode(options)) {\n isUpdated = true\n isAnyUpdated = true\n break segmentLoop\n }\n }\n } while (isUpdated)\n return isAnyUpdated\n}\n","import { Text as SlateText } from \"slate\"\n\nimport { Segment } from \"../../../types\"\nimport { assertUnreachable } from \"../../../utils\"\nimport { serializeImageShared } from \"../../serialize-image-shared\"\nimport { serializeCodeText } from \"../segment/serialize-code-text\"\nimport { serializeAnchor } from \"./serialize-anchor\"\nimport { serializeNonCodeText } from \"./serialize-non-code-text\"\n\nexport function serializeSegment(segment: Segment): string {\n if (SlateText.isText(segment)) {\n /**\n * If the segment is a `code` segment, we need to use a different strategy\n * for escaping the `code` segment. This is why it needs a separate\n * serializing function.\n */\n if (segment.code) return serializeCodeText(segment)\n /**\n * Otherwise, we use the standard text escaping code.\n */\n return serializeNonCodeText(segment)\n }\n switch (segment.type) {\n case \"anchor\": {\n return serializeAnchor(segment)\n }\n case \"image-inline\":\n return serializeImageShared(segment)\n default:\n assertUnreachable(segment)\n }\n}\n","import { Text } from \"../../../types\"\n\nexport function serializeCodeText(text: Text): string {\n let max = 0\n for (const match of text.text.matchAll(/[`]+/g)) {\n max = Math.max(max, match[0].length)\n }\n if (max === 0) return `\\`${text.text.replace(/[`]/g, \"\\\\`\")}\\``\n return `${\"`\".repeat(max + 1)} ${text.text} ${\"`\".repeat(max + 1)}`\n}\n","import { AnchorElement } from \"../../../../anchor-plugin\"\n\nimport { Segment } from \"../../../types\"\nimport { serializeLine } from \"../serialize-line\"\nimport { getCommonAnchorMarks } from \"../utils\"\n\nfunction escapeTitle(title: string): string {\n return title.replace(/\"/g, '\\\\\"')\n}\n\nexport function serializeAnchor(anchor: AnchorElement): string {\n const commonAnchorMarks = getCommonAnchorMarks(anchor.children as Segment[])\n if (anchor.href.startsWith(\"$\"))\n return serializeLine(\n anchor.children as Segment[],\n commonAnchorMarks,\n commonAnchorMarks\n )\n if (typeof anchor.title === \"string\" && anchor.title.length > 0) {\n return (\n /**\n * TODO: Handle anchor children more elegantly in serializeAnchor.\n *\n * We type cast `children` as `Segment` here because the children of an\n * `anchor` is limited to be Inline types. There are two things to do\n * related to this though:\n *\n * - [ ] consider fixing the `anchor` type to actually limit the\n * children as expected.\n * - [ ] consider expanding the definition of `Segment` to include\n * inline images as that is an acceptable inline value which is\n * currently not defined as part of Segment.\n */\n `[${serializeLine(\n anchor.children as Segment[],\n commonAnchorMarks,\n commonAnchorMarks\n )}](${anchor.href} \"${escapeTitle(anchor.title)}\")`\n )\n } else {\n return (\n /**\n * TODO: Handle anchor children more elegantly in serializeAnchor.\n *\n * We type cast `children` as `Segment` here because the children of an\n * `anchor` is limited to be Inline types. There are two things to do\n * related to this though:\n *\n * - [ ] consider fixing the `anchor` type to actually limit the\n * children as expected.\n * - [ ] consider expanding the definition of `Segment` to include\n * inline images as that is an acceptable inline value which is\n * currently not defined as part of Segment.\n */\n `[${serializeLine(\n anchor.children as Segment[],\n commonAnchorMarks,\n commonAnchorMarks\n )}](${anchor.href})`\n )\n }\n}\n","import { Text } from \"../../../types\"\nimport { escapeText } from \"../utils\"\n\nexport function serializeNonCodeText(text: Text): string {\n return escapeText(text.text)\n}\n","import {\n TableCellElement,\n TableColumnAlign,\n TableContentElement,\n TableElement,\n TableRowElement,\n} from \"../../../table-plugin\"\n\nimport { Segment } from \"../../types\"\nimport { assert, assertElementType } from \"../../utils\"\nimport { serializeLine } from \"../serialize-line\"\n\nexport function serializeTable(element: TableElement): string {\n const lines: string[] = []\n lines.push(serializeTableRow(element.children[0]))\n lines.push(serializeColumns(element.columns))\n element.children.slice(1).forEach((row) => {\n lines.push(serializeTableRow(row))\n })\n return `${lines.join(\"\\n\")}\\n\\n`\n}\n\nfunction serializeColumns(columns: TableElement[\"columns\"]): string {\n const isAllLeft = columns.every((column) => column.align === \"left\")\n /**\n * If all of the columns are to the left, it looks nicer if we don't specify\n * column alignment in the markdown at all. Just use the default `---` to\n * specify each column.\n */\n if (isAllLeft) {\n return `|${columns.map(() => \"---\").join(\"|\")}|`\n }\n /**\n * If one or more of the columns is not aligned left, let's add some clarity\n * and specify the alignment of all the columns including the `left` aligned\n * ones.\n */\n return `|${columns.map((column) => serializeAlign(column.align)).join(\"|\")}|`\n}\n\nfunction serializeAlign(align: TableColumnAlign) {\n switch (align) {\n case \"left\":\n return \":---\"\n case \"center\":\n return \":---:\"\n case \"right\":\n return \"---:\"\n }\n}\n\nfunction serializeTableRow(element: TableRowElement): string {\n assertElementType(element, \"table-row\")\n return `|${element.children.map(serializeTableCell).join(\"|\")}|`\n}\n\nfunction serializeTableCell(element: TableCellElement): string {\n assertElementType(element, \"table-cell\")\n assert(\n element.children.length === 1,\n `Expected table-cell to have one child but is ${JSON.stringify(\n element.children\n )}`\n )\n return element.children.map(serializeTableContent).join()\n}\n\nfunction serializeTableContent(element: TableContentElement): string {\n assertElementType(element, \"table-content\")\n return serializeLine(element.children as Segment[])\n}\n","import { Element, Segment } from \"../types\"\nimport { assertUnreachable } from \"../utils\"\nimport { serializeElements } from \"./serialize-elements\"\nimport { serializeCodeBlock } from \"./serialize-code-block\"\nimport { serializeImageBlock } from \"./serialize-image-block\"\nimport { serializeLine } from \"./serialize-line\"\nimport { serializeTable } from \"./serialize-table\"\n\nconst LIST_INDENT_SIZE = 4\n\nexport function serializeElement(element: Element, orders: number[]): string {\n switch (element.type) {\n case \"anchor\":\n return `[${serializeLine(element.children as Segment[])}](${element.href\n })`\n case \"block-quote\": {\n const lines = serializeElements(element.children as Element[])\n return `${lines\n .split(\"\\n\")\n .map((line) => `> ${line}`.trim())\n .join(\"\\n\")}\\n\\n`\n }\n case \"heading\":\n return `${\"#\".repeat(element.level)} ${serializeLine(\n element.children as Segment[]\n )}\\n\\n`\n case \"horizontal-rule\":\n return \"---\\n\\n\"\n case \"paragraph\":\n return `${serializeLine(element.children as Segment[])}\\n\\n`\n /**\n * Table\n */\n case \"table\":\n return serializeTable(element)\n case \"table-row\":\n case \"table-cell\":\n case \"table-content\":\n throw new Error(\n `Table elements should only be present as children of table which should be handled by serializeTable. Got ${element.type} may indicate an error in normalization.`\n )\n /**\n * List\n */\n case \"unordered-list-item\": {\n const indent = \" \".repeat(element.depth * LIST_INDENT_SIZE)\n return `${indent}- ${serializeLine(element.children as Segment[])}\\n`\n }\n case \"ordered-list-item\": {\n const indent = \" \".repeat(element.depth * LIST_INDENT_SIZE)\n return `${indent}${orders[element.depth]}. ${serializeLine(\n element.children as Segment[]\n )}\\n`\n }\n case \"task-list-item\": {\n const indent = \" \".repeat(element.depth * LIST_INDENT_SIZE)\n let line = serializeLine(element.children as Segment[])\n if (line.trim() === \"\") {\n line = \" \"\n }\n return `${indent}- [${element.checked ? \"x\" : \" \"}] ${line}\\n`\n }\n case \"image-block\":\n return serializeImageBlock(element)\n case \"code-block\":\n return serializeCodeBlock(element)\n case \"code-block-line\":\n throw new Error(\n `Code block line elements should only be present as children of code-block which should be handled by serializeCodeBlock. Got code-block-line may indicate an error in normalization.`\n )\n case \"html-block\":\n return `${element.html}\\n\\n`\n }\n assertUnreachable(element)\n}\n","import { Element } from \"../types\"\nimport { serializeElement } from \"./serialize-element\"\n\nexport function serializeElements(elements: Element[]): string {\n const segments: string[] = []\n\n /**\n * The orders array keeps track of the number of ordered list items at each\n * depth. This is used to generate the number for each ordered list item.\n */\n let orders: number[] = []\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n const nextElement = i < elements.length - 1 ? elements[i + 1] : null;\n\n if (element.type === \"ordered-list-item\") {\n /**\n * When we're at an ordered list item, we increment the order at the\n * current depth level and we remove any orders at a deeper depth level.\n */\n orders[element.depth] = (orders[element.depth] || 0) + 1\n orders = orders.slice(0, element.depth + 1)\n } else if (\n element.type === \"unordered-list-item\" ||\n element.type === \"task-list-item\"\n ) {\n /**\n * When we're at an unordered list item, we slice the orders array to\n * remove any orders at a deeper depth level.\n */\n orders = orders.slice(0, element.depth)\n } else {\n /**\n * When we're at any other element, we reset the orders array because\n * we're no longer in a list.\n */\n orders = []\n }\n\n // Get the serialized element\n let serialized = serializeElement(element, orders);\n\n // If this is a list item and the next element is not a list item,\n // add an extra newline to create proper spacing between list and paragraph\n if ((element.type === \"ordered-list-item\" ||\n element.type === \"unordered-list-item\" ||\n element.type === \"task-list-item\") &&\n (!nextElement ||\n (nextElement.type !== \"ordered-list-item\" &&\n nextElement.type !== \"unordered-list-item\" &&\n nextElement.type !== \"task-list-item\"))) {\n serialized = serialized.replace(/\\n$/, \"\\n\\n\");\n }\n\n segments.push(serialized);\n }\n /**\n * NOTE:\n *\n * We remove trailing whitespace because we want minimum viable markdown.\n * It also makes it easier to test.\n */\n const joined = segments.join(\"\") //.trim()\n\n /**\n * If there is no content return an empty string for the Markdown.\n */\n if (joined.trim() === \"\") return \"\"\n\n /**\n * The following code replaces consecutive newlines with a single newline\n * with a bit of additional logic to handle newlines at the beginning.\n */\n return replaceConsecutiveNewlines(replaceLeadingNewlines(joined)).trim()\n}\n\n/**\n * Replace two leading newlines with a backslash to indicate a\n * paragraph that won't be collapsed.\n * Using backslash (Markdown hard line break) for Obsidian compatibility.\n */\nfunction replaceLeadingNewlines(input: string): string {\n return input.replace(/^\\n\\n/g, \"\\\\\\n\\n\")\n}\n\n/**\n * In the rest of the Markdown, replace four or more consecutive newlines with\n * backslashes and newlines to indicate a paragraph that won't be collapsed.\n * Using backslash (Markdown hard line break) for Obsidian compatibility.\n */\nfunction replaceConsecutiveNewlines(input: string): string {\n return input.replace(/(\\n{4,})/g, (match) => {\n const newlineCount = match.length\n const count = Math.floor((newlineCount - 2) / 2)\n return \"\\n\\n\" + Array(count).fill(\"\\\\\").join(\"\\n\\n\") + \"\\n\\n\"\n })\n}\n","import { Element } from \"../types\"\nimport { normalizeElementListDepths } from \"./normalize/normalizeElementListDepths\"\nimport { serializeElements } from \"./serialize-elements\"\n\nexport function serialize(elements: Element[]): string {\n const normalizedElements = normalizeElementListDepths(elements)\n return serializeElements(normalizedElements)\n}\n","interface Translations {\n [key: string]: {\n bold: string;\n italic: string;\n strike: string;\n inlineCode: string;\n underline: string;\n highlight: string;\n increaseDepth: string;\n decreaseDepth: string;\n heading1: string;\n heading2: string;\n heading3: string;\n normal: string;\n paragraph: string;\n paragraphStyle: string;\n bulletList: string;\n numberedList: string;\n checkList: string;\n list: string;\n linkUrl: string;\n linkText: string;\n linkTextHint: string;\n tooltipText: string;\n tooltipHint: string;\n apply: string;\n cancel: string;\n insertLink: string;\n quote: string;\n insertTable: string;\n insertImage: string;\n insertImageFromUrl: string;\n insert: string;\n format: string;\n imageUrlRequired: string;\n altText: string;\n title: string;\n imageDescription: string;\n imageTitle: string;\n switchToVisualEditor: string;\n switchToRawMarkdown: string;\n codeBlock: string;\n increaseQuoteDepth: string;\n register: string;\n imageSourceUrl: string;\n imageSourceFile: string;\n selectFile: string;\n uploading: string;\n saving: string;\n uploadComplete: string;\n vaultPath: string;\n vaultPathHint: string;\n };\n}\n\nexport const translations: Translations = {\n ja: {\n bold: \"太字\",\n italic: \"斜体\",\n strike: \"取り消し線\",\n inlineCode: \"インラインコード\",\n underline: \"下線\",\n highlight: \"ハイライト\",\n increaseDepth: \"階層を深くする\",\n decreaseDepth: \"階層を浅くする\",\n heading1: \"見出し1\",\n heading2: \"見出し2\",\n heading3: \"見出し3\",\n normal: \"標準\",\n paragraph: \"段落\",\n paragraphStyle: \"段落スタイル\",\n bulletList: \"箇条書き\",\n numberedList: \"番号付きリスト\",\n checkList: \"チェックリスト\",\n list: \"リスト\",\n linkUrl: \"リンクのURL\",\n linkText: \"リンクテキスト\",\n linkTextHint: \"リンクとして表示されるテキスト\",\n tooltipText: \"ツールチップテキスト\",\n tooltipHint: \"マウスホバー時に表示されるツールチップ\",\n apply: \"適用\",\n cancel: \"キャンセル\",\n insertLink: \"リンク\",\n quote: \"引用\",\n insertTable: \"表\",\n insertImage: \"画像\",\n insertImageFromUrl: \"画像\",\n insert: \"挿入\",\n format: \"書式\",\n imageUrlRequired: \"画像URL(必須):\",\n altText: \"代替テキスト:\",\n title: \"ツールチップ:\",\n imageDescription: \"画像の説明\",\n imageTitle: \"画像のツールチップ\",\n switchToVisualEditor: \"ビジュアルエディタに切り替え\",\n switchToRawMarkdown: \"マークダウン表示に切り替え\",\n codeBlock: \"コードブロック\",\n increaseQuoteDepth: \"引用を重ねる\",\n register: \"登録\",\n imageSourceUrl: \"URL\",\n imageSourceFile: \"ファイル\",\n selectFile: \"ファイルを選択\",\n uploading: \"アップロード中...\",\n saving: \"保存中...\",\n uploadComplete: \"アップロード完了\",\n vaultPath: \"保存先パス:\",\n vaultPathHint: \"vault内の保存先パスを入力してください\",\n },\n en: {\n bold: \"Bold\",\n italic: \"Italic\",\n strike: \"Strikethrough\",\n inlineCode: \"Inline Code\",\n underline: \"Underline\",\n highlight: \"Highlight\",\n increaseDepth: \"Increase Depth\",\n decreaseDepth: \"Decrease Depth\",\n heading1: \"Heading 1\",\n heading2: \"Heading 2\",\n heading3: \"Heading 3\",\n normal: \"Normal\",\n paragraph: \"Paragraph\",\n paragraphStyle: \"Paragraph Style\",\n bulletList: \"Bullet List\",\n numberedList: \"Numbered List\",\n checkList: \"Check List\",\n list: \"List\",\n linkUrl: \"Link URL\",\n linkText: \"Link Text\",\n linkTextHint: \"Text displayed as the link\",\n tooltipText: \"Tooltip Text\",\n tooltipHint: \"Tooltip shown on mouse hover\",\n apply: \"Apply\",\n cancel: \"Cancel\",\n insertLink: \"Link\",\n quote: \"Quote\",\n insertTable: \"Table\",\n insertImage: \"Image\",\n insertImageFromUrl: \"Image\",\n insert: \"Insert\",\n format: \"Format\",\n imageUrlRequired: \"Image URL (required):\",\n altText: \"Alt Text:\",\n title: \"tooltip:\",\n imageDescription: \"Description of the image\",\n imageTitle: \"tooltip\",\n switchToVisualEditor: \"Switch to visual editor\",\n switchToRawMarkdown: \"Switch to raw markdown\",\n codeBlock: \"Code Block\",\n increaseQuoteDepth: \"Increase Quote Depth\",\n register: \"Register\",\n imageSourceUrl: \"URL\",\n imageSourceFile: \"File\",\n selectFile: \"Select File\",\n uploading: \"Uploading...\",\n saving: \"Saving...\",\n uploadComplete: \"Upload Complete\",\n vaultPath: \"Save Path:\",\n vaultPathHint: \"Enter the path within the vault to save the file\",\n },\n};\n\nexport type TranslationKey = keyof Translations[\"en\"];\n\nconst getLanguage = (): string => {\n try {\n // Check if we're in a browser environment\n if (typeof window !== 'undefined' && window.navigator) {\n return window.navigator.language.split(\"-\")[0];\n }\n } catch {\n // Ignore any errors\n }\n // Default to 'en' in server environment\n return 'en';\n};\n\nexport const t = (key: TranslationKey): string => {\n const lang = getLanguage();\n return translations[lang === \"ja\" ? \"ja\" : \"en\"][key];\n};\n\nexport const r = (value: string): string => {\n const lang = getLanguage();\n // 値がvalueと一致するキーを取得\n const key = Object.keys(translations[lang === \"ja\" ? \"ja\" : \"en\"]).find(\n (k) => translations[lang === \"ja\" ? \"ja\" : \"en\"][k as TranslationKey] === value\n ) as TranslationKey;\n return key || \"\";\n};\n","import { InputPluginSchema, TypedPluginFunction } from \"../types\"\nimport { BasePlugin } from \"../types/plugin/plugin\"\n\n/**\n * The `createPlugin` method here takes a function and returns the same\n * function.\n *\n * From a JavaScript point of view, it does nothing itself return itself.\n *\n * From a typing point of view, it takes these two arguments...\n *\n * - The CustomTypes used by the plugin as a Generic\n * - A function that when executed with an `Editor` object, returns a\n * PluginObject as a function argument\n *\n * ...and ensure that the function argument adheres to the limits of the\n * Generic Argument.\n *\n * For example, if the CustomTypes defines an `Element`, then the function\n * argument will have its element related methods constrained to the Element\n * given in CustomTypes.\n *\n * The benefit of this is that it helps the Plugin only see what is relevant\n * to this plugin. In fact, it insists on it. This will prevent accidental\n * dependency on another plugin.\n *\n * You can add dependencies between plugins, but when we do that, it insists\n * on having that done explicitly.\n */\nexport const createPlugin = <T extends InputPluginSchema>(\n fn: TypedPluginFunction<T>\n) => {\n return { fn } as BasePlugin\n}\n","import { useEffect, useMemo } from \"react\"\nimport { Editor } from \"slate\"\nimport { useSlateStatic } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { SinkEditor } from \"../types\"\nimport { createDecorate } from \"./create-decorate\"\nimport { createEditable } from \"./create-editable\"\nimport {\n createOnDrop,\n createOnKeyDown,\n createOnKeyUp,\n createOnPaste,\n} from \"./create-handler\"\nimport { createRenderElement } from \"./create-render-element\"\nimport { createRenderLeaf } from \"./create-render-leaf\"\nimport { createRenderPlaceholder } from \"./create-render-placeholder\"\nexport { SinkReset } from \"./styles\"\n\n/**\n * In Editable, we use the Slate context to grab the right things from\n * the editor.\n */\nexport function SinkEditable(originalProps: EditableProps): React.ReactElement {\n const editor = useSlateStatic() as unknown as Editor & SinkEditor\n\n /**\n * We ask Slate to normalize the editor once at the very start.\n *\n * This is helpful for plugins that need to store some useful state in the\n * document and to add or fix certain parts of the document. Not all of\n * these values are stored in the saved documents.\n *\n * Some examples:\n *\n * - inserting collapsible paragraphs between void components. These should\n * not be saved.\n *\n * - Add column and row indexes to help with rendering which should not\n * be saved.\n *\n * Ideally, we wouldn't have to do any of this but pragmatically, it is\n * the most performant route.\n *\n * Once we normalize the document once, the document is kept up to date\n * through regular normalizing steps that are more performance because\n * they only check changed nodes.\n */\n useEffect(() => {\n Editor.normalize(editor, { force: true })\n }, [])\n\n const { plugins } = editor.sink\n\n const nextProps: EditableProps = useMemo(\n () => ({\n ...originalProps,\n decorate: createDecorate(originalProps.decorate, plugins),\n renderElement: createRenderElement(originalProps.renderElement, plugins),\n renderLeaf: createRenderLeaf(originalProps.renderLeaf, plugins),\n renderPlaceholder: createRenderPlaceholder(\n originalProps.renderPlaceholder,\n plugins\n ),\n /**\n * NOTE: We skip `onKeyUp` as it is deprecated. If somebody needs it in new\n * code, we can add it back in.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event\n */\n onKeyDown: createOnKeyDown(originalProps.onKeyDown, plugins),\n onKeyUp: createOnKeyUp(originalProps.onKeyUp, plugins),\n onPaste: createOnPaste(originalProps.onPaste, plugins),\n onDrop: createOnDrop(originalProps.onDrop, plugins),\n }),\n Object.values(originalProps)\n )\n\n const NextEditable = useMemo(() => createEditable(plugins), [plugins])\n\n /**\n * NOTE:\n *\n * The following code is used to see if we are getting unnecessary re-renders.\n *\n * Comment it out when we are happy.\n *\n * - We SHOULD see `SinkeEditable render` whenever the markdown is updated\n * - We SHOULD NOT see `SinkEditable mount` or unmount at each update\n */\n // console.log(\"SinkEditable render\")\n\n // console.log(Object.values(nextProps))\n\n // useEffect(() => {\n // console.log(\"SinkEditable mount\")\n // return () => {\n // console.log(\"SinkEditable unmount\")\n // }\n // }, [NextEditable, nextProps])\n\n return <NextEditable {...nextProps} />\n}\n","export function defined<T>(value: T | undefined): value is T {\n return !!value\n}\n","import { NodeEntry, Range } from \"slate\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `decorate` method.\n *\n * With decorate, we are taking all the ranges from all the decorators and\n * combining them together, including the ranges created from the `decorate`\n * attribute on `SinkEditable`.\n */\nexport function createDecorate(\n originalFn: EditableProps[\"decorate\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"decorate\"]> {\n const fns = plugins\n .map((plugin) => plugin.editableProps?.decorate)\n .filter(defined)\n return function (entry: NodeEntry): Range[] {\n const ranges: Range[] = []\n for (const fn of fns) {\n const resultRanges = fn(entry)\n ranges.push(...resultRanges)\n }\n if (originalFn) ranges.push(...originalFn(entry))\n return ranges\n }\n}\n","import { Editable } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\ntype EditableType = (editableProps: EditableProps) => React.ReactElement\n\n/**\n * create a new Editable component that takes all the `renderEditable` functions\n * which are components and have them wrap around the original Editable component.\n */\nexport function createEditable(\n plugins: BasePluginPolicy[]\n): NonNullable<EditableType> {\n const fns = plugins.map((plugin) => plugin.renderEditable).filter(defined)\n\n /**\n * This creates the inner-most RenderEditable.\n */\n let CurrentRenderEditable = (props: EditableProps) => <Editable {...props} />\n /**\n * We iterate through all the `renderEditable` functions and wrap them\n * around the next inner-most `renderEditable`.\n */\n for (const fn of fns) {\n /**\n * Assigns the CurrentRenderEditable as the previous one so that we can\n * have it available to call in the NextRenderEditable\n */\n const PrevRenderEditable = CurrentRenderEditable\n\n CurrentRenderEditable = (props: EditableProps) => {\n return fn({\n attributes: props,\n Editable: PrevRenderEditable,\n })\n }\n }\n\n return CurrentRenderEditable\n}\n","import { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\n\n/**\n * Create the substituted event handler method.\n *\n * Generally, we are looking for the first result from any plugin or on\n * SinkEditable and return the first one that returns a value only.\n *\n * Iterate over all the plugin handlers. If one handler returns `false`\n * then we go to the next one until we get one that returns `true`. If we don't\n * fine on that returns `true`, then we go to the handler passed to the\n * `SinkEditable` component.\n */\n\n/**\n * TODO:\n *\n * It's probably not THAT important, but the holy grail as a programmer here is\n * to:\n *\n * 1. Have these functions created without the boilerplate. It really feels\n * like it could be one function that takes `plugins` and a `key` and all\n * the typing and stuff would work.\n *\n * 2. Build it in a way that's easy to reason about. There is probably a way\n * to do this that works, but nobody will ever be able to work on it if there\n * is a problem, and probably a way to do it where it's somewhat\n * comprehensible.\n */\n\n/**\n * Here we define strictly the type for a method that creates an Event Handler\n * on Editable. We define this separately because (a) it is easier to do it and\n * give clarity to it as a separate type and (b) we want to check the actual\n * method that we created against this type as an early warning signal if we\n * did something wrong.\n *\n * A method that creates a method, that pulls from a plugin a function that is\n * similar to, but not exactly, like the function that it is going to be\n * returning, is a bit of a nightmare and this helps make sure we don't make\n * mistakes.\n *\n * In other words, don't remove this and use the automatic typing as it's a\n * good way to make sure that this method is typed correctly.\n */\ntype CreateHandler<K extends keyof EditableProps> = (\n originalFn: EditableProps[K],\n plugins: BasePluginPolicy[]\n) => NonNullable<EditableProps[K]>\n\n/**\n * Takes an array of Plugin objects and extracts all of the specified\n * `editableProps` handler functions from it. If it's not defined, we skip it\n * so that we end up with an Array that is populated with the functions only\n * and no `undefined` in it.\n */\nfunction extractEditableFns<\n K extends keyof Required<BasePluginPolicy>[\"editableProps\"]\n>(\n plugins: BasePluginPolicy[],\n key: K\n): NonNullable<Required<BasePluginPolicy>[\"editableProps\"][K]>[] {\n const fns: NonNullable<Required<BasePluginPolicy>[\"editableProps\"][K]>[] = []\n for (const plugin of plugins) {\n const maybeFn = plugin.editableProps?.[key]\n if (maybeFn) fns.push(maybeFn)\n }\n return fns\n}\n\n/**\n * Takes an array of handler functions that will return a boolean which\n * indicates that an event was handled. If the function was handled, then we\n * return and stop execution immediately.\n *\n * We keep going through all the handlers until something handles it.\n *\n * If none of the plugin fns handle it, then we check to see if there was an\n * original function defined and execute that if there is.\n */\nfunction createHandlerFn<A>(\n fns: ((arg: A) => boolean)[],\n originalFn: ((arg: A) => void) | undefined\n) {\n return function (event: A) {\n for (const fn of fns) {\n if (fn(event)) return\n }\n originalFn?.(event)\n }\n}\n\n/**\n * keyDown handler\n */\nexport const createOnKeyDown: CreateHandler<\"onKeyDown\"> = (\n originalFn,\n plugins\n) => {\n const fns = extractEditableFns(plugins, \"onKeyDown\")\n return createHandlerFn(fns, originalFn)\n}\n\n/**\n * keyUp handler\n */\nexport const createOnKeyUp: CreateHandler<\"onKeyUp\"> = (\n originalFn,\n plugins\n) => {\n const fns = extractEditableFns(plugins, \"onKeyUp\")\n return createHandlerFn(fns, originalFn)\n}\n\n/**\n * onPaste handler\n */\nexport const createOnPaste: CreateHandler<\"onPaste\"> = (\n originalFn,\n plugins\n) => {\n const fns = extractEditableFns(plugins, \"onPaste\")\n return createHandlerFn(fns, originalFn)\n}\n\n/**\n * onDrop handler\n */\nexport const createOnDrop: CreateHandler<\"onDrop\"> = (originalFn, plugins) => {\n const fns = extractEditableFns(plugins, \"onDrop\")\n return createHandlerFn(fns, originalFn)\n}\n","import { RenderElementProps } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `renderElement` method.\n *\n * Generally, we are looking for the first result from any plugin or on\n * SinkEditable and return the first one that returns a value only.\n *\n * Iterate over all the plugin `renderElement`. If they return nothing\n * then we go to the next one until we hit a result. If we don't hit a\n * result, then we go to the `renderElement` passed to the `SinkEditable`\n * component.\n */\n\nexport function createRenderElement(\n originalFn: EditableProps[\"renderElement\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"renderElement\"]> {\n const fns = plugins\n .map((plugin) => plugin.editableProps?.renderElement)\n .filter(defined)\n return function renderElement(\n renderElementProps: RenderElementProps\n ): JSX.Element {\n for (const fn of fns) {\n const result = fn(renderElementProps)\n if (result) return result\n }\n if (originalFn === undefined) {\n throw new Error(\n `Element with type ${renderElementProps.element.type} not handled. Note that renderElement is not defined on SinkEditable so this is only the result of checking the Sink Plugins.`\n )\n }\n return originalFn(renderElementProps)\n }\n}\n","import { cloneElement } from \"react\"\nimport { RenderLeafProps } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `renderLeaf` method.\n *\n * Generally, we are looking for all the results from all the plugins and\n * SinkEditable and merge the results together by nesting the responses\n * starting from the first plugin on the outside to the `renderLeaf` method\n * on `SinkEditable` on the inside.\n */\n\nexport function createRenderLeaf(\n originalFn: EditableProps[\"renderLeaf\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"renderLeaf\"]> {\n if (originalFn === undefined) {\n throw new Error(`renderLeaf was not defined on SinkEditable`)\n }\n\n /**\n * These get handled in reverse order. We wrap the last one around the\n * actual `Text` and the earlier ones wrap around those. This\n * feels more natural because the first plugin handles the outermost\n * and we work our way inward.\n */\n const fns = plugins\n .map((plugin) => plugin.editableProps?.renderLeaf)\n .filter(defined)\n .reverse()\n\n return function (renderLeafProps) {\n let value = originalFn({\n ...renderLeafProps,\n /**\n * We override this because `attributes` should only appear on the\n * uppermost leaf element if there are several nested ones and it's\n * possible that this won't be the uppermost leaf.\n *\n * We add attributes back on at the very end so no need to worry if\n * we omit it here.\n */\n attributes: {} as RenderLeafProps[\"attributes\"],\n })\n for (const fn of fns) {\n const possibleValue = fn({\n ...renderLeafProps,\n children: value,\n })\n if (possibleValue) {\n value = possibleValue\n }\n }\n value = cloneElement(value, renderLeafProps.attributes) //{ key: 'your-unique-key-here' })\n return value\n }\n}\n","import { RenderPlaceholderProps } from \"slate-react\"\nimport { EditableProps } from \"slate-react/dist/components/editable\"\n\nimport { BasePluginPolicy } from \"../types\"\nimport { defined } from \"./utils\"\n\n/**\n * Create the substituted `renderElement` method.\n *\n * Generally, we are looking for the first result from any plugin or on\n * SinkEditable and return the first one that returns a value only.\n *\n * Iterate over all the plugin `renderElement`. If they return nothing\n * then we go to the next one until we hit a result. If we don't hit a\n * result, then we go to the `renderElement` passed to the `SinkEditable`\n * component.\n */\n\nexport function createRenderPlaceholder(\n originalFn: EditableProps[\"renderPlaceholder\"],\n plugins: BasePluginPolicy[]\n): NonNullable<EditableProps[\"renderPlaceholder\"]> | undefined {\n if (originalFn) return originalFn\n const fns = plugins\n .map((plugin) => plugin.editableProps?.renderPlaceholder)\n .filter(defined)\n if (fns.length === 0) return undefined\n return function (\n renderPlaceholderProps: RenderPlaceholderProps\n ): JSX.Element {\n if (fns.length > 1) {\n throw new Error(\n `Only one plugin can define renderPlaceholder but there are ${fns.length}`\n )\n }\n const fn = fns[0]\n if (fn == null) throw new Error(`Expected fn to be defined`)\n return fn(renderPlaceholderProps)\n }\n}\n","import styled from \"@emotion/styled\"\n\nexport const SinkReset = styled(\"div\")`\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-size: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;\n box-sizing: border-box;\n`\n","import { Element, Node } from \"slate\"\n\nimport { BasePluginPolicy, FullSinkEditor } from \"../types\"\n\n/**\n * Creates an overrideable editor action that takes a `Node` and returns a\n * `boolean` and creates a new version of the action that incorporates the\n * plugins.\n *\n * If the plugin returns a boolean, it takes the result and returns it.\n *\n * If the plugin returns undefined, it tries the next one.\n *\n * If no plugin handles the result, it returns the result of the original action.\n */\nexport function createBooleanAction<\n K extends \"isVoid\" | \"isInline\" | \"isMaster\" | \"isSlave\" | \"isStandalone\"\n>(\n editor: FullSinkEditor,\n actionKey: K,\n plugins: BasePluginPolicy[]\n): (node: Element) => boolean {\n const originalAction = editor[actionKey]\n const actionPlugins = plugins.filter((plugin) => plugin.editor?.[actionKey])\n return function nextBooleanAction(node: Node): boolean {\n for (const plugin of actionPlugins) {\n const editorPlugin = plugin.editor as Record<string, ((n: Node) => boolean | undefined) | undefined> | undefined\n const actionFn = editorPlugin?.[actionKey]\n const result = actionFn?.(node)\n if (typeof result === \"boolean\") return result\n }\n const origFn = originalAction as (n: Node) => boolean\n return origFn(node)\n }\n}\n","import { BaseEditor } from \"slate\"\n\nimport { BasePluginPolicy } from \"../types\"\n\n/**\n * Creates an overrideable editor action like `insertBreak` or `deleteBackward`\n * that usually returns `void` and creates a new version of the action that\n * adds the action from the plugin.\n *\n * If the plugin returns `true` it takes the result and returns it.\n *\n * If the plugin returns `false`, it tries the next one.\n *\n * If no plugin handles the result, it executed the original action.\n */\nexport function createVoidAction<\n K extends\n | \"normalizeNode\"\n | \"deleteBackward\"\n | \"deleteForward\"\n | \"deleteFragment\"\n | \"insertBreak\"\n | \"insertFragment\"\n | \"insertNode\"\n | \"insertText\"\n>(editor: BaseEditor, actionKey: K, plugins: BasePluginPolicy[]) {\n const originalAction = editor[actionKey]\n const actionPlugins = plugins.filter((plugin) => plugin.editor?.[actionKey])\n return function nextVoidAction(...args: Parameters<BaseEditor[K]>[]): void {\n let isHandled = false\n const afterHandledCallbacks: (() => void)[] = []\n for (const plugin of actionPlugins) {\n // @ts-expect-error - dynamic key access\n const response = plugin.editor?.[actionKey]?.(...args)\n if (typeof response === \"function\") {\n afterHandledCallbacks.push(response)\n } else if (response === true) {\n isHandled = true\n break\n }\n }\n if (!isHandled) {\n // @ts-expect-error - dynamic args spread\n originalAction(...args)\n }\n afterHandledCallbacks.forEach((callback) => callback())\n }\n}\n","import { BaseEditor } from \"slate\"\n\nimport { BasePluginFn, ExtractedPluginSchema, FullSinkEditor } from \"../types\"\nimport { createBooleanAction } from \"./create-boolean-action\"\nimport { createVoidAction } from \"./create-void-action\"\n\nexport function createWithSink<T extends ExtractedPluginSchema>(\n pluginFns: BasePluginFn[]\n) {\n /**\n * The `editor` in the props can be a `BaseEditor` but we transform it\n * into a `SinkEditor` before returning it.\n */\n return <E extends BaseEditor>(\n originalEditor: E,\n options: T[\"Options\"]\n ): E & FullSinkEditor => {\n const editor = originalEditor as E & FullSinkEditor\n\n /**\n * Executes the plugin on the `editor` with every one of the\n * `pluginFunctions` to get the `pluginObject`\n */\n const plugins = pluginFns.map((plugin) =>\n plugin(editor, options, { createPolicy: (x) => x })\n )\n editor.sink = { plugins }\n\n /**\n * Create the default for SinkEditor methods if they don't already exist.\n */\n editor.isMaster = \"isMaster\" in editor ? editor.isMaster : () => false\n editor.isSlave = \"isSlave\" in editor ? editor.isSlave : () => false\n editor.isStandalone =\n \"isStandalone\" in editor ? editor.isStandalone : () => false\n\n Object.assign(editor, {\n /**\n * void\n */\n normalizeNode: createVoidAction(editor, \"normalizeNode\", plugins),\n deleteBackward: createVoidAction(editor, \"deleteBackward\", plugins),\n deleteForward: createVoidAction(editor, \"deleteForward\", plugins),\n deleteFragment: createVoidAction(editor, \"deleteFragment\", plugins),\n insertBreak: createVoidAction(editor, \"insertBreak\", plugins),\n insertFragment: createVoidAction(editor, \"insertFragment\", plugins),\n insertNode: createVoidAction(editor, \"insertNode\", plugins),\n insertText: createVoidAction(editor, \"insertText\", plugins),\n /**\n * boolean\n */\n isInline: createBooleanAction(editor, \"isInline\", plugins),\n isVoid: createBooleanAction(editor, \"isVoid\", plugins),\n isMaster: createBooleanAction(editor, \"isMaster\", plugins),\n isSlave: createBooleanAction(editor, \"isSlave\", plugins),\n isStandalone: createBooleanAction(editor, \"isStandalone\", plugins),\n })\n\n return editor\n }\n}\n","import { SinkEditable } from \"../editable\"\nimport { createWithSink } from \"../editor\"\nimport { BasePlugin, ExtractedPluginSchema } from \"../types\"\n\n/**\n * A sink is just a function\n */\nexport const createSink = <T extends ExtractedPluginSchema>(\n pluginFunctions: BasePlugin[]\n) => {\n const fns = pluginFunctions.map((plugin) => plugin.fn)\n const withSink = createWithSink<T>(fns)\n\n const returnValue = { withSink, SinkEditable }\n return returnValue\n}\n","export const isDebug = false\n","import { Editor, Element, Location } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\n/**\n * Defines a value you'd find in a function's parameters as a replacement for\n * `at`. The benefit of using `BetterAt` is that it allows you to search\n * using an `Element`.\n */\nexport type BetterAt = Location | Element | null\n\n/**\n * Takes a `BetterAt` type which can include an `Element` and returns a\n * Location.\n */\nexport function betterAt(editor: Editor, at: Location | Element): Location {\n if (!Element.isElement(at)) return at\n return ReactEditor.findPath(editor, at)\n}\n","/**\n * Takes a function and returns a new function with the first X arguments of\n * that function pre-filled with the provided values.\n *\n * NOTE:\n *\n * This is not a full implementation of a curry but gives us what we want in a\n * lightweight manner, with low complexity and good typing. Namely, we need to\n * specify how many arguments to curry.\n *\n * This can probably be done in a way where the argument number doesn't have to\n * be specified ahead of time; however, these are the reasons I've kept it this\n * way for now.\n *\n * - It's easier to understand. We don't need to create a recursive TypeScript\n * type.\n * - We only ever need currying a little anyways\n * - It's probably a little more performant this way\n *\n * WARNING FOR GENERICS:\n *\n * If the function you are currying has a generic, you will need to write a\n * generic manually for it then apply it manually using `as`. For example:\n *\n * const curriedToggleElements = curry(toggleElements, editor) as\n * CurriedToggleElements\n */\n\n/**\n * Curry one argument from the left\n */\nexport function curryOne<CurriedArg, RestArgs extends unknown[], R>(\n fn: (curriedArg: CurriedArg, ...restArgs: RestArgs) => R,\n curriedArg: CurriedArg\n): (...args: RestArgs) => R {\n return fn.bind(null, curriedArg)\n}\n\n/**\n * Curry two arguments from the left\n */\nexport function curryTwo<Arg1, Arg2, RestArgs extends unknown[], R>(\n fn: (arg1: Arg1, arg2: Arg2, ...restArgs: RestArgs) => R,\n arg1: Arg1,\n arg2: Arg2\n): (...args: RestArgs) => R {\n return fn.bind(null, arg1, arg2)\n}\n","const IS_MAC_REGEX = /mac os x|macintosh/i\n\nlet isMacValue: boolean | undefined = undefined\n\n/**\n * `isMac` is a function and not a const because `window.navigator` only exists\n * on the browser and will throw an Error on the server.\n */\nexport function isMac() {\n /**\n * Memoized for performance\n */\n if (isMacValue !== undefined) return isMacValue\n try {\n const { userAgent } = window.navigator\n isMacValue = IS_MAC_REGEX.test(userAgent)\n } catch {\n isMacValue = false\n }\n return isMacValue\n}\n","/**\n * Tiny helper to call `e.preventDefault()` and `e.stopPropagation()` as the\n * same time.\n */\nexport function stopEvent(e: Event | React.SyntheticEvent) {\n e.preventDefault()\n e.stopPropagation()\n}\n","import { Ancestor, Editor, Element, NodeEntry, Path } from \"slate\"\n\nimport { BetterAt, betterAt } from \"../core-utils/better-at\"\nimport {\n NodeMatcher,\n standardizeNodeMatcher,\n} from \"../standardize-utils/standardize-node-matcher\"\n\n/**\n * Checks to see if the current selection is inside of a Node that matches\n * `matchNode`.\n */\nexport function findElementUp<T extends Ancestor & Element = Element>(\n editor: Editor,\n matchNode: NodeMatcher,\n { at = editor.selection }: { at?: BetterAt } = {}\n): NodeEntry<T> | undefined {\n // if no selection, there will be no match\n if (at === null) return\n const nextAt = betterAt(editor, at)\n const match = standardizeNodeMatcher(matchNode)\n /**\n * Normally, we are looking up from a range or a point, but if the `at`\n * `Location` is a `Path`, then we need to check for an exact match at the\n * `at` `Location` in addition to looking `Editor.above` the current\n * `at` `Location`\n */\n if (Path.isPath(nextAt)) {\n const nodeEntryExactlyAt = Editor.node(editor, nextAt)\n if (nodeEntryExactlyAt && match(nodeEntryExactlyAt[0])) {\n return nodeEntryExactlyAt as NodeEntry<T>\n }\n }\n // look for a matching element\n return Editor.above(editor, { at: nextAt, match })\n}\n\nexport function findElementUpPath(...args: Parameters<typeof findElementUp>) {\n const entry = findElementUp(...args)\n return entry?.[1]\n}\n","import { Element, Node } from \"slate\"\n\nexport type NodeMatcher = string | string[] | ((node: Node) => boolean)\n\n/**\n * Takes a string or a function that matches a Node and in both cases,\n * returns a function that matches a Node.\n *\n * The `matchNode` argument can either be a function that takes a `Node` and\n * returns a boolean or it can be a string representing the `type` property of\n * an `Element`\n */\n\nexport function standardizeNodeMatcher(\n matchNode: NodeMatcher\n): (node: Node) => boolean {\n if (typeof matchNode === \"function\") return matchNode\n if (typeof matchNode === \"string\")\n return (node: Node) => Element.isElement(node) && node.type === matchNode\n if (Array.isArray(matchNode))\n return (node: Node) =>\n Element.isElement(node) && matchNode.includes(node.type)\n const exhaustiveCheck: never = matchNode\n throw new Error(\n `Expected matchNode to be a function, string or array but is ${exhaustiveCheck as string}`\n )\n}\n","import { SVGProps } from \"react\"\n\n/**\n * A shortcut type to SVGProps<SVGSVGElement> but also more explicit in its\n * intent and allows for changing the props in the future without another\n * refactor.\n */\nexport type TablerIconProps = SVGProps<SVGSVGElement>\n\n/**\n * Efficient way to create a Tabler Icon.\n *\n * https://tabler-icons.io/\n *\n * - Grab the SVG from the Tabler Icon.\n * - Run it through https://react-svgr.com/playground/?icon=true&typescript=true\n * - Grab everything EXCEPT the first `path` which is unnecessary\n * - Place it as the children of this `<Icon>`\n */\nexport const TablerIcon = ({\n strokeWidth = 1.5,\n ...props\n}: TablerIconProps) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n strokeWidth={strokeWidth}\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 24 24\"\n {...props}\n />\n)\n","import { Range } from \"slate\"\n\nexport function isCollapsed(\n selection: Range | null | undefined\n): selection is Range {\n if (selection == null) return false\n return Range.isCollapsed(selection)\n}\n","import { Element, Node } from \"slate\"\n\nexport function isElementType<T extends Element>(\n node: Node,\n type: T[\"type\"] | Array<T[\"type\"]>\n): node is T {\n if (Array.isArray(type)) {\n return Element.isElement(node) && type.includes(node.type)\n }\n if (typeof type === \"string\") {\n return Element.isElement(node) && node.type === type\n }\n const exhaustiveCheck: never = type\n throw new Error(\n `Expected elementType to be string or array of string but is ${exhaustiveCheck as string}`\n )\n}\n\nexport function createIsElementType<T extends Element>(\n type: T[\"type\"] | Array<T[\"type\"]>\n): (node: Node) => node is T {\n if (Array.isArray(type)) {\n return (node: Node): node is T =>\n Element.isElement(node) && type.includes(node.type)\n } else {\n return (node: Node): node is T =>\n Element.isElement(node) && type == node.type\n }\n}\n","import { Editor } from \"slate\"\n\nimport { findElementUp } from \"../find-utils/find-element-up\"\nimport { NodeMatcher } from \"../standardize-utils/standardize-node-matcher\"\nimport { isCollapsed } from \"./is-collapsed\"\n\n/**\n * Checks to see if the current selection is at the end of line for a node\n * that matches the `matchNode` argument.\n *\n * The `matchNode` argument can either be a function that takes a `Node` and\n * returns a boolean or it can be a string representing the `type` property of\n * an `Element`\n */\n\nexport function isEndOfElement(\n editor: Editor,\n matchNode: NodeMatcher\n): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const entry = findElementUp(editor, matchNode, { at: selection })\n return !!entry && Editor.isEnd(editor, selection.anchor, entry[1])\n}\n","import { Editor } from \"slate\"\n\nimport { findElementUp } from \"../find-utils/find-element-up\"\nimport { NodeMatcher } from \"../standardize-utils/standardize-node-matcher\"\nimport { isCollapsed } from \"./is-collapsed\"\n\n/**\n * Checks to see if we are currently in an empty element.\n *\n * All these must be true:\n *\n * - There is a selection\n * - The selection is inside the matching element\n * - The matching element is empty\n */\nexport function isInEmptyElement(\n editor: Editor,\n matchNode: NodeMatcher\n): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const entry = findElementUp(editor, matchNode)\n if (entry === undefined) return false\n return Editor.isEmpty(editor, entry[0])\n}\n","import { Editor } from \"slate\"\n\nimport { findElementUp } from \"../find-utils/find-element-up\"\nimport { NodeMatcher } from \"../standardize-utils/standardize-node-matcher\"\nimport { isCollapsed } from \"./is-collapsed\"\n\n/**\n * Checks to see if the current selection is at the end of line for a node\n * that matches the `matchNode` argument.\n *\n * The `matchNode` argument can either be a function that takes a `Node` and\n * returns a boolean or it can be a string representing the `type` property of\n * an `Element`\n */\n\nexport function isStartOfElement(\n editor: Editor,\n matchNode: NodeMatcher\n): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const entry = findElementUp(editor, matchNode, { at: selection })\n return !!entry && Editor.isStart(editor, selection.anchor, entry[1])\n}\n","import { isHotkey } from \"is-hotkey\"\nimport { Editor, Element as SlateElement, Range, Transforms } from \"slate\"\n\nimport { findElementUp, stopEvent } from \"../..\"\n\nexport const isSpace = isHotkey(\" \")\nexport const isShiftSpace = isHotkey(\"SHIFT+SPACE\")\n\nexport function createAutocompleteSpaceHandler(\n editor: Editor,\n methods: Record<string, undefined | (() => void)>\n) {\n return (e: React.SyntheticEvent<Element, KeyboardEvent>): boolean => {\n /**\n * We support `shift+space` as well because when we are typing something\n * like `## ` sometimes the finger hasn't left the shift key yet. In normal\n * usage, we still get a space and so the feature feels intermittently\n * broken if we don't support `shift+space`.\n */\n if (!isSpace(e.nativeEvent) && !isShiftSpace(e.nativeEvent)) return false\n\n /**\n * Make sure theere is a selection and it's collapsed\n */\n const { selection } = editor\n if (selection === null) return false\n if (Range.isExpanded(selection)) return false\n\n /**\n * Find a convertible block and if we can't find one, exit.\n */\n const convertibleBlockEntry = findElementUp(\n editor,\n (node) =>\n /**\n * NOTE: We alias to SlateElement because this page needs acces to both\n * the global Eleent and the Slate Element.\n */\n SlateElement.isElement(node) &&\n editor.convertElement.isConvertibleElement(node)\n )\n if (!convertibleBlockEntry) return false\n\n /**\n * Find a matching method. Note that the keys in `methods` are the `string`\n * prefixes we are looking for like `##` for heading level 2.\n *\n * If no match, exit.\n */\n const range = {\n anchor: Editor.start(editor, convertibleBlockEntry[1]),\n focus: selection.focus,\n }\n const text = Editor.string(editor, range)\n const method = methods[text]\n if (!method) return false\n\n /**\n * We have a match. Stop other event handlers.\n */\n stopEvent(e)\n\n /**\n * Delete the autocomplete text that came before the space bar was pressed.\n */\n const deleteRange = {\n anchor: Editor.start(editor, convertibleBlockEntry[1]),\n focus: selection.focus,\n }\n Transforms.delete(editor, { at: deleteRange })\n\n /**\n * Execute the matching method.\n */\n method()\n return true\n }\n}\n","import { isHotkey } from \"is-hotkey\"\n\nimport { isMac } from \"../core-utils/is-mac\"\n\nexport function isBetterHotkey(hotkey: string) {\n const modifiedHotkey = hotkey.replace(\n /\\bsuper\\b/g,\n isMac() ? \"cmd+alt\" : \"ctrl+shift\"\n )\n return isHotkey(modifiedHotkey)\n}\n","import { isBetterHotkey } from \"./is-better-hotkey\"\n\n/**\n * The function that is executed when the hotkey is pressed.\n *\n * If it returns `void` (undefined) we assume the Action was executed.\n * If we return a `boolean`, the Action is considered executed if it returns\n * `true` or not handled if it returns `false`.\n */\ntype Action = () => boolean | void\n\ntype IsKeyboardShortcut = (event: KeyboardEvent) => boolean\n\ntype ShortcutTuple = [IsKeyboardShortcut, Action]\n\n/**\n * Creates a `keyDown` handler from an object where the keys are the shortcut\n * and the values are the `Action` function to execute. If the\n * function returns `true`, the event is considered handled and the event\n * is stopped.\n *\n * In some situations, we don't want the event to be stopped.\n *\n * For example, hitting `up` or `down` in a table, starts a `setTimeout` but\n * we want the original keyboard event to be handled by the browser.\n */\n\nexport function createHotkeyHandler(shortcutsObject: Record<string, Action>) {\n /**\n * Don't populate the shortcuts at this point because it will run on the\n * server. We can't run it on the server because we need to determine if we\n * are on Mac or Windows and checking `window.navigate.userAgent` will cause\n * a failure.\n */\n let shortcuts: ShortcutTuple[] | null = null\n\n return function handleShortcuts(\n event: React.SyntheticEvent<Element, KeyboardEvent>\n ) {\n /**\n * We initialize shortcuts once on first usage.\n */\n if (shortcuts == null) {\n shortcuts = Object.entries(shortcutsObject).map(([shortcut, fn]) => [\n isBetterHotkey(shortcut),\n fn,\n ])\n }\n for (const [isShortcut, action] of shortcuts) {\n if (isShortcut(event.nativeEvent)) {\n /**\n * If the keyboardAction returns true then the event has been handled.\n * We can stop the event at this point and exit the loop.\n */\n const response = action()\n if (response === true || response === undefined) {\n event.preventDefault()\n event.stopPropagation()\n return true\n }\n }\n }\n return false\n }\n}\n","import { Editor, Path, Transforms } from \"slate\"\n\n/**\n * Takes a given and makes that specific path dirty with respect to\n * normalization and executes a normalization path (unless in a\n * `withoutNormalizing` block in which case it will wait until it is completed).\n *\n * A few things you should know:\n *\n * - It doesn't dirty the ancestors. So if you are targeting an Element to be\n * dirtied, make sure you aren't dirtying the Text node as that won't cause\n * the parent Element to be dirtied.\n *\n * - It works by setting a key that doesn't make sense to a value and then\n * unsetting it. This adds some unnecessary noise to the list of operations.\n *\n * The ideal method to implement this would be to modify the DIRTY_PATHS and\n * DIRTY_PATH_KEYS directly; however, these are presently not being exported.\n * This should probably be fixed in the future by an exported function called\n * something like `addDirtyPaths`.\n */\nexport function forceNormalizePath(editor: Editor, path: Path) {\n Editor.withoutNormalizing(editor, () => {\n Transforms.setNodes(\n editor,\n // @ts-expect-error - intentional dummy property for normalization\n { __DOESNT_MATTER_JUST_TO_START_NORMALIZING__: \"123\" },\n { at: path }\n )\n Transforms.setNodes(\n editor,\n // @ts-expect-error - intentional dummy property for normalization\n { __DOESNT_MATTER_JUST_TO_START_NORMALIZING__: null },\n { at: path }\n )\n })\n}\n","import { Descendant, Editor, NodeEntry } from \"slate\"\n\n/**\n * This normalization utility is useful when you need to adjust an Element\n * depending on the Element before or after it.\n *\n * For example, if two of the same nodes are next to each other, they can be\n * merged together.\n *\n * Or in the case of a numbered list, we want to reset the counter only if\n * the list is deeper than the previous one.\n *\n * The thing that makes these method efficient is that it can often replace\n * having to search through all children of the parent of the current element.\n * Normally, to compare siblings, you'd have to look at the parent in order\n * to make sure you normalize siblings propertly; however, this method will\n * look both at the pair before/current and current/after to make sure that\n * neighbor siblings do the right thing.\n *\n * When used through a full normalization, it can solve bigger problems. For\n * example, if you have 5 elements that are all the same and they need to\n * all be merged, one by one, they will merged into a single Element.\n *\n * HINT:\n *\n * If there is a bug related to not being able to find a Path, remember to\n * return `true` in the `transform` function when a `transform` is executed.\n *\n * After a `transform` is run, the state of the document is changed and\n * running the second `transform` may result in accessing an invalid path.\n */\nexport function normalizeSiblings<T extends Descendant>(\n editor: Editor,\n entry: NodeEntry<T>,\n transform: (a: NodeEntry<T>, b: NodeEntry<T>) => boolean\n): boolean {\n const [, path] = entry\n\n const prevEntry = Editor.previous<T>(editor, { at: path })\n if (prevEntry && transform(prevEntry, entry)) return true\n\n const nextEntry = Editor.next<T>(editor, { at: path })\n if (nextEntry && transform(entry, nextEntry)) return true\n\n return false\n}\n","import { Editor, Path, Transforms } from \"slate\"\n\n/**\n * Puts the selection at the start of a Node at the given path.\n */\nexport function selectStartOfElement(editor: Editor, path: Path) {\n Transforms.select(editor, Editor.start(editor, path))\n}\n\n/**\n * Puts the selection at the start of a Node at the given path.\n */\nexport function selectEndOfElement(editor: Editor, path: Path) {\n Transforms.select(editor, Editor.end(editor, path))\n}\n","import { Element } from \"slate\"\n\n/**\n * The TargetElement can be specified either as the actual value or as a\n * function that takes a srcElement and returns the targetElement.\n */\nexport type TargetElement<T extends Element = Element> =\n | Omit<T, \"children\">\n | ((srcElement: Element) => Omit<T, \"children\">)\n\n/**\n * TODO:\n *\n * This should probably just be moved into the `rewrapElement` function page\n * since it is not used outside of it. Originally, this may have served a\n * dual purpose but currently it seems like it only exists for the use of\n * `rewrapElement`.\n */\n\n/**\n * This function takes a `srcElement` and the idea is that we convert it into\n * some other type of element, which is the `targetElement`.\n *\n * The `TargetElement` can be specified either as:\n *\n * - an actual `Element` but without the `children`. This is because we are\n * converting the `srcElement` to the `targetElement` and the `targetElement`\n * will take on the `children` of the `srcElement`\n *\n * - A function that takes the `srcElement` and returns the `targetElement`\n * without the `children`. This form of `TargetElement` can be useful in\n * cases where we want to retain some of the properties of the `srcElement`.\n * An example of this is a list item where we convert from a bullet to a\n * numbered item. We would like to keep the `depth` information if it exists\n * in this scenario.\n */\nexport function createTargetElement<T extends Element>(\n srcElement: Element,\n targetElement: TargetElement<T>\n) {\n if (typeof targetElement !== \"function\") return targetElement\n return targetElement(srcElement)\n}\n","import { Editor, Element, Location, Path, Transforms } from \"slate\"\n\nimport { findElementUp } from \"../..\"\n\n/**\n * Inserts an Element into the document such that if it is in a `isMaster`\n * element (i.e. an Element that has a number of dependants like a table or\n * code block) then then inserted Element will appear after the `isMaster`\n * element.\n *\n * This prevents invalid states from happening like inserting a table inside\n * a table, or a code block in a table, or a table in a code block.\n */\nexport function insertRootElement(\n editor: Editor,\n element: Element,\n { at = editor.selection }: { at?: Location | null } = {}\n): boolean {\n /**\n * If there's no `at` then insertion does not happen\n */\n if (at == null) return false\n /**\n * Look for a parent that `isMaster`\n */\n const entry = findElementUp(\n editor,\n (node) => Element.isElement(node) && editor.isMaster(node)\n )\n if (entry == null) {\n /**\n * If not `isMaster` then do a regular insert, select the original\n * insertion point and move forward to select the first position inside\n * the newly inserted element.\n */\n const selection = editor.selection\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at })\n if (selection) {\n Transforms.select(editor, selection)\n Transforms.move(editor)\n }\n })\n } else {\n /**\n * If it `isMaster` then find the next adjacent path to the master, insert\n * there, and then select at the start of the insertion point.\n */\n const nextPath = Path.next(entry[1])\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at: nextPath })\n Transforms.select(editor, Editor.start(editor, nextPath))\n })\n }\n return true\n}\n","import { Editor, Element, NodeEntry, Path, Transforms } from \"slate\"\n\nimport {\n createTargetElement,\n TargetElement,\n} from \"../standardize-utils/target-element\"\n\n/**\n * Takes an existing Element at path `at` and swaps out that Element with a\n * new Element. It does this by unwrapping the Element and rewrapping it with\n * the new Element.\n *\n * This is useful because if we do it this way, we can preserve the selection.\n */\nexport function rewrapElement<T extends Element = Element>(\n editor: Editor,\n targetElement: TargetElement<T>,\n at: Path\n) {\n Editor.withoutNormalizing(editor, () => {\n const originalEntry = Editor.node(editor, at) as NodeEntry<Element>\n const nextElement = createTargetElement(originalEntry[0], targetElement)\n /**\n * Technicall, it's Omit<Element, 'children'> but `wrapNodes` actually\n * accepts that just fine so we override the type.\n */\n Transforms.wrapNodes(editor, nextElement as T, { at })\n Transforms.unwrapNodes(editor, { at: [...at, 0] })\n })\n}\n","import { Editor, EditorNodesOptions, Node, Transforms } from \"slate\"\n\n/**\n * An improved version of `setNodes` that takes a `convert` option.\n *\n * In existing `setNodes` we can specify how we want to setNodes statically.\n * That is, before we execute `setNodes` we need to know which properties\n * we want to set.\n *\n * This version of `setNodes` allows us to dynamically setNodes by allowing\n * us to specify a function argument. The function takes the original value of\n * an Element and returns the match.\n */\nexport function setNodesDynamic<T extends Node>(\n editor: Editor,\n convert: (node: T) => Partial<T>,\n options: EditorNodesOptions<T>\n) {\n const entries = Array.from(Editor.nodes<T>(editor, options))\n if (entries.length === 0) return false\n for (const entry of entries) {\n const [node] = entry\n Transforms.setNodes(editor, convert(node), { at: entry[1] })\n }\n return true\n}\n","import { Editor } from \"slate\"\n\nexport function onPaste(\n editor: Editor,\n e: React.ClipboardEvent<HTMLDivElement>\n) {\n const clipboardData = e.clipboardData\n const { types } = clipboardData\n\n // Remove debug console log\n // console.log(clipboardData.getData(\"text/html\"))\n\n /**\n * We don't want to handle it if it's not just plain text. If it is\n * plain text, it will have only one type and it will be \"text/plain\".\n * HTML, for example, also has \"text/plain\" but also \"text/html\"\n */\n if (types.length > 1) return false\n if (types[0] !== \"text/plain\") return false\n\n /**\n * Check to make sure the text is a URL\n */\n const text = clipboardData.getData(\"text/plain\")\n if (!isUrl(text)) return false\n\n /**\n * If it is a URL, then insert the link\n */\n e.preventDefault()\n e.stopPropagation()\n editor.anchor.insertLink(text)\n return true\n}\nfunction isUrl(s: string): boolean {\n let url\n try {\n url = new URL(s)\n } catch {\n return false\n }\n return (\n url.protocol === \"http:\" ||\n url.protocol === \"https:\" ||\n url.protocol === \"mailto:\"\n )\n}\n","import { Editor, Node, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"../../sink\"\nimport { AnchorElement } from \"..\"\n\nexport function editLink(\n editor: Editor,\n { href, title, text }: { href: string; title?: string; text?: string },\n { at }: { at?: BetterAt }\n) {\n const link = findElementUp(editor, \"anchor\", { at })\n if (!link) return false\n const [element, path] = link\n\n // Update href and title\n Transforms.setNodes<AnchorElement>(editor, { href, title }, { at: path })\n\n // Update text if provided and different from current\n if (text !== undefined) {\n const currentText = Node.string(element)\n if (text !== currentText) {\n // Remove all children and insert new text\n Editor.withoutNormalizing(editor, () => {\n const childCount = element.children.length\n for (let i = childCount - 1; i >= 0; i--) {\n Transforms.removeNodes(editor, { at: [...path, i] })\n }\n Transforms.insertNodes(editor, { text }, { at: [...path, 0] })\n })\n }\n }\n\n return true\n}\n","import { Editor, Range, Text, Transforms } from \"slate\"\n\nexport function insertLink(\n editor: Editor,\n href: string,\n text: string = href,\n { select = true, title }: { select?: boolean; title?: string } = {}\n) {\n /**\n * If there is no selection, we default by inserting at the start of document.\n */\n const selection = editor.selection || {\n anchor: Editor.start(editor, [0]),\n focus: Editor.start(editor, [0]),\n }\n if (Range.isCollapsed(selection)) {\n /**\n * Insert the node and select it if select is true\n */\n Transforms.insertNodes(\n editor,\n {\n type: \"anchor\",\n href,\n title,\n children: [{ text }],\n },\n { select, at: selection }\n )\n /**\n * If select is true then select the inserted link\n */\n if (select && editor.selection) {\n const entry = Editor.node(editor, editor.selection)\n Transforms.select(editor, entry[1])\n }\n } else {\n /**\n * If there is a selection, we wrap the selection with our anchor.\n */\n Transforms.wrapNodes(\n editor,\n { type: \"anchor\", href, title, children: [] },\n {\n split: true,\n match: (node) => Text.isText(node) || Editor.isInline(editor, node),\n }\n )\n }\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"../../sink\"\n\nexport function removeLink(editor: Editor, { at }: { at?: BetterAt }) {\n const link = findElementUp(editor, \"anchor\", { at })\n if (!link) return false\n Transforms.unwrapNodes(editor, { at: link[1] })\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport { editLink } from \"./editLink\"\nimport { insertLink } from \"./insertLink\"\nimport { removeLink } from \"./removeLink\"\n\nexport function createAnchorMethods(editor: Editor) {\n return {\n insertLink: curryOne(insertLink, editor),\n removeLink: curryOne(removeLink, editor),\n editLink: curryOne(editLink, editor),\n }\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\n/**\n * If there is an anchor node inside an anchor node, unwrap the inner anchor\n * node as that is not allowed.\n *\n * Another approach would be to lift the nodes but I think unwrapping the\n * inner one makes more sense. Consider these two scenarios (keeping in mind\n * that they will likely be rare):\n *\n * - User selects text that includes a link. Then user links it. The user would\n * have a strong expectation that the link just applied would override the\n * link on the inside.\n *\n * - The opposite: User select text inside an existing link then tries to link\n * it. That's unusual and while the user may expect that inner selection to\n * get linked, I think this is a rare enough case whereas the prior one seems\n * like a slightly more natural one.\n *\n * We could, of course, solve both of these by adding more code paths at the\n * time the link is inserted. That won't change this normalization code and\n * not sure if it is worth the extra complexity.\n */\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n if (!Element.isElement(entry[0])) return false\n if (entry[0].type !== \"anchor\") return false\n const children = entry[0].children\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n if (!Element.isElement(child) || child.type !== \"anchor\") continue\n Transforms.unwrapNodes(editor, { at: [...entry[1], i] })\n return true\n }\n return false\n}\n","import { clsx } from \"clsx\"\nimport React from \"react\"\nimport { useEffect, useRef } from \"react\"\nimport { useSelected, useSlate } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { useLayer } from \"../../use-layer\"\nimport { AnchorElement } from \"../index\"\nimport { $Anchor, $Edge } from \"../styles\"\nimport { AnchorDialog } from \"./AnchorDialog\"\n\nexport function Anchor({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<AnchorElement>) {\n const startEdgeRef = useRef<HTMLSpanElement>(null)\n const anchorRef = useRef<HTMLAnchorElement>(null)\n const selected = useSelected()\n const editor = useSlate()\n const dialog = useLayer(\"dialog\")\n\n /**\n * TODO:\n *\n * Finish implementing the anchor dialog.\n *\n * Stopped partway through because the entire document is being re-rendered\n * on every keypress.\n */\n\n useEffect(() => {\n const anchor = anchorRef.current\n const startEdge = startEdgeRef.current\n if (!anchor || !startEdge) return\n /**\n * NOTE: Do not use `focused && selected` here because when we click or\n * focus on the pop up dialogs themselves, this will cause the dialogs to\n * close.\n *\n * TODO: Figure out how to make the dialogs not close when clicking on them.\n *\n * It has to support these use cases:\n *\n * - Closes when user clicks somewhere in the document outside the link\n * - Stays open when user clicks on the dialog\n * - Stays open when user is in an input in the dialog\n * - Closes when the editor loses focus but stays open when the editor loses\n * focus to the anchor dialog or the anchor edit dialog\n */\n // Only show dialog when the link is precisely selected (not part of a larger selection)\n const hasSelection = editor.selection &&\n editor.selection.anchor.offset !== editor.selection.focus.offset;\n\n if (selected && !hasSelection) {\n /**\n * The setTimeout delay is necessary when first clicking into the browser\n * and when switching from one link to another. Without it, the dialog\n * will not open.\n */\n setTimeout(() => {\n dialog.open(() => (\n <AnchorDialog\n destAnchor={anchor}\n destStartEdge={startEdge}\n element={element}\n />\n ))\n })\n } else {\n dialog.close()\n }\n }, [selected, element])\n\n return (\n <$Anchor\n className={clsx({ \"--selected\": selected })}\n href={element.href}\n target={element.target}\n {...attributes}\n ref={anchorRef}\n >\n {/* Edge allow Chrome to differentiate in/out of the link */}\n <$Edge ref={startEdgeRef} contentEditable={false} />\n <span>{children}</span>\n {/* Edge allow Chrome to differentiate in/out of the link */}\n <$Edge contentEditable={false} />\n </$Anchor>\n )\n}\n","import { createContext, useState } from \"react\"\n\nimport { Portal } from \"./portal\"\nimport { Layer, LayersContextValue, LayersRecord } from \"./types\"\n\n/**\n * Wrap this around the Component in which you want to have the ability to\n * display one or more layers at once.\n */\nexport const LayersContext = createContext<LayersContextValue>(\n /**\n * This is set to an invalid value and then typecast as the correct type.\n *\n * This is okay though because in `LayersProvider` we set the value to the\n * proper type before they are used for the first time.\n */\n {} as LayersContextValue\n)\n\nexport const LayerContext = createContext<Layer>({} as Layer)\n\n/**\n * The `Layers` Component should be wrapped around the Component or Components\n * which you want to have layer support.\n *\n * The `useLayer` hook must be called inside a `Layers` Component.\n *\n * It provides these necessary functions:\n *\n * - Makes available the resources necessary to open and close layers.\n *\n * - Renders the currently open layers to the DOM at the top level of the\n * DOM. We do this to simplify positioning as we can position everything\n * relative to the full window which is what is returned by\n * `getBoundingClientRect`\n *\n * NOTE:\n *\n * As a design decision, we wrap many components with the Layer instead of\n * having a Layer per component. This design decision is important because\n * we may want to open multiple layers of the same type and if we open another\n * layer of the same type, we want any other layers to close.\n *\n * For example, consider a Dialog. If we open a differnet Dialog, we want the\n * first one to close. This can only be done when a single component knows\n * about the existence of both.\n */\nexport function Layers({ children }: { children: React.ReactNode }) {\n const [layers, setLayers] = useState<LayersRecord>({})\n\n /**\n * Open a layer of the given type\n */\n function openLayer(layer: Layer) {\n setLayers((layers) => {\n return {\n ...layers,\n [layer.type]: layer,\n }\n })\n }\n\n /**\n * Close a layer of the given type\n */\n function closeLayer(layerType: string) {\n setLayers((layers) => {\n const nextLayers = { ...layers }\n delete nextLayers[layerType]\n return nextLayers\n })\n }\n\n /**\n * - provide the layers context\n * - render the layers at the top of the DOM using a Portal\n */\n return (\n <LayersContext.Provider\n value={{ layers, setLayers, openLayer, closeLayer }}\n >\n {children}\n {Object.entries(layers).map(([, layer]) => {\n return (\n <Portal key={layer.type}>\n <LayerContext.Provider value={layer}>\n <layer.Component />\n </LayerContext.Provider>\n </Portal>\n )\n })}\n </LayersContext.Provider>\n )\n}\n","import { createPortal } from \"react-dom\"\n\n/**\n * Portal to `document.body`\n *\n * NOTE:\n * Consider creating a version of Portal with a Reset in it.\n *\n * The reason is that when showing a portal, it will carry the baggage of\n * any styling from `<html>` and `<body>` element.\n */\nexport function Portal({ children }: { children: React.ReactNode }) {\n return createPortal(children, document.body)\n}\n","import { FunctionComponent, useContext } from \"react\"\n\nimport { LayersContext } from \"./layers\"\nimport { Layer } from \"./types\"\n\n/**\n * `useLayer` may only be called when it is inside a Component that is itself\n * nested under the `Layers` component. This is necessary because `useLayer`\n * uses a React Context which is set up in the `Layers` component.\n *\n * Using the `useLayer` hook returns a layer object that has an `open` and\n * `close` method. You can use it something like this:\n *\n * ```typescript\n * function MyComponent() {\n *\n * const tooltip = useLayer('tooltip')\n *\n * const openTootlip = () => {\n * tooltip.open(() => <Tooltip title=\"Hey Dudes\" />)\n * }\n *\n * return <div\n * onMouseEnter={openTooltip}\n * onMouseLeave={tooltip.close}\n * >Thing that needs a tooltip</div>\n * }\n * ```\n *\n * In this scenario, it opens a `Tooltip` component when the mouse enters the\n * div and closes it when the mouse leave it.\n *\n * This library is simple but flexible enough to be used to handle different\n * kinds of components that pop up in the DOM.\n *\n * - tooltips\n * - dialog boxes positioned where a button is clicked\n * - dialog boxes positioned in the center of a viewport\n * - notifications\n *\n * `useLayer` is designed to handle just the opening and closing of the layers\n * that overlays on top of all the other components at the top of the DOM.\n *\n * It also ensures only one of each kind of layer is open at a time. So when\n * a second tooltip is opened, the first is closed.\n *\n * The positioning of the tooltips, dialogs and notifications, especially when\n * the position is relative to another element like a button that was clicked\n * it the domain of the `useReposition` micro library.\n *\n * These libraries are not tied together in any way (there is nothing\n * opinionated that ties them toegher); however they were designed and built\n * at the same time and work together well to solve all the issues related to\n * popup windows/dialogs/tooltips of any kind.\n */\nexport function useLayer(type: string) {\n const { openLayer, closeLayer, layers } = useContext(LayersContext)\n\n /**\n * Call this method to open a layer that contains the Component at the given\n * layer type.\n *\n * Opening a layer of this type will close any other layers of this type.\n * For example, if a `tooltip` layer was currently open, opening a new\n * tooltip would close the previously open one.\n *\n * When opening a layer, we pass in a function (that takes no arguments) and\n * returns our rendered Component something like:\n *\n * ```ts\n * const dialog = useLayer('dialog')\n *\n * const openDialog = () => {\n * dialog.open(() => <MyDialog title=\"My Title\" />)\n * }\n * ```\n *\n * If you are getting TypeScript issues, especially when passing props as\n * properties of some other object, the easiest way to fix these issues are\n * to assign those values to a `const` first. This can happen when the\n * values on the object could potentially be `undefined` or change during\n * a re-render.\n *\n * For example, this could give typing issues:\n *\n * ```ts\n * type Item = {\n * title?: string\n * }\n *\n * const dialog = useLayer('dialog')\n *\n * const openDialog = () => {\n * if (item.title === undefined) return\n * dialog.open(() => <MyDialog title={item.title} />)\n * }\n * ```\n *\n * It's a little non-obvious because it looks like we did a check to make\n * sure that `item.title` is defined. But remember that it could change\n * during a re-render.\n *\n * Here's how to fix this.\n *\n * ```ts\n * type Item = {\n * title?: string\n * }\n *\n * const dialog = useLayer('dialog')\n *\n * const openDialog = () => {\n * if (item.title === undefined) return\n * const title = item.title\n * dialog.open(() => <MyDialog title={title} />)\n * }\n * ```\n *\n * Now `title` is of type `string` because we already asserted that\n * `item.title` was a string. We assigned it to a `const` meaning that it\n * won't change, even if re-rendered later.\n */\n function open(Component: FunctionComponent<Record<string, never>>) {\n const layer: Layer = { type, Component }\n openLayer(layer)\n }\n\n /**\n * Call this method to close the current layer of the given layer type.\n */\n function close() {\n closeLayer(type)\n }\n\n return {\n open,\n close,\n layer: layers[type],\n type,\n }\n}\n","import styled from \"@emotion/styled\"\n\nexport const $Anchor = styled(\"a\")`\n /**\n * Link colors\n */\n color: var(--link-color, blue);\n &:hover {\n color: var(--link-hover-color, blue);\n }\n /**\n * When the cursor is in the anchor and not outside the anchor, we style the\n * anchor with a very light shade. This is enough to subtly intuit to the user\n * that when they type, it will appear inside the link. When the shade is\n * not present, they intuit they are just outside the link.\n */\n border-radius: 0.125em;\n transition: background-color 250ms;\n &.--selected {\n background: var(--blue-50);\n }\n`\n/**\n * This edge piece that are at the edge of the inside of the anchor are visibly\n * designed to be 1px wide. A <span> can't be given a width so we fake this by\n * creating an empty span with 1px of width.\n */\nexport const $Edge = styled(\"span\")`\n display: inline;\n padding: 0 1px 0 0;\n`\n\n/**\n * Shows progress bar of an uploading attachment. This part is the outline.\n */\nexport const $ProgressBar = styled(\"span\")`\n position: fixed;\n width: 100px;\n background: var(--shade-50);\n height: 8px;\n border-radius: 7px;\n border: 1px solid var(--shade-400);\n overflow: hidden;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n`\n\n/**\n * Show the fill part of the progress bar.\n */\nexport const $ProgressBarFill = styled(\"span\")`\n position: absolute;\n left: 0;\n top: 0;\n height: 14px;\n background: var(--blue-400);\n transition: width 100ms linear;\n`\n","import styled from \"@emotion/styled\"\nimport { useCallback, useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { $Panel } from \"../../shared-overlays\"\nimport { useLayer } from \"../../use-layer\"\nimport { useAbsoluteReposition } from \"../../use-reposition\"\nimport { useTooltip } from \"../../use-tooltip\"\nimport { AnchorElement } from \"../index\"\nimport { AnchorEditDialog } from \"./AnchorEditDialog\"\nimport { CloseIcon, ExternalLinkIcon, LinkOffIcon, PencilIcon } from \"./icons\"\nimport { DraggableHeader } from \"../../toolbar-plugin/components/dialog/DraggableHeader\"\n\nconst $AnchorDialog = styled($Panel)`\n position: absolute;\n width: 20em;\n z-index: 1000;\n padding: 0;\n overflow: hidden;\n color: var(--shade-400);\n\n .--icons {\n display: flex;\n overflow: hidden;\n flex: 0 0 6em;\n }\n\n .--link {\n text-decoration: none;\n display: flex;\n flex: 0 0 14em;\n overflow: hidden;\n color: var(--shade-400);\n &:hover {\n color: var(--blue-600);\n }\n transition: all 200ms;\n }\n\n .--url {\n margin-left: 0.5em;\n .--hostname {\n font-size: 0.875em;\n width: 14em;\n line-height: 1.5em;\n color: var(--blue-600);\n overflow-wrap: break-word;\n /* width: 13.5em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis; */\n }\n .--pathname {\n margin-top: 0.125em;\n font-size: 0.75em;\n width: 16.25em;\n line-height: 1.5em;\n overflow-wrap: break-word;\n }\n .--tooltip {\n box-sizing: border-box;\n position: relative;\n margin-top: 1em;\n font-size: 0.875em;\n width: 14em;\n line-height: 1.5em;\n background: var(--shade-200);\n border-radius: 0.5em;\n padding: 0.5em 0.75em;\n color: var(--shade-600);\n overflow-wrap: break-word;\n }\n .--tooltip::before {\n content: \"\";\n position: absolute;\n top: -0.5em; /* Height of the triangle */\n left: 0.5em; /* Position it on the left side */\n border-left: 0.5em solid transparent; /* Half the width of the triangle */\n border-right: 0.5em solid transparent; /* Half the width of the triangle */\n border-bottom: 0.5em solid var(--shade-200); /* Height and color of the triangle */\n }\n }\n\n .--icon {\n cursor: pointer;\n margin-left: 0.5em;\n &:hover {\n color: var(--blue-600);\n }\n }\n\n svg {\n flex: 0 0 auto;\n width: 1.25em;\n height: 1.25em;\n stroke-width: 1.5;\n }\n`\n\nfunction parseUrl(s: string): { hostname: string; pathname: string } {\n try {\n const url = new URL(s)\n return { hostname: url.hostname, pathname: url.pathname }\n } catch {\n return { hostname: \"\", pathname: \"\" }\n }\n}\n\nexport function AnchorDialog({\n destAnchor,\n destStartEdge,\n element,\n}: {\n destAnchor: HTMLAnchorElement\n destStartEdge: HTMLSpanElement\n element: AnchorElement\n}) {\n const dialog = useLayer(\"dialog\")\n const editor = useSlateStatic()\n const url = parseUrl(element.href)\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })\n\n const handleDrag = useCallback((deltaX: number, deltaY: number) => {\n setDragOffset(prev => ({ x: prev.x + deltaX, y: prev.y + deltaY }))\n }, [])\n\n const baseStyle = useAbsoluteReposition(\n { destAnchor, destStartEdge },\n ({ destAnchor, destStartEdge }) => {\n return {\n left: destStartEdge.left,\n top: destAnchor.top + destAnchor.height,\n }\n }\n )\n\n const style = {\n ...baseStyle,\n left: (baseStyle.left as number) + dragOffset.x,\n top: (baseStyle.top as number) + dragOffset.y,\n }\n\n const removeTooltip = useTooltip({ title: \"リンクを削除\" })\n const editTooltip = useTooltip({ title: \"リンクを編集\" })\n const closeTooltip = useTooltip({ title: \"閉じる\" })\n\n const closeDialog = useCallback(() => {\n dialog.close()\n }, [dialog])\n\n const removeLink = useCallback(() => {\n editor.anchor.removeLink({ at: element })\n // Close the dialog after removing the link\n dialog.close()\n }, [editor, dialog])\n\n const openEditDialog = useCallback(() => {\n /**\n * Force close the tooltip otherwise it will stay open because the\n * `onMouseLeave` never gets called. Technically, the mouse never leaves\n * the icon through a mouse movement. The edit icon simply disappears.\n */\n editTooltip.onMouseLeave()\n dialog.open(() => {\n return (\n <AnchorEditDialog\n destAnchor={destAnchor}\n destStartEdge={destStartEdge}\n element={element}\n />\n )\n })\n }, [destAnchor, destStartEdge, element])\n\n return (\n <$AnchorDialog contentEditable={false} style={style}>\n <DraggableHeader onDrag={handleDrag} />\n <div style={{ display: \"flex\", padding: \"1em\" }}>\n <a\n className=\"--link\"\n href={element.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <ExternalLinkIcon />\n <div className=\"--url\">\n <div className=\"--hostname\">{url.hostname}</div>\n {url.pathname === \"\" || url.pathname === \"/\" ? null : (\n <div className=\"--pathname\">{url.pathname}</div>\n )}\n {element.title == null || element.title === \"\" ? null : (\n <div className=\"--tooltip\">{element.title}</div>\n )}\n </div>\n </a>\n <span className=\"--icons\">\n <span\n className=\"--icon\"\n onClick={removeLink}\n onMouseEnter={removeTooltip.onMouseEnter}\n onMouseLeave={removeTooltip.onMouseLeave}\n >\n <LinkOffIcon />\n </span>\n <span\n className=\"--icon\"\n onMouseEnter={editTooltip.onMouseEnter}\n onMouseLeave={editTooltip.onMouseLeave}\n onClick={openEditDialog}\n >\n <PencilIcon />\n </span>\n <span\n className=\"--icon\"\n onClick={closeDialog}\n onMouseEnter={closeTooltip.onMouseEnter}\n onMouseLeave={closeTooltip.onMouseLeave}\n >\n <CloseIcon />\n </span>\n </span>\n </div>\n </$AnchorDialog>\n )\n}\n","import React, { useRef } from \"react\"\n\nimport { $CloseMask } from \"../../styles/$CloseMask\"\n\n/**\n * Add this `CloseMask` before the Component you want this `CloseMask` to be\n * the background for.\n *\n * When users click on the `CloseMask`, it will close the layer.\n */\nexport function CloseMask({ close }: { close: () => void }) {\n const ref = useRef<HTMLDivElement>(null)\n return <$CloseMask ref={ref} onClick={close} />\n}\n","import styled from \"@emotion/styled\"\n\nexport const $CloseMask = styled(\"div\")`\n position: fixed;\n user-select: none;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow-y: auto;\n background: rgba(0, 0, 0, 0.01);\n`\n","import { isMac } from \"../../../sink\"\n\n/**\n * Character Reference\n *\n * Ctrl+P Ctrl+Shift+P Ctrl+Alt+P\n * ⌘P ⇧⌘P ⌥⌘P\n */\n\nexport const key = {\n cmd: \"\\u2318\",\n ctrl: \"\\u2303\",\n shift: \"⇧\",\n opt: \"⌥\",\n enter: \"⏎\",\n}\n\nconst MAC_KEYS = {\n shift: key.shift,\n opt: key.opt,\n alt: key.opt,\n ctrl: key.ctrl,\n mod: key.cmd,\n cmd: key.cmd,\n enter: key.enter,\n super: `${key.opt}${key.cmd}`,\n}\n\nconst PC_KEYS = {\n alt: \"ALT\",\n ctrl: \"CTRL\",\n opt: \"ALT\",\n shift: \"SHIFT\",\n mod: \"CTRL\",\n cmd: \"CTRL\",\n enter: key.enter,\n super: \"CTRL+SHIFT\",\n}\n\nfunction pull<T>(arr: T[], value: T): void {\n const index: number = arr.findIndex((el: T) => el === value)\n if (index !== -1) {\n arr.splice(index, 1)\n }\n}\n\nfunction formatMac(segments: string[]) {\n const result = []\n Object.entries(MAC_KEYS).forEach(([key, symbol]) => {\n if (segments.includes(key)) {\n result.push(symbol)\n pull(segments, key)\n }\n })\n result.push(...segments.map((s) => s.toUpperCase()))\n return result.join(\"\")\n}\n\nfunction formatPC(segments: string[]) {\n const result = []\n Object.entries(PC_KEYS).forEach(([key, symbol]) => {\n if (segments.includes(key)) {\n result.push(symbol)\n pull(segments, key)\n }\n })\n result.push(...segments.map((s) => s.toUpperCase()))\n return result.join(\"+\")\n}\n\nexport function formatHotkey(shortcut: string) {\n const segments = shortcut.toLowerCase().split(\"+\")\n if (isMac()) {\n return formatMac(segments)\n } else {\n return formatPC(segments)\n }\n}\n","import { useRef } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { useAbsoluteReposition } from \"../../../use-reposition\"\n\nimport { $Menu, $MenuDivider } from \"../../../toolbar-plugin/styles\"\nimport { MenuItemData } from \"../../types\"\nimport { CloseMask } from \"../CloseMask\"\nimport { MenuItem } from \"./MenuItem\"\n\nexport function Menu({\n dest,\n items,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n items: MenuItemData[]\n}) {\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(null)\n const style = useAbsoluteReposition({ src: ref, dest }, ({ dest }) => {\n return { left: dest.left - 8, top: dest.top + dest.height }\n })\n\n return (\n <>\n <CloseMask close={close} />\n <$Menu ref={ref} style={style}>\n {items.map((item, index) => {\n if (item === \"divider\") {\n return <$MenuDivider key={index} />\n } else if (item.show && !item.show(editor)) {\n return null\n } else {\n return (\n <MenuItem\n key={index}\n editor={editor}\n item={item}\n close={close}\n dest={dest}\n />\n )\n }\n })}\n </$Menu>\n </>\n )\n}\n","import { Rect } from \"../types\"\n\n/**\n * Returns a `Rect` representing the `fixed` positioning coordinates of\n * the `HTMLElement`\n */\nexport function getFixedRect(domElement: HTMLElement): Rect {\n const bounds = domElement.getBoundingClientRect()\n return {\n top: bounds.top,\n right: bounds.right,\n bottom: bounds.bottom,\n left: bounds.left,\n width: bounds.width,\n height: bounds.height,\n }\n}\n","import { Rect } from \"../types\"\nimport { getFixedRect } from \"./get-fixed-rect\"\n\n/**\n * Returns a `Rect` representing the `absolute` positioning coordinates of\n * the `HTMLElement`\n *\n * NOTE: we add `window.scrollY` to get the `absolute` position.\n */\nexport function getAbsoluteRect(domElement: HTMLElement): Rect {\n const rect = getFixedRect(domElement)\n const { scrollY } = window\n return Object.assign(rect, {\n top: rect.top + scrollY,\n bottom: rect.bottom + scrollY,\n })\n}\n","import { Rect } from \"../types\"\n\n/**\n * Returns a `Rect` representing the `fixed` positioning coordinates of\n * the window viewport.\n */\nexport function getFixedViewport(): Rect {\n /**\n * Get the width of the viewport not including the scrollbar\n *\n * https://stackoverflow.com/a/25298418\n */\n const width =\n document.documentElement.clientWidth || document.body.clientWidth\n return {\n top: 0,\n right: width,\n bottom: window.innerHeight,\n left: 0,\n width: width,\n height: window.innerHeight,\n }\n}\n","import { Rect } from \"../types\"\nimport { getFixedViewport } from \"./get-fixed-viewport\"\n\n/**\n * Returns a `Rect` representing the `absolute` positioning coordinates of\n * the window viewport.\n *\n * NOTE: we add `window.scrollY` to get the `absolute` position.\n */\nexport function getAbsoluteViewport(): Rect {\n const rect = getFixedViewport()\n return Object.assign(rect, {\n top: window.scrollY,\n bottom: window.scrollY + rect.height,\n })\n}\n","var objectMapValues = map;\n\n/*\n // returns a new object with the predicate applied to each value\n // like just-map-object, but (value, key, object) are passed to the predicate\n map({a: 3, b: 5, c: 9}, (value) => value + 1); // {a: 4, b: 6, c: 10}\n map({a: 3, b: 5, c: 9}, (value, key) => value + key); // {a: 3a, b: 5b, c: 9c}\n map({a: 3, b: 5, c: 9}, (value, key, object) => object.b); // {a: 5, b: 5, c: 5}\n*/\n\nfunction map(obj, predicate) {\n var result = {};\n var keys = Object.keys(obj);\n var len = keys.length;\n for (var i = 0; i < len; i++) {\n var key = keys[i];\n result[key] = predicate(obj[key], key, obj);\n }\n return result;\n}\n\nexport {objectMapValues as default};\n","import mapValues from \"just-map-values\"\nimport { RefObject } from \"react\"\n\nimport { MapHTMLElementLikeRecordToRectRecord, Rect } from \"./types\"\n\n/**\n * Tries to convert an `HTMLElement` to a `Rect` using the supplied\n * `convertElementToRect` method.\n *\n * The input Record can have as its values either an `HTMLElement` or a\n * `RefObject<HTMLElement>`. When it is a `RefObject` then it may or may not\n * refer to an `HTMLElement` so...\n *\n * - If the value is an `HTMLElement` we convert it to a `Rect`\n * - If the value is a `RefObject<HTMLElement>` we convert it to a\n * `Rect | null` depending on whether the `RefObject` contains the\n * `HTMLElement`.\n */\nexport function mapHTMLElementLikeRecordToRectRecord<\n T extends Record<string, HTMLElement | RefObject<HTMLElement>>\n>(\n elementLikeRecord: T,\n converElementToRect: (element: HTMLElement) => Rect\n): MapHTMLElementLikeRecordToRectRecord<T> {\n const rectRecord = mapValues(elementLikeRecord, (value) => {\n const maybeHTMLElement =\n value instanceof HTMLElement ? value : value.current\n const nextValue = maybeHTMLElement\n ? converElementToRect(maybeHTMLElement)\n : null\n return nextValue\n }) as MapHTMLElementLikeRecordToRectRecord<T>\n return rectRecord\n}\n","import { useEffect } from \"react\"\n\nimport {\n useThrottledRefresh,\n UseThrottledRefreshReturnType,\n} from \"./use-throttled-refresh\"\n\n/**\n * Refreshes the Component whenever the page is resized or the window is\n * scrolled. This is because these are usually the only two events that cause\n * the elements on a page to be repositioned.\n *\n * If there are yet other events that can cause the elements to be repositioned\n * or resized, you can also call the returned `refresh` method. This will\n * update the components while still respected the fact that the updates will\n * be throttled so as not to overload the browser.\n */\nexport function useReposition(): UseThrottledRefreshReturnType {\n /**\n * Create a throttled `refresh` method.\n */\n const refresh = useThrottledRefresh()\n\n /**\n * refresh on page resize or scroll (throttled)\n */\n useEffect(() => {\n refresh()\n window.addEventListener(\"resize\", refresh)\n window.addEventListener(\"scroll\", refresh)\n return () => {\n window.removeEventListener(\"resize\", refresh)\n window.removeEventListener(\"scroll\", refresh)\n }\n }, [])\n\n return refresh\n}\n","/**\n * NOTE:\n *\n * We have a preference for `just` packages like `just-throttle` since they\n * tend to be micro, but `just-throttle` has a bug. It does not execute\n * on the trailing edge even when told to do so.\n *\n * We ran a test where we logged the call to `refresh` and when the refresh was\n * executed and there were leftover `refresh` calls without a trailing\n * execution.\n */\nimport throttle from \"lodash.throttle\"\nimport { useState } from \"react\"\n\nexport type UseThrottledRefreshReturnType = ReturnType<typeof throttle> & {\n counter: number\n}\n\n/**\n * Creates a hook that rerenders a component when the returned `refresh`\n * method is called; however, it throttles the refresh based on the\n * `intervalInMs` argument passed in.\n *\n * This is a useful component used when throttling reposition updates.\n */\nexport function useThrottledRefresh(\n intervalInMs = 100\n): UseThrottledRefreshReturnType {\n const [counter, setState] = useState(0)\n\n const refresh = throttle(\n () => {\n setState((counter) => counter + 1)\n },\n intervalInMs,\n { trailing: true }\n )\n\n return Object.assign(refresh, { counter })\n}\n","import { RefObject } from \"react\"\n\nimport { getAbsoluteRect } from \"../get-methods/get-absolute-rect\"\nimport { getAbsoluteViewport } from \"../get-methods/get-absolute-viewport\"\nimport { MapHTMLElementLikeRecordToRectRecord, Rect } from \"../types\"\nimport { mapHTMLElementLikeRecordToRectRecord } from \"../utils\"\nimport { useReposition } from \"./use-reposition\"\n\n/**\n * For `absolute` positioning.\n *\n * For `fixed` positioning see `useFixedReposition`\n *\n * An all-in-one hook that helps you position elements relative to other\n * elements and to the viewport.\n *\n * It automatically refreshes when the user scrolls or the window is resized.\n *\n * The method takes as its first argument an object where the values can be\n * either an `HTMLElement` or a ref to an `HTMLElement` created using\n * `useRef(null)`.\n *\n * As the second argument, it takes a function that you use to process\n * everything and return a value you can use to position the element. It's\n * typical to return this in the form of a `style` Object but it doesn't have\n * to be.\n *\n * That function you pass in can take these arguments:\n *\n * - The first argument is in the same shape as the object of `HTMLElement` or\n * `ref` to `HTMLElement`; however, instead, its values are `Rect` or\n * if the original value was a `ref`, a `Rect | null`. The value can be\n * `null` because a `ref` can potentially contain no value and hence we can't\n * find a `Rect` for it.\n * - The second argument is a `Rect` representing the viewport of the `window`.\n * - The third argument is a `refresh` method you can call to force a\n * refresh. The refresh is throttled in sync with the ot\n */\nexport function useAbsoluteReposition<\n T extends Record<string, HTMLElement | RefObject<HTMLElement>>,\n NV\n>(\n elementLikeRecord: T,\n fn: (\n elementRecord: MapHTMLElementLikeRecordToRectRecord<T>,\n viewport: Rect,\n refresh: () => void\n ) => NV\n) {\n const refresh = useReposition()\n const rectRecord = mapHTMLElementLikeRecordToRectRecord(\n elementLikeRecord,\n (element) => getAbsoluteRect(element)\n )\n return fn(rectRecord, getAbsoluteViewport(), refresh)\n}\n","import { Rect } from \"../types\"\n\n/**\n * Takes a source Rect of the Element you are trying to position and makes\n * sure it is inside the container Rect.\n *\n * The source Rect can be `null` (e.g. when the `ref` hasn't been set yet) and\n * while it is, the item is positioned far off to the left of the screen.\n *\n * Can specify an optional `margin` as well.\n */\nexport function positionInside(\n src: Rect | null,\n container: Rect,\n pos: { left: number; top: number },\n { margin = 0 }: { margin?: number } = {}\n) {\n if (src == null) return { ...pos, left: -1024 }\n\n const { top } = pos\n let { left } = pos\n\n const containerWidth = container.right - container.left - margin * 2\n\n // If modal is wider than container, align to left edge\n if (src.width >= containerWidth) {\n left = container.left + margin\n } else {\n // Check if it goes beyond right edge\n const right = left + src.width\n if (right > container.right - margin) {\n left = container.right - src.width - margin\n }\n\n // Check if it goes beyond left edge\n if (left < container.left + margin) {\n left = container.left + margin\n }\n }\n\n return { left, top }\n}\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays/styles/$Panel\"\n\nexport const $AnchorDialog = styled($Panel)`\n width: 24em;\n padding: 0;\n overflow: hidden;\n`\nexport const $AnchorDialogInputLine = styled(\"div\")`\n display: flex;\n gap: 0.5em;\n`\n\nexport const $AnchorDialogInput = styled(\"input\")`\n flex: 1 1 auto;\n padding: 0.5em 0.75em;\n border-radius: 0.25em;\n color: var(--shade-700);\n background: var(--shade-50);\n border: 1px solid var(--shade-300);\n font-size: 0.9375em;\n &:focus {\n outline: 2px solid var(--blue-200);\n }\n`\n","import styled from \"@emotion/styled\"\n\nimport { SinkReset } from \"../../sink/editable\"\n\n/**\n * $Panel is a nice box that goes around a Drop Down menu or a Dialog Box.\n *\n * We don't use $Panel directly and instead we extend it.\n *\n * The $Panel itself extends the `SinkReset` and we do this because the\n * Component appears at the root. So any styling, for example like from\n * Bootstrap or Material UI will affect what's in the Panel.\n */\nexport const $Panel = styled(SinkReset)`\n position: absolute;\n z-index: 1000;\n border: 1px solid var(--table-border-color);\n border-radius: 0.5em;\n overflow: clip;\n filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07))\n drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));\n background: white;\n /**\n * If you are tempted to add the transitions back in, here's why we left\n * them off:\n *\n * - When we initially unhide the panel (by setting a negative 'left' pos)\n * the panel slides in very quickly. So we'd need to fix this first which\n * adds complexity.\n *\n * - Even if we fixed it, the browser window updates the scrolls and resizes\n * in a stepped manner (i.e. like frames in an animation). Keeping the\n * smooth animations makes the panel step in sync with the page refreshes\n * and so actually looks better.\n *\n * In other words, there's a technical issue we'd still need to solve but\n * even if we did, it looks better this way.\n */\n /* transition: left 100ms, top 100ms; */\n`\n","import styled from \"@emotion/styled\"\n\nimport { $Container } from \"../../shared-layout\"\n\nexport const $Editable = styled(\"div\")`\n padding: 2em;\n`\n\nexport const $OuterContainer = styled($Container)`\n /**\n * We use this to make sure the top of the container is rounded even though\n * the toolbar inside is square. We keep the toolbar square so that as the\n * toolbar hits the top when scrolling, it can become sticky. We can try to\n * round the toolbar, but it causes an issue where the part under the\n * rounded part is still visible (i.e. the edge of the container). We can\n * then try to put an absolutely positioned background on it with an opaque\n * color, but that doesn't work unless we know the color of the background\n * so... ultimately, it's not a good solution.\n *\n * NOTE:\n *\n * Using \"overflow: hidden;\" will break the \"position: sticky;\" and it will\n * not work. \"overflow: clip;\" does work though.\n *\n * https://stackoverflow.com/a/73051006\n */\n overflow-y: clip;\n display: flex;\n flex-direction: column;\n`\n","import styled from \"@emotion/styled\"\n\nimport { SinkReset } from \"../sink/editable\"\n\n/**\n * NOTE:\n *\n * This $Container should be extended and the following should be\n * added to it:\n *\n * - padding: We add this separately because if there is a toolbar, there\n * should be no padding on the container but there should be\n * padding on the actual editable. If it is the basic layout, we can add\n * the padding on the $Container but also use the $Container styling\n * directly on the Editable Component.\n */\nexport const $Container = styled(SinkReset)`\n border: 1px solid var(--shade-300); /* shade-300 */\n border-radius: 0.5em;\n color: rgb(39 39 42); /* shade-800 */\n line-height: 1.5;\n /**\n * !important is required because of role=\"textbox\" I think\n */\n outline: 2px solid transparent !important;\n transition: all 250ms;\n &.--focused {\n /**\n * !important is required because of role=\"textbox\" I think\n */\n outline: 2px solid var(--select-editor-color) !important;\n }\n`\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays/styles/$Panel\"\n\n/**\n * Drop Down Menu\n */\nexport const $Menu = styled($Panel)`\n position: absolute;\n padding-top: 0.5em;\n padding-bottom: 0.5em;\n transition: all 200ms;\n min-width: 12em;\n /**\n * Prevent clicks from stealing focus from the editor\n */\n user-select: none;\n`\n\n/**\n * Individual items in Drop Down Menu\n */\nexport const $MenuItem = styled(\"div\")`\n display: flex;\n z-index: 10;\n padding: 0 1em 0 1.5em;\n height: 2em;\n align-items: center;\n /**\n * Normally we don't do it this way but since each part of the MenuItem\n * is tightly related to the display: flex, this seemed the easiest way\n * to set this up.\n */\n .--icon {\n flex: 0 0;\n display: block;\n font-size: 1.25em;\n height: 1em;\n padding-right: 0.75em;\n color: var(--shade-400);\n svg {\n position: relative;\n stroke-width: 1.5px;\n }\n }\n .--title {\n flex: 1 1 auto;\n font-size: 0.875em;\n color: var(--shade-800);\n white-space: nowrap;\n }\n .--hotkey {\n flex: 0 0;\n font-size: 0.75em;\n padding-left: 1.5em;\n color: var(--shade-500);\n }\n background: white;\n cursor: pointer;\n &:hover {\n background: var(--blue-50);\n }\n`\n\nexport const $MenuDivider = styled(\"div\")`\n height: 1px;\n background: var(--shade-200);\n margin-top: 0.25em;\n margin-bottom: 0.25em;\n`\n","import styled from \"@emotion/styled\"\n\nexport const $ToolbarContainer = styled(\"div\")`\n /**\n * This flex rule applies to the \"display: flex;\" of the parent container.\n * Ensures the toolbar does not shrink or grow vertically.\n */\n flex: 0 0 auto;\n /**\n * If \"position: sticky;\" is not working, check the ancestor for \"overflow:\n * hidden;\" of any kind. This will stop sticky from working. A good workaround\n * is to use \"overflow: clip;\" instead.\n *\n * https://stackoverflow.com/a/73051006\n */\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--shade-50);\n /* font-size: 0.875em; */\n font-size: 0.9375em;\n padding: 0 0.5em;\n border-bottom: 1px solid var(--shade-300);\n /**\n * Prevent clicks from stealing focus from the editor\n */\n user-select: none;\n /**\n * Extreme attention to detail. When the sticky is ending and the toolbar\n * is stuck to the bottom of the editor, setting margin-bottom to -1px will\n * fix the 2px bottom border and make it the proper 1px.\n */\n margin-bottom: -1px;\n\n /**\n * NOTE: The space in the equation is significant\n */\n height: calc(\n 3em + 1px\n ); // $ToolbarDivider height + border-bottom of 1px above\n overflow: hidden;\n`\n\nexport const $Toolbar = styled(\"div\")`\n display: inline-block;\n height: calc(\n 3em + 1px\n ); // $ToolbarDivider height + border-bottom of 1px above\n`\n\nexport const $ToolbarDividerContainer = styled(\"div\")`\n display: inline-block;\n height: 3em;\n padding: 0 0.375em;\n`\n\nexport const $ToolbarDivider = styled(\"div\")`\n display: inline-block;\n background: var(--shade-300);\n opacity: 50%;\n width: 1px;\n height: 3em;\n`\n\nexport const $ToolbarButton = styled(\"div\")`\n box-sizing: border-box;\n position: relative;\n display: inline-block;\n vertical-align: top;\n font-size: 1.25em;\n margin-top: 0.25em;\n height: 2em;\n padding: 0.375em 0.375em;\n border-radius: 0.25em;\n text-align: center;\n color: var(--shade-500);\n transition: all 100ms;\n cursor: pointer;\n border: 1px solid rgba(0, 0, 0, 0);\n &.--disabled {\n opacity: 0.3;\n cursor: default;\n pointer-events: none;\n }\n &.--active {\n color: var(--shade-700);\n background: rgba(0, 0, 0, 0.05);\n svg {\n /* stroke-width: 2px; */\n }\n }\n svg {\n stroke-width: 1.5px;\n }\n @media (hover: hover) {\n &:not(.--disabled):hover {\n color: var(--shade-700);\n background: var(--blue-100);\n svg {\n /* stroke-width: 2px; */\n }\n }\n }\n\n &.--more {\n padding: 0.375em 0.5em;\n }\n .--more-icon {\n position: absolute;\n bottom: -0.2em;\n left: 50%;\n margin-left: -0.25em;\n opacity: 0.375;\n }\n`\n","import { useCallback } from \"react\"\nimport { Editor } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { $MenuItem } from \"../../../toolbar-plugin/styles\"\nimport { useLayer } from \"../../../use-layer\"\nimport { MenuItemData } from \"../../types\"\nimport { formatHotkey } from \"./formatHotkey\"\n\nexport function MenuItem({\n editor,\n item,\n close,\n dest,\n}: {\n editor: Editor\n item: Exclude<MenuItemData, \"divider\">\n close: () => void\n dest: HTMLElement\n}) {\n const menuLayer = useLayer(\"menu\")\n\n const onClick = useCallback(() => {\n if (item.Component) {\n const Component = item.Component\n menuLayer.open(() => <Component dest={dest} close={menuLayer.close} />)\n } else if (item.action) {\n item.action(editor)\n ReactEditor.focus(editor)\n close()\n }\n }, [editor, item])\n return (\n <>\n <$MenuItem onClick={onClick}>\n <div className=\"--icon\">\n <item.icon />\n </div>\n <div className=\"--title\">{item.title}</div>\n <div className=\"--hotkey\">\n {item.hotkey ? formatHotkey(item.hotkey) : undefined}\n </div>\n </$MenuItem>\n </>\n )\n}\n","import { MouseEvent, useCallback } from \"react\"\n\nimport { useLayer } from \"../use-layer\"\n\nimport { Tooltip } from \"./tooltip\"\nimport { Triangle } from \"./triangle\"\n\n/**\n * Takes a title and a hotkey and renders it as a tooltip.\n *\n * You'll notice that hotkey can be a function and the reason is very specific\n * to our needs which is that we don't know what the hotkey should look like\n * until we are in the browser (i.e. not the server) because it checks the user\n * agent to see if we are on a Mac or on Windows.\n *\n * We can defer this request until the tooltip is displayed.\n *\n * The editor currently has no need to display this hotkey shortcuts except in\n * things like tooltips so this isn't a problem for us. Potentially, we may need\n * to figure out a way to render this on the server or figure out a way to\n * render on the server without the hotkey and then fill it in when we are in\n * the browser.\n *\n * If we ever fix this requirement that hotkeys can only be shown in the browser\n * (i.e. we get server side rendering of hotkeys working) then `useTooltip` can\n * be simplified to not take a function.\n */\nexport function useTooltip(\n {\n title,\n hotkey,\n }: {\n title: string\n hotkey?: string | (() => string | undefined)\n },\n deps: React.DependencyList = []\n) {\n const label = useLayer(\"tooltip-label\")\n const triangle = useLayer(\"tooltip-triangle\")\n\n /**\n * On hover over\n */\n const onMouseEnter = useCallback((e: MouseEvent<HTMLElement>) => {\n const dest = e.currentTarget\n /**\n * Open tooltip\n */\n if (title !== undefined) {\n label.open(() => (\n <Tooltip\n title={title}\n hotkey={typeof hotkey === \"function\" ? hotkey() : hotkey}\n dest={dest}\n />\n ))\n triangle.open(() => <Triangle dest={dest} />)\n }\n }, deps)\n\n /**\n * On hover out\n */\n const onMouseLeave = useCallback(() => {\n label.close()\n triangle.close()\n }, deps)\n return { onMouseEnter, onMouseLeave }\n}\n","import styled from \"@emotion/styled\"\n\nexport function useRect(dest: HTMLElement): DOMRect {\n return dest.getBoundingClientRect()\n}\n\nconst $Tooltip = styled(\"div\")`\n position: fixed;\n z-index: 10;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-size: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif;\n color: white;\n font-size: 0.875em;\n line-height: 1.5em;\n padding: 0 0.5em;\n color: var(--shade-300);\n background: var(--shade-700);\n border-radius: 0.25em;\n white-space: nowrap;\n`\n\nconst $Hotkey = styled(\"span\")`\n margin-left: 0.75em;\n font-size: 0.875em;\n font-weight: 500;\n color: var(--shade-400);\n`\n\nexport function Tooltip({\n title,\n hotkey,\n dest,\n}: {\n title: string\n hotkey?: string\n dest: HTMLElement\n}) {\n const rect = useRect(dest)\n return (\n <$Tooltip\n style={{\n left: rect.left,\n top: `calc(${rect.top}px - 2em)`,\n }}\n >\n {title}\n\n {hotkey ? <$Hotkey>{hotkey}</$Hotkey> : null}\n </$Tooltip>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { useRect } from \"./tooltip\"\n\nconst $Triangle = styled(\"span\")`\n position: fixed;\n z-index: 10;\n width: 0;\n height: 0;\n border-left: 0.375em solid transparent;\n border-right: 0.375em solid transparent;\n border-top: 0.375em solid var(--shade-700);\n`\n\nexport function Triangle({ dest }: { dest: HTMLElement }) {\n const rect = useRect(dest)\n return (\n <$Triangle\n style={{\n left: `calc(${rect.left + rect.width / 2}px - 0.375em)`,\n top: `calc(${rect.top}px - 0.5em)`,\n }}\n />\n )\n}\n","import styled from \"@emotion/styled\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { Node } from \"slate\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { $Panel } from \"../../shared-overlays\"\nimport { t } from \"../../utils/translations\"\nimport {\n $CancelButton,\n $FormCaption,\n $FormGroup,\n $FormHint,\n $Input,\n $PrimaryButton,\n $Textarea,\n} from \"../../shared-styles\"\nimport { useLayer } from \"../../use-layer\"\nimport { useAbsoluteReposition } from \"../../use-reposition\"\nimport { AnchorElement } from \"../index\"\nimport { AnchorDialog } from \"./AnchorDialog\"\nimport { DraggableHeader } from \"../../toolbar-plugin/components/dialog/DraggableHeader\"\n\nconst $AnchorEditDialog = styled($Panel)`\n position: absolute;\n width: 20em;\n padding: 0;\n overflow: hidden;\n`\n\nexport function AnchorEditDialog({\n destAnchor,\n destStartEdge,\n element,\n}: {\n destAnchor: HTMLAnchorElement\n destStartEdge: HTMLSpanElement\n element: AnchorElement\n}) {\n const dialog = useLayer(\"dialog\")\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })\n\n const handleDrag = useCallback((deltaX: number, deltaY: number) => {\n setDragOffset(prev => ({ x: prev.x + deltaX, y: prev.y + deltaY }))\n }, [])\n\n const baseStyle = useAbsoluteReposition(\n { destAnchor, destStartEdge },\n ({ destAnchor, destStartEdge }) => {\n return {\n left: destStartEdge.left,\n top: destAnchor.top + destAnchor.height,\n }\n }\n )\n\n const style = {\n ...baseStyle,\n left: (baseStyle.left as number) + dragOffset.x,\n top: (baseStyle.top as number) + dragOffset.y,\n }\n\n const editor = useSlateStatic()\n\n const [href, setHref] = useState<string>(element.href)\n const [text, setText] = useState<string>(Node.string(element))\n const [title, setTitle] = useState<string>(element.title || \"\")\n\n const formRef = useRef({ href, text, title })\n formRef.current = { href, text, title }\n\n const handleHrefChange = useCallback<\n React.ChangeEventHandler<HTMLInputElement>\n >((e) => {\n setHref(e.target.value)\n }, [])\n\n const handleTextChange = useCallback<\n React.ChangeEventHandler<HTMLInputElement>\n >((e) => {\n setText(e.target.value)\n }, [])\n\n const handleTitleChange = useCallback<\n React.ChangeEventHandler<HTMLInputElement>\n >((e) => {\n setTitle(e.target.value)\n }, [])\n\n const openAnchorDialog = useCallback(() => {\n dialog.open(() => (\n <AnchorDialog\n destAnchor={destAnchor}\n destStartEdge={destStartEdge}\n element={element}\n />\n ))\n }, [destAnchor, destStartEdge, element])\n\n const handleSubmit = useCallback(() => {\n const { href, text, title } = formRef.current\n editor.anchor.editLink({ href, text, title }, { at: element })\n openAnchorDialog()\n }, [openAnchorDialog])\n\n return (\n <$AnchorEditDialog contentEditable={false} style={style}>\n <DraggableHeader onDrag={handleDrag} />\n <div style={{ padding: \"1em\" }}>\n <$FormGroup>\n <$FormCaption>{t(\"linkUrl\")}</$FormCaption>\n <$Textarea as=\"textarea\" value={href} onChange={handleHrefChange} />\n </$FormGroup>\n <$FormGroup>\n <$FormCaption>{t(\"linkText\")}</$FormCaption>\n <$Input type=\"text\" value={text} onChange={handleTextChange} />\n <$FormHint>{t(\"linkTextHint\")}</$FormHint>\n </$FormGroup>\n <$FormGroup>\n <$FormCaption>{t(\"tooltipText\")}</$FormCaption>\n <$Input type=\"text\" value={title} onChange={handleTitleChange} />\n <$FormHint>{t(\"tooltipHint\")}</$FormHint>\n </$FormGroup>\n <$FormGroup>\n <$PrimaryButton onClick={handleSubmit}>{t(\"apply\")}</$PrimaryButton>\n </$FormGroup>\n <$FormGroup>\n <$CancelButton onClick={openAnchorDialog}>{t(\"cancel\")}</$CancelButton>\n </$FormGroup>\n </div>\n </$AnchorEditDialog>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $FormGroup = styled(\"div\")`\n margin: 0.5em 0;\n &:first-of-type {\n margin-top: 0;\n }\n &:last-of-type {\n margin-bottom: 0;\n }\n`\n\nexport const $FormCaption = styled(\"div\")`\n font-size: 0.9375em;\n margin-bottom: 0.25em;\n color: var(--shade-700);\n`\n\nexport const $FormHint = styled(\"div\")`\n font-size: 0.875em;\n margin-top: 0.25em;\n color: var(--shade-500);\n`\n\nexport const $Textarea = styled(\"input\")`\n box-sizing: border-box;\n width: 100%;\n height: 6em;\n padding: 0.5em 0.75em;\n border-radius: 0.25em;\n color: var(--shade-700);\n background: var(--shade-50);\n font-family: inherit;\n border: 1px solid var(--shade-300);\n font-size: 0.9375em;\n &:focus {\n outline: 2px solid var(--blue-200);\n }\n`\n\nexport const $Input = styled(\"input\")`\n box-sizing: border-box;\n width: 100%;\n padding: 0.5em 0.75em;\n border-radius: 0.25em;\n color: var(--shade-700);\n background: var(--shade-50);\n border: 1px solid var(--shade-300);\n font-size: 0.9375em;\n &:focus {\n outline: 2px solid var(--blue-200);\n }\n`\n\nexport const $BaseButton = styled(\"div\")`\n /* Center vertically and horizontally */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n padding: 0.25em 0.75em;\n text-align: center;\n transition: all 100ms;\n border-radius: 0.25em;\n svg {\n font-size: 1.25em;\n stroke-width: 2px;\n }\n`\n\nexport const $PrimaryButton = styled($BaseButton)`\n color: var(--blue-50);\n background: var(--blue-500);\n outline: 0px solid white;\n &:hover {\n color: white;\n background: var(--blue-600);\n outline: 2px solid var(--blue-200);\n }\n svg {\n color: var(--blue-200);\n }\n`\n\nexport const $CancelButton = styled($BaseButton)`\n color: var(--shade-500);\n background: var(--shade-200);\n outline: 0px solid white;\n &:hover {\n color: var(--shade-600);\n background: var(--shade-300);\n outline: 2px solid var(--shade-200);\n }\n svg {\n color: var(--shade-400);\n }\n`\n","import { useRef, useCallback } from \"react\"\nimport styled from \"@emotion/styled\"\n\nconst $DragHandle = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px 0;\n cursor: grab;\n background: linear-gradient(to bottom, #f8f8f8, #e8e8e8);\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n user-select: none;\n touch-action: none;\n\n &:active {\n cursor: grabbing;\n }\n`\n\nconst $DragIndicator = styled.div`\n width: 32px;\n height: 4px;\n background: #ccc;\n border-radius: 2px;\n`\n\ninterface DraggableHeaderProps {\n onDrag: (deltaX: number, deltaY: number) => void\n}\n\nexport function DraggableHeader({ onDrag }: DraggableHeaderProps) {\n const startPos = useRef<{ x: number; y: number } | null>(null)\n\n const handleStart = useCallback((clientX: number, clientY: number) => {\n startPos.current = { x: clientX, y: clientY }\n }, [])\n\n const handleMove = useCallback((clientX: number, clientY: number) => {\n if (!startPos.current) return\n const deltaX = clientX - startPos.current.x\n const deltaY = clientY - startPos.current.y\n startPos.current = { x: clientX, y: clientY }\n onDrag(deltaX, deltaY)\n }, [onDrag])\n\n const handleEnd = useCallback(() => {\n startPos.current = null\n }, [])\n\n // Mouse events\n const onMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n handleStart(e.clientX, e.clientY)\n\n const onMouseMove = (e: MouseEvent) => {\n handleMove(e.clientX, e.clientY)\n }\n const onMouseUp = () => {\n handleEnd()\n document.removeEventListener(\"mousemove\", onMouseMove)\n document.removeEventListener(\"mouseup\", onMouseUp)\n }\n\n document.addEventListener(\"mousemove\", onMouseMove)\n document.addEventListener(\"mouseup\", onMouseUp)\n }, [handleStart, handleMove, handleEnd])\n\n // Touch events\n const onTouchStart = useCallback((e: React.TouchEvent) => {\n if (e.touches.length !== 1) return\n const touch = e.touches[0]\n handleStart(touch.clientX, touch.clientY)\n }, [handleStart])\n\n const onTouchMove = useCallback((e: React.TouchEvent) => {\n if (e.touches.length !== 1) return\n // touch-action: none in CSS prevents scrolling, so no need for preventDefault\n const touch = e.touches[0]\n handleMove(touch.clientX, touch.clientY)\n }, [handleMove])\n\n const onTouchEnd = useCallback(() => {\n handleEnd()\n }, [handleEnd])\n\n return (\n <$DragHandle\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n onTouchMove={onTouchMove}\n onTouchEnd={onTouchEnd}\n >\n <$DragIndicator />\n </$DragHandle>\n )\n}\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"../../sink\"\n\nexport const ExternalLinkIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"M12 6H6a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6M11 13l9-9M15 4h5v5\" />\n </TablerIcon>\n)\n\nexport const LinkOffIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"m9 15 3-3m2-2 1-1M11 6l.463-.536a5 5 0 0 1 7.071 7.072L18 13M3 3l18 18M13 18l-.397.534a5.068 5.068 0 0 1-7.127 0 4.972 4.972 0 0 1 0-7.071L6 11\" />\n </TablerIcon>\n)\n\nexport const PencilIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"M4 20h4L18.5 9.5a1.5 1.5 0 0 0-4-4L4 16v4M13.5 6.5l4 4\" />\n </TablerIcon>\n)\n\nexport const CloseIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </TablerIcon>\n)\n","import { Descendant } from \"slate\"\n\nimport { createPlugin, curryOne } from \"../sink\"\n\nimport { TypedPlugin } from \"../sink/types/plugin/plugin\"\nimport { onPaste } from \"./editable/on-paste\"\nimport { createAnchorMethods } from \"./methods\"\nimport { normalizeNode } from \"./normalize-node\"\nimport { Anchor } from \"./render-element/anchor\"\n\ntype AnchorMethods = ReturnType<typeof createAnchorMethods>\n\nexport type AnchorEditor = {\n anchor: AnchorMethods\n}\n\nexport type AnchorElement = {\n type: \"anchor\"\n href: string\n target?: string\n title?: string\n children: Descendant[]\n}\n\nexport type AnchorPluginCustomTypes = {\n Name: \"anchor\"\n Editor: AnchorEditor\n Element: AnchorElement\n}\n\nexport const AnchorPlugin = createPlugin<AnchorPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.anchor = createAnchorMethods(editor)\n return createPolicy({\n name: \"anchor\",\n editor: {\n isInline(element) {\n if (element.type === \"anchor\") return true\n },\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n onPaste: curryOne(onPaste, editor),\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"anchor\") {\n return (\n <Anchor element={element} attributes={attributes}>\n {children}\n </Anchor>\n )\n }\n },\n },\n })\n }\n) as TypedPlugin<AnchorPluginCustomTypes>\n","import { Editor, Transforms } from \"slate\"\n\nimport { createPlugin, TypedPlugin } from \"../sink\"\n\nimport { isSafeDelete } from \"./is-safe-delete\"\n\ntype AtomicDeleteEditor = {\n atomicDelete: true\n}\n\nexport type AtomicDeletePluginCustomTypes = {\n Name: \"atomic-delete\"\n Editor: AtomicDeleteEditor\n}\n\n/**\n * The Atomic Delete plugin protects master/slave related elements from being\n * put into a bad state after a delete.\n *\n * This can happen because Slate's default delete behavior does not take into\n * account the relationship between master/slave elements.\n *\n * Specifically, atomic delete protects against the following situations:\n *\n * - User forward deletes from just before a table. The first cell in the\n * table is deleted leaving a first row with one less cell than the rest\n * of the table.\n *\n * - User forward deletes at the end of a code block. Text from outside the\n * code block is pulled into the code block.\n *\n * - User backward deletes from just after a code block. Text from outside the\n * code block is pulled into the code block.\n *\n * - User backward deletes at the start of a code block. Text from inside the\n * code block is pulled outside the code block.\n */\nexport const AtomicDeletePlugin = createPlugin<AtomicDeletePluginCustomTypes>(\n (editor) => {\n editor.atomicDelete = true\n return {\n name: \"atomic-delete\",\n editor: {\n deleteBackward() {\n if (editor.selection == null) return false\n const entry = Editor.node(editor, editor.selection)\n const prevEntry = Editor.previous(editor, { mode: \"lowest\" })\n if (isSafeDelete(editor, entry, prevEntry)) return false\n Transforms.move(editor, { unit: \"character\", reverse: true })\n return true\n },\n deleteForward() {\n if (editor.selection == null) return false\n const entry = Editor.node(editor, editor.selection)\n const nextEntry = Editor.next(editor, { mode: \"lowest\" })\n if (isSafeDelete(editor, entry, nextEntry)) return false\n Transforms.move(editor, { unit: \"character\" })\n return true\n },\n },\n }\n }\n) as TypedPlugin<AtomicDeletePluginCustomTypes>\n","import { Editor, Element, NodeEntry, Path } from \"slate\"\n\nimport { findElementUp } from \"../sink\"\n\nexport function isSafeDelete(\n editor: Editor,\n a: NodeEntry | undefined,\n b: NodeEntry | undefined\n) {\n if (!a || !b) return true\n /**\n * If the current Node and the next Node are the same, short circuit\n * and leave early. Good for performance.\n */\n if (Path.equals(a[1], b[1])) return true\n const masterEntryA = findElementUp(\n editor,\n (el) => Element.isElement(el) && editor.isMaster(el),\n { at: a[1] }\n )\n const masterEntryB = findElementUp(\n editor,\n (el) => {\n return Element.isElement(el) && editor.isMaster(el)\n },\n { at: b[1] }\n )\n /**\n * If neither have a master, then don't worry about it.\n */\n if (!masterEntryA && !masterEntryB) return true\n /**\n * If they both have a master but it's the same master, then don't\n * worry about it.\n */\n if (\n masterEntryA &&\n masterEntryB &&\n Path.equals(masterEntryA[1], masterEntryB[1])\n )\n return true\n return false\n}\n","import { Editor, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { createPlugin, curryOne, TypedPlugin } from \"../sink\"\n\nimport { createImageMethods } from \"./methods\"\nimport { normalizeNode } from \"./normalize-node\"\nimport { renderElement } from \"./render-element\"\nimport { ImagePluginConfig, ImagePluginCustomTypes } from \"./types\"\n\n/**\n * Handle drop events for image files\n */\nfunction createOnDrop(editor: Editor) {\n return (event: React.DragEvent<HTMLDivElement>): boolean => {\n const { dataTransfer } = event\n\n // Check if there are files being dropped\n if (!dataTransfer.files || dataTransfer.files.length === 0) {\n return false\n }\n\n // Check if any of the files are images\n const imageFiles = Array.from(dataTransfer.files).filter((file) =>\n file.type.startsWith(\"image/\")\n )\n\n if (imageFiles.length === 0) {\n return false\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n // Get the drop position and move cursor there\n const range = ReactEditor.findEventRange(editor, event)\n if (range) {\n Transforms.select(editor, range)\n }\n\n // Get the onImageChange handler from the editor\n const onImageChange = editor.wysimark?.onImageChange\n\n // Process each image file\n for (const file of imageFiles) {\n if (onImageChange) {\n onImageChange(file)\n .then((url) => {\n if (url) {\n editor.image.insertImageFromUrl(url, file.name, \"\")\n }\n })\n .catch(() => {\n // Failed to upload image - silently ignore\n })\n } else {\n // If no onImageChange handler, create a data URL\n const reader = new FileReader()\n reader.onload = () => {\n const dataUrl = reader.result as string\n editor.image.insertImageFromUrl(dataUrl, file.name, \"\")\n }\n reader.readAsDataURL(file)\n }\n }\n\n return true\n }\n}\n\nconst DEFAULT_OPTIONS: ImagePluginConfig = {\n maxInitialInlineImageSize: { width: 64, height: 64 },\n maxInitialImageSize: { width: 320, height: 320 },\n maxImageSize: { width: 1024, height: 1024 },\n imageBlockPresets: [\n /**\n * Pixel Presets\n */\n { name: \"S\", title: \"Small\", type: \"bounds\", width: 160, height: 160 },\n { name: \"M\", title: \"Medium\", type: \"bounds\", width: 320, height: 320 },\n { name: \"L\", title: \"Large\", type: \"bounds\", width: 640, height: 640 },\n /**\n * Scale Presets\n */\n { name: \"⅓\", title: \"1/3 scale\", type: \"scale\", scale: 1 / 3 },\n { name: \"½\", title: \"1/2 scale\", type: \"scale\", scale: 0.5 },\n { name: \"Full\", title: \"Full size\", type: \"scale\", scale: 1 },\n ],\n imageInlinePresets: [\n /**\n * Pixel Presets\n */\n {\n name: \"16\",\n title: \"16 pixels\",\n type: \"bounds\",\n width: 16,\n height: 16,\n },\n {\n name: \"24\",\n title: \"24 pixels\",\n type: \"bounds\",\n width: 24,\n height: 24,\n },\n {\n name: \"32\",\n title: \"32 pixels\",\n type: \"bounds\",\n width: 32,\n height: 32,\n },\n /**\n * Scale Presets\n */\n { name: \"⅓\", title: \"1/3 scale\", type: \"scale\", scale: 1 / 3 },\n { name: \"½\", title: \"1/2 scale\", type: \"scale\", scale: 0.5 },\n { name: \"Full\", title: \"Full size\", type: \"scale\", scale: 1 },\n ],\n}\n\nexport const ImagePlugin = //({\n createPlugin<ImagePluginCustomTypes>(\n (editor, sinkOptions, { createPolicy }) => {\n const options: ImagePluginConfig = {\n ...DEFAULT_OPTIONS,\n ...sinkOptions.image,\n }\n editor.image = {\n ...createImageMethods(editor),\n maxInitialInlineImageSize: options.maxInitialInlineImageSize,\n maxInitialImageSize: options.maxInitialImageSize,\n maxImageSize: options.maxImageSize,\n imageBlockPresets: options.imageBlockPresets,\n imageInlinePresets: options.imageInlinePresets,\n }\n\n return createPolicy({\n name: \"image\",\n editor: {\n isVoid: (element) => {\n if ([\"image-block\", \"image-inline\"].includes(element.type)) {\n return true\n }\n },\n isInline: (element) => {\n if (element.type === \"image-inline\") return true\n },\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n renderElement,\n onDrop: createOnDrop(editor),\n },\n })\n }\n ) as TypedPlugin<ImagePluginCustomTypes>\n","import { Editor, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { curryOne } from \"../../sink\"\nimport { ImageBlockElement} from \"../types\"\n\nfunction noop(_editor: Editor) {\n // Intentionally empty - noop function\n}\n\nfunction insertImageFromUrl(\n editor: Editor,\n url: string,\n alt?: string,\n title?: string,\n) {\n const { selection } = editor\n \n Transforms.insertNodes(editor, {\n type: \"image-block\",\n url,\n alt: alt || \"\",\n title: title || \"\",\n width: 320,\n height: 240,\n children: [{ text: \"\" }],\n } as ImageBlockElement)\n\n /**\n * If there is no selection the element is inserted at the bottom of the\n * editor. When this happens, the insertion point may not be visible and\n * so this code scrolls to the bottom of the editor. We don't do this if\n * there is a selection because if the user made a selection, it is\n * likely already in view.\n */\n if (!selection) {\n const lastPos = Editor.end(editor, [])\n Transforms.select(editor, lastPos)\n ReactEditor.focus(editor)\n }\n}\n\nexport function createImageMethods(editor: Editor) {\n return {\n noop: curryOne(noop, editor),\n insertImageFromUrl: curryOne(insertImageFromUrl, editor),\n }\n}\n","import { Editor, Node, NodeEntry } from \"slate\"\n\nexport function normalizeNode(_editor: Editor, _entry: NodeEntry<Node>): boolean {\n // No normalization needed for image nodes\n return false\n}\n","import { useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { $ImageBlock } from \"../styles/image-block-styles\"\nimport { ImageBlockElement } from \"../types\"\nimport { ImageWithControls } from \"./image-with-controls\"\n\nexport function ImageBlock({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ImageBlockElement>) {\n const editor = useSlateStatic()\n return (\n <div {...attributes}>\n <$ImageBlock contentEditable={false}>\n <ImageWithControls\n element={element}\n presets={editor.image.imageBlockPresets}\n />\n </$ImageBlock>\n {children}\n </div>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageBlock = styled(\"div\")`\n display: block;\n margin: 1em 0;\n`\n","import { clsx } from \"clsx\"\nimport React, { useState } from \"react\"\nimport { useSelected } from \"slate-react\"\n\nimport {\n $Image,\n $ImageContainer,\n} from \"../../styles/image-with-controls-styles/image-with-controls-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSizePreset,\n} from \"../../types\"\nimport { ImageResizeControl } from \"./image-resize-controls/image-resize-control\"\nimport { ImageSizeStatus } from \"./image-size-status/image-size-status\"\nimport { ImageToolbar } from \"./image-toolbar/image-toolbar\"\n\n/**\n * The `Image` Component is responsible for:\n *\n * - rendering the image\n * - displaying the UI for the image including\n * - resize controls\n * - current width/height\n * - image preset size controls\n *\n * It's outer $ImageContainer is represented as an `inline-block` and is\n * placed inside a `block` element for the `image-block` and a `span` element\n * for `image-inline`.\n */\nexport function ImageWithControls({\n element,\n presets,\n}: {\n element: ImageBlockElement | ImageInlineElement\n presets: ImageSizePreset[]\n}) {\n const url = element.url\n const selected = useSelected()\n const [isDragging, setIsDragging] = useState(false)\n const [size, setSize] = useState(\n element.srcWidth && element.srcHeight && element.width && element.height\n ? { width: element.width, height: element.height }\n : null\n )\n\n /**\n * Creates a `srcSize` object if there is both a srcWidth and a srcHeight.\n * This also acts as an indicator that the image can be resized. If there is\n * a `srcSize` present we know that the image can be resized.\n */\n const srcSize =\n element.srcWidth && element.srcHeight\n ? { width: element.srcWidth, height: element.srcHeight }\n : null\n\n /**\n * Show resize controls if the element is selected, it has a `size` and\n * it has a `srcSize`\n */\n const showControls = selected && size && srcSize\n\n /**\n * Add classes for different states.\n */\n const className = clsx({\n \"--selected\": selected,\n \"--dragging\": isDragging,\n \"--small\": size && (size.width <= 64 || size.height <= 64),\n })\n\n /**\n * The purpose of the surrounding $ImageContainer is simply to surround the\n * image tightly so that we can place the other control elements relative\n * to the image.\n *\n * In order to do this, the $ImageContainer must be an `inline-block` or else\n * space gets added on the inside of the container.\n *\n * NOTE:\n *\n * Everything inside the $ImageContainer must be safe to insert into a\n * `<p>` tag which means `<div>` tags are not allowed. Use `<span>` tags\n * instead, even if they are blocks. This is because we get some invalid\n * nested warning otherwise as `<div>` tags are not supposed to be children\n * of `<p>` tags.\n */\n return (\n <$ImageContainer className={className}>\n <$Image src={url} width={size?.width} height={size?.height} />\n {showControls ? (\n <ImageToolbar\n element={element}\n size={size}\n setSize={setSize}\n srcSize={srcSize}\n presets={presets}\n />\n ) : null}\n {/**\n * Show the size status bar only when the user is dragging to resize the\n * image.\n */}\n {isDragging && size ? <ImageSizeStatus size={size} /> : null}\n {showControls ? (\n <ImageResizeControl\n element={element}\n srcSize={srcSize}\n isDragging={isDragging}\n setIsDragging={setIsDragging}\n size={size}\n setSize={setSize}\n />\n ) : null}\n </$ImageContainer>\n )\n}\n","import styled from \"@emotion/styled\"\n\n/**\n * Wrap the image with a container so we can accurately place UI elements\n * around it.\n */\nexport const $ImageContainer = styled(\"span\")`\n /**\n * In order for this container to wrap tightly (without space), it needs to be\n * an \"inline-block\". If it's just an \"inline\" we end up with spacing\n * artificats related to how spacing is placed around text.\n */\n display: inline-block;\n /**\n * This wrapper's primary purpose (why we don't use the image by itself) is\n * so that we can place UI controls for the image in and around the image.\n */\n position: relative;\n`\n\nexport const $Image = styled(\"img\")`\n /**\n * TODO:\n *\n * This is a bit of a hack but is a better experience than not anything.\n *\n * Constrains the maximum resize width of an image to 100% of the space\n * available. This prevents the image from stepping outside its boundaries.\n *\n * Problem:\n *\n * - The \"height\" is set to \"auto\" which likely conflicts with the height\n * provided as an image attribute of \"height\" set by the application.\n * Effectively, this means that the \"height\" is ignored which is fine\n * except when the image hasn't been loaded yet, I think it's possible\n * and perhaps likely that there may be a reflow that happens before/after\n * the image is loaded.\n */\n max-width: 100%;\n height: auto;\n\n /**\n * Rounded borders are pretty and also help the selection outline look\n * pretty.\n */\n transition: border-radius 250ms;\n border-radius: 0.5em;\n .--small > & {\n border-radius: 1px;\n }\n display: block;\n\n /**\n * Selection border. We leave a space between the outline and the image so\n * that an image that is the same color as the selection border will still\n * look selected.\n */\n .--selected > & {\n outline: 2px solid var(--select-color);\n outline-offset: 1px;\n }\n /**\n * If the image isn't loaded yet, we want to have some color filling the space\n * that the image will eventually load into. This helps indicates to the user\n * the space that the image will fill into.\n *\n * Once the image is finished loading, we want to respect transparency so at\n * that point we hide the background shading.\n */\n .--loading > & {\n background: var(--shade-100);\n }\n\n /**\n * When we change the image via a preset, we want to animate the change;\n * however, when we are dragging to resize, a transition adds a janky delay\n * to the resize so we remove the transition during drag resizing.\n */\n transition: width 100ms, height 100ms;\n .--dragging > & {\n transition: border-radius 250ms;\n }\n`\n","import { clsx } from \"clsx\"\nimport { Dispatch, SetStateAction, useCallback } from \"react\"\nimport { Editor, Transforms } from \"slate\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { stopEvent } from \"../../../../sink\"\nimport { useResizeBrowser } from \"../../../../use-reposition/hooks\"\n\nimport {\n $ImageResizeHandle,\n $ImageResizeInvisibleHandle,\n} from \"../../../styles/image-with-controls-styles/image-resize-handle-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n} from \"../../../types\"\nimport { getEditorWidth, minMax, resizeToWidth } from \"../../../utils\"\n\n/**\n * Helper function finds the `img` inside the current Slate `Element`.\n *\n * The `Element` in the DOM points to the surrounding container, so we search\n * inside of it for the `img` tag which know there is only one of.\n *\n * We then get the client rect from it.\n */\nfunction getImageBoundsFromSlateElement(\n editor: Editor,\n element: ImageBlockElement | ImageInlineElement\n): DOMRect {\n const imageContainerDOMNode = ReactEditor.toDOMNode(editor, element)\n const imgDOMNode = imageContainerDOMNode.querySelector(\"img\")\n if (!imgDOMNode)\n throw new Error(`Image Element could not be found but should exist`)\n return imgDOMNode.getBoundingClientRect()\n}\n\nexport function ImageResizeControl({\n element,\n srcSize,\n size,\n setSize,\n isDragging,\n setIsDragging,\n}: {\n element: ImageBlockElement | ImageInlineElement\n srcSize: ImageSize\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n isDragging: boolean\n setIsDragging: Dispatch<SetStateAction<boolean>>\n}) {\n const editor = useSlateStatic()\n\n /**\n * Refreshes the rendering of the resize handle if the browser width is\n * changed. This is useful, for example, if the browser is resized, making\n * the editable area smaller, which in some cases shoudl cause the resize\n * handle to indicate that the image can only be resized smaller.\n */\n useResizeBrowser()\n\n /**\n * Retrieve the inner (usable) width of the editor.\n */\n const editorWidth = getEditorWidth(editor)\n\n /**\n * Create some convenience constants that we use a lot below\n */\n const width = size.width\n const maxWidth = Math.min(srcSize.width, editorWidth)\n const minWidth = Math.min(12, srcSize.width)\n\n /**\n * Start dragging\n */\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n stopEvent(e)\n setIsDragging(true)\n\n /**\n * Position of mouse pointer when mouse down is pressed\n */\n const startX = e.clientX\n\n /**\n * The initial image size for the visual image (i.e. the image we are\n * seeing on the screen) can vary from the image width as stored in the\n * Document value.\n *\n * This is because if the document image width value is larger than the\n * screen width, we have constrained the image so that it fits.\n *\n * When we start a resize, we want the resize to start at the visual\n * image width though or the drag may appear broken. For example, if you\n * start resizing smaller, if the image is larger than the width of the\n * screen, the resize will take no effect.\n *\n * For this reason, we start with the visual screen width.\n */\n const bounds = getImageBoundsFromSlateElement(editor, element)\n const startWidth = bounds.width\n\n let nextSize = { ...size }\n\n /**\n * Watch mouse movement during dragging\n */\n const onDocumentMouseMove = (e: MouseEvent) => {\n const nextWidth = minMax({\n value: startWidth + e.clientX - startX,\n min: minWidth,\n max: maxWidth,\n })\n nextSize = resizeToWidth(nextWidth, srcSize)\n\n setSize(nextSize)\n }\n\n /**\n * Remove dragging event listeners when releasing mouse button\n */\n const onDocumentMouseUp = () => {\n document.removeEventListener(\"mousemove\", onDocumentMouseMove)\n document.removeEventListener(\"mouseup\", onDocumentMouseUp)\n const path = ReactEditor.findPath(editor, element)\n /**\n * When we save the image to the document, at the moment, we have\n * decided to save the image at the actual resize width, as stored\n * in the resize state. This is different than using the visual\n * image width which is constrained to the width of the screen.\n *\n * Not sure if this is the right approach, but it does allow for a\n * manual workaround if desired where the content is being edited in\n * a smaller screen than the output window and the user wants to have\n * the image display at a larger size.\n *\n * Note that this is already possible (to save at a larger size than\n * the screen width) when using presets so it's not entirely out of\n * character for our editor either.\n */\n const size = {\n width: nextSize.width,\n height: nextSize.height,\n }\n /**\n * It's not, at the moment, strictly necessary to set the size because\n * the size is set during mouse move; however, I'm keeping this here\n * as (a) a sanity check to ensure this is always correct and (b) if\n * we ever decide to modify the size before saving (see the comment\n * above when setting size) then we don't end up in a bad state. This\n * is something that already occurred once during experimenting.\n */\n setSize(size)\n Transforms.setNodes(editor, size, { at: path })\n setIsDragging(false)\n }\n\n /**\n * Attach event listeners directly to document\n */\n document.addEventListener(\"mousemove\", onDocumentMouseMove)\n document.addEventListener(\"mouseup\", onDocumentMouseUp)\n },\n [srcSize.width, srcSize.height, size.width, element]\n )\n\n /**\n * FIXME:\n *\n * This can be refactored so that it shares more code with `onMouseDown`\n * above. They are nearly identical except:\n *\n * - the event listeners that are added/removed\n * - the way way in which clientX is retrieved\n */\n const onTouchStart = useCallback(\n (e: React.TouchEvent) => {\n stopEvent(e)\n setIsDragging(true)\n const startX = e.changedTouches[0].clientX\n const startWidth = size.width\n\n let nextSize = { ...size }\n\n const onDocumentTouchMove = (te: TouchEvent) => {\n // stopEvent(te)\n const e = te.changedTouches[0]\n\n const nextWidth = minMax({\n value: startWidth + e.clientX - startX,\n min: minWidth,\n max: maxWidth,\n })\n nextSize = resizeToWidth(nextWidth, srcSize)\n\n setSize(nextSize)\n }\n const onDocumentTouchEnd = () => {\n document.removeEventListener(\"touchmove\", onDocumentTouchMove)\n document.removeEventListener(\"touchend\", onDocumentTouchEnd)\n const path = ReactEditor.findPath(editor, element)\n Transforms.setNodes(\n editor,\n { width: nextSize.width, height: nextSize.height },\n { at: path }\n )\n setIsDragging(false)\n }\n\n document.addEventListener(\"touchmove\", onDocumentTouchMove)\n document.addEventListener(\"touchend\", onDocumentTouchEnd)\n },\n [srcSize.width, srcSize.height, size.width, element]\n )\n\n /**\n * Add special classNames to modify appearance of resize controls\n */\n const className = clsx({\n \"--center\": width < maxWidth && width > minWidth,\n \"--left\": width >= maxWidth && width > minWidth,\n \"--right\": width <= minWidth && width < maxWidth,\n \"--dragging\": isDragging,\n \"--small\": width <= 64 || size.height <= 64,\n })\n\n return (\n <>\n {/**\n * The invisible handle is not visible but gives a larger drag handle\n * target for the mouse and touch events\n */}\n <$ImageResizeInvisibleHandle\n className={className}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n >\n <$ImageResizeHandle>\n <span className=\"--bar --bar-left\" />\n <span className=\"--bar --bar-center\" />\n <span className=\"--bar --bar-right\" />\n </$ImageResizeHandle>\n </$ImageResizeInvisibleHandle>\n </>\n )\n}\n","import { useEffect } from \"react\"\n\nimport { useThrottledRefresh } from \"./use-throttled-refresh\"\n\n/**\n * Refreshes the Component whenever the page is resized or the window is\n * scrolled. This is because these are usually the only two events that cause\n * the elements on a page to be repositioned.\n *\n * If there are yet other events that can cause the elements to be repositioned\n * or resized, you can also call the returned `refresh` method. This will\n * update the components while still respected the fact that the updates will\n * be throttled so as not to overload the browser.\n */\nexport function useResizeBrowser() {\n /**\n * Create a throttled `refresh` method.\n */\n const refresh = useThrottledRefresh()\n\n /**\n * refresh on page resize or scroll (throttled)\n */\n useEffect(() => {\n refresh()\n window.addEventListener(\"resize\", refresh)\n return () => {\n window.removeEventListener(\"resize\", refresh)\n }\n }, [])\n\n return refresh\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageResizeInvisibleHandle = styled(\"span\")`\n position: absolute;\n display: block;\n /**\n * Prevent touch dragging from exhibiting a kind of scroll bounce behavior\n * when we just want the image to resize.\n */\n touch-action: none;\n background: rgba(127, 127, 127, 0.001);\n top: 0;\n right: calc(-1em - 2px);\n width: 2em;\n bottom: 0;\n &.--left {\n cursor: w-resize;\n }\n &.--center {\n cursor: ew-resize;\n }\n &.--right {\n cursor: e-resize;\n }\n &.--small {\n right: calc(-1.25em);\n /* background: green; */\n width: 1.25em;\n }\n`\nexport const $ImageResizeHandle = styled(\"span\")`\n position: absolute;\n display: block;\n background: var(--select-color);\n top: 50%;\n margin-top: -1em;\n width: 1em;\n height: 2em;\n outline: 1px solid white;\n transition: all 250ms;\n /**\n * The handle is 3 visible states depending on whether the image is at\n * maximum size or minimum size.\n *\n * There are three indicators that let the user know which directions are\n * available (left, right or both) that the user can drag:\n *\n * - rounded corners on the side that are available to drag towards\n * - on larger size image, the handle is on the inside, middle or outside\n * of the outline\n * - the cursor pointer indicates the direction available for resizing.\n */\n .--center > & {\n left: 0.5em;\n border-radius: 0.375em;\n }\n .--left > & {\n border-radius: 0.5em 0 0 0.5em;\n left: 1px;\n }\n .--right > & {\n border-radius: 0 0.5em 0.5em 0;\n left: calc(50% - 1px);\n }\n .--bar {\n position: absolute;\n background: var(--blue-200);\n width: 1px;\n top: 0.5em;\n bottom: 0.5em;\n }\n /**\n * Each of 3 bars is 1px wide and 3px apart\n */\n .--bar-left {\n left: calc(50% - 3.5px);\n }\n .--bar-center {\n left: calc(50% - 0.5px);\n }\n .--bar-right {\n left: calc(50% + 2.5px);\n }\n /**\n * When the image is small, we reduce the size of the handler and place it\n * outside the image. The reasons we do this:\n * \n * - If the handle is not outside the image at small sizes, the handle\n * obscures the image too much. At larger sizes, it works okay and the\n * inside handle placement makes the available direction of the drags more\n * intuitive.\n *\n * - Also, at small sizes, a large handle can overwhelm the image. That is,\n * the handle can be twice as tall as the image itself which looks poor.\n * It's still possible for the handle to be larger than the image at small\n * sizes, but this is okay in that we don't want the handle to become so\n * small that it is hard to see and hard to click.\n */\n .--small > & {\n /**\n * We opt to mainly adjust the size of the handle at smaller sizes by\n * adjusting the font-size. This is more efficient than changing all the\n * border-sizes because changing the font-size automatically changes the\n * size of the border, but we don't have to redo the different combinations\n * border-size and the corner that they need to display on.\n */\n font-size: 0.5em;\n width: 1.5em;\n left: 0.5em;\n margin-top: -1em;\n }\n /**\n * Each of 2 bars is 1px wide and 3px apart\n */\n .--small > & > .--bar-left {\n left: calc(50% - 2px);\n }\n .--small > & > .--bar-center {\n display: none;\n }\n .--small > & > .--bar-right {\n left: calc(50% + 1px);\n }\n`\n","/**\n * A more intuitive of ensuring a value is within a min/max range.\n */\n\nexport function minMax({\n value,\n min,\n max,\n}: {\n value: number\n min: number\n max: number\n}): number {\n if (!(max >= min)) throw new Error(`Expected max >= min but is not`)\n return Math.max(min, Math.min(max, value))\n}\n","import { Editor } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { ImageSize, ImageSizePreset } from \"../types\"\n\n/**\n * Takes a src image and resizes it to the exact width while preserving the\n * aspect ratio.\n *\n * NOTE: This is resizing to exact width, and not to inside width.\n */\nexport function resizeToWidth(width: number, srcSize: ImageSize): ImageSize {\n width = Math.round(width)\n const aspect = srcSize.width / srcSize.height\n return { width, height: Math.round(width / aspect) }\n}\n\n/**\n * Takes a src image and resizes it to the exact height while preserving the\n * aspect ratio.\n *\n * NOTE: This is resizing to exact height, and not to inside height.\n */\nexport function resizeToHeight(height: number, srcSize: ImageSize): ImageSize {\n height = Math.round(height)\n const aspect = srcSize.width / srcSize.height\n return { width: Math.round(height * aspect), height }\n}\n\n/**\n * Intuitive way of taking a size and a bounds and shrinking the size within\n * the given bounds if necessary.\n */\nexport function resizeInBounds(size: ImageSize, bounds: ImageSize): ImageSize {\n const aspect = size.width / size.height\n const boundsAspect = bounds.width / bounds.height\n if (aspect >= boundsAspect) {\n if (size.width > bounds.width) {\n return resizeToWidth(bounds.width, size)\n }\n } else {\n if (size.height > bounds.width) {\n return resizeToHeight(bounds.height, size)\n }\n }\n return size\n}\n\n/**\n * Takes an image size and an image resize preset and calculates the size of\n * the image when the preset is applied.\n *\n * Notably, there are two `preset` algorithms.\n *\n * - `bounds` which sets a maximum width/height and we find the maximum image\n * size that fits within those bounds.\n *\n * - `scale` which multiples the width/height by a given scale. Note that by\n * convention that scale should be 1 or less.\n */\nexport function resizeInPreset(\n size: ImageSize,\n srcSize: ImageSize,\n preset: ImageSizePreset\n): ImageSize {\n switch (preset.type) {\n case \"bounds\":\n return resizeInBounds(srcSize, preset)\n case \"scale\":\n return {\n width: Math.round(srcSize.width * preset.scale),\n height: Math.round(srcSize.height * preset.scale),\n }\n }\n}\n\n/**\n * Takes an editor object and returns the maximum width that elements inside of\n * the editor can be rendered at without overflowing.\n *\n * We get the `clientWidth` which is the \"box\" without the border but including\n * the padding. We then subtract the padding to get the value we want.\n */\nexport function getEditorWidth(editor: Editor) {\n const element = ReactEditor.toDOMNode(editor, editor)\n const computed = getComputedStyle(element)\n const padding =\n parseInt(computed.paddingLeft) + parseInt(computed.paddingRight)\n return element.clientWidth - padding\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageSizeStatus = styled(\"span\")`\n position: absolute;\n /**\n * The status appears with a 1px gap from the outline.\n *\n * - 1px for gap from image to outline\n * - 2px for outline width\n * - 1px more for the space to the status\n */\n bottom: calc(-2em - 4px);\n left: 0;\n font-size: 0.625em; /* 10px tiny */\n line-height: 2em;\n padding: 0 0.5em;\n color: var(--shade-100);\n background: var(--shade-600);\n outline: 1px solid rgba(255, 255, 255, 0.5);\n border-radius: 0.5em;\n white-space: nowrap;\n\n /* force numbers to be monospaced for better alignment */\n font-variant-numeric: tabular-nums;\n`\n","import { $ImageSizeStatus } from \"../../../styles/image-with-controls-styles/image-size-status-styles\"\nimport { ImageSize } from \"../../../types\"\n\nexport function ImageSizeStatus({ size }: { size: ImageSize }) {\n return (\n <$ImageSizeStatus>\n {size.width} × {size.height}\n </$ImageSizeStatus>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageToolbar = styled(\"span\")`\n position: absolute;\n /**\n * On top of the image +1 for space inside outline, +2 for outline,\n * +2 for space outside outline.\n *\n * DO NOT MOVE TO BOTTOM:\n *\n * This is a reminder not to move the preset to the bottom. Visually, it is\n * less obtrusive at the bottom; however, an issue is that when switching\n * between different presets, the preset UI moves up/down making it difficult\n * to switch between different presets. When kept at the top, the preset\n * UI doesn't move.\n */\n top: calc(-1.5em - 5px);\n /**\n * Align left to the outline: +1 for space inside outline, +2 for outline\n * width\n */\n left: -3px;\n /**\n * When we're resizing, the controls aren't usable and just add to visual\n * clutter so we hide it. The transition lets us do it smoothly and less\n * obtrusively.\n */\n transition: opacity 200ms;\n .--dragging & {\n opacity: 0;\n }\n display: flex;\n gap: 0.25em;\n`\n","import styled from \"@emotion/styled\"\n\n/**\n * Styling for a collection of buttons in the $ImageButtonsContainer at the top\n * of the image.\n */\nexport const $ImageButtonGroup = styled(\"span\")`\n /* font-size: 0.75em; */\n border-radius: 0.5em;\n display: flex;\n /**\n * So that inner Preset design shows within the rounded corners.\n */\n overflow: clip;\n /**\n * Let's the menu pop a little over other content. Without it, may be able to\n * see the border of the buttons.\n */\n outline: 1px solid white;\n`\n\nexport const $ImageButton = styled(\"span\")`\n font-size: 0.75em;\n line-height: 2em;\n padding: 0 0.625em;\n &:last-child {\n border-right: none;\n }\n cursor: pointer;\n\n /**\n * We don't want it to wrap\n */\n white-space: nowrap;\n\n /**\n * Preset default colors\n */\n color: var(--shade-600);\n background: var(--shade-200);\n border-right: 1px solid var(--shade-100);\n /**\n * When preset is disabled, it is lighter in color and with elss contrast.\n */\n &.--disabled {\n cursor: default;\n color: var(--shade-300);\n background: var(--shade-100);\n &:hover {\n color: var(--shade-300);\n background: var(--shade-100);\n }\n }\n &.--selected {\n cursor: default;\n color: var(--blue-700);\n background: var(--blue-200);\n &:hover {\n color: var(--blue-700);\n background: var(--blue-200);\n }\n }\n /**\n * On hover, it is dark, and with higher contrast.\n */\n &:hover {\n color: var(--shade-700);\n background: var(--shade-300);\n }\n svg {\n position: relative;\n top: 0.25em;\n font-size: 1.33em;\n line-height: 1em;\n }\n`\n","import { clsx } from \"clsx\"\nimport { Dispatch, SetStateAction, useCallback } from \"react\"\nimport { Transforms } from \"slate\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { useTooltip } from \"../../../../../use-tooltip\"\n\nimport { $ImageButton } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n ImageSizePreset,\n} from \"../../../../types\"\nimport { resizeInPreset } from \"../../../../utils\"\n\n/**\n * Shows a single preset image sizes as defined by the `Preset` type.\n *\n * If the srcSize is smaller than the preset, clicking the preset would do\n * nothing except show the image at its full size. For this reason, the\n * preset is disabled if the srcSize is smaller than the preset.\n */\nexport function ImagePresetButton({\n element,\n preset,\n size,\n setSize,\n srcSize,\n}: {\n element: ImageBlockElement | ImageInlineElement\n preset: ImageSizePreset\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n srcSize: ImageSize\n}) {\n const editor = useSlateStatic()\n const presetSize = resizeInPreset(size, srcSize, preset)\n const tooltip = useTooltip({\n title: preset.title,\n hotkey: `${presetSize.width}x${presetSize.height}`,\n })\n\n const onClick = useCallback(() => {\n const path = ReactEditor.findPath(editor, element)\n const nextSize = resizeInPreset(size, srcSize, preset)\n setSize(nextSize)\n Transforms.setNodes(editor, nextSize, { at: path })\n }, [element, preset, size, srcSize])\n\n const isEnabled =\n preset.type === \"scale\"\n ? true\n : preset.width <= srcSize.width || preset.height <= srcSize.height\n\n const isDisabled = !isEnabled\n\n const isSelected =\n size.width === presetSize.width && size.height === presetSize.height\n\n const className = clsx({\n \"--disabled\": isDisabled,\n \"--selected\": !isDisabled && isSelected,\n })\n\n return (\n <$ImageButton\n className={className}\n onClick={isDisabled ? undefined : onClick}\n onMouseEnter={tooltip.onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n >\n {preset.name}\n </$ImageButton>\n )\n}\n","import { Dispatch, SetStateAction } from \"react\"\n\nimport { $ImageButtonGroup } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n ImageSizePreset,\n} from \"../../../../types\"\nimport { ImagePresetButton } from \"./image-preset-button\"\n\nexport function ImagePresetButtonGroup({\n element,\n size,\n setSize,\n srcSize,\n presets,\n}: {\n element: ImageBlockElement | ImageInlineElement\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n\n srcSize: ImageSize\n presets: ImageSizePreset[]\n}) {\n return (\n <$ImageButtonGroup>\n {presets.map((preset, i) => {\n return (\n <ImagePresetButton\n element={element}\n key={i}\n preset={preset}\n size={size}\n setSize={setSize}\n srcSize={srcSize}\n />\n )\n })}\n </$ImageButtonGroup>\n )\n}\n","import { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { useTooltip } from \"../../../../../use-tooltip\"\n\nimport { $ImageButton } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport { ImageBlockElement, ImageInlineElement } from \"../../../../types\"\nimport { InlineIcon } from \"../../../icons\"\nimport { convertToInlineImage } from \"./convert-to-inline-image\"\n\nexport function BlockImageTypeButton({\n element,\n}: {\n element: ImageBlockElement | ImageInlineElement\n}) {\n const editor = useSlateStatic()\n const tooltip = useTooltip({\n title: \"Inline Image\",\n hotkey: \"In a line with text\",\n })\n\n const onClickInline = useCallback(() => {\n if (element.type !== \"image-block\") return\n convertToInlineImage(editor, element)\n }, [editor, element])\n return (\n <$ImageButton\n className={element.type === \"image-inline\" ? \"--selected\" : \"\"}\n onClick={element.type === \"image-inline\" ? undefined : onClickInline}\n onMouseEnter={tooltip.onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n >\n <InlineIcon />\n </$ImageButton>\n )\n}\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"../../sink\"\n\nexport const ResizeIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"m7 8-4 4 4 4M17 8l4 4-4 4M3 12h18\" />\n </TablerIcon>\n)\n\nexport const BlockIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <rect width={6} height={6} x={4} y={5} rx={1} />\n <path d=\"M4 15h16M4 19h16\" />\n </TablerIcon>\n)\n\nexport const InlineIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <rect width={6} height={6} x={9} y={5} rx={1} />\n <path d=\"M4 7h1M4 11h1M19 7h1M19 11h1M4 15h16M4 19h16\" />\n </TablerIcon>\n)\n","import { Editor, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { ImageBlockElement } from \"../../../../types\"\nimport { resizeInPreset } from \"../../../../utils\"\n\nexport function convertToInlineImage(\n editor: Editor,\n element: ImageBlockElement\n) {\n /**\n * TODO:\n *\n * This should be handled or thought about better. Like maybe if these\n * values don't exist, we still change the type.\n */\n if (\n !element.width ||\n !element.height ||\n !element.srcWidth ||\n !element.srcHeight\n )\n return\n const size = { width: element.width, height: element.height }\n const srcSize = { width: element.srcWidth, height: element.srcHeight }\n const path = ReactEditor.findPath(editor, element)\n Editor.withoutNormalizing(editor, () => {\n /**\n * TODO:\n *\n * `resizeInPreset` should probably be renamed to something like\n * `resizeIn` which can be used more generically. Perhaps it takes the\n * `type`, `width` and `height` as an Interface making it compatible with\n * a Preset which would extend it.\n */\n const nextSize = resizeInPreset(size, srcSize, {\n name: \"initial-inline-image\",\n title: \"\",\n type: \"bounds\",\n width: 24,\n height: 24,\n })\n Transforms.setNodes(\n editor,\n { type: \"image-inline\", ...nextSize },\n { at: path }\n )\n Transforms.wrapNodes(\n editor,\n { type: \"paragraph\", children: [] },\n { at: path }\n )\n })\n}\n","import { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { useTooltip } from \"../../../../../use-tooltip\"\n\nimport { $ImageButton } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport { ImageBlockElement, ImageInlineElement } from \"../../../../types\"\nimport { BlockIcon } from \"../../../icons\"\nimport { convertToBlockImage } from \"./convert-to-block-image\"\n\nexport function InlineImageTypeButton({\n element,\n}: {\n element: ImageBlockElement | ImageInlineElement\n}) {\n const editor = useSlateStatic()\n const tooltip = useTooltip({\n title: \"Block Image\",\n hotkey: \"On a line by itself\",\n })\n\n const onClickBlock = useCallback(() => {\n if (element.type !== \"image-inline\") return\n convertToBlockImage(editor, element)\n }, [editor, element])\n\n return (\n <$ImageButton\n className={element.type === \"image-block\" ? \"--selected\" : \"\"}\n onClick={element.type === \"image-block\" ? undefined : onClickBlock}\n onMouseEnter={tooltip.onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n >\n <BlockIcon />\n </$ImageButton>\n )\n}\n","import { Editor, Text, Transforms } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { findElementUp } from \"../../../../../sink\"\nimport { ImageInlineElement } from \"../../../../types\"\nimport { resizeInPreset } from \"../../../../utils\"\n\nexport function convertToBlockImage(\n editor: Editor,\n element: ImageInlineElement\n) {\n /**\n * TODO:\n *\n * This should be handled or thought about better. Like maybe if these\n * values don't exist, we still change the type.\n */\n if (\n !element.width ||\n !element.height ||\n !element.srcWidth ||\n !element.srcHeight\n )\n return\n const size = { width: element.width, height: element.height }\n const srcSize = { width: element.srcWidth, height: element.srcHeight }\n const path = ReactEditor.findPath(editor, element)\n\n Editor.withoutNormalizing(editor, () => {\n /**\n * TODO:\n *\n * `resizeInPreset` should probably be renamed to something like\n * `resizeIn` which can be used more generically. Perhaps it takes the\n * `type`, `width` and `height` as an Interface making it compatible with\n * a Preset which would extend it.\n */\n const nextSize = resizeInPreset(size, srcSize, {\n name: \"initial-block-image\",\n title: \"\",\n type: \"bounds\",\n width: 320,\n height: 320,\n })\n /**\n * Convert the inline image to a block image.\n *\n * When we make this change, it causes the normalization rules to change\n * from the rules of an inline to the rules of a block. Inlines can only\n * co-exist with Text and other Inline elments. They must also always be\n * followed by and preceded by a Text nod.\n *\n * Some of the code below help to fix the inconsistencies caused by this\n * change.\n */\n Transforms.setNodes(\n editor,\n { type: \"image-block\", ...nextSize },\n { at: path }\n )\n /**\n * Here we find the enclosing parent block for the inline.\n *\n * Note that there should always be a parent block for an inline. If there\n * isn't, something isn't working properly because the Slate normalization\n * rules require a block parent to an inline.\n */\n const parentEntry = findElementUp(\n editor,\n (node) => Editor.isBlock(editor, node) && node.type !== \"image-block\"\n )\n if (!parentEntry) throw new Error(\"This shouldn't happen\")\n const [parentElement, parentPath] = parentEntry\n const siblings = parentElement.children\n const siblingCount = parentElement.children.length\n const index = path.slice(-1)[0]\n\n /**\n * Before we lift the inline node, we want to remove **empty** Text blocks\n * at the beginning of the block when the inline node is the second item\n * and at the end of the block when the inline is the second to last item.\n *\n * We do this because Slate adds empty text nodes always at the beginning\n * and end of a line if the node next to it is an inline. This behavior\n * works fine in most cases, but when we want to lift the inline element\n * up, Slate sees that there is content next to it and when the element is\n * lifted up, the block is split into 3 pieces, including a piece with an\n * empty Text node.\n *\n * From a user expectation point of view though, we don't want these extra\n * blocks inserted. If the inline image is at the end of the line, we want\n * it converted to a block image with a block of stuff before it. There is\n * no use for the extra block at the end with no content in it.\n */\n /**\n * Remove the last sibling if it's empty and next to the inline image\n */\n const lastSibling = siblings[siblingCount - 1]\n if (\n index === siblingCount - 2 &&\n Text.isText(lastSibling) &&\n lastSibling.text === \"\"\n ) {\n Transforms.removeNodes(editor, {\n at: [...parentPath, siblingCount - 1],\n })\n }\n /**\n * Remove the first sibling if it's empty and next to the inline image\n */\n const firstSibling = siblings[0]\n const removeFirstSibling =\n index === 1 && Text.isText(firstSibling) && firstSibling.text === \"\"\n if (removeFirstSibling) {\n Transforms.removeNodes(editor, { at: [...parentPath, 0] })\n }\n /**\n * Now lift the node, but if the first sibling was removed, we need to account fo rthe fact that the index of the image changed.\n */\n Transforms.liftNodes(editor, {\n at: [...parentPath, removeFirstSibling ? index - 1 : index],\n })\n })\n}\n","import { $ImageButtonGroup } from \"../../../../styles/image-with-controls-styles/image-buttons-styles\"\nimport { ImageBlockElement, ImageInlineElement } from \"../../../../types\"\nimport { BlockImageTypeButton } from \"./block-image-type-button\"\nimport { InlineImageTypeButton } from \"./inline-image-type-button\"\n\nexport function ImageTypeButtonGroup({\n element,\n}: {\n element: ImageBlockElement | ImageInlineElement\n}) {\n return (\n <$ImageButtonGroup>\n <InlineImageTypeButton element={element} />\n <BlockImageTypeButton element={element} />\n </$ImageButtonGroup>\n )\n}\n","import React, { Dispatch, SetStateAction } from \"react\"\n\nimport { $ImageToolbar } from \"../../../styles/image-with-controls-styles/image-toolbar-styles\"\nimport {\n ImageBlockElement,\n ImageInlineElement,\n ImageSize,\n ImageSizePreset,\n} from \"../../../types\"\nimport { ImagePresetButtonGroup } from \"./image-preset-buttons/image-preset-button-group\"\nimport { ImageTypeButtonGroup } from \"./image-type-buttons/image-type-button-group\"\n\n/**\n * The ImageToolbar appears above an image when the image is selected.\n *\n * It includes:\n *\n * - A set of image resize presets when clicked resizes the image to the preset\n * - Buttons to toggle between a block image and an inline image\n */\nexport function ImageToolbar({\n element,\n size,\n setSize,\n srcSize,\n presets,\n}: {\n element: ImageBlockElement | ImageInlineElement\n size: ImageSize\n setSize: Dispatch<SetStateAction<ImageSize | null>>\n srcSize: ImageSize\n presets: ImageSizePreset[]\n}) {\n return (\n <$ImageToolbar>\n <ImageTypeButtonGroup element={element} />\n <ImagePresetButtonGroup\n element={element}\n size={size}\n setSize={setSize}\n srcSize={srcSize}\n presets={presets}\n />\n </$ImageToolbar>\n )\n}\n","import { useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { $ImageInline } from \"../styles/image-inline-styles\"\nimport { ImageInlineElement } from \"../types\"\nimport { ImageWithControls } from \"./image-with-controls\"\n\nexport function ImageInline({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ImageInlineElement>) {\n const editor = useSlateStatic()\n return (\n <span {...attributes} style={{ display: \"inline-block\" }}>\n <$ImageInline contentEditable={false}>\n <ImageWithControls\n element={element}\n presets={editor.image.imageInlinePresets}\n />\n </$ImageInline>\n {children}\n </span>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $ImageInline = styled(\"span\")`\n display: inline;\n`\n","import { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { ImageBlockElement, ImageInlineElement } from \"../types\"\nimport { ImageBlock } from \"./image-block\"\nimport { ImageInline } from \"./image-inline\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ImageBlockElement | ImageInlineElement>) {\n switch (element.type) {\n case \"image-block\":\n return (\n <ImageBlock element={element} attributes={attributes}>\n {children}\n </ImageBlock>\n )\n case \"image-inline\":\n return (\n <ImageInline element={element} attributes={attributes}>\n {children}\n </ImageInline>\n )\n }\n}\n","import { Descendant, Editor, Element, Node, Transforms } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n normalizeSiblings,\n TypedPlugin,\n} from \"../sink\"\n\nimport { $BlockQuote } from \"./styles\"\n\nexport type BlockQuoteEditor = {\n supportsBlockQuote: true\n blockQuotePlugin: {\n indent: () => void\n outdent: () => void\n isActive: () => boolean\n increaseDepth: () => void\n decreaseDepth: () => void\n canIncreaseDepth: () => boolean\n canDecreaseDepth: () => boolean\n }\n}\n\nexport type BlockQuoteElement = {\n type: \"block-quote\"\n children: Descendant[]\n}\n\nexport type BlockQuotePluginCustomTypes = {\n Name: \"block-quote\"\n Editor: BlockQuoteEditor\n Element: BlockQuoteElement\n}\n\nfunction matchBlockQuoteSafe(node: Node) {\n return (\n Element.isElement(node) &&\n /**\n * TODO:\n *\n * This is probably:\n * Element.isElement(node) && !Element.isInline(node) &&\n * !Element.isDependant(node)\n */\n (node.type === \"paragraph\" ||\n node.type === \"code-block\" ||\n node.type === \"table\" ||\n node.type === \"horizontal-rule\" ||\n node.type === \"task-list-item\" ||\n node.type === \"unordered-list-item\" ||\n node.type === \"ordered-list-item\" ||\n node.type === \"heading\")\n )\n}\n\nconst MAX_DEPTH = 2\n\nexport const BlockQuotePlugin = createPlugin<BlockQuotePluginCustomTypes>(\n (editor) => {\n editor.supportsBlockQuote = true\n editor.blockQuotePlugin = {\n indent: () => {\n Transforms.wrapNodes(\n editor,\n { type: \"block-quote\", children: [] },\n { match: matchBlockQuoteSafe }\n )\n },\n outdent: () => {\n Transforms.liftNodes(editor, {\n match: (node, path) => matchBlockQuoteSafe(node) && path.length > 1,\n })\n },\n isActive: () => {\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n return !!match\n },\n increaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return\n\n // Check if we're already at max depth\n if (!editor.blockQuotePlugin.canIncreaseDepth()) return\n\n const [, path] = match\n\n // Select all content inside the block-quote\n Transforms.select(editor, path)\n\n // Create a new block-quote wrapping the selected content\n Transforms.wrapNodes(\n editor,\n { type: \"block-quote\", children: [] },\n { at: path, split: false }\n )\n },\n decreaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return\n\n // Check if we can decrease depth\n if (!editor.blockQuotePlugin.canDecreaseDepth()) return\n\n const [node, path] = match\n\n // Get the children of the block-quote\n const children = (node as Element).children\n\n // Check if the first child is a block-quote\n if (\n children.length === 1 &&\n Element.isElement(children[0]) &&\n children[0].type === \"block-quote\"\n ) {\n // Unwrap the nested block-quote\n Transforms.unwrapNodes(editor, {\n at: [...path, 0], // Path to the nested block-quote\n match: (n) => Element.isElement(n) && n.type === \"block-quote\",\n })\n }\n },\n canIncreaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return false\n\n const [node] = match\n\n // Calculate the current depth\n let depth = 0\n let current = node\n\n while (\n (current as Element).children.length === 1 &&\n Element.isElement((current as Element).children[0]) &&\n (current as Element).children[0] &&\n (current as Element).children[0] &&\n ((current as Element).children[0] as Element).type === \"block-quote\"\n ) {\n depth++\n current = (current as Element).children[0]\n }\n\n return depth < MAX_DEPTH\n },\n canDecreaseDepth: () => {\n // Find the current block-quote\n const [match] = Editor.nodes(editor, {\n match: (n: Node) => Element.isElement(n) && n.type === \"block-quote\",\n })\n\n if (!match) return false\n\n const [node] = match\n\n // Check if the first child is a block-quote\n return (\n (node as Element).children.length === 1 &&\n Element.isElement((node as Element).children[0]) &&\n (node as Element).children[0] &&\n ((node as Element).children[0] as Element).type === \"block-quote\"\n )\n },\n }\n return {\n name: \"block-quote\",\n editor: {\n normalizeNode(entry) {\n const [node, path] = entry\n if (!Element.isElement(node)) return false\n if (node.type !== \"block-quote\") return false\n return normalizeSiblings<Element>(editor, [node, path], (a, b) => {\n if (\n Element.isElement(a[0]) &&\n Element.isElement(b[0]) &&\n a[0].type === \"block-quote\" &&\n b[0].type === \"block-quote\"\n ) {\n Transforms.mergeNodes(editor, { at: b[1] })\n }\n return true\n })\n },\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"block-quote\") {\n return <$BlockQuote {...attributes}>{children}</$BlockQuote>\n }\n },\n onKeyDown: createHotkeyHandler({\n \"super+.\": editor.blockQuotePlugin.indent,\n \"super+,\": editor.blockQuotePlugin.outdent,\n }),\n },\n }\n }\n) as TypedPlugin<BlockQuotePluginCustomTypes>\n","import styled from \"@emotion/styled\"\n\nexport const $BlockQuote = styled(\"blockquote\")`\n position: relative;\n margin-top: 1em;\n margin-bottom: 1em;\n margin-left: 0;\n border-left: 0.25em solid rgba(0, 0, 0, 0.075);\n padding-left: 1.5em;\n`\n","import { Editor, Element, Transforms } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n curryOne,\n findElementUp,\n isCollapsed,\n TypedPlugin,\n} from \"../sink\"\n\nimport { decorate } from \"./decorate\"\nimport { createCodeBlockMethods } from \"./methods\"\nimport { tokenStyles } from \"./prism-theme\"\nimport { CodeBlockPluginCustomTypes } from \"./types\"\nexport * from \"./decorate\"\nexport * from \"./types\"\n\nimport { normalizeNode } from \"./normalizeNode\"\nimport { renderElement } from \"./render-element\"\n\nexport const CodeBlockPlugin = createPlugin<CodeBlockPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.codeBlock = createCodeBlockMethods(editor)\n\n function onDelete(): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const codeBlockEntry = findElementUp(editor, \"code-block\")\n if (codeBlockEntry == null) return false\n const codeBlockText = Editor.string(editor, codeBlockEntry[1])\n if (codeBlockText === \"\") {\n Transforms.removeNodes(editor, { at: codeBlockEntry[1] })\n return true\n }\n return false\n }\n\n return createPolicy({\n name: \"code-block\",\n editor: {\n deleteBackward: onDelete,\n deleteForward: onDelete,\n isInline(element) {\n if (\n element.type === \"code-block\" ||\n element.type === \"code-block-line\"\n )\n return false\n },\n isVoid(element) {\n if (\n element.type === \"code-block\" ||\n element.type == \"code-block-line\"\n )\n return false\n },\n isMaster(element) {\n if (element.type === \"code-block\") return true\n },\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n decorate,\n onKeyDown: createHotkeyHandler({\n \"super+`\": () =>\n editor.codeBlock.createCodeBlock({ language: \"text\" }),\n \"mod+a\": () => {\n /**\n * When selection is in code-block and the user pressed mod+a,\n * select the code-block instead of the full document.\n */\n const entry = findElementUp(\n editor,\n (el) => Element.isElement(el) && el.type === \"code-block\"\n )\n if (!entry) return false\n Transforms.select(editor, entry[1])\n return true\n },\n }),\n renderElement,\n renderLeaf: ({ leaf, children }) => {\n const style = leaf.prismToken\n ? tokenStyles[leaf.prismToken] || null\n : null\n if (style === null) {\n return children\n } else {\n return <span style={style}>{children}</span>\n }\n },\n },\n })\n }\n) as TypedPlugin<CodeBlockPluginCustomTypes>\n","import Prism from \"prismjs\"\nconst { languages, tokenize } = Prism\nimport { Element, Node, Path, Range } from \"slate\"\n\nimport { CodeBlockElement, CodeBlockLineElement } from \"./types\"\n\n/**\n * Decorate Overview:\n *\n * We decorate the entire `code-block` at once because if we do it by line,\n * code that continues through multiple lines is not higlighted correctly.\n *\n * In order to higlight the entire `code-block` at once, we need to add a\n * newline to the end of each `code-line`. We cannot use `Node.string` on the\n * entire `code-block`.\n *\n * Once we receive the Prism tokens back, we need to create the ranges.\n *\n * The important part is that we track the offsets from the start. With the\n * offsets, we need to map those back to a `path` and `offset` of each\n * `code-line`. We also need to take into consideration that we have added\n * newlines to the end of each line so the algorithm needs to account for that.\n */\n\n/**\n * Takes an array of text lines and returns an array with the offset\n * in characters of the start of each line.\n */\n\nfunction getLineOffsets(lines: string[]) {\n let offset = 0\n const lineOffsets: number[] = []\n for (const line of lines) {\n lineOffsets.push(offset)\n offset = offset + line.length\n }\n return lineOffsets\n}\n\n/**\n * `decorate` method passed to `Editable`\n */\n\nexport function decorate(\n nodeEntry: [CodeBlockElement | CodeBlockLineElement, Path]\n): Range[] {\n const [node, path] = nodeEntry\n\n if (!Element.isElement(node)) return []\n if (node.type !== \"code-block\") return []\n\n const lang: Prism.Grammar | undefined = languages[node.language]\n\n if (lang === undefined) return []\n\n /**\n * To decorate a code-block, we need to look at all the code in a code-block.\n *\n * We can't `Node.string` the entire block because it will join lines\n * together without newlines.\n *\n * For this reason, we create an array of `textLines` which is the text of\n * each codeLine plus a newline on the end of it.\n *\n * Then we join all of those together to get the text that was pass into\n * Prism.\n *\n * We need to keep `textLines` around so that we can extract the\n * `linePositions`\n */\n\n const codeLineElements = node.children\n\n const textLines = codeLineElements.map((node) => `${Node.string(node)}\\n`)\n\n const text = textLines.join(\"\")\n\n const lineOffsets: number[] = getLineOffsets(textLines)\n\n /**\n * Takes a character offset from the beginning of the `code-block` and\n * returns the `path` to the `code-line` and the `offset` within the\n * `code-line` which Slate needs to make the decoration.\n */\n\n function getPointFromOffset(offset: number) {\n for (let i = lineOffsets.length; i >= 0; i--) {\n const lineOffset = lineOffsets[i]\n if (lineOffset <= offset) {\n return {\n path: [...path, i],\n offset: offset - lineOffset,\n }\n }\n }\n throw new Error(\"This shouldn't happen and indicates a bug in the logic\")\n }\n\n const ranges: (Range & { prismToken: string })[] = []\n\n const tokens = tokenize(text, lang)\n\n /**\n * Track current character offset from beginning of `textLines` joined\n * together.\n */\n\n let offset = 0\n\n /**\n * Tokens are either:\n *\n * - string: which means it is not syntax highlighted\n * - { type: string, content: string, length: number }: the highlight and content\n */\n for (const token of tokens) {\n if (typeof token === \"string\") {\n offset += token.length\n } else {\n const anchor = getPointFromOffset(offset)\n const focus = getPointFromOffset(offset + token.length)\n ranges.push({\n anchor,\n focus,\n prismToken: token.type,\n })\n offset += token.length\n }\n }\n\n return ranges\n}\n","import { Editor } from \"slate\"\n\nimport { insertRootElement } from \"../../sink\"\n\nimport { BuiltInLanguage } from \"../types\"\n\nexport function createCodeBlock(\n editor: Editor,\n { language }: { language: BuiltInLanguage }\n) {\n insertRootElement(editor, {\n type: \"code-block\",\n language,\n children: [{ type: \"code-block-line\", children: [{ text: \"\" }] }],\n })\n}\n","import { Editor, Element, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"../../sink\"\n\nimport { BuiltInLanguage } from \"../types\"\n\n/**\n * Set the current CodeBlock's language if the selection is currently in a\n * CodeBlock. Returns true if the language was set, false otherwise.\n */\nexport function setCodeBlockLanguage(\n editor: Editor,\n language: BuiltInLanguage,\n options: { at?: BetterAt } = {}\n): boolean {\n const entry = findElementUp(\n editor,\n (el) => Element.isElement(el) && el.type === \"code-block\",\n { at: options.at }\n )\n if (!entry) return false\n Transforms.setNodes(editor, { language }, { at: entry[1] })\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport { createCodeBlock } from \"./createCodeBlock\"\nimport { setCodeBlockLanguage } from \"./setCodeBlockLanguage\"\n\nexport function createCodeBlockMethods(editor: Editor) {\n return {\n createCodeBlock: curryOne(createCodeBlock, editor),\n setCodeBlockLanguage: curryOne(setCodeBlockLanguage, editor),\n }\n}\n","/**\n * Styles from\n * https://github.com/PrismJS/prism-themes/blob/master/themes/prism-ghcolors.css\n */\n\nimport { CSSProperties } from \"react\"\n\nconst commentStyle = { color: \"#999988\", fontStyle: \"italic\" }\nconst dimStyle = { opacity: \"0.7\" }\nconst stringStyle = { color: \"#e3116c\" }\nconst operatorStyle = { color: \"#393a34\" }\nconst valueStyle = { color: \"#36acaa\" }\nconst keywordStyle = { color: \"#00a4db\" }\nconst functionStyle = { color: \"#9a050f\" }\nconst tagStyle = { color: \"#00009f\" }\nconst boldStyle = { fontWeight: \"bold\" }\nconst italicStyle = { fontStyle: \"italic\" }\n\ntype TokenStyles = Record<string, CSSProperties>\n\nexport const tokenStyles: TokenStyles = {\n comment: commentStyle,\n prolog: commentStyle,\n doctype: commentStyle,\n cdata: commentStyle,\n namespace: dimStyle,\n string: stringStyle,\n \"attr-value\": stringStyle,\n puncutation: operatorStyle,\n operator: operatorStyle,\n entity: valueStyle,\n url: valueStyle,\n symbol: valueStyle,\n number: valueStyle,\n boolean: valueStyle,\n variable: valueStyle,\n constant: valueStyle,\n property: valueStyle,\n regex: valueStyle,\n insert: valueStyle,\n atrule: keywordStyle,\n keyword: keywordStyle,\n \"attr-name\": keywordStyle,\n function: { ...functionStyle, ...boldStyle },\n delete: functionStyle,\n tag: tagStyle,\n selector: tagStyle,\n important: boldStyle,\n bold: boldStyle,\n italic: italicStyle,\n}\n","import { Text } from \"slate\"\n\nimport { createCodeBlockMethods } from \"./methods\"\n\ntype CodeBlockMethods = ReturnType<typeof createCodeBlockMethods>\n\nexport type BuiltInLanguage =\n | \"text\"\n | \"html\"\n | \"svg\"\n | \"markup\"\n | \"css\"\n | \"javascript\"\n | \"js\"\n | \"java\"\n | \"c\"\n | \"clike\"\n\n/**\n * Maps a number of supported or semi-supported syntax highlighting languages\n * to the built-in Prism languages.\n */\nexport const LanguageMap: Record<string, BuiltInLanguage> = {\n plain: \"text\",\n plaintext: \"text\",\n text: \"text\",\n txt: \"text\",\n html: \"markup\",\n mathml: \"markup\",\n svg: \"markup\",\n xml: \"markup\",\n ssml: \"markup\",\n atom: \"markup\",\n rss: \"markup\",\n css: \"css\",\n c: \"clike\",\n clike: \"clike\",\n \"c#\": \"clike\",\n \"c++\": \"clike\",\n java: \"clike\",\n javascript: \"javascript\",\n js: \"javascript\",\n}\n\nexport const LanguageCaptionMap: Record<string, string> = {\n javascript: \"Javascript\",\n js: \"Javascript\",\n}\n\nexport const LanguageList: BuiltInLanguage[] = [\n \"text\",\n \"html\",\n \"css\",\n \"svg\",\n \"javascript\",\n \"java\",\n \"c\",\n]\n\nexport type CodeBlockEditor = {\n codeBlock: CodeBlockMethods\n}\n\n/**\n * The code block element is the root element of a code block.\n */\nexport type CodeBlockElement = {\n type: \"code-block\"\n /**\n * The language of the code block. Can accept any string because Markdown can\n * accept any string; however, the built-in Prism languages are defined in:\n * `BuiltInLanguage`\n */\n language: string\n children: CodeBlockLineElement[]\n}\n\nexport type CodeBlockLineElement = {\n type: \"code-block-line\"\n children: Text[]\n}\n\nexport type CodeBlockPluginCustomTypes = {\n Name: \"code-block\"\n Editor: CodeBlockEditor\n Element: CodeBlockElement | CodeBlockLineElement\n Text: { text: string; prismToken?: string }\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n if (!Element.isElement(entry[0])) return false\n /**\n * Code lines should only contain plain text.\n *\n * - If they contain void elements like images, remove them\n * - If they contain non-void elements, unwrap them\n *\n * TODO:\n *\n * Convert pasted in elements to Markdown code\n */\n if (entry[0].type === \"code-block-line\") {\n for (const [child, path] of Node.children(editor, entry[1])) {\n if (!Element.isElement(child)) continue\n if (editor.isVoid(child)) {\n Transforms.removeNodes(editor, { at: path })\n return true\n } else {\n Transforms.unwrapNodes(editor, { at: path })\n return true\n }\n }\n }\n /**\n * Code blocks should only contain code lines.\n *\n * - If they contain void blocks like images, remove them\n * - If they contain non-void blocks, then convert them to code lines\n *\n * TODO:\n *\n * Convert pasted in elements to Markdown code\n */\n if (entry[0].type === \"code-block\") {\n for (const [child, path] of Node.children(editor, entry[1])) {\n if (!Element.isElement(child)) continue\n if (child.type === \"code-block-line\") continue\n if (child.type === \"code-block\") {\n /**\n * When pasting two or more lines of `code-block-line`, Slate will paste\n * it as a `code-block` which will create a `code-block` in a\n * `code-block`. The following code removes the lower `code-block`.\n */\n Transforms.unwrapNodes(editor, { at: path })\n return true\n } else if (editor.isVoid(child)) {\n Transforms.removeNodes(editor, { at: path })\n return true\n } else {\n Transforms.removeNodes(editor, { at: path })\n Transforms.insertNodes(editor, {\n type: \"code-block-line\",\n children: [{ text: Node.string(child) }],\n })\n return true\n }\n }\n }\n return false\n}\n","import { useCallback, useRef } from \"react\"\nimport { useSelected } from \"slate-react\"\n\nimport { Menu, MenuItemData } from \"../../shared-overlays\"\nimport { ConstrainedRenderElementProps } from \"../../sink\"\nimport { useLayer } from \"../../use-layer\"\nimport { ChevronDownIcon } from \"../icons/ChevronDownIcon\"\nimport { $CodeBlock, $CodeBlockLanguage, $CodeBlockScroller } from \"../styles\"\nimport { CodeBlockElement, LanguageList } from \"../types\"\n\nexport function CodeBlock({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<CodeBlockElement>) {\n const ref = useRef<HTMLDivElement>(null)\n const selected = useSelected()\n const dropdown = useLayer(\"code-block-dropdown\")\n const onClick = useCallback(() => {\n if (dropdown.layer) dropdown.close()\n const dest = ref.current\n if (dest === null) return\n const items: MenuItemData[] = LanguageList.map((language) => {\n return {\n icon: () => <span />,\n title: language,\n action: (editor) => {\n editor.codeBlock.setCodeBlockLanguage(language, { at: element })\n },\n }\n })\n // Menu\n dropdown.open(() => (\n <Menu dest={dest} items={items} close={dropdown.close} />\n ))\n }, [element])\n\n return (\n <$CodeBlock className={selected ? \"--selected\" : \"\"} {...attributes}>\n <$CodeBlockLanguage contentEditable={false} onClick={onClick} ref={ref}>\n <span>{element.language}</span>\n <ChevronDownIcon />\n </$CodeBlockLanguage>\n <$CodeBlockScroller>{children}</$CodeBlockScroller>\n </$CodeBlock>\n )\n}\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"../../sink\"\n\nexport const ChevronDownIcon = (props: SVGProps<SVGSVGElement>) => (\n <TablerIcon {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </TablerIcon>\n)\n","import styled from \"@emotion/styled\"\n\nexport const $CodeBlock = styled(\"div\")`\n position: relative;\n background: var(--code-block-bgcolor);\n margin: 1em 0;\n border-radius: 0.5em;\n border: 1px solid var(--code-block-border-color);\n /**\n * DO NOT REMOVE: Code for adding line numbering if enabled. See $CodeBlockLine\n * for more details.\n * counter-reset: line;\n */\n &.--selected {\n outline: 2px solid var(--select-color);\n }\n /**\n * NOTE: Required to make the border radius work on the first and last lines.\n * Otherwise they will be square.\n */\n overflow-x: hidden;\n`\n\nexport const $CodeBlockScroller = styled(\"div\")`\n padding: 2.25em 1em 1.5em 1em;\n border-radius: 0.5em;\n overflow-x: auto;\n`\n\nexport const $CodeBlockLanguage = styled(\"span\")`\n cursor: pointer;\n position: absolute;\n top: 0.25em;\n right: 0.25em;\n width: 8em;\n display: flex;\n font-size: 0.75em;\n color: var(--shade-700);\n background: var(--shade-200);\n padding: 0.25em 0.5em;\n border-radius: 0.5em;\n align-items: center;\n gap: 0.25em;\n span {\n text-align: right;\n flex: 1 1 auto;\n }\n svg {\n flex: 0 0 auto;\n position: relative;\n }\n &:hover {\n color: var(--shade-800);\n background: var(--shade-300);\n }\n`\n\nexport const $CodeBlockLine = styled(\"div\")`\n white-space: pre;\n line-height: 1.5em;\n counter-increment: line;\n font-family: \"andale mono\", AndaleMono, monospace;\n font-size: 0.875em;\n &.--selected {\n background-color: var(--shade-100);\n }\n /*\n DO NOT REMOVE: Code for adding line numbering.\n TODO: Make optional in future.\n */\n /* &:before {\n content: counter(line);\n color: rgba(0, 0, 0, 0.25);\n border-right: 1px solid rgba(0, 0, 0, 0.05);\n margin-right: 1em;\n padding: 0em 1em 0 0;\n text-align: right;\n display: inline-block;\n width: 2em;\n } */\n`\n","import { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\nimport { $CodeBlockLine } from \"../styles\"\nimport { CodeBlockLineElement } from \"../types\"\n\nexport function CodeBlockLine({\n attributes,\n children,\n}: ConstrainedRenderElementProps<CodeBlockLineElement>) {\n const selected = useSelected()\n return (\n <$CodeBlockLine\n className={selected ? \"--selected\" : \"\"}\n {...attributes}\n spellCheck=\"false\"\n >\n {children}\n </$CodeBlockLine>\n )\n}\n","import { ConstrainedRenderElementProps } from \"../../sink\"\nimport { CodeBlockElement, CodeBlockLineElement } from \"../types\"\nimport { CodeBlock } from \"./CodeBlock\"\nimport { CodeBlockLine } from \"./CodeBlockLine\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<CodeBlockElement | CodeBlockLineElement>) {\n if (element.type === \"code-block\") {\n return (\n <CodeBlock element={element} attributes={attributes}>\n {children}\n </CodeBlock>\n )\n } else if (element.type === \"code-block-line\") {\n return (\n <CodeBlockLine element={element} attributes={attributes}>\n {children}\n </CodeBlockLine>\n )\n }\n}\n","import { Transforms } from \"slate\"\n\nimport { createPlugin, findElementUp, isCollapsed, TypedPlugin } from \"../sink\"\n\nimport { HtmlBlockPluginCustomTypes } from \"./types\"\nimport { HtmlBlock } from \"./render-element\"\nexport * from \"./types\"\n\nexport const HtmlBlockPlugin = createPlugin<HtmlBlockPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n function onDelete(): boolean {\n const { selection } = editor\n if (!isCollapsed(selection)) return false\n const htmlBlockEntry = findElementUp(editor, \"html-block\")\n if (htmlBlockEntry == null) return false\n Transforms.removeNodes(editor, { at: htmlBlockEntry[1] })\n return true\n }\n\n return createPolicy({\n name: \"html-block\",\n editor: {\n deleteBackward: onDelete,\n deleteForward: onDelete,\n isInline(element) {\n if (element.type === \"html-block\") return false\n },\n isVoid(element) {\n if (element.type === \"html-block\") return true\n },\n isMaster(element) {\n if (element.type === \"html-block\") return true\n },\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"html-block\") {\n return (\n <HtmlBlock element={element} attributes={attributes}>\n {children}\n </HtmlBlock>\n )\n }\n },\n },\n })\n }\n) as TypedPlugin<HtmlBlockPluginCustomTypes>\n","import styled from \"@emotion/styled\"\n\nexport const $HtmlBlock = styled(\"div\")`\n position: relative;\n background-color: var(--shade-100);\n border: 1px solid var(--shade-300);\n border-radius: 0.5em;\n padding: 2em 1em 1em 1em;\n margin: 1em 0;\n font-family: \"andale mono\", AndaleMono, monospace;\n font-size: 0.875em;\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--shade-700);\n overflow-x: auto;\n\n &.--selected {\n outline: 2px solid var(--select-color);\n }\n`\n\nexport const $HtmlBlockLabel = styled(\"span\")`\n position: absolute;\n top: 0.25em;\n right: 0.5em;\n font-size: 0.625em;\n color: var(--shade-500);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n`\n","import { RenderElementProps } from \"slate-react\"\nimport { HtmlBlockElement } from \"./types\"\nimport { $HtmlBlock, $HtmlBlockLabel } from \"./styles\"\nimport { unescapeUrlSlashes } from \"../convert/utils\"\n\ntype HtmlBlockRenderElementProps = RenderElementProps & {\n element: HtmlBlockElement\n}\n\nexport function HtmlBlock({\n attributes,\n children,\n element,\n}: HtmlBlockRenderElementProps) {\n return (\n <$HtmlBlock {...attributes} contentEditable={false}>\n <$HtmlBlockLabel>HTML</$HtmlBlockLabel>\n <div>{unescapeUrlSlashes(element.html)}</div>\n {children}\n </$HtmlBlock>\n )\n}\n","import { Descendant, Editor } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n curryOne,\n TypedPlugin,\n} from \"../sink\"\n\nimport { normalizeNode } from \"./normalize-node\"\nimport { Paragraph } from \"./render-element/paragraph\"\n\nexport type CollapsibleParagraphEditor = {\n collapsibleParagraph: {\n convertParagraph: () => void\n }\n}\n\nexport type ParagraphElement = {\n type: \"paragraph\"\n __collapsible?: true\n children: Descendant[]\n}\n\nexport type CollapsibleParagraphPluginCustomTypes = {\n Name: \"collapsible-paragraph\"\n Editor: CollapsibleParagraphEditor\n Element: ParagraphElement\n}\n\nexport const CollapsibleParagraphPlugin =\n createPlugin<CollapsibleParagraphPluginCustomTypes>((editor) => {\n const { insertBreak } = editor\n editor.insertBreak = () => {\n const { selection } = editor\n if (selection && selection.anchor.path[0] === selection.focus.path[0]) {\n // Get text from start of block to cursor position\n const blockPath = [selection.anchor.path[0]]\n const blockStart = Editor.start(editor, blockPath)\n const textBeforeCursor = Editor.string(editor, {\n anchor: blockStart,\n focus: selection.anchor,\n })\n\n // Check if cursor is right after a newline (creating empty line / paragraph break)\n if (textBeforeCursor.endsWith('\\n')) {\n // Create a new paragraph\n insertBreak()\n } else {\n // Insert a single line break\n editor.insertText('\\n')\n }\n } else {\n // Otherwise fall back to default behavior\n insertBreak()\n }\n }\n\n editor.convertElement.addConvertElementType(\"paragraph\")\n editor.collapsibleParagraph = {\n convertParagraph: () => {\n editor.convertElement.convertElements<ParagraphElement>(\n () => false,\n {\n type: \"paragraph\",\n },\n false\n )\n },\n }\n if (!editor.normalizeAfterDelete) {\n throw new Error(\n `The collapsible-paragraph-plugin has a dependency on the normalize-after-delete plugin. Please add that plugin before this one.`\n )\n }\n\n return {\n name: \"collapsible-paragraph\",\n editor: {\n normalizeNode: curryOne(normalizeNode, editor),\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n switch (element.type) {\n case \"paragraph\": {\n return (\n <Paragraph element={element} attributes={attributes}>\n {children}\n </Paragraph>\n )\n }\n }\n },\n onKeyDown: createHotkeyHandler({\n \"super+0\": editor.collapsibleParagraph.convertParagraph,\n }),\n },\n }\n }) as TypedPlugin<CollapsibleParagraphPluginCustomTypes>\n","import { Editor, Element, Node, NodeEntry } from \"slate\"\n\nimport { normalizeSiblingParagraphs } from \"./normalize-sibling-paragraphs\"\nimport { normalizeSiblingWalls } from \"./normalize-sibling-walls\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n const [node, path] = entry\n if (!Element.isElement(node)) return false\n if (normalizeSiblingWalls(editor, [node, path])) return true\n if (normalizeSiblingParagraphs(editor, [node, path])) return true\n return false\n}\n","import { Editor, Element, NodeEntry, Transforms } from \"slate\"\n\nimport { normalizeSiblings } from \"../../sink\"\n\nimport { ParagraphElement } from \"..\"\n\nfunction isParagraph(node: Element): node is ParagraphElement {\n return Element.isElement(node) && node.type === \"paragraph\"\n}\n/**\n * If there are two sibling paragraphs next to each other and they are both\n * marked as `__collapsible`, this indicates to us that some kind of wall\n * Element was removed.\n *\n * These two collapsible paragraphs should then be merged into one.\n */\nexport function normalizeSiblingParagraphs(\n editor: Editor,\n entry: NodeEntry<Element>\n): boolean {\n return normalizeSiblings(editor, entry, (a, b) => {\n if (!isParagraph(a[0]) || !isParagraph(b[0])) return false\n if (a[0].__collapsible && b[0].__collapsible) {\n Transforms.removeNodes(editor, { at: a[1] })\n return true\n }\n return false\n })\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\nimport { normalizeSiblings } from \"../../sink\"\n\nfunction isWall(editor: Editor, node: Node) {\n if (!Element.isElement(node)) return false\n return editor.isVoid(node) || editor.isMaster(node)\n}\n/**\n * We want to create collapsible paragraphs in places where we can't easily\n * create them. For example, between two images.\n *\n * Currently, we look for elements that are\n *\n * - `isVoid` like images or\n * - `isMaster` like `table` and `code-block`.\n *\n * If there is nothing between them, we insert a collapsible paragraph.\n */\n\nexport function normalizeSiblingWalls(\n editor: Editor,\n entry: NodeEntry<Element>\n): boolean {\n if (!isWall(editor, entry[0])) return false\n return normalizeSiblings(editor, entry, (a, b) => {\n if (!isWall(editor, a[0]) || !isWall(editor, b[0])) return false\n Transforms.insertNodes(\n editor,\n {\n type: \"paragraph\",\n __collapsible: true,\n children: [{ text: \"\" }],\n },\n { at: b[1] }\n )\n return true\n })\n}\n","import { clsx } from \"clsx\"\nimport { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { ParagraphElement } from \"..\"\nimport { $Paragraph } from \"./styles\"\nimport { getIsEmpty } from \"./utils\"\n\nexport function Paragraph({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ParagraphElement>) {\n const selected = useSelected()\n const isEmpty = getIsEmpty(element)\n return (\n <$Paragraph\n {...attributes}\n className={clsx({\n \"--selected\": selected,\n \"--empty\": isEmpty,\n \"--collapsible\": !!element.__collapsible,\n })}\n >\n {children}\n </$Paragraph>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $Paragraph = styled(\"p\")`\n padding: 0;\n margin: 0;\n &:first-child {\n margin-top: 0;\n }\n\n transition: background-color 200ms, margin-top 200ms, padding-top 200ms,\n margin-bottom 200ms, padding-bottom 200ms, font-size 200ms;\n\n &.--collapsible&.--empty {\n font-size: 0.25em; /* font-size is collapsed to 1/4 of regular em */\n margin: -0.4em 0;\n padding: 0.1em 0; /* this is kind of eye-balling it */\n border-radius: 1em;\n &:hover {\n background: rgba(0, 127, 255, 0.1);\n cursor: pointer;\n }\n }\n &.--collapsible&.--empty&.--selected {\n font-size: 1em;\n padding: 0;\n margin: 0;\n &:hover {\n background: none;\n cursor: default;\n }\n border-radius: 8px;\n }\n`\n","import { Element, Node } from \"slate\"\n\n/**\n * We check for empty by checking for one node that contains a text that is\n * empty. If there is an inline element, this will introduce at a minimum\n * 3 nodes based on the way Slate normalizes to always have text nodes at\n * the end which is why this check works.\n */\nexport function getIsEmpty(element: Element) {\n return (\n element.children.length === 1 &&\n Node.string(element.children[0]).length === 0\n )\n}\n","import { Editor, Element } from \"slate\"\n\n/**\n * This method lets other plugins register specific elements by their `type`\n * being able to be toggled with a paragraph.\n *\n * In order for an Element to be toggle compatible, generally it should be a\n * non-void block Element whose direct descendants are `Text` or inline elements\n * like:\n *\n * - headings\n * - list items\n */\nexport function addConvertElementType(\n editor: Editor,\n type: Element[\"type\"] | Array<Element[\"type\"]>\n): void {\n if (Array.isArray(type)) {\n editor.convertElement.convertElementTypes.push(...type)\n } else {\n editor.convertElement.convertElementTypes.push(type)\n }\n}\n","import { Editor, Element, Node, Path, Point, Range, Transforms } from \"slate\"\n\nimport { rewrapElement, TargetElement } from \"../../sink\"\n\n/**\n * Calculates the character offset of a point within an element.\n * Returns -1 if the point is not within the element.\n */\nfunction getOffsetInElement(\n editor: Editor,\n point: Point,\n elementPath: Path\n): number {\n try {\n const elementStart = Editor.start(editor, elementPath)\n const elementEnd = Editor.end(editor, elementPath)\n\n // Check if point is within element\n if (Point.isBefore(point, elementStart) || Point.isAfter(point, elementEnd)) {\n return -1\n }\n\n // Calculate offset from element start to point\n const range = { anchor: elementStart, focus: point }\n return Editor.string(editor, range).length\n } catch {\n return -1\n }\n}\n\n/**\n * Restores the selection to a specific offset within an element.\n */\nfunction restoreSelectionInElement(\n editor: Editor,\n elementPath: Path,\n offset: number\n): void {\n try {\n const element = Node.get(editor, elementPath)\n if (!Element.isElement(element)) return\n\n const text = Node.string(element)\n const safeOffset = Math.min(offset, text.length)\n\n // Find the exact point at the offset\n const elementStart = Editor.start(editor, elementPath)\n let currentOffset = 0\n let targetPath = elementStart.path\n let targetOffset = 0\n\n // Traverse through text nodes to find the correct position\n for (const [node, path] of Node.texts(element)) {\n const nodeLength = node.text.length\n if (currentOffset + nodeLength >= safeOffset) {\n // path is already relative to element, so just concat with elementPath\n targetPath = [...elementPath, ...path]\n targetOffset = safeOffset - currentOffset\n break\n }\n currentOffset += nodeLength\n }\n\n const point: Point = { path: targetPath, offset: targetOffset }\n Transforms.select(editor, { anchor: point, focus: point })\n } catch {\n // If restoration fails, don't crash\n }\n}\n\n/**\n * A type with generic for `convertElements` (below) to be used with the curry\n * method. TypeScript, unfortunately, cannot automatically curry generics for\n * us so we have to do it manually.\n */\nexport type CurriedConvertElements = <T extends Element = Element>(\n matchForToggle: (element: Element) => boolean,\n targetElement: TargetElement<T>,\n allowToggle: boolean\n) => void\n\n/**\n * Checks if an element contains newline characters in its text content\n */\nfunction elementContainsNewlines(element: Element): boolean {\n const text = Node.string(element)\n return text.includes(\"\\n\")\n}\n\n/**\n * Given a selection range and an element, determines which line indices are selected.\n * Returns an object with startLineIndex and endLineIndex.\n */\nfunction getSelectedLineIndices(\n editor: Editor,\n element: Element,\n elementPath: Path,\n selection: Range\n): { startLineIndex: number; endLineIndex: number } {\n const text = Node.string(element)\n const lines = text.split(\"\\n\")\n\n // Get the start and end points relative to this element\n const elementStart = Editor.start(editor, elementPath)\n const elementEnd = Editor.end(editor, elementPath)\n\n // Clamp selection to element boundaries\n const start = Point.isBefore(selection.anchor, elementStart)\n ? elementStart\n : Point.isAfter(selection.anchor, elementEnd)\n ? elementEnd\n : selection.anchor\n const end = Point.isBefore(selection.focus, elementStart)\n ? elementStart\n : Point.isAfter(selection.focus, elementEnd)\n ? elementEnd\n : selection.focus\n\n // Calculate offsets from element start\n const startOffset = Math.min(\n Editor.string(editor, { anchor: elementStart, focus: start }).length,\n text.length\n )\n const endOffset = Math.min(\n Editor.string(editor, { anchor: elementStart, focus: end }).length,\n text.length\n )\n\n const minOffset = Math.min(startOffset, endOffset)\n const maxOffset = Math.max(startOffset, endOffset)\n\n // Find which lines contain these offsets\n let currentOffset = 0\n let startLineIndex = 0\n let endLineIndex = lines.length - 1\n\n for (let i = 0; i < lines.length; i++) {\n const lineEnd = currentOffset + lines[i].length\n if (currentOffset <= minOffset && minOffset <= lineEnd) {\n startLineIndex = i\n }\n if (currentOffset <= maxOffset && maxOffset <= lineEnd) {\n endLineIndex = i\n break\n }\n currentOffset = lineEnd + 1 // +1 for newline\n }\n\n return { startLineIndex, endLineIndex }\n}\n\n/**\n * Splits an element at cursor/selection line boundaries.\n * Only splits out the lines that are selected, keeping other lines in original element.\n * Returns the path of the selected line(s) block.\n */\nfunction splitElementAtSelectedLines(\n editor: Editor,\n element: Element,\n path: Path,\n selection: Range\n): Path {\n const text = Node.string(element)\n if (!text.includes(\"\\n\")) {\n return path\n }\n\n const lines = text.split(\"\\n\")\n if (lines.length <= 1) {\n return path\n }\n\n const { startLineIndex, endLineIndex } = getSelectedLineIndices(\n editor,\n element,\n path,\n selection\n )\n\n // Lines before selection, selected lines, and lines after selection\n const beforeLines = lines.slice(0, startLineIndex)\n const selectedLines = lines.slice(startLineIndex, endLineIndex + 1)\n const afterLines = lines.slice(endLineIndex + 1)\n\n // If all lines are selected, no need to split\n if (beforeLines.length === 0 && afterLines.length === 0) {\n return path\n }\n\n Editor.withoutNormalizing(editor, () => {\n const basePath = path.slice(0, -1)\n const baseIndex = path[path.length - 1]\n\n // Insert after lines as new element (if any) - do this first as it goes after\n if (afterLines.length > 0) {\n const afterText = afterLines.join(\"\\n\")\n const afterElement: Element = {\n ...element,\n children: [{ text: afterText }],\n } as Element\n Transforms.insertNodes(editor, afterElement, {\n at: [...basePath, baseIndex + 1],\n })\n }\n\n // Update original element to contain only before lines + selected lines\n const childrenCount = element.children.length\n for (let j = childrenCount - 1; j >= 0; j--) {\n Transforms.removeNodes(editor, { at: [...path, j] })\n }\n\n if (beforeLines.length > 0) {\n // Original element keeps before lines\n Transforms.insertNodes(\n editor,\n { text: beforeLines.join(\"\\n\") },\n { at: [...path, 0] }\n )\n\n // Insert selected lines as new element after before lines\n const selectedText = selectedLines.join(\"\\n\")\n const selectedElement: Element = {\n type: \"paragraph\",\n children: [{ text: selectedText }],\n }\n Transforms.insertNodes(editor, selectedElement, {\n at: [...basePath, baseIndex + 1],\n })\n } else {\n // No before lines, original element becomes selected lines\n Transforms.insertNodes(\n editor,\n { text: selectedLines.join(\"\\n\") },\n { at: [...path, 0] }\n )\n }\n })\n\n // Return the path of the selected lines block\n if (beforeLines.length > 0) {\n return [...path.slice(0, -1), path[path.length - 1] + 1]\n }\n return path\n}\n\n/**\n * The `convertElements` takes a Block Element that has been identified as being\n * convertible and converts it into another type of Element.\n *\n * For example:\n *\n * - headings\n * - list items\n *\n * It also allows for toggling. In this scenario, if all the convertible\n * elements are already in the target state (e.g. we are converting to a heading\n * 2 and all the convertible elemtns are already a heading 2) then the elements\n * will convert back to a `paragraph` element.\n *\n * NOTE:\n *\n * Why is there an unusual signature?\n *\n * This method has a somewhat unusual and not-DRY signature which is in the form\n * of having a `matchForToggle` (which allows us to specify when an Element is\n * already matching the `targetElement`) and also an `allowToggle`; however, we\n * could make `matchForToggle` optional and only `allowToggle` if it is\n * specified.\n *\n * That being said, the signature is set up this way to reduce friction when\n * creating a specific convert function like `convertHeading`. In this scenario,\n * we can have the created `convertHeading` pass through the argument to\n * `allowToggle` and pass it through to this `convertElements` function making\n * that code easier to understand.\n */\nexport function convertElements<T extends Element = Element>(\n editor: Editor,\n matchForToggle: (element: Element) => boolean,\n targetElement: TargetElement<T>,\n allowToggle: boolean\n): boolean {\n const { selection } = editor\n if (!selection) return false\n\n /**\n * Save the cursor position (anchor offset) within the first convertible element\n * so we can restore it after conversion\n */\n let savedAnchorOffset = -1\n let savedFocusOffset = -1\n const isCollapsed = Range.isCollapsed(selection)\n\n /**\n * Find convertible elements\n */\n const entries = Array.from(\n Editor.nodes<Element>(editor, {\n match: (node) =>\n Element.isElement(node) &&\n editor.convertElement.isConvertibleElement(node),\n })\n )\n\n /**\n * Save cursor offset relative to the first entry before any transformations\n */\n if (entries.length > 0) {\n const [, firstPath] = entries[0]\n savedAnchorOffset = getOffsetInElement(editor, selection.anchor, firstPath)\n savedFocusOffset = getOffsetInElement(editor, selection.focus, firstPath)\n }\n /**\n * If there aren't any convertible elements, there's nothing to do\n */\n if (entries.length === 0) return false\n\n /**\n * Split elements that contain newlines at selected line boundaries\n * Process in reverse order to maintain path validity\n */\n const allPaths: Path[] = []\n Editor.withoutNormalizing(editor, () => {\n for (let i = entries.length - 1; i >= 0; i--) {\n const [element, path] = entries[i]\n if (elementContainsNewlines(element)) {\n const splitPath = splitElementAtSelectedLines(\n editor,\n element,\n path,\n selection\n )\n allPaths.unshift(splitPath)\n } else {\n allPaths.unshift(path)\n }\n }\n })\n\n /**\n * Re-fetch all elements at the updated paths\n */\n const updatedEntries: [Element, Path][] = allPaths\n .map((path) => {\n try {\n const node = Node.get(editor, path)\n if (Element.isElement(node)) {\n return [node, path] as [Element, Path]\n }\n return null\n } catch {\n return null\n }\n })\n .filter((entry): entry is [Element, Path] => entry !== null)\n\n if (updatedEntries.length === 0) return false\n\n /**\n * If `allowToggle` is `true` and all of the convertible elements match the\n * `matchForToggle` (for example, if converting to a heading level 2, if all\n * the matching convertible elements are heading level 2) then we want to\n * toggle back to a paragraph.\n */\n const shouldToggle =\n allowToggle && updatedEntries.every((entry) => matchForToggle(entry[0]))\n\n if (shouldToggle) {\n /**\n * If all of the entries are already the target type, then revert them to\n * a paragraph\n */\n Editor.withoutNormalizing(editor, () => {\n for (const entry of updatedEntries) {\n rewrapElement(editor, { type: \"paragraph\" }, entry[1])\n }\n })\n } else {\n /**\n * If any of the entries aren't the target type, then convert them to the\n * target type.\n */\n Editor.withoutNormalizing(editor, () => {\n for (const entry of updatedEntries) {\n rewrapElement(editor, targetElement, entry[1])\n }\n })\n }\n\n /**\n * Restore cursor position after conversion.\n * Use the first updated entry's path to restore the cursor at the saved offset.\n */\n if (updatedEntries.length > 0 && savedAnchorOffset >= 0) {\n const [, firstPath] = updatedEntries[0]\n if (isCollapsed) {\n // For collapsed selection (cursor), just restore anchor position\n restoreSelectionInElement(editor, firstPath, savedAnchorOffset)\n } else if (savedFocusOffset >= 0) {\n // For expanded selection, restore both anchor and focus\n try {\n const element = Node.get(editor, firstPath)\n if (Element.isElement(element)) {\n const text = Node.string(element)\n const safeAnchorOffset = Math.min(savedAnchorOffset, text.length)\n const safeFocusOffset = Math.min(savedFocusOffset, text.length)\n\n const elementStart = Editor.start(editor, firstPath)\n\n // Calculate anchor point\n let anchorPath = elementStart.path\n let anchorOffset = safeAnchorOffset\n let currentOffset = 0\n for (const [node, path] of Node.texts(element)) {\n const nodeLength = node.text.length\n if (currentOffset + nodeLength >= safeAnchorOffset) {\n // path is already relative to element, so just concat with firstPath\n anchorPath = [...firstPath, ...path]\n anchorOffset = safeAnchorOffset - currentOffset\n break\n }\n currentOffset += nodeLength\n }\n\n // Calculate focus point\n let focusPath = elementStart.path\n let focusOffset = safeFocusOffset\n currentOffset = 0\n for (const [node, path] of Node.texts(element)) {\n const nodeLength = node.text.length\n if (currentOffset + nodeLength >= safeFocusOffset) {\n // path is already relative to element, so just concat with firstPath\n focusPath = [...firstPath, ...path]\n focusOffset = safeFocusOffset - currentOffset\n break\n }\n currentOffset += nodeLength\n }\n\n Transforms.select(editor, {\n anchor: { path: anchorPath, offset: anchorOffset },\n focus: { path: focusPath, offset: focusOffset },\n })\n }\n } catch {\n // Fall back to collapsed selection at anchor\n restoreSelectionInElement(editor, firstPath, savedAnchorOffset)\n }\n }\n }\n\n return true\n}\n","import { Editor, Element } from \"slate\"\n\n/**\n * Returns true if the passed in `element` object is an element type that has\n * previously been registered as a convertible element using the\n * `editor.convertElement.addConvertElementType` method.\n */\nexport function isConvertElement(editor: Editor, element: Element): boolean {\n return editor.convertElement.convertElementTypes.includes(element.type)\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport { addConvertElementType } from \"./add-convert-element-type\"\nimport { convertElements, CurriedConvertElements } from \"./convert-elements\"\nimport { isConvertElement } from \"./is-convert-element\"\n\nexport function createConvertElementMethods(editor: Editor) {\n return {\n convertElementTypes: [] as string[],\n addConvertElementType: curryOne(addConvertElementType, editor),\n isConvertibleElement: curryOne(isConvertElement, editor),\n convertElements: curryOne(\n convertElements,\n editor\n ) as CurriedConvertElements,\n }\n}\n","import { createPlugin, TypedPlugin } from \"../sink\"\n\nimport { createConvertElementMethods } from \"./methods\"\n\nexport type ConvertElementEditor = {\n convertElement: ReturnType<typeof createConvertElementMethods>\n}\n\nexport type ConvertElementPluginCustomTypes = {\n Name: \"convert-element\"\n Editor: ConvertElementEditor\n}\n\nexport const ConvertElementPlugin =\n createPlugin<ConvertElementPluginCustomTypes>((editor) => {\n editor.convertElement = createConvertElementMethods(editor)\n return {\n name: \"convert-element\",\n }\n }) as TypedPlugin<ConvertElementPluginCustomTypes>\n","import { Editor, Path, Range, Transforms } from \"slate\"\n\nimport { findElementUp } from \"../sink\"\nimport { HeadingElement } from \"./types\"\n\nexport function insertBreak(editor: Editor) {\n const entry = findElementUp<HeadingElement>(editor, \"heading\")\n if (!entry) return false\n if (!editor.selection) return false\n if (Range.isExpanded(editor.selection)) return false\n if (!Editor.isEnd(editor, editor.selection.anchor, entry[1])) return false\n const nextPath = Path.next(entry[1])\n Transforms.insertNodes(\n editor,\n { type: \"paragraph\", children: [{ text: \"\" }] },\n { at: nextPath }\n )\n Transforms.select(editor, {\n anchor: Editor.start(editor, nextPath),\n focus: Editor.start(editor, nextPath),\n })\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport { HeadingElement } from \"../types\"\n\nfunction convertHeading(\n editor: Editor,\n level: 1 | 2 | 3 | 4 | 5 | 6,\n allowToggle: boolean\n) {\n editor.convertElement.convertElements<HeadingElement>(\n (element) => element.type === \"heading\" && element.level == level,\n { type: \"heading\", level },\n allowToggle\n )\n}\n\nfunction isHeadingActive(editor: Editor, level: 1 | 2 | 3 | 4 | 5 | 6) {\n const [match] = Editor.nodes(editor, {\n match: n => {\n return (\n 'type' in n &&\n 'level' in n &&\n n.type === 'heading' &&\n n.level === level\n )\n },\n })\n return !!match\n}\n\nexport function createHeadingMethods(editor: Editor) {\n return {\n convertHeading: curryOne(convertHeading, editor),\n isHeadingActive: curryOne(isHeadingActive, editor),\n }\n}\n","import { css } from \"@emotion/react\"\nimport styled from \"@emotion/styled\"\n\nconst headingStyles = css`\n margin-top: 1em;\n &:first-child {\n margin-top: 0;\n }\n font-weight: bold;\n`\n\nexport const $H1 = styled(\"h1\")`\n ${headingStyles}\n font-size: 2.25em;\n letter-spacing: -0.01em;\n`\n\nexport const $H2 = styled(\"h2\")`\n ${headingStyles}\n font-size: 1.5em;\n`\n\nexport const $H3 = styled(\"h3\")`\n ${headingStyles}\n font-size: 1.25em;\n`\n\nexport const $H4 = styled(\"h4\")`\n ${headingStyles}\n font-size: 1em;\n`\n\nexport const $H5 = styled(\"h5\")`\n ${headingStyles}\n font-size: 1em;\n`\n\nexport const $H6 = styled(\"h6\")`\n ${headingStyles}\n font-size: 1em;\n`\n","export * from \"./types\"\n\nimport {\n createAutocompleteSpaceHandler,\n createHotkeyHandler,\n createPlugin,\n curryOne,\n curryTwo,\n TypedPlugin,\n} from \"../sink\"\n\nimport { insertBreak } from \"./insert-break\"\nimport { createHeadingMethods } from \"./methods\"\nimport { $H1, $H2, $H3, $H4, $H5, $H6 } from \"./styles\"\nimport { HeadingPluginCustomTypes } from \"./types\"\n\nexport const HeadingPlugin = createPlugin<HeadingPluginCustomTypes>(\n (editor) => {\n editor.convertElement.addConvertElementType(\"heading\")\n editor.heading = createHeadingMethods(editor)\n const hotkeyHandler = createHotkeyHandler({\n \"super+1\": curryTwo(editor.heading.convertHeading, 1, true),\n \"super+2\": curryTwo(editor.heading.convertHeading, 2, true),\n \"super+3\": curryTwo(editor.heading.convertHeading, 3, true),\n \"super+4\": curryTwo(editor.heading.convertHeading, 4, true),\n \"super+5\": curryTwo(editor.heading.convertHeading, 5, true),\n \"super+6\": curryTwo(editor.heading.convertHeading, 6, true),\n })\n const autocompleteHandler = createAutocompleteSpaceHandler(editor, {\n \"#\": curryTwo(editor.heading.convertHeading, 1, false),\n \"##\": curryTwo(editor.heading.convertHeading, 2, false),\n \"###\": curryTwo(editor.heading.convertHeading, 3, false),\n \"####\": curryTwo(editor.heading.convertHeading, 4, false),\n \"#####\": curryTwo(editor.heading.convertHeading, 5, false),\n \"######\": curryTwo(editor.heading.convertHeading, 6, false),\n })\n return {\n name: \"heading\",\n editor: {\n insertBreak: curryOne(insertBreak, editor),\n },\n editableProps: {\n renderElement: ({ element, attributes, children }) => {\n if (element.type === \"heading\") {\n switch (element.level) {\n case 1:\n return <$H1 {...attributes}>{children}</$H1>\n case 2:\n return <$H2 {...attributes}>{children}</$H2>\n case 3:\n return <$H3 {...attributes}>{children}</$H3>\n case 4:\n return <$H4 {...attributes}>{children}</$H4>\n case 5:\n return <$H5 {...attributes}>{children}</$H5>\n case 6:\n return <$H6 {...attributes}>{children}</$H6>\n default: {\n const exhaustiveCheck: never = element.level\n throw new Error(\n `Expected element.level to be 1-6 but got ${exhaustiveCheck as number}`\n )\n }\n }\n }\n },\n onKeyDown: (e) => {\n if (hotkeyHandler(e)) return true\n if (autocompleteHandler(e)) return true\n return false\n },\n },\n }\n }\n) as TypedPlugin<HeadingPluginCustomTypes>\n","import { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../sink\"\n\nimport { HorizontalRuleElement } from \".\"\nimport { $HorizontalRule } from \"./styles\"\n\nexport function HorizontalRule({\n attributes,\n children,\n}: ConstrainedRenderElementProps<HorizontalRuleElement>) {\n const selected = useSelected()\n return (\n <div {...attributes} draggable>\n {children}\n <div contentEditable={false}>\n <$HorizontalRule className={selected ? \"--selected\" : \"\"} />\n </div>\n </div>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $HorizontalRule = styled(\"hr\")`\n position: relative;\n height: 1em;\n /* background-color: var(--hr-color); */\n margin: 1em 0;\n &::before {\n position: absolute;\n content: \"\";\n left: 0.125em;\n right: 0.125em;\n top: 50%;\n height: 1px;\n background-color: var(--hr-color);\n border-radius: 1px;\n }\n border-radius: 0.25em;\n cursor: pointer;\n border: none;\n &:hover {\n background-color: rgba(0, 127, 255, 0.1);\n /* &::before {\n outline: 2px solid var(--hover-color);\n } */\n }\n &.--selected {\n background: none;\n &::before {\n outline: 2px solid var(--select-color, blue);\n }\n }\n`\n","import { Editor } from \"slate\"\n\nimport { curryOne, insertRootElement } from \"../../sink\"\n\nfunction insertHorizontalRule(editor: Editor) {\n return insertRootElement(editor, {\n type: \"horizontal-rule\",\n children: [{ text: \"\" }],\n })\n}\n\nexport function createHorizontalRuleMethods(editor: Editor) {\n return {\n insertHorizontalRule: curryOne(insertHorizontalRule, editor),\n }\n}\n","import { createHotkeyHandler, createPlugin, TypedPlugin } from \"../sink\"\n\nimport { HorizontalRule } from \"./horizontal-rule\"\nimport { createHorizontalRuleMethods } from \"./methods\"\nimport { HorizontalRulePluginCustomTypes } from \"./types\"\nexport * from \"./types\"\n\nexport const HorizontalRulePlugin =\n createPlugin<HorizontalRulePluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.horizontalRule = createHorizontalRuleMethods(editor)\n return createPolicy({\n name: \"horizontal-rule\",\n editor: {\n isVoid(element) {\n if (element.type === \"horizontal-rule\") return true\n },\n },\n editableProps: {\n renderElement: (props) => {\n if (props.element.type === \"horizontal-rule\") {\n return <HorizontalRule {...props} />\n }\n },\n onKeyDown: createHotkeyHandler({\n \"super+-\": editor.horizontalRule.insertHorizontalRule,\n }),\n },\n })\n }\n ) as TypedPlugin<HorizontalRulePluginCustomTypes>\n","import styled from \"@emotion/styled\"\n\nexport const $InlineCode = styled(\"code\")`\n color: var(--shade-600);\n background-color: var(--inline-code-bgcolor);\n border: 1px solid var(--inline-code-border-color);\n border-radius: 0.25em;\n padding: 0.1375em 0.125em;\n /**\n * Font Stack from\n * https://qwtel.com/posts/software/the-monospaced-system-ui-css-font-stack/\n */\n font-family: ui-monospace, Menlo, Monaco, \"Cascadia Mono\", \"Segoe UI Mono\",\n \"Roboto Mono\", \"Oxygen Mono\", \"Ubuntu Monospace\", \"Source Code Pro\",\n \"Fira Mono\", \"Droid Sans Mono\", \"Courier New\", monospace;\n /**\n * This font size may seem smaller but any larger (including 0.875) means that\n * it messes up the line height of the normal text. Not sure why this happens\n * with the monospace font but seems to happen on both the default 'monospace'\n * font as well as the font stack above.\n */\n font-size: 0.75em;\n vertical-align: baseline;\n`\n\n/**\n * These invisible spans fix a bug in Chrome which doesn't allow the cursor to\n * sit on both the \"inside\" and \"outside\" of the inline-code span. By placing\n * this 1px wide span just inside of the inline code, we are able to workaround\n * this limitation.\n */\nexport const $InvisibleSpan = styled(\"span\")`\n display: inline-block;\n opacity: 0;\n width: 1px;\n overflow: hidden;\n`\n","import { createHotkeyHandler, createPlugin, TypedPlugin } from \"../sink\"\n\nimport { $InlineCode, $InvisibleSpan } from \"./styles\"\nimport { InlineCodePluginCustomTypes } from \"./types\"\nexport * from \"./styles\"\nexport * from \"./types\"\n\nexport const InlineCodePlugin = createPlugin<InlineCodePluginCustomTypes>(\n (editor) => {\n if (!editor.marksPlugin)\n throw new Error(\n \"InlineCodePlugin has a dependency on the MarksPlugin but the MarksPlugin has not been added or is added after the InlineCodePlugin\"\n )\n editor.inlineCode = {\n toggleInlineCode: () => editor.marksPlugin.toggleMark(\"code\"),\n }\n return {\n name: \"inline-code\",\n editableProps: {\n renderLeaf: ({ leaf, children }) => {\n if (leaf.code) {\n return (\n /**\n * Disable spellCheck because it's computer code usually.\n */\n <$InlineCode spellCheck={false}>\n {/* These invisible spans are necessary. See comments for $InvisibleSpan. */}\n <$InvisibleSpan contentEditable={false}>|</$InvisibleSpan>\n {children}\n {/* These invisible spans are necessary. See comments for $InvisibleSpan. */}\n <$InvisibleSpan contentEditable={false}>|</$InvisibleSpan>\n </$InlineCode>\n )\n } else {\n return children\n }\n },\n onKeyDown: createHotkeyHandler({\n \"mod+j\": () => editor.inlineCode.toggleInlineCode(),\n }),\n },\n }\n }\n) as TypedPlugin<InlineCodePluginCustomTypes>\n","import { Editor, Path } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createIsElementType,\n createPlugin,\n curryOne,\n findElementUp,\n isStartOfElement,\n TypedPlugin,\n} from \"../sink\"\n\nimport { createListMethods } from \"./methods\"\nimport { normalizeNode } from \"./normalize-node\"\nimport { renderElement } from \"./render-element\"\nimport { ListItemElement, ListPluginCustomTypes } from \"./types\"\n\nexport * from \"./types\"\n\nexport const LIST_ITEM_TYPES: ListItemElement[\"type\"][] = [\n \"unordered-list-item\",\n \"ordered-list-item\",\n \"task-list-item\",\n]\n\nexport const isListItem = createIsElementType<ListItemElement>(LIST_ITEM_TYPES)\n\nexport const ListPlugin = createPlugin<ListPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.convertElement.addConvertElementType(LIST_ITEM_TYPES)\n const list = (editor.list = createListMethods(editor))\n const hotkeyHandler = createHotkeyHandler({\n tab: list.indent,\n \"shift+tab\": list.outdent,\n \"super+7\": curryOne(list.convertOrderedList, true),\n \"super+8\": curryOne(list.convertUnorderedList, true),\n \"super+9\": curryOne(list.convertTaskList, true),\n })\n\n return createPolicy({\n name: \"list\",\n editor: {\n normalizeNode: (entry) => normalizeNode(editor, entry),\n insertBreak: list.insertBreak,\n deleteBackward: (unit) => {\n /**\n * This handles the logic where if the cursor is at the start of a\n * list item, and the user presses backspace, then the list item\n * should be converted to a paragraph if there are no list items\n * before it. If there is a list item before it, then the normal\n * delete behavior which would merge the list items together will\n * occur.\n */\n if (unit !== \"character\") return false\n if (!isStartOfElement(editor, isListItem)) return false\n const listItem = findElementUp<ListItemElement>(editor, isListItem)\n if (!listItem) return false\n const listItemPath = listItem[1]\n /**\n * If the current list item is the first element in the document,\n * convert it to a paragraph.\n */\n if (!Path.hasPrevious(listItemPath)) {\n editor.collapsibleParagraph.convertParagraph()\n return true\n }\n const prevElementPath = Path.previous(listItemPath)\n const prevElementEntry = Editor.node(editor, prevElementPath)\n if (isListItem(prevElementEntry[0])) return false\n /**\n * If the previous element is not a list item, then convert the\n * current list item to a paragraph.\n */\n editor.collapsibleParagraph.convertParagraph()\n return true\n },\n },\n editableProps: {\n renderElement,\n onKeyDown(e) {\n if (!Editor.nodes(editor, { match: isListItem })) return false\n return hotkeyHandler(e)\n },\n },\n })\n }\n) as TypedPlugin<ListPluginCustomTypes>\n","import { Editor } from \"slate\"\n\nimport {\n OrderedListItemElement,\n TaskListItemElement,\n UnorderedListItemElement,\n} from \"..\"\n\nexport function convertOrderedList(editor: Editor, allowToggle: boolean) {\n return editor.convertElement.convertElements<OrderedListItemElement>(\n (element) => element.type === \"ordered-list-item\",\n (element) => {\n return {\n type: \"ordered-list-item\",\n depth: \"depth\" in element ? element.depth : 0,\n }\n },\n allowToggle\n )\n}\n\nexport function convertTaskList(editor: Editor, allowToggle: boolean) {\n return editor.convertElement.convertElements<TaskListItemElement>(\n (element) => element.type === \"task-list-item\",\n (element) => {\n return {\n type: \"task-list-item\",\n checked: \"checked\" in element ? element.checked : false,\n depth: \"depth\" in element ? element.depth : 0,\n }\n },\n allowToggle\n )\n}\n\nexport function convertUnorderedList(editor: Editor, allowToggle: boolean) {\n return editor.convertElement.convertElements<UnorderedListItemElement>(\n (element) => element.type === \"unordered-list-item\",\n (element) => {\n return {\n type: \"unordered-list-item\",\n depth: \"depth\" in element ? element.depth : 0,\n }\n },\n allowToggle\n )\n}\n","import { Editor } from \"slate\"\nimport { findElementUp, isStartOfElement } from \"../../sink\"\nimport { isListItem } from \"..\"\nimport { ListItemElement } from \"../types\"\n\nconst MAX_DEPTH = 2\n\nexport function getListDepth(editor: Editor): number {\n const listItem = findElementUp<ListItemElement>(editor, isListItem)\n if (!listItem) return 0\n return listItem[0].depth\n}\n\nexport function canIncreaseDepth(editor: Editor): boolean {\n if (!isStartOfElement(editor, isListItem)) return false\n const depth = getListDepth(editor)\n return depth < MAX_DEPTH\n}\n\nexport function canDecreaseDepth(editor: Editor): boolean {\n if (!isStartOfElement(editor, isListItem)) return false\n const depth = getListDepth(editor)\n return depth > 0\n}\n\nexport function increaseDepth(editor: Editor): void {\n if (!canIncreaseDepth(editor)) return\n editor.list.indent()\n}\n\nexport function decreaseDepth(editor: Editor): void {\n if (!canDecreaseDepth(editor)) return\n editor.list.outdent()\n}\n","import { Editor } from \"slate\"\n\nimport { setNodesDynamic } from \"../../sink\"\n\nimport { isListItem, ListItemElement } from \"..\"\n\nexport function indent(editor: Editor) {\n return setNodesDynamic<ListItemElement>(\n editor,\n (node) => ({ depth: node.depth + 1 }),\n {\n match: isListItem,\n }\n )\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { findElementUp, rewrapElement } from \"../../sink\"\n\nimport { isListItem } from \"..\"\nimport { ListItemElement } from \"../types\"\n\nexport function insertBreak(editor: Editor): boolean {\n const entry = findElementUp<ListItemElement>(editor, isListItem)\n if (!entry) return false\n const [element, path] = entry\n\n /**\n * If we're in an empty list\n */\n if (Editor.isEmpty(editor, element)) {\n if (element.depth > 0) {\n /**\n * If it's indented, then unindent it\n */\n Transforms.setNodes(editor, { depth: element.depth - 1 }, { at: path })\n return true\n } else {\n /**\n * If it's fully unindented, turn it into a paragraph\n */\n rewrapElement(editor, { type: \"paragraph\" }, path)\n return true\n }\n }\n /**\n * Otherwise perform default insertBreak transform\n */\n Transforms.splitNodes(editor, { always: true })\n /**\n * Then find the list item we are now in\n */\n const nextEntry = findElementUp<ListItemElement>(editor, isListItem)\n if (!nextEntry) return true\n /**\n * And if it's a checked task list that is checked, we want to uncheck it.\n * New list items are by default always unchecked.\n */\n if (nextEntry[0].type === \"task-list-item\" && nextEntry[0].checked === true) {\n Transforms.setNodes(editor, { checked: false }, { at: nextEntry[1] })\n }\n return true\n}\n","import { Editor } from \"slate\"\n\nimport { setNodesDynamic } from \"../../sink\"\n\nimport { isListItem, ListItemElement } from \"..\"\n\nexport function outdent(editor: Editor): boolean {\n const entries = Array.from(\n Editor.nodes<ListItemElement>(editor, {\n match: isListItem,\n })\n )\n /**\n * Don't allow `shift+tab` if any of the list items are already at a\n * depth of `0`\n */\n for (const entry of entries) {\n if (entry[0].depth === 0) return true\n }\n return setNodesDynamic<ListItemElement>(\n editor,\n (node) => ({ depth: Math.max(0, node.depth - 1) }),\n {\n match: isListItem,\n }\n )\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt, findElementUp } from \"../../sink\"\n\nimport { TaskListItemElement } from \"../types\"\n\nexport function toggleTaskListItem(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const taskListItem = findElementUp<TaskListItemElement>(\n editor,\n \"task-list-item\",\n { at }\n )\n if (!taskListItem) return false\n const nextChecked = !taskListItem[0].checked\n Transforms.setNodes<TaskListItemElement>(\n editor,\n { checked: nextChecked },\n { at: taskListItem[1] }\n )\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport {\n convertOrderedList,\n convertTaskList,\n convertUnorderedList,\n} from \"./convert-list-item\"\nimport {\n getListDepth,\n canIncreaseDepth,\n canDecreaseDepth,\n increaseDepth,\n decreaseDepth,\n} from \"./depth\"\nimport { indent } from \"./indent\"\nimport { insertBreak } from \"./insert-break\"\nimport { outdent } from \"./outdent\"\nimport { toggleTaskListItem } from \"./toggleTaskListItem\"\n\nexport function createListMethods(editor: Editor) {\n return {\n indent: curryOne(indent, editor),\n outdent: curryOne(outdent, editor),\n convertUnorderedList: curryOne(convertUnorderedList, editor),\n convertOrderedList: curryOne(convertOrderedList, editor),\n convertTaskList: curryOne(convertTaskList, editor),\n insertBreak: curryOne(insertBreak, editor),\n toggleTaskListItem: curryOne(toggleTaskListItem, editor),\n getListDepth: curryOne(getListDepth, editor),\n canIncreaseDepth: curryOne(canIncreaseDepth, editor),\n canDecreaseDepth: curryOne(canDecreaseDepth, editor),\n increaseDepth: curryOne(increaseDepth, editor),\n decreaseDepth: curryOne(decreaseDepth, editor),\n }\n}\n","import { Editor, Element, Node, NodeEntry, Transforms } from \"slate\"\n\nimport { createIsElementType, normalizeSiblings } from \"../../sink\"\n\nimport { isListItem, OrderedListItemElement } from \"..\"\n\nconst isOrderedListItem = createIsElementType<OrderedListItemElement>([\n \"ordered-list-item\",\n])\n\n/**\n * Makes sure that when a list item is deeper than a preceding one, that we\n * reset the counter.\n *\n * How it works:\n *\n * If we have any two list item siblings where the second sibling is an\n * `ordered-list-item`, then the second sibling should have the property\n * `_firstOfType` be `true` if the depth of the second sibling is higher or\n * the previous sibling is not an ordered list item (e.g. a paragraph or a\n * bullet)\n *\n * Why we need it:\n *\n * We need to do this manually because our implementation of lists does not\n * actually nest lists within lists. We took the approach because the cost\n * of actually nesting lists is very high in terms of added complexity. It is\n * much easier to manually reset the counters than it is to implement\n * everything to W3C specifications, especially given that from a UI\n * perspective, users expect lists to behave similar to paragraphs and\n * headings.\n */\n\nexport function normalizeOrderedFirstAtDepth(\n editor: Editor,\n entry: NodeEntry<Node>\n): boolean {\n const [node, path] = entry\n if (!Element.isElement(node)) return false\n return normalizeSiblings<Element>(editor, [node, path], (a, b) => {\n /**\n * If the second item (the item we are actually looking at) is not an\n * ordered list item, then we aren't interested.\n */\n if (!isOrderedListItem(b[0])) return false\n /**\n * The second item is an ordered-list-item. If the item before it is not\n * or the second item is deeper than the first, then we want to set\n * `__firstAtDepth` to `true`.\n */\n // For non-list items, treat them as depth 0\n const __firstAtDepth = isOrderedListItem(a[0]) ? b[0].depth > a[0].depth : isListItem(a[0]) ? b[0].depth > a[0].depth : true\n /**\n * Check if the setting is already correct.\n */\n if (b[0].__firstAtDepth !== __firstAtDepth) {\n Transforms.setNodes(editor, { __firstAtDepth }, { at: b[1] })\n return true\n }\n return false\n })\n}\n","import { Editor, Node, NodeEntry } from \"slate\"\n\nimport { isListItem } from \"..\"\nimport { normalizeOrderedFirstAtDepth } from \"./normalize-ordered-first-at-depth\"\nexport * from \"./normalize-ordered-first-at-depth\"\n\nexport function normalizeNode(editor: Editor, entry: NodeEntry<Node>): boolean {\n const [node] = entry\n /**\n * Short circuit return if current entry isn't any type of list item element.\n */\n if (!isListItem(node)) return false\n return normalizeOrderedFirstAtDepth(editor, entry)\n}\n","import { clsx } from \"clsx\"\nimport { useEffect } from \"react\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { normalizeOrderedFirstAtDepth } from \"../normalize-node\"\nimport { OrderedListItemElement as OrderedListItemElement } from \"../types\"\nimport { $OrderedListItem } from \"./styles\"\n\nexport function OrderedListItem({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<OrderedListItemElement>) {\n const editor = useSlateStatic()\n useEffect(() => {\n const path = ReactEditor.findPath(editor, element)\n normalizeOrderedFirstAtDepth(editor, [element, path])\n }, [])\n const style = {\n marginLeft: `${2 + element.depth * 2}em`,\n \"--list-item-var\": `list-item-depth-${element.depth}`,\n } as React.CSSProperties\n const className = clsx({ \"--first-at-depth\": element.__firstAtDepth })\n return (\n <$OrderedListItem {...attributes} className={className} style={style}>\n {children}\n </$OrderedListItem>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { isDebug } from \"../../sink\"\n\nconst $ListItem = styled(\"li\")`\n margin-top: 0.5em;\n margin-bottom: 0.5em;\n list-style-position: outside;\n`\n\nexport const $UnorderedListItem = styled($ListItem)`\n position: relative;\n list-style-type: none;\n .--list-item-icon {\n position: absolute;\n top: 0.25em;\n left: -1.375em;\n line-height: 1.5em;\n color: var(--shade-600);\n }\n`\n\nexport const $OrderedListItem = styled($ListItem)`\n position: relative;\n list-style-type: none;\n counter-increment: var(--list-item-var);\n\n &.--first-at-depth {\n counter-reset: var(--list-item-var);\n /**\n * if isDebug is true, then show a highlight on list items that are marked\n * as the first at a given depth.\n */\n background: ${isDebug ? \"rgba(0, 255, 0, 0.2)\" : \"inherit\"};\n }\n\n &:before {\n position: absolute;\n content: counter(var(--list-item-var)) \".\";\n top: 0;\n left: -2em;\n width: 1.5em;\n text-align: right;\n color: var(--shade-500);\n /* force numbers to be monospaced for better alignment */\n font-variant-numeric: tabular-nums;\n }\n`\n\nexport const $TaskListItem = styled($ListItem)`\n position: relative;\n list-style-type: none;\n .--list-item-icon {\n position: absolute;\n top: 0.25em;\n left: -1.5em;\n line-height: 1.5em;\n color: var(--shade-300);\n .--checkmark {\n color: green;\n stroke-width: 3px;\n }\n }\n`\n","import { useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { TaskListItemElement } from \"../types\"\nimport { CheckedIcon, UncheckedIcon } from \"./list-icons\"\nimport { $TaskListItem } from \"./styles\"\n\nexport function TaskListItem({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<TaskListItemElement>) {\n const editor = useSlateStatic()\n const toggle = useCallback(() => {\n editor.list.toggleTaskListItem({ at: element })\n }, [editor, element])\n\n const marginLeft = `${2 + element.depth * 2}em`\n return (\n <$TaskListItem {...attributes} style={{ marginLeft }}>\n <div className=\"--list-item-icon\" contentEditable={false}>\n {element.checked ? (\n <CheckedIcon onClick={toggle} style={{ cursor: \"pointer\" }} />\n ) : (\n <UncheckedIcon onClick={toggle} style={{ cursor: \"pointer\" }} />\n )}\n </div>\n {children}\n </$TaskListItem>\n )\n}\n","import * as React from \"react\"\nimport { SVGProps } from \"react\"\n\n/**\n * https://tabler-icons.io/\n */\nexport const UncheckedIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n strokeWidth={2}\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 24 24\"\n {...props}\n >\n <path d=\"M0 0h24v24H0z\" stroke=\"none\" />\n <rect x={4} y={4} width={16} height={16} rx={2} />\n </svg>\n)\n\n/**\n * https://tabler-icons.io/\n */\nexport const CheckedIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"icon icon-tabler icon-tabler-checkbox\"\n width=\"1em\"\n height=\"1em\"\n strokeWidth={2}\n stroke=\"currentColor\"\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 24 24\"\n {...props}\n >\n <path d=\"M0 0h24v24H0z\" stroke=\"none\" />\n <path d=\"m9 11 3 3 8-8\" className=\"--checkmark\" />\n <path d=\"M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h9\" />\n </svg>\n)\n\n/**\n * Modified viewfinder-circle from https://heroicons.com/\n */\nexport const BulletIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n {...props}\n >\n <path d=\"M12 8.25a3.75 3.75 0 1 0 0 7.5 3.75 3.75 0 0 0 0-7.5z\" />\n </svg>\n)\n","import { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { UnorderedListItemElement } from \"../types\"\nimport { BulletIcon } from \"./list-icons\"\nimport { $UnorderedListItem } from \"./styles\"\n\nexport function UnorderedListItem({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<UnorderedListItemElement>) {\n const marginLeft = `${2 + element.depth * 2}em`\n return (\n <$UnorderedListItem {...attributes} style={{ marginLeft }}>\n <div className=\"--list-item-icon\" contentEditable={false}>\n <BulletIcon />\n </div>\n {children}\n </$UnorderedListItem>\n )\n}\n","import { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { ListItemElement } from \"../types\"\nimport { OrderedListItem } from \"./ordered-list-item\"\nimport { TaskListItem } from \"./task-list-item\"\nimport { UnorderedListItem } from \"./unordered-list-item\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<ListItemElement>) {\n switch (element.type) {\n case \"ordered-list-item\":\n return (\n <OrderedListItem element={element} attributes={attributes}>\n {children}\n </OrderedListItem>\n )\n case \"unordered-list-item\":\n return (\n <UnorderedListItem element={element} attributes={attributes}>\n {children}\n </UnorderedListItem>\n )\n case \"task-list-item\":\n return (\n <TaskListItem element={element} attributes={attributes}>\n {children}\n </TaskListItem>\n )\n }\n}\n","import { clsx } from \"clsx\"\nimport { Editor, Point, Range } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n TypedPlugin,\n} from \"../sink\"\n\nimport { createMarksMethods } from \"./methods\"\nimport { $MarksSpan } from \"./styles\"\n\nexport type MarksEditor = {\n /**\n * IMPORTANT:\n *\n * This cannot be named `marks` because it conflicts with the `editor.marks`\n * built into the BaseEditor.j\n */\n marksPlugin: ReturnType<typeof createMarksMethods>\n activeMarks?: {\n bold?: boolean\n italic?: boolean\n underline?: boolean\n strike?: boolean\n highlight?: boolean\n }\n}\n\nexport type MarksText = {\n text: string\n bold?: true\n italic?: true\n underline?: true\n strike?: true\n highlight?: true\n}\n\nexport type MarksPluginCustomTypes = {\n Name: \"marks\"\n Editor: MarksEditor\n Text: MarksText\n}\n\nexport const MarksPlugin = createPlugin<MarksPluginCustomTypes>((editor) => {\n editor.marksPlugin = createMarksMethods(editor)\n editor.activeMarks = {}\n const hotkeyHandler = createHotkeyHandler({\n \"mod+b\": editor.marksPlugin.toggleBold,\n \"mod+i\": editor.marksPlugin.toggleItalic,\n \"mod+u\": editor.marksPlugin.toggleUnderline,\n \"super+0\": editor.marksPlugin.removeMarks,\n \"super+k\": editor.marksPlugin.toggleStrike,\n \"mod+h\": editor.marksPlugin.toggleHighlight,\n })\n // Override insertText to apply active marks\n const { insertText: defaultInsertText } = editor\n editor.insertText = (text) => {\n if (editor.activeMarks && Object.keys(editor.activeMarks).length > 0) {\n const { activeMarks } = editor\n // Apply marks before inserting text\n Object.entries(activeMarks).forEach(([mark, isActive]) => {\n if (isActive) {\n editor.addMark(mark, true)\n }\n })\n }\n defaultInsertText(text)\n }\n\n // Override removeMarks to clear activeMarks at line end\n const { removeMarks } = editor.marksPlugin\n editor.marksPlugin.removeMarks = () => {\n removeMarks()\n if (editor.selection) {\n const point = Range.isRange(editor.selection) ? editor.selection.focus : editor.selection\n if (Point.isPoint(point)) {\n const isAtLineEnd = Editor.after(editor, point) === null ||\n Editor.isEnd(editor, point, Editor.end(editor, []))\n if (isAtLineEnd) {\n editor.activeMarks = {}\n }\n }\n }\n }\n\n return {\n name: \"marks\",\n editableProps: {\n renderLeaf: ({ leaf, children }) => {\n return (\n <$MarksSpan\n className={clsx({\n \"--bold\": leaf.bold,\n \"--italic\": leaf.italic,\n \"--underline\": leaf.underline,\n \"--strike\": leaf.strike,\n \"--highlight\": leaf.highlight,\n })}\n >\n {children}\n </$MarksSpan>\n )\n },\n onKeyDown: (e) => {\n if (hotkeyHandler(e)) return true\n // if (\n // autocompleteMarker(editor, e, {\n // triggerMarker: \"`\",\n // regexp: /([`])(\\S.*?)([`])$/,\n // mark: \"code\",\n // })\n // ) {\n // return true\n // }\n // if (\n // autocompleteMarker(editor, e, {\n // triggerMarker: \"*\",\n // regexp: /([*])(.+?)([*])$/,\n // mark: \"italic\",\n // })\n // ) {\n // return true\n // }\n return false\n },\n },\n }\n}) as TypedPlugin<MarksPluginCustomTypes>\n\n// function autocompleteMarker(\n// editor: Editor,\n// e: React.KeyboardEvent<HTMLDivElement>,\n// {\n// triggerMarker,\n// regexp,\n// mark,\n// }: { triggerMarker: string; regexp: RegExp; mark: keyof Text }\n// ): boolean {\n// /**\n// * Make sure theere is a selection and it's collapsed\n// */\n// console.log(\n// { triggerMarker, mark },\n// e.key,\n// e.which,\n// toKeyCode(\"*\"),\n// toKeyName(\"*\"),\n// isHotkey(\"*\", { byKey: true })(e.nativeEvent)\n// )\n// if (editor.selection === null) return false\n// if (Range.isExpanded(editor.selection)) return false\n// /**\n// * WHAT I'M WORKING ON:\n// *\n// * So, basically, `is-hotkey` doesn't work with an asterisk. We need to find\n// * an alternate way of testing but it's a little tricky and there are a few\n// * approaches we can take:\n// *\n// * - The first approach is to write our own key checker, but be careful\n// * because we want to make sure we aren't interception hotkeys with modifier\n// * keys for example. Like CMD+OPTION+8 should not trigger the `*` trigger.\n// *\n// * - NOTE: tested and paste does not trigger insertText. The second approach\n// * is to tie into `insertText` instead. This may be a more reliable method\n// * but we also need to at least think about whether insertText gets\n// * triggered during a paste event, for example, and if it does, that would\n// * be weird to have that suddenly bold some text.\n// *\n// */\n// // if (isHotkey(triggerMarker, e.nativeEvent)) {\n// if (isHotkey(triggerMarker, e.nativeEvent)) {\n// console.log(\"triggered\")\n// stopEvent(e)\n// const markerText = triggerMarker\n// Transforms.insertText(editor, markerText)\n// const { selection } = editor\n\n// /**\n// * Make sure we are in a block that is not void.\n// */\n// const blockEntry = findElementUp(\n// editor,\n// (node) =>\n// Element.isElement(node) &&\n// !Editor.isVoid(editor, node) &&\n// Editor.isBlock(editor, node)\n// )\n// if (blockEntry == null) return true\n\n// /**\n// * Grab all the text from the beginning of the block until now\n// */\n// const range = {\n// anchor: Editor.start(editor, blockEntry[1]),\n// focus: selection.focus,\n// }\n// const text = Editor.string(editor, range)\n\n// /**\n// * See if the text matches our pattern\n// */\n// const match = text.match(regexp)\n// if (match == null) return true\n// if (match.length !== 4)\n// throw new Error(\n// `Expected the RegExp to have 3 grouped subexpressions but returned ${\n// match.length - 1\n// }`\n// )\n\n// /**\n// * Delete the closing markers\n// */\n// const closingMarkersRange = getRangeBackwards(\n// editor,\n// editor.selection.focus,\n// match[3].length\n// )\n// Transforms.delete(editor, { at: closingMarkersRange })\n\n// /**\n// * Delete the opening markers\n// */\n// const openingMarkersRange = getRangeBackwards(\n// editor,\n// editor.selection.focus,\n// match[2].length + match[3].length,\n// match[2].length\n// )\n// Transforms.delete(editor, { at: openingMarkersRange })\n\n// /**\n// * Create a range that represents the selected text\n// */\n// const matchRange = getRangeBackwards(\n// editor,\n// editor.selection.focus,\n// match[2].length\n// )\n\n// /**\n// * Feels like `withoutMerging` should work but if we undo twice after this,\n// * causes a crash.\n// *\n// * This looks like a good solution that isn't in main\n// * https://github.com/ianstormtaylor/slate/issues/3874\n// *\n// * NOTE:\n// *\n// * Manually calling `editor.onChange()` won't work\n// *\n// * An appropriate starting point for searching more in issues\n// * https://github.com/ianstormtaylor/slate/issues?q=is%3Aissue+withoutMerging+is%3Aclosed\n// */\n// editor.marksPlugin.toggleMark(mark, undefined, { at: matchRange })\n\n// return true\n// }\n// return false\n// }\n\n// function getRangeBackwards(\n// editor: Editor,\n// point: Point,\n// startDistance: number,\n// endDistance?: number\n// ) {\n// const startPoint = Editor.before(editor, point, {\n// unit: \"character\",\n// distance: startDistance,\n// })\n// const endPoint =\n// endDistance === undefined\n// ? point\n// : Editor.before(editor, point, {\n// unit: \"character\",\n// distance: endDistance,\n// })\n// if (!startPoint)\n// throw new Error(\n// `startPoint not found. The distance backward from the point may be invalid.`\n// )\n// if (!endPoint)\n// throw new Error(\n// `endPoint not found. The distance backward from the point may be invalid.`\n// )\n// return {\n// anchor: startPoint,\n// focus: endPoint,\n// }\n// }\n","import { Editor, Location, Text, Transforms } from \"slate\"\n\n/**\n * Toggles a mark.\n *\n * Certain marks may not be able to co-exist with another mark. For example,\n * superscript and subscript cannot be applied at the same time. In these\n * cases, you can provide a final argument of `unsetKey` that when the mark\n * is toggled on, the `unsetKey` mark is toggled off automatically. When the\n * mark is toggled off, it will ignore the `unsetKey`\n */\n\nexport function removeMarks(\n editor: Editor,\n { at = editor.selection }: { at?: Location | null } = {}\n) {\n if (at == null) return\n const nodeEntries = [\n ...Editor.nodes(editor, {\n match: (n) => Text.isText(n),\n at,\n }),\n ]\n const setter: Record<string, null> = {}\n for (const [node] of nodeEntries) {\n for (const key of Object.keys(node)) {\n if (key === \"text\") continue\n setter[key] = null\n }\n }\n Transforms.setNodes(editor, setter, {\n match: (n) => Text.isText(n),\n split: true,\n at,\n })\n}\n","import { Editor, Location, Point, Range, Text } from \"slate\"\n\n/**\n * Toggles a mark.\n *\n * Certain marks may not be able to co-exist with another mark. For example,\n * superscript and subscript cannot be applied at the same time. In these\n * cases, you can provide a final argument of `unsetKey` that when the mark\n * is toggled on, the `unsetKey` mark is toggled off automatically. When the\n * mark is toggled off, it will ignore the `unsetKey`\n */\n\nexport function toggleMark(\n editor: Editor,\n markKey: keyof Text,\n unsetKey?: keyof Text,\n { at = editor.selection }: { at?: Location | null } = {}\n) {\n if (at == null) return\n\n // Check if selection is at end of line\n const point = Range.isRange(at) ? at.focus : at\n const isAtLineEnd = Point.isPoint(point) && (\n Editor.after(editor, point) === null || \n Editor.isEnd(editor, point, Editor.end(editor, []))\n )\n\n const validMarkKey = markKey as 'bold' | 'italic' | 'underline' | 'strike'\n const marks = Editor.marks(editor) || {}\n const isActive = marks[validMarkKey] === true\n\n // Store mark state for next insert if at line end\n if (isAtLineEnd) {\n if (!isActive) {\n // Turning mark on\n editor.activeMarks = {\n ...editor.activeMarks,\n [validMarkKey]: true\n }\n } else {\n // Turning mark off\n const { [validMarkKey]: _unused, ...remainingMarks } = editor.activeMarks || {}\n void _unused\n editor.activeMarks = remainingMarks\n }\n }\n\n // Toggle mark in current selection\n if (isActive) {\n Editor.removeMark(editor, validMarkKey)\n } else {\n Editor.addMark(editor, validMarkKey, true)\n }\n\n // Handle unset key if provided\n if (typeof unsetKey === \"string\") {\n Editor.removeMark(editor, unsetKey)\n }\n}\n","import { Editor } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport { removeMarks } from \"./removeMarks\"\nimport { toggleMark } from \"./toggle-mark\"\n\nexport function createMarksMethods(editor: Editor) {\n return {\n removeMarks: curryOne(removeMarks, editor),\n toggleMark: curryOne(toggleMark, editor),\n toggleBold: () => toggleMark(editor, \"bold\"),\n toggleItalic: () => toggleMark(editor, \"italic\"),\n toggleUnderline: () => toggleMark(editor, \"underline\"),\n toggleStrike: () => toggleMark(editor, \"strike\"),\n toggleHighlight: () => toggleMark(editor, \"highlight\"),\n }\n}\n","import styled from \"@emotion/styled\"\n\nexport const $MarksSpan = styled(\"span\")`\n &.--bold {\n font-weight: bold;\n }\n &.--italic {\n font-style: italic;\n }\n &.--underline {\n text-decoration: underline;\n }\n &.--strike {\n text-decoration: line-through;\n }\n /**\n * Text decorations don't merge automatically so we make a special one\n * when there is both an underline and a strike through.\n */\n &.--underline.--strike {\n text-decoration: underline line-through;\n }\n &.--highlight {\n background-color: #ffff00;\n }\n`\n","import { Editor, Point } from \"slate\"\n\nimport { createPlugin, forceNormalizePath, TypedPlugin } from \"../sink\"\n\nexport type NormalizeAfterDeleteEditor = {\n normalizeAfterDelete: true\n}\n\nexport type NormalizeAfterDeletePluginCustomTypes = {\n Name: \"normalize-after-delete\"\n Editor: NormalizeAfterDeleteEditor\n}\n\nfunction forceNormalizeNearestElement(editor: Editor) {\n if (!editor.selection) return\n const entry = Editor.parent(editor, editor.selection)\n forceNormalizePath(editor, entry[1])\n}\n\n/**\n * The purpose of this plugin is to have the Slate normalizer execute when an\n * Element is deleted. When text is deleted, the normalizer executes properly\n * but if an entire element is deleted, Slate behaves as if no normalization\n * is required.\n *\n * This fails us in a few normalization scenarios:\n *\n * - The normalizer needs to run when a sibling (previous or next) changes.\n * - The normalizer needs to run when a child is removed\n *\n * The plugin takes a few steps to make things more efficient. Namely, it only\n * executes a normalization if we are deleting backwards and we are at the\n * start of an element, or deleting forwards and we are at the end of an\n * Element. If neither of these are true, the delete will cause a normalzation\n * on its own because the text will have changed.\n */\nexport const NormalizeAfterDeletePlugin =\n createPlugin<NormalizeAfterDeletePluginCustomTypes>((editor) => {\n editor.normalizeAfterDelete = true\n return {\n name: \"normalize-after-delete\",\n editor: {\n deleteBackward() {\n if (!editor.selection) return false\n const entry = Editor.parent(editor, editor.selection)\n const isStart = Point.equals(\n Editor.start(editor, entry[1]),\n editor.selection.anchor\n )\n if (!isStart) return false\n return function () {\n forceNormalizeNearestElement(editor)\n }\n },\n deleteForward() {\n if (!editor.selection) return false\n const entry = Editor.parent(editor, editor.selection)\n const isEnd = Point.equals(\n Editor.end(editor, entry[1]),\n editor.selection.anchor\n )\n if (!isEnd) return false\n return function () {\n forceNormalizeNearestElement(editor)\n }\n },\n },\n editableProps: {},\n }\n }) as TypedPlugin<NormalizeAfterDeletePluginCustomTypes>\n","import { Element, NodeEntry } from \"slate\"\n\nimport {\n createHotkeyHandler,\n createPlugin,\n findElementUp,\n isEndOfElement,\n isStartOfElement,\n TypedPlugin,\n} from \"../sink\"\n\nimport { deleteFragmentWithProtectedTypes } from \"./delete-fragment\"\nimport { createTableMethods } from \"./methods\"\nimport { normalizeTableIndexes } from \"./normalize/normalize-table\"\nimport { normalizeTableCell } from \"./normalize/normalize-table-cell\"\nimport { renderElement } from \"./render-element\"\nimport {\n TableCellElement,\n TableContentElement,\n TableElement,\n TableRowElement,\n} from \"./types\"\n\nexport * from \"./types\"\n\nexport type TableEditor = {\n supportsTable: true\n tablePlugin: ReturnType<typeof createTableMethods>\n}\n\nexport type TablePluginCustomTypes = {\n Name: \"table\"\n Editor: TableEditor\n Element:\n | TableElement\n | TableRowElement\n | TableCellElement\n | TableContentElement\n}\n\nexport const TablePlugin = createPlugin<TablePluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.supportsTable = true\n editor.tablePlugin = createTableMethods(editor)\n return createPolicy({\n name: \"table\",\n editor: {\n deleteBackward: () => {\n /**\n * If we're at start of a cell, disable delete backward because we\n * don't want the cell to be deleted.\n */\n return isStartOfElement(editor, \"table-cell\")\n },\n deleteForward: () => {\n /**\n * If we're at end of a cell, disable delete forward because we don't\n * want the cell to be deleted.\n */\n return isEndOfElement(editor, \"table-cell\")\n },\n deleteFragment: () =>\n deleteFragmentWithProtectedTypes(editor, [\"table-cell\"]),\n insertBreak: () => {\n /**\n * IF we're anywhere in a table cell, insert a soft break instead\n */\n const entry = findElementUp(editor, \"table-cell\")\n if (entry) {\n editor.insertText(\"\\n\")\n return true\n }\n return false\n },\n isMaster(element) {\n if (element.type === \"table\") return true\n },\n normalizeNode: (entry): boolean => {\n const [node] = entry\n if (!Element.isElement(node)) return false\n switch (node.type) {\n case \"table\":\n return normalizeTableIndexes(\n editor,\n entry as NodeEntry<TableElement>\n )\n case \"table-cell\": {\n return normalizeTableCell(\n editor,\n entry as NodeEntry<TableCellElement>\n )\n }\n }\n return false\n },\n },\n editableProps: {\n renderElement,\n onKeyDown: createHotkeyHandler({\n /**\n * navigation\n */\n tab: editor.tablePlugin.tabForward,\n \"shift+tab\": editor.tablePlugin.tabBackward,\n \"shift+enter\": editor.tablePlugin.shiftEnterForward,\n down: editor.tablePlugin.down,\n up: editor.tablePlugin.up,\n /**\n * selection\n */\n \"mod+a\": editor.tablePlugin.selectCell,\n /**\n * insert\n */\n \"super+t\": () => editor.tablePlugin.insertTable(3, 2),\n \"mod+shift+enter\": () => editor.tablePlugin.insertRow({ offset: 0 }),\n \"mod+enter\": () => editor.tablePlugin.insertRow({ offset: 1 }),\n \"super+[\": () => editor.tablePlugin.insertColumn({ offset: 0 }),\n \"super+]\": () => editor.tablePlugin.insertColumn({ offset: 1 }),\n /**\n * remove\n */\n \"super+backspace\": editor.tablePlugin.removeTable,\n \"mod+backspace\": editor.tablePlugin.removeRow,\n \"mod+shift+backspace\": editor.tablePlugin.removeColumn,\n }),\n },\n })\n }\n) as TypedPlugin<TablePluginCustomTypes>\n","import { Editor, Path, Transforms } from \"slate\"\n\nimport { findElementUpPath } from \"../../sink\"\n\nimport { getReversedDeleteSafeRanges } from \"./get-reversed-delete-safe-ranges\"\n\n/**\n * This is a special version of deleteFragment that respects elements of the\n * given `protectedTypes` so that they aren't deleted whole and only their\n * children are deleted.\n *\n * This is used in cases like a `table-cell` where we want to protect the\n * shape of the `table`.\n *\n * If the start or end of the deletion range isn't in a protectedType, we don't\n * need to anything special so we let the default delete handle it.\n *\n * If the start or end of the deletion range is in a protectedType but it is\n * the same Element, then the default handler works fine too.\n *\n * In other cases, we break down the full deletion range into multiple ranges.\n * Each range won't go across a protectedType. In effect, this means that we\n * only delete the content of protectedTypes and we do the regular deletes\n * across everything else.\n */\nexport function deleteFragmentWithProtectedTypes(\n editor: Editor,\n protectedTypes: string[]\n) {\n if (editor.selection == null) return false\n const [start, end] = Editor.edges(editor, editor.selection)\n const startProtectedPath = findElementUpPath(editor, protectedTypes, {\n at: start,\n })\n const endProtectedPath = findElementUpPath(editor, protectedTypes, {\n at: end,\n })\n /**\n * If the start or the end of the selection isn't in a protectedType element\n * then just do a normal delete so we return `false`.\n */\n if (!startProtectedPath && !endProtectedPath) {\n return false\n }\n\n /**\n * If the start and end are in the same protectedType element, then the\n * default handler works fine so return `false`\n */\n if (\n startProtectedPath &&\n endProtectedPath &&\n Path.equals(startProtectedPath, endProtectedPath)\n ) {\n return false\n }\n\n /**\n * Breaks the range to delete into chunks of ranges that are safe to delete.\n * We do this by not allowing a deletion across one of the `protectedTypes`\n */\n const reversedRanges = getReversedDeleteSafeRanges(\n editor,\n editor.selection,\n protectedTypes\n )\n\n /**\n * We iterate through the ranges backwards deleting each delete safe range.\n * At the end, we collapse the originally selected deletion range to the\n * front.\n *\n * NOTE:\n *\n * Ideally, we'd actually collapse this to the start or end depending on the\n * direction of the delete; however, that information is not presently\n * provided to us. Might be a small improvement in the future that requires\n * us to update Slate.\n */\n Editor.withoutNormalizing(editor, () => {\n for (const range of reversedRanges) {\n Transforms.delete(editor, { at: range })\n }\n Transforms.collapse(editor, { edge: \"start\" })\n })\n\n return true\n}\n","import { BasePoint, Editor, Path, Range } from \"slate\"\n\nimport { findElementUpPath } from \"../../sink\"\n\nexport function getReversedDeleteSafeRanges(\n editor: Editor,\n deleteRange: Range,\n protectedTypes: string[]\n): Range[] {\n /**\n * Editor.positions returns a bunch of positions which essentially represent\n * the start and end of Nodes with the exception of the start of the passed\n * in Range and the end of the passed in Range.\n */\n const positions = [...Editor.positions(editor, { at: deleteRange })]\n\n /**\n * We create our own set of deleteSafeRanges here\n */\n const deleteSafeRanges: Range[] = []\n\n let startPos: BasePoint, prevPos: BasePoint, startTdPath: Path | undefined\n startPos = prevPos = positions[0]\n startTdPath = findElementUpPath(editor, protectedTypes, {\n at: startPos,\n })\n\n for (const pos of positions) {\n const tdPath = findElementUpPath(editor, protectedTypes, {\n at: pos,\n })\n /**\n * What we're looking for is that if we search for a protectedType from\n * this point, and the protectedType is the same as the prvious point we\n * looked at, then keep going.\n *\n * We keep track of the `prevPos` though because when we are in a different\n * protectedType (or switch to not being in one) then we need the `prevPos`\n */\n if (\n (startTdPath && tdPath && Path.equals(startTdPath, tdPath)) ||\n (startTdPath == undefined && tdPath == undefined)\n ) {\n prevPos = pos\n } else {\n /**\n * Once we see a difference (i.e. a new protectedType or we switch to\n * being or not being in a protectedType) then we create a Range and\n * add it to `deleteSafeRanges`.\n *\n * We also reset some of our variables that we are tracking.\n */\n const range = { anchor: startPos, focus: prevPos }\n deleteSafeRanges.push(range)\n startPos = prevPos = pos\n startTdPath = tdPath\n }\n }\n const range = { anchor: startPos, focus: prevPos }\n deleteSafeRanges.push(range)\n deleteSafeRanges.reverse()\n return deleteSafeRanges\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt, curryOne } from \"../../sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { insertColumn } from \"./insert-column\"\nimport { insertRow } from \"./insert-row\"\nimport { insertTable } from \"./insert-table\"\nimport { down, up } from \"./navigation\"\nimport { removeColumn } from \"./remove-column\"\nimport { removeRow } from \"./remove-row\"\nimport { removeTable } from \"./remove-table\"\nimport { setTableColumnAlign } from \"./setTableColumnAlign\"\nimport { shiftEnterForward, tabBackward, tabForward } from \"./tab\"\n\nexport function createTableMethods(editor: Editor) {\n return {\n getTableInfo: curryOne(getTableInfo, editor),\n insertTable: curryOne(insertTable, editor),\n insertColumn: curryOne(insertColumn, editor),\n insertRow: curryOne(insertRow, editor),\n removeTable: curryOne(removeTable, editor),\n removeColumn: curryOne(removeColumn, editor),\n removeRow: curryOne(removeRow, editor),\n tabForward: curryOne(tabForward, editor),\n tabBackward: curryOne(tabBackward, editor),\n shiftEnterForward: curryOne(shiftEnterForward, editor),\n selectCell: curryOne(selectCell, editor),\n down: curryOne(down, editor),\n up: curryOne(up, editor),\n setTableColumnAlign: curryOne(setTableColumnAlign, editor),\n }\n}\n\nfunction selectCell(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const t = getTableInfo(editor, { at })\n if (t === undefined) return false\n const { cellPath } = t\n Transforms.select(editor, cellPath)\n return true\n}\n","import { Editor, Element, Location, Path } from \"slate\"\n\nimport { findElementUp } from \"../../sink\"\n\nimport {\n TableCellElement,\n TableColumn,\n TableElement,\n TableRowElement,\n} from \"../types\"\n\n/**\n * The TableInfo object that includes quick access information starting from a\n * cell in a table including information about the row and the table.\n *\n * NOTE:\n *\n * This is flat and not nested because it makes destructuring easier, for\n * example, in the table methods.\n */\nexport type TableInfo = {\n tableElement: TableElement\n tablePath: Path\n tableColumns: TableColumn[]\n rowElement: TableRowElement\n rowPath: Path\n rowIndex: number\n rowCount: number\n cellElement: TableCellElement\n cellPath: Path\n cellIndex: number\n cellCount: number\n}\n\n/**\n * get table info\n */\n\nexport function getTableInfo(\n editor: Editor,\n { at = editor.selection }: { at?: Location | Element | null } = {}\n): TableInfo | undefined {\n if (at == null) return undefined\n const cellMatch = findElementUp<TableCellElement>(editor, \"table-cell\", {\n at,\n })\n if (!cellMatch) return undefined\n const rowMatch = findElementUp<TableRowElement>(editor, \"table-row\", {\n at,\n })\n if (!rowMatch) return undefined\n const tableMatch = findElementUp<TableElement>(editor, \"table\", { at })\n if (!tableMatch) return undefined\n const [tableElement, tablePath] = tableMatch\n const [rowElement, rowPath] = rowMatch\n const [cellElement, cellPath] = cellMatch\n return {\n tableElement,\n tablePath,\n tableColumns: tableElement.columns,\n rowElement,\n rowPath,\n rowIndex: rowPath.slice(-1)[0],\n rowCount: tableElement.children.length,\n cellElement,\n cellPath,\n cellIndex: cellPath.slice(-1)[0],\n cellCount: rowElement.children.length,\n }\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"../../sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { createCell } from \"./utils\"\n\nexport function insertColumn(\n editor: Editor,\n { offset = 0, at = editor.selection }: { offset?: 0 | 1; at?: BetterAt } = {}\n): boolean {\n const t = getTableInfo(editor, { at })\n if (t === undefined) return false\n const { tableElement, tablePath, cellIndex } = t\n const nextCellIndex = cellIndex + offset\n Editor.withoutNormalizing(editor, () => {\n const { columns } = tableElement\n const nextColumns = [...columns]\n /**\n * Insert a Column into `TableElement.columns` which is the same as the\n * value of the current column. This is the `alignment` of the column.\n */\n nextColumns.splice(nextCellIndex, 0, columns[nextCellIndex])\n Transforms.setNodes(editor, { columns: nextColumns }, { at: tablePath })\n\n /**\n * Insert a `TableCell` at the correct spot.\n */\n tableElement.children.forEach((rowElement, i) => {\n Transforms.insertNodes(editor, createCell(nextCellIndex), {\n at: [...tablePath, i, nextCellIndex],\n })\n })\n })\n return true\n}\n\n// export function insertColumnLeft(\n// editor: Editor,\n// { at }: { at?: MatchAt } = {}\n// ) {\n// return insertColumn(editor, { at })\n// }\n\n// export function insertColumnRight(\n// editor: Editor,\n// { at }: { at?: MatchAt } = {}\n// ) {\n// return insertColumn(editor, { at, offset: 1 })\n// }\n","import { TableCellElement, TableContentElement } from \"../types\"\n\nexport function createCell(\n index: number,\n children: TableContentElement[] = [\n {\n type: \"table-content\",\n children: [{ text: \"\" }],\n },\n ]\n): TableCellElement {\n return {\n type: \"table-cell\",\n children,\n }\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"../../sink\"\n\nimport { TableRowElement } from \"../types\"\nimport { getTableInfo } from \"./get-table-info\"\nimport { createCell } from \"./utils\"\n\nfunction createRow(columnCount: number): TableRowElement {\n return {\n type: \"table-row\",\n children: [...Array(columnCount).keys()].map((index) => createCell(index)),\n }\n}\n\n/**\n * Used internally for `insertRowAbove` and `insertRowBelow` to do an insert\n * with an offset to improve code reused.\n */\nexport function insertRow(\n editor: Editor,\n { at = editor.selection, offset = 0 }: { at?: BetterAt; offset?: 0 | 1 } = {}\n): boolean {\n const t = getTableInfo(editor, { at })\n if (!t) return false\n const nextRowElement = createRow(t.tableElement.columns.length)\n Transforms.insertNodes(editor, nextRowElement, {\n at: [...t.tablePath, t.rowIndex + offset],\n })\n return true\n}\n\n/**\n * Insert row above current selection\n */\nexport function insertRowAbove(\n editor: Editor,\n { at }: { at?: BetterAt } = {}\n): boolean {\n return insertRow(editor, { at })\n}\n\n/**\n * Insert row below current selection\n */\nexport function insertRowBelow(\n editor: Editor,\n { at }: { at?: BetterAt } = {}\n): boolean {\n return insertRow(editor, { at, offset: 1 })\n}\n","import { Editor, Element, Location, Path, Transforms } from \"slate\"\n\nimport { findElementUp } from \"../../sink\"\n\nimport { TableColumn, TableElement, TableRowElement } from \"../types\"\nimport { createCell } from \"./utils\"\n\nfunction createRange(size: number): number[] {\n return [...Array(size).keys()]\n}\n\nfunction createColumns(columnCount: number): TableColumn[] {\n return createRange(columnCount).map(() => ({ align: \"left\" }))\n}\n\nfunction createTable(columnCount: number, rowCount: number): TableElement {\n return {\n type: \"table\",\n columns: createColumns(columnCount),\n children: createRange(rowCount).map(() => createRow(columnCount)),\n }\n}\n\nfunction createRow(columnCount: number): TableRowElement {\n return {\n type: \"table-row\",\n children: [...Array(columnCount).keys()].map((index) => createCell(index)),\n }\n}\n\n/**\n * Used internally for `insertRowAbove` and `insertRowBelow` to do an insert\n * with an offset to improve code reused.\n */\nexport function insertTable(\n editor: Editor,\n columnCount: number,\n rowCount: number,\n { at = editor.selection }: { at?: Location | null } = {}\n): boolean {\n const table = createTable(columnCount, rowCount)\n return insertRootElement(editor, table, { at })\n}\n\nexport function insertRootElement(\n editor: Editor,\n element: Element,\n { at = editor.selection }: { at?: Location | null } = {}\n) {\n if (at == null) return false\n const entry = findElementUp(\n editor,\n (node) => Element.isElement(node) && editor.isMaster(node)\n )\n if (entry == null) {\n const selection = editor.selection\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at })\n if (selection) {\n Transforms.select(editor, selection)\n Transforms.move(editor)\n }\n })\n } else {\n const nextPath = Path.next(entry[1])\n Editor.withoutNormalizing(editor, () => {\n Transforms.insertNodes(editor, element, { at: nextPath })\n Transforms.select(editor, Editor.start(editor, nextPath))\n })\n }\n return true\n}\n","import { Editor, Path } from \"slate\"\n\nimport { selectEndOfElement, selectStartOfElement } from \"../../../sink\"\n\nimport { TableInfo } from \"../get-table-info\"\n\nexport function selectElementBelow(editor: Editor, t: TableInfo) {\n const { cellIndex, rowIndex, rowCount, tablePath } = t\n /**\n * if we aren't in the last row of a table, move down a row\n */\n if (rowIndex < rowCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, cellIndex])\n return true\n }\n /**\n * If we are in the last row of a table, move to the start of the Element\n * after the table\n */\n try {\n selectStartOfElement(editor, Path.next(tablePath))\n return true\n } catch {\n return false\n }\n}\n\nexport function selectElementAbove(editor: Editor, t: TableInfo) {\n const { cellIndex, rowIndex, tablePath } = t\n /**\n * if we aren't in the first row of a table, move up a row\n */\n if (rowIndex > 0) {\n selectStartOfElement(editor, [...tablePath, rowIndex - 1, cellIndex])\n return true\n }\n /**\n * If we are in the first row of a table, move to the end of the Element\n * before the table\n */\n try {\n selectEndOfElement(editor, Path.previous(tablePath))\n return true\n } catch {\n return false\n }\n}\n","import { Descendant, Editor, Element } from \"slate\"\nimport { ReactEditor } from \"slate-react\"\n\n/**\n * This is named with `...Unreliable...` because at the beginning of a line\n * (e.g. the second line of a paragraph) the DOMRect returned will be for a\n * position at the end of the previous line.\n *\n * So why have an unreliable version? Because, there actually is no reliable\n * version and the unreliable one works in most cases. It's better than not\n * having an unreliable selection rect.\n *\n * So it's useful, but we need to handle the case where it's on the end of the\n * previous line instead of the beginning of the line.\n *\n * NOTE:\n *\n * Inserting a `span` and removing it does not work. We can kind of getting it\n * to work by inserting a span with some with (like has the letter \"A\") inside.\n * It will then sometimes switch the problem so that the DOMRect return is on\n * the next line instead of the previous; however, makes the cursor move into\n * the wrong position when cursoring down the right side and this is worse than\n * the problem is solves.\n */\nexport function getUnreliableSelectionRect(): DOMRect | null {\n const s = window.getSelection()\n if (!s) return null\n const range = s.getRangeAt(0)\n return range.getBoundingClientRect()\n}\n\n/**\n * Takes a Slate Element and returns a DOMRect representing the Element as\n * it is in the DOM.\n */\nfunction getElementRect(editor: Editor, element: Descendant) {\n return ReactEditor.toDOMNode(editor, element).getBoundingClientRect()\n}\n\nexport function checkIsInElement(editor: Editor, element: Element): boolean {\n /**\n * Get the unreliable selection rect. If there is no selection, we consider\n * that the selection is not in the last line which will usually indicates\n * default behavior.\n */\n const selectionRect = getUnreliableSelectionRect()\n if (!selectionRect) return false\n const elementRect = getElementRect(editor, element)\n return (\n selectionRect.right < elementRect.right &&\n selectionRect.left > elementRect.left &&\n selectionRect.bottom < elementRect.bottom &&\n selectionRect.top > elementRect.top\n )\n}\n","import { Editor } from \"slate\"\n\nimport { getTableInfo } from \"../get-table-info\"\nimport { selectElementAbove, selectElementBelow } from \"./select-element\"\nimport { checkIsInElement } from \"./utils\"\n\n/**\n * arrow down\n */\nexport function down(editor: Editor): boolean {\n const t = getTableInfo(editor)\n /**\n * don't handle if we're not in a table\n */\n if (!t) return false\n setTimeout(() => {\n if (!checkIsInElement(editor, t.cellElement)) {\n selectElementBelow(editor, t)\n }\n })\n return false\n}\n\n/**\n * arrow up\n */\nexport function up(editor: Editor): boolean {\n const t = getTableInfo(editor)\n /**\n * don't handle if we're not in a table\n */\n if (!t) return false\n setTimeout(() => {\n if (!checkIsInElement(editor, t.cellElement)) {\n selectElementAbove(editor, t)\n }\n })\n return false\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"../../sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { removeTable } from \"./remove-table\"\n\nexport function removeColumn(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const t = getTableInfo(editor, { at })\n if (!t) return false\n\n const { tableElement, tablePath, rowIndex, cellIndex, cellCount } = t\n if (cellCount === 1) {\n return removeTable(editor)\n }\n Editor.withoutNormalizing(editor, () => {\n // Set the new `align` value based on the current `td` column (not the position\n // to insert at)\n const columns = [...tableElement.columns]\n columns.splice(cellIndex, 1)\n Transforms.setNodes(editor, { columns }, { at: tablePath })\n tableElement.children.forEach((rowElement, rowIndex) => {\n Transforms.removeNodes(editor, {\n at: [...tablePath, rowIndex, cellIndex],\n })\n })\n const selection = Editor.start(editor, [\n ...tablePath,\n rowIndex,\n Math.min(cellIndex, cellCount - 2),\n ])\n Transforms.select(editor, selection)\n })\n}\n","import { Editor, Transforms } from \"slate\"\n\nexport function removeTable(editor: Editor): boolean {\n const t = editor.tablePlugin.getTableInfo()\n if (t === undefined) return false\n Transforms.removeNodes(editor, { at: t.tablePath })\n return true\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { BetterAt } from \"../../sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { removeTable } from \"./remove-table\"\n\nexport function removeRow(\n editor: Editor,\n { at = editor.selection }: { at?: BetterAt } = {}\n) {\n const t = getTableInfo(editor, { at })\n if (t === undefined) return false\n if (t.rowCount === 1) {\n removeTable(editor)\n return true\n }\n Editor.withoutNormalizing(editor, () => {\n Transforms.removeNodes(editor, { at: t.rowPath })\n Transforms.select(\n editor,\n Editor.start(editor, [\n ...t.tablePath,\n Math.min(t.rowIndex, t.rowCount - 2),\n t.cellIndex,\n ])\n )\n })\n return true\n}\n","import { Editor, Transforms } from \"slate\"\n\nimport { getTableInfo } from \"./get-table-info\"\n\nexport function setTableColumnAlign(\n editor: Editor,\n options: { align: \"left\" | \"center\" | \"right\" }\n) {\n const t = getTableInfo(editor)\n if (t === undefined) return false\n const { tableElement, tablePath, cellIndex } = t\n const nextColumns = tableElement.columns.slice()\n nextColumns.splice(cellIndex, 1, { align: options.align })\n Transforms.setNodes(editor, { columns: nextColumns }, { at: tablePath })\n return true\n}\n","import { Editor, Path, Transforms } from \"slate\"\n\nimport { selectStartOfElement } from \"../../sink\"\n\nimport { getTableInfo } from \"./get-table-info\"\nimport { insertRowBelow } from \"./insert-row\"\n\nexport function tabForward(editor: Editor) {\n const t = getTableInfo(editor)\n if (!t) return false\n\n const { cellIndex, cellCount, rowIndex, rowCount, tablePath } = t\n\n /**\n * If we aren't in the last cell of the row, then select the next cell\n */\n if (cellIndex < cellCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex, cellIndex + 1])\n return true\n }\n\n /**\n * If we are in the last cell of the row but we aren't in the last row of\n * the table, then select the first cell in the next row.\n */\n if (rowIndex < rowCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, 0])\n return true\n }\n\n /**\n * If we are in the last cell of the table, exit the table\n * by inserting a new paragraph after the table and selecting it.\n */\n const nextPath = Path.next(tablePath)\n Transforms.insertNodes(\n editor,\n { type: \"paragraph\", children: [{ text: \"\" }] },\n { at: nextPath }\n )\n selectStartOfElement(editor, nextPath)\n\n return true\n}\n\nexport function tabBackward(editor: Editor) {\n const t = getTableInfo(editor)\n if (!t) return false\n\n const { cellIndex, cellCount, rowIndex, tablePath } = t\n\n if (cellIndex > 0) {\n selectStartOfElement(editor, [...tablePath, rowIndex, cellIndex - 1])\n return true\n }\n\n if (rowIndex > 0) {\n selectStartOfElement(editor, [...tablePath, rowIndex - 1, cellCount - 1])\n return true\n }\n}\n\n/**\n * Shift+Enter: Move to next cell, or add new row at end of table\n */\nexport function shiftEnterForward(editor: Editor) {\n const t = getTableInfo(editor)\n if (!t) return false\n\n const { cellIndex, cellCount, rowIndex, rowCount, tablePath } = t\n\n /**\n * If we aren't in the last cell of the row, then select the next cell\n */\n if (cellIndex < cellCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex, cellIndex + 1])\n return true\n }\n\n /**\n * If we are in the last cell of the row but we aren't in the last row of\n * the table, then select the first cell in the next row.\n */\n if (rowIndex < rowCount - 1) {\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, 0])\n return true\n }\n\n /**\n * If we are in the last cell of the table, insert a new row and then\n * select the first cell in the new row.\n */\n insertRowBelow(editor)\n selectStartOfElement(editor, [...tablePath, rowIndex + 1, 0])\n\n return true\n}\n","import { Editor, NodeEntry, Transforms } from \"slate\"\n\nimport { TableElement } from \"../types\"\n\nexport function normalizeTableIndexes(\n editor: Editor,\n entry: NodeEntry<TableElement>\n): boolean {\n let isTransformed = false\n const rowElements = entry[0].children\n rowElements.forEach((rowElement, y) => {\n const cellElements = rowElement.children\n cellElements.forEach((cellElement, x) => {\n if (cellElement.x !== x || cellElement.y !== y) {\n Transforms.setNodes(editor, { x, y }, { at: [...entry[1], y, x] })\n isTransformed = true\n }\n })\n })\n return isTransformed\n}\n","import { Editor, NodeEntry, Transforms } from \"slate\"\n\nimport { TableCellElement } from \"../types\"\n\nexport function normalizeTableCell(\n editor: Editor,\n entry: NodeEntry<TableCellElement>\n): boolean {\n const [node, path] = entry\n if (node.children.length === 1 && node.children[0].type === \"table-content\") {\n return false\n }\n Editor.withoutNormalizing(editor, () => {\n /**\n * This ensures that the first child node of a `table-cell`\n * is a `table-content` node. It won't be if a user pastes\n * in the start of a `table-cell`.\n *\n * We want this because our algorithm will merge all following\n * nodes into this node. If we don't do this, we are merging\n * into a potentially non `table-content` cell and might end up\n * with some other `Element` like a `code-block`.\n *\n * NOTE:\n *\n * In order to make sure this doesn't turn into a noop, we add\n * some text here. It is arbitrarily an `X`.\n */\n Transforms.insertNodes(\n editor,\n {\n type: \"table-content\",\n children: [{ text: \"X\" }],\n },\n { at: [...entry[1], 0] }\n )\n /**\n * We then iterate from the back of the children to the front\n * and merging left. Because we inserted an extra node, the\n * for loop looks a little unusual in that `i` starts at\n * `node.children.length` instead of `node.children.length - 1`.\n */\n for (let i = node.children.length; i >= 0; i--) {\n Transforms.mergeNodes(editor, { at: [...path, i] })\n }\n /**\n * When we're done, we remove the `X`.\n *\n * There might be a cleaner way to do this whout adding and\n * removing the `X` and when we find it, we can improve this\n * code.\n *\n * IMPORTANT:\n *\n * Whatever a replacement is, remember that we need to execute\n * the commands such that it preserves the cursor position.\n */\n Transforms.delete(editor, {\n at: { path: [...path, 0, 0], offset: 0 },\n unit: \"character\",\n })\n })\n return true\n}\n","import { useEffect } from \"react\"\nimport { ReactEditor, useSelected, useSlateStatic } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { normalizeTableIndexes } from \"../normalize/normalize-table\"\nimport { TableElement } from \"../types\"\nimport { $Table } from \"./styles\"\nimport { TableContext } from \"./table-context\"\n\nexport function Table({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableElement>) {\n const editor = useSlateStatic()\n const isSelected = useSelected()\n /**\n * The first time we render a table, we make sure it is normalized.\n * When it comes out of an `initialValue` it's not guaranteed to include\n * `x` and `y` properties as they are optional.\n *\n * This mainly helps us not have to manually add these values when the\n * `x` and `y` are purely an internal requirement for rendering.\n */\n useEffect(() => {\n const path = ReactEditor.findPath(editor, element)\n normalizeTableIndexes(editor, [element, path])\n }, [])\n return (\n <TableContext.Provider value={{ isSelected }}>\n <$Table {...attributes} columns={element.columns}>\n <tbody>{children}</tbody>\n </$Table>\n </TableContext.Provider>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { TableColumn } from \"../../types\"\nexport * from \"./table-menu-styles\"\n\n/**\n * Table\n */\nexport const $Table = styled(\"table\")<{ columns: TableColumn[] }>`\n border-collapse: collapse;\n margin: 1em 0;\n ${({ columns }) =>\n columns\n .map(\n (column, index) =>\n `td:nth-of-type(${index + 1}) { text-align: ${column.align}; }`\n )\n .join(\"\\n\")}\n`\n\n/**\n * Table Row\n */\nexport const $TableRow = styled(\"tr\")`\n position: relative;\n &:first-of-type {\n background: var(--table-head-bgcolor);\n }\n`\n\n/**\n * Table Cell\n *\n * - `--selected` indicates selected cell\n */\nexport const $TableCell = styled(\"td\")`\n position: relative;\n border-width: 1px;\n border-style: solid;\n border-color: rgba(0, 0, 0, 0.2) rgba(0, 0, 0, 0.05);\n border-color: var(--table-row-border-color) var(--table-column-border-color);\n padding: 0.75em 1em;\n min-width: 2em;\n &.--selected {\n outline: 2px solid var(--select-color, blue);\n }\n /**\n * Stronger borders on the left and right edge\n */\n &:first-of-type {\n border-left-color: var(--table-border-color);\n }\n &:last-of-type {\n border-right-color: var(--table-border-color);\n }\n`\n\n/**\n * Table Content (inside Table Cell)\n */\nexport const $TableContent = styled(\"div\")`\n /**\n * Smaller font inside a table than outside of it\n */\n font-size: 0.9375em; /* 15px */\n /**\n * Even smaller font and dimmer for the heading row\n */\n tr:first-of-type & {\n color: rgba(0, 0, 0, 0.6);\n font-size: 0.875em; /* 14px */\n }\n`\n","import styled from \"@emotion/styled\"\n\n/**\n * Table Menu\n */\n\nconst $BaseMenu = styled(\"div\")`\n position: absolute;\n /**\n * very slightly shaded\n */\n background: rgba(0, 0, 0, 0.001);\n\n /**\n * hover \n */\n &:hover {\n /**\n * needs to pop up so that it doesn't jump back and forth with neighbor\n * below\n */\n z-index: 1000;\n /**\n * Makes the visible tile get darker on hover over any part of the\n * menu including the invisible part\n */\n .--tile {\n background: rgba(0, 0, 0, 0.15);\n }\n }\n`\n\nexport const $ColumnMenu = styled($BaseMenu)`\n cursor: pointer;\n /**\n * hangs out on top\n */\n left: -1px;\n right: -1px;\n right: 0;\n height: 3em;\n top: -3em;\n`\n\nexport const $RowMenu = styled($BaseMenu)`\n /**\n * hangs out on left\n */\n top: -1px;\n bottom: -1px;\n width: 3em;\n left: -3em;\n`\n\n/**\n * Menu Tile\n */\n\nconst $MenuTile = styled(\"div\")`\n position: absolute;\n background: rgba(0, 0, 0, 0.05);\n border: 1px solid rgba(0, 0, 0, 0.05);\n transition: all 200ms;\n /**\n * NOTE: One of these should be overridden\n */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n`\n\n/**\n * The `$RowMenuTile` is the visible part of the `$RowMenu` and is the right\n * half of the `$RowMenu`.\n */\nexport const $ColumnMenuTile = styled($MenuTile)`\n top: 50%;\n border-bottom: none;\n border-right: none;\n bottom: 1px;\n td:first-of-type & {\n border-top-left-radius: 0.5em;\n }\n td:last-of-type & {\n border-top-right-radius: 0.5em;\n border-right: 1px solid rgba(0, 0, 0, 0.05);\n right: -1px;\n }\n svg {\n position: absolute;\n top: 0.1875em;\n left: 50%;\n margin-left: -0.5em;\n color: rgba(0, 0, 0, 0.2);\n }\n &:hover svg {\n color: rgba(0, 0, 0, 0.5);\n }\n\n /* border-top-left-radius: 0.5em;\n border-top-right-radius: 0.5em; */\n`\n\n/**\n * The `$RowMenuTile` is the visible part of the `$RowMenu` and is the right\n * half of the `$RowMenu`.\n */\nexport const $RowMenuTile = styled($MenuTile)`\n left: 50%;\n border-right: none;\n border-bottom: none;\n right: 1px;\n tr:first-of-type & {\n border-top-left-radius: 0.5em;\n }\n tr:last-of-type & {\n border-bottom-left-radius: 0.5em;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n bottom: 0;\n }\n svg {\n position: absolute;\n left: 0.25em;\n top: 50%;\n margin-top: -0.5em;\n color: rgba(0, 0, 0, 0.2);\n }\n &:hover svg {\n color: rgba(0, 0, 0, 0.5);\n }\n\n /* border-top-left-radius: 0.5em;\n border-bottom-left-radius: 0.5em; */\n`\n\n/**\n * Menu Button\n */\n\nconst $MenuButton = styled(\"div\")`\n position: absolute;\n font-size: 1.5em;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n svg {\n display: block;\n }\n`\n\nexport const $AddMenuButton = styled($MenuButton)`\n color: #c0c0c0;\n &:hover {\n color: royalblue;\n }\n`\n\nexport const $RemoveMenuButton = styled($MenuButton)`\n color: #c0c0c0;\n &:hover {\n color: firebrick;\n }\n`\n","import { createContext } from \"react\"\n\nexport const TableContext = createContext<{ isSelected: boolean }>({\n isSelected: false,\n})\n","import { useContext } from \"react\"\nimport { useSelected } from \"slate-react\"\n\nimport { ConstrainedRenderElementProps } from \"../../../sink\"\n\nimport { TableCellElement } from \"../../types\"\nimport { $TableCell } from \"../styles\"\nimport { TableContext } from \"../table-context\"\nimport { ColumnMenu } from \"./column-menu\"\nimport { RowMenu } from \"./row-menu\"\nimport { TableMenu } from \"./table-menu\"\n\nexport function TableCell({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableCellElement>) {\n const tableContext = useContext(TableContext)\n const selected = useSelected()\n /**\n * table has slection and we are in the top left cell\n */\n const showTableMenu =\n tableContext.isSelected && element.x === 0 && element.y === 0\n /**\n * table has selection and we are in the left columns\n */\n const showRowMenu = tableContext.isSelected && element.x === 0\n /**\n * table has selection and we are in the top row\n */\n const showColumnMenu = tableContext.isSelected && element.y === 0\n return (\n <$TableCell\n className={selected ? \"--selected\" : \"\"}\n {...attributes}\n data-x={element.x}\n data-y={element.y}\n >\n {children}\n {showTableMenu ? <TableMenu /> : null}\n {showRowMenu ? <RowMenu cellElement={element} /> : null}\n {showColumnMenu ? <ColumnMenu cellElement={element} /> : null}\n </$TableCell>\n )\n}\n","import React, { useCallback, useRef, useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { Menu, MenuItemData } from \"../../../../shared-overlays\"\nimport { useLayer } from \"../../../../use-layer\"\n\nimport {\n AlignCenter,\n AlignLeft,\n AlignRight,\n BarsIcon,\n MinusIcon,\n PlusIcon,\n} from \"../../../icons\"\nimport { TableCellElement } from \"../../../types\"\nimport {\n $AddMenuButton,\n $ColumnMenu,\n $ColumnMenuTile,\n $RemoveMenuButton,\n} from \"../../styles\"\n\nexport function ColumnMenu({ cellElement }: { cellElement: TableCellElement }) {\n const editor = useSlateStatic()\n const menu = useLayer(\"column-menu\")\n const buttonRef = useRef<HTMLDivElement>(null)\n const [hover, setHover] = useState(false)\n\n const onMouseEnter = useCallback(() => {\n setHover(true)\n }, [])\n\n const onMouseLeave = useCallback(() => {\n setHover(false)\n }, [])\n\n const onClick = useCallback(() => {\n if (menu.layer) menu.close()\n const dest = buttonRef.current\n if (dest === null) return\n const items: MenuItemData[] = [\n {\n icon: AlignLeft,\n title: \"左揃え\",\n action: () => {\n editor.tablePlugin.setTableColumnAlign({ align: \"left\" })\n },\n },\n {\n icon: AlignCenter,\n title: \"中央揃え\",\n action: () => {\n editor.tablePlugin.setTableColumnAlign({ align: \"center\" })\n },\n },\n {\n icon: AlignRight,\n title: \"右揃え\",\n action: () => {\n editor.tablePlugin.setTableColumnAlign({ align: \"right\" })\n },\n },\n ]\n // Menu\n menu.open(() => <Menu dest={dest} items={items} close={menu.close} />)\n }, [])\n\n return (\n <$ColumnMenu\n ref={buttonRef}\n contentEditable={false}\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <$ColumnMenuTile className=\"--tile\">\n <BarsIcon />\n </$ColumnMenuTile>\n {hover ? (\n <>\n <$RemoveMenuButton\n style={{\n top: 0,\n left: \"50%\",\n marginLeft: \"-0.5em\",\n }}\n onMouseDown={() =>\n editor.tablePlugin.removeColumn({ at: cellElement })\n }\n >\n <MinusIcon />\n </$RemoveMenuButton>\n\n <$AddMenuButton\n style={{ left: \"-0.5em\", top: 0 }}\n onMouseDown={() =>\n editor.tablePlugin.insertColumn({ at: cellElement })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n <$AddMenuButton\n style={{ right: \"-0.5em\", top: 0 }}\n onMouseDown={() =>\n editor.tablePlugin.insertColumn({ at: cellElement, offset: 1 })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n </>\n ) : null}\n </$ColumnMenu>\n )\n}\n","import { SVGProps } from \"react\"\n\nimport { TablerIcon } from \"../sink\"\n\nexport const PlusIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm.75-11.25a.75.75 0 0 0-1.5 0v2.5h-2.5a.75.75 0 0 0 0 1.5h2.5v2.5a.75.75 0 0 0 1.5 0v-2.5h2.5a.75.75 0 0 0 0-1.5h-2.5v-2.5z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\n\nexport const MinusIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM6.75 9.25a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-6.5z\"\n clipRule=\"evenodd\"\n />\n </svg>\n)\n\nexport const BarsIcon = () => (\n <TablerIcon>\n <path d=\"M4 6h16M4 12h16M4 18h16\" />\n </TablerIcon>\n)\n\nexport const AlignLeft = () => (\n <TablerIcon>\n <path d=\"M4 6h16M4 12h10M4 18h14\" />\n </TablerIcon>\n)\n\nexport const AlignCenter = () => (\n <TablerIcon>\n <path d=\"M4 6h16M8 12h8M6 18h12\" />\n </TablerIcon>\n)\n\nexport const AlignRight = () => (\n <TablerIcon>\n <path d=\"M4 6h16M10 12h10M6 18h14\" />\n </TablerIcon>\n)\n","import React, { useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { BarsIcon, MinusIcon, PlusIcon } from \"../../../icons\"\nimport { TableCellElement } from \"../../../types\"\nimport {\n $AddMenuButton,\n $RemoveMenuButton,\n $RowMenu,\n $RowMenuTile,\n} from \"../../styles\"\n\nexport function RowMenu({ cellElement }: { cellElement: TableCellElement }) {\n const editor = useSlateStatic()\n const [hover, setHover] = useState(false)\n\n return (\n <$RowMenu\n contentEditable={false}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n >\n <$RowMenuTile className=\"--tile\">\n <BarsIcon />\n </$RowMenuTile>\n {hover ? (\n <>\n <$RemoveMenuButton\n style={{\n top: \"50%\",\n left: \"0.5em\",\n marginTop: \"-0.5em\",\n }}\n onMouseDown={() =>\n editor.tablePlugin.removeRow({ at: cellElement })\n }\n >\n <MinusIcon />\n </$RemoveMenuButton>\n <$AddMenuButton\n style={{ top: \"-0.5em\", left: \"0.5em\" }}\n onMouseDown={() =>\n editor.tablePlugin.insertRow({ at: cellElement })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n <$AddMenuButton\n style={{ bottom: \"-0.5em\", left: \"0.5em\" }}\n onMouseDown={() =>\n editor.tablePlugin.insertRow({ at: cellElement, offset: 1 })\n }\n >\n <PlusIcon />\n </$AddMenuButton>\n </>\n ) : null}\n </$RowMenu>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $TableMenu = styled(\"div\")`\n position: absolute;\n /**\n * very slightly shaded\n */\n background: rgba(0, 0, 0, 0.001);\n\n /**\n * hangs out on left\n */\n top: -1.5em;\n left: -4em;\n height: 2.5em;\n width: 2.5em;\n\n /**\n * hover \n */\n &:hover {\n /**\n * needs to pop up so that it doesn't jump back and forth with neighbor\n * below\n */\n z-index: 1000;\n /**\n * Makes the visible tile get darker on hover over any part of the\n * menu including the invisible part\n */\n .--row-menu-tile {\n background: rgba(0, 0, 0, 0.15);\n }\n }\n`\n\n/**\n * The `$RowMenuTile` is the visible part of the `$RowMenu` and is the right\n * half of the `$RowMenu`.\n */\nexport const $TableMenuTile = styled(\"div\")`\n position: absolute;\n left: 0;\n top: 0;\n width: 1.5em;\n height: 1.5em;\n background: rgba(0, 0, 0, 0.05);\n border-radius: 50%;\n`\n","import { $TableMenu, $TableMenuTile } from \"./$table-menu\"\n\nexport function TableMenu() {\n return (\n <$TableMenu contentEditable={false}>\n <$TableMenuTile className=\"--table-menu-tile\" />\n </$TableMenu>\n )\n}\n","import { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { TableContentElement } from \"../types\"\nimport { $TableContent } from \"./styles\"\n\nexport function TableContent({\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableContentElement>) {\n return <$TableContent {...attributes}>{children}</$TableContent>\n}\n","import { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport { TableRowElement } from \"../types\"\nimport { $TableRow } from \"./styles\"\n\nexport function TableRow({\n attributes,\n children,\n}: ConstrainedRenderElementProps<TableRowElement>) {\n return <$TableRow {...attributes}>{children}</$TableRow>\n}\n","import { ConstrainedRenderElementProps } from \"../../sink\"\n\nimport {\n TableCellElement,\n TableContentElement,\n TableElement,\n TableRowElement,\n} from \"../types\"\nimport { Table } from \"./table\"\nimport { TableCell } from \"./table-cell\"\nimport { TableContent } from \"./table-content\"\nimport { TableRow } from \"./table-row\"\n\nexport function renderElement({\n element,\n attributes,\n children,\n}: ConstrainedRenderElementProps<\n TableElement | TableRowElement | TableCellElement | TableContentElement\n>) {\n switch (element.type) {\n case \"table\":\n return (\n <Table element={element} attributes={attributes}>\n {children}\n </Table>\n )\n case \"table-row\":\n return (\n <TableRow element={element} attributes={attributes}>\n {children}\n </TableRow>\n )\n case \"table-cell\":\n return (\n <TableCell element={element} attributes={attributes}>\n {children}\n </TableCell>\n )\n case \"table-content\":\n return (\n <TableContent element={element} attributes={attributes}>\n {children}\n </TableContent>\n )\n }\n}\n","import { Global } from \"@emotion/react\"\n\nimport { createPlugin, TypedPlugin } from \"../sink\"\n\nimport { globalStyles } from \"./global-styles\"\n\nexport type ThemeEditor = {\n theme: true\n}\n\nexport type ThemePluginCustomTypes = {\n Name: \"theme\"\n Editor: ThemeEditor\n}\n\nexport const ThemePlugin = createPlugin<ThemePluginCustomTypes>((editor) => {\n editor.theme = true\n return {\n name: \"theme\",\n editor: {},\n renderEditable: ({ attributes, Editable }) => {\n return (\n <>\n <Global styles={globalStyles} />\n <Editable {...attributes} />\n </>\n )\n },\n editableProps: {},\n }\n}) as TypedPlugin<ThemePluginCustomTypes>\n","import { css } from \"@emotion/react\"\n\nconst blue = `\n--blue-50: rgb(239 246 255);\n--blue-100: rgb(219 234 254);\n--blue-200: rgb(191 219 254);\n--blue-300: rgb(147 197 253);\n--blue-400: rgb(96 165 250);\n--blue-500: rgb(59 130 246);\n--blue-600: rgb(37 99 235);\n--blue-700: rgb(29 78 216);\n--blue-800: rgb(30 64 175);\n--blue-900: rgb(30 58 138);\n`\n\nconst zincShades = `\n--shade-50: rgb(250 250 250);\n--shade-100: rgb(244 244 245);\n--shade-200: rgb(228 228 231);\n--shade-300: rgb(212 212 216);\n--shade-400: rgb(161 161 170);\n--shade-500: rgb(113 113 122);\n--shade-600: rgb(82 82 91);\n--shade-700: rgb(63 63 70);\n--shade-800: rgb(39 39 42);\n--shade-900: rgb(24 24 27);\n`\n\nexport const globalStyles = css`\n :root {\n /* Tailwind Colors */\n ${blue}\n ${zincShades}\n /* Select Colors */\n --select-color: var(--blue-400);\n --select-editor-color: var(--blue-200);\n --hover-color: var(--blue-200);\n /* Link Colors */\n --link-color: var(--blue-600);\n --link-hover-color: var(--blue-700);\n /* Code Block Colors */\n /* Inline Code Colors */\n --inline-code-bgcolor: var(--shade-100);\n --inline-code-border-color: var(--shade-200);\n /* Table Colors */\n --table-border-color: var(--shade-300);\n --table-row-border-color: var(--shade-300);\n --table-column-border-color: var(--shade-100);\n --table-head-bgcolor: var(--shade-50);\n --table-menu-bgcolor: var(--shade-100);\n --table-menu-hover-bgcolor: var(--shade-200);\n /* Horizontal Rule Colors */\n --hr-color: var(--shade-300);\n }\n`\n","import { clsx } from \"clsx\"\nimport { useCallback, useRef } from \"react\"\nimport { Editor, Transforms } from \"slate\"\nimport { ReactEditor, useFocused, useSlateStatic } from \"slate-react\"\n\nimport { RenderEditableProps } from \"../../sink\"\nimport { Layers } from \"../../use-layer\"\n\nimport { Toolbar } from \"../components\"\nimport { $Editable, $OuterContainer } from \"../styles\"\n\nexport function renderEditable({ attributes, Editable }: RenderEditableProps) {\n const outerContainerRef = useRef<HTMLDivElement>(null)\n\n const editor = useSlateStatic()\n const focused = useFocused()\n\n /**\n * When the user clicks inside the outer container but outside of the content\n * or the toolbar, we want the user to see the cursor inside the editable\n * region.\n */\n const onClickOuterContainer = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n /**\n * If the user clicked on the toolbar, we don't want to do anything.\n *\n * If the user clicked on the content, we don't want to do anything\n * because focus and selection will be handled by Slate.\n */\n if (e.target !== e.currentTarget) return\n /**\n * Select the last position in the editor\n */\n Transforms.select(editor, Editor.end(editor, []))\n ReactEditor.focus(editor)\n },\n [editor]\n )\n\n return (\n <Layers>\n <$OuterContainer\n ref={outerContainerRef}\n className={clsx({ \"--focused\": focused })}\n style={{\n height: editor.toolbar.height,\n minHeight: editor.toolbar.minHeight,\n maxHeight: editor.toolbar.maxHeight,\n }}\n onClick={onClickOuterContainer}\n >\n <Toolbar />\n <Editable\n as={$Editable}\n {...attributes}\n style={{ overflowY: \"auto\" }}\n />\n </$OuterContainer>\n </Layers>\n )\n}\n","import { clsx } from \"clsx\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { CloseMask } from \"../../../shared-overlays\"\nimport { useAbsoluteReposition } from \"../../../use-reposition\"\n\nimport {\n $TableDialog,\n $TableDialogGrid,\n $TableDialogGridCell,\n} from \"../../styles/table-styles\"\n\nfunction createRange(size: number): number[] {\n return [...Array(size).keys()]\n}\n\nexport function TableDialog({\n dest,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n}) {\n const [hover, setHover] = useState({ x: 0, y: 0 })\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(null)\n const style = useAbsoluteReposition({ src: ref, dest }, ({ dest }) => {\n return { left: dest.left - 8, top: dest.top + dest.height }\n })\n const rows = createRange(5).map((i) => i + 1)\n const cols = createRange(5).map((i) => i + 1)\n\n const hoverCell = useCallback(\n (x: number, y: number) => {\n setHover({ x, y })\n },\n [setHover]\n )\n\n const createTable = useCallback(\n (x: number, y: number) => {\n editor.tablePlugin.insertTable(x, y)\n ReactEditor.focus(editor)\n close()\n },\n [editor]\n )\n\n return (\n <>\n <CloseMask close={close} />\n <$TableDialog ref={ref} style={style}>\n <$TableDialogGrid onMouseLeave={() => hoverCell(0, 0)}>\n {rows.map((y) => {\n return cols.map((x) => {\n const selected = x <= hover.x && y <= hover.y\n return (\n <$TableDialogGridCell\n className={clsx({ \"--selected\": selected })}\n key={`${x},${y}`}\n onMouseEnter={() => hoverCell(x, y)}\n onClick={() => createTable(x, y)}\n />\n )\n })\n })}\n </$TableDialogGrid>\n </$TableDialog>\n </>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays\"\n\nexport const $TableDialog = styled($Panel)`\n padding: 0.5em;\n`\nexport const $TableDialogGrid = styled(\"div\")`\n display: grid;\n grid-template-columns: repeat(5, 1.75em);\n grid-template-rows: 1.5em;\n /* grid-gap: 1px; */\n`\nexport const $TableDialogGridCell = styled(\"div\")`\n background: var(--shade-100);\n height: 1.5em;\n border-radius: 0.125em;\n border-right: 1px solid white;\n border-top: 1px solid white;\n cursor: pointer;\n &.--selected {\n background: var(--blue-100);\n }\n`\n","import throttle from \"lodash.throttle\"\nimport { useEffect, useRef, useState } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { MenuItemData } from \"../../../shared-overlays/types\"\nimport { initialItems, itemSets } from \"../../items\"\nimport {\n $Toolbar,\n $ToolbarContainer,\n $ToolbarDivider,\n $ToolbarDividerContainer,\n} from \"../../styles\"\nimport { ToolbarButton } from \"./toolbar-button\"\n\n/**\n * Render a toolbar item which is either a button or a divider.\n */\nfunction ToolbarItem({ item }: { item: MenuItemData }) {\n const editor = useSlateStatic()\n if (item === \"divider\") {\n return (\n <$ToolbarDividerContainer data-item-type=\"divider\">\n <$ToolbarDivider />\n </$ToolbarDividerContainer>\n )\n }\n const show = item.show === undefined ? true : item.show(editor)\n if (!show) return null\n return <ToolbarButton item={item} />\n}\n\n/**\n * Returns the width of the toolbar, the width of a button, and the width of a\n * divider.\n */\nfunction getWidths(toolbar: HTMLDivElement) {\n const button = toolbar.querySelector<HTMLDivElement>(\n \"[data-item-type=button]\"\n )\n const divider = toolbar.querySelector<HTMLDivElement>(\n \"[data-item-type=divider]\"\n )\n if (!button || !divider) throw new Error(\"Button or divider not found\")\n return {\n toolbar: toolbar.offsetWidth,\n button: button.offsetWidth,\n divider: divider.offsetWidth,\n }\n}\n\n/**\n * Takes an array of items representing a set of toolbar buttons and items and\n * returns the width of the set in pixels\n */\nfunction measureItemSetWidth(\n items: MenuItemData[],\n buttonWidth: number,\n dividerWidth: number\n): number {\n let width = 0\n for (const item of items) {\n width += item === \"divider\" ? dividerWidth : buttonWidth\n }\n return width\n}\n\n// Allow a little slack so we don't collapse the toolbar while there is still\n// plenty of visible space. This helps avoid early wrapping on wide screens.\nconst WIDTH_BUFFER_PX = 48\n\nexport function Toolbar() {\n const ref = useRef<HTMLDivElement>(null)\n const [items, setItems] = useState<MenuItemData[]>(initialItems)\n useEffect(() => {\n const refresh = throttle(\n () => {\n const toolbar = ref.current\n if (!toolbar) throw new Error(\"Toolbar not found\")\n const widths = getWidths(toolbar)\n /**\n * Iterate through the item sets and find the first one that fits within\n * the toolbar width. If none fit, use the last item set.\n */\n for (let i = 0; i < itemSets.length - 1; i++) {\n const itemSetWidth = measureItemSetWidth(\n itemSets[i],\n widths.button,\n widths.divider\n )\n if (itemSetWidth < widths.toolbar - WIDTH_BUFFER_PX) {\n setItems(itemSets[i])\n return\n }\n }\n setItems(itemSets[itemSets.length - 1])\n },\n 100,\n { trailing: true }\n )\n // Delay initial refresh to ensure DOM is fully rendered\n const timeoutId = setTimeout(refresh, 0)\n window.addEventListener(\"resize\", refresh)\n return () => {\n clearTimeout(timeoutId)\n window.removeEventListener(\"resize\", refresh)\n }\n }, [])\n return (\n <$ToolbarContainer ref={ref}>\n <$Toolbar>\n {items.map((item, index) => (\n <ToolbarItem\n key={typeof item === \"string\" ? index : item.title}\n item={item}\n />\n ))}\n </$Toolbar>\n </$ToolbarContainer>\n )\n}\n","import { TablerIcon } from \"../sink\"\n\nexport const H = () => (\n <TablerIcon>\n <path d=\"M7 12h10M7 5v14M17 5v14M15 19h4M15 5h4M5 19h4M5 5h4\" />\n </TablerIcon>\n)\n\nexport const More = () => (\n <TablerIcon className=\"--more-icon\" width=\"0.5em\" viewBox=\"0 0 12 24\">\n <path d=\"m2 12 4 4 4-4\" />\n </TablerIcon>\n)\n\nexport const LinkPlus = () => (\n <TablerIcon width=\"0.5em\" viewBox=\"6 0 12 24\">\n <path d=\"M9 12h6M12 9v6\" />\n </TablerIcon>\n)\n\nexport const H1 = () => (\n <TablerIcon>\n <path d=\"M19 18v-8l-2 2M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H2 = () => (\n <TablerIcon>\n <path d=\"M17 12a2 2 0 1 1 4 0c0 .591-.417 1.318-.816 1.858L17 18.001h4M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H3 = () => (\n <TablerIcon>\n <path d=\"M19 14a2 2 0 1 0-2-2M17 16a2 2 0 1 0 2-2M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H4 = () => (\n <TablerIcon>\n <path d=\"M20 18v-8l-4 6h5M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H5 = () => (\n <TablerIcon>\n <path d=\"M17 18h2a2 2 0 1 0 0-4h-2v-4h4M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const H6 = () => (\n <TablerIcon>\n <path d=\"M19 14a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\" />\n <path d=\"M21 12a2 2 0 1 0-4 0v4M4 6v12M12 6v12M11 18h2M3 18h2M4 12h8M3 6h2M11 6h2\" />\n </TablerIcon>\n)\n\nexport const Normal = () => (\n <TablerIcon>\n <path d=\"M8 18V6h2l6 9V6h2v12h-2l-6-9v9H8z\" />\n </TablerIcon>\n)\n\nexport const Bold = () => (\n <TablerIcon>\n {/* <path d=\"M0 0h24v24H0z\" stroke=\"none\" /> */}\n <path d=\"M7 5h6a3.5 3.5 0 0 1 0 7H7zM13 12h1a3.5 3.5 0 0 1 0 7H7v-7\" />\n </TablerIcon>\n)\n\nexport const Italic = () => (\n <TablerIcon>\n <path d=\"M11 5h6M7 19h6M14 5l-4 14\" />\n </TablerIcon>\n)\n\nexport const Style = () => (\n <TablerIcon>\n <path d=\"M4 20h3M14 20h7M6.9 15h6.9M10.2 6.3 16 20M5 20l6-16h2l7 16\" />\n </TablerIcon>\n)\n\nexport const Link = () => (\n <TablerIcon>\n <path d=\"M10 14a3.5 3.5 0 0 0 5 0l4-4a3.5 3.5 0 0 0-5-5l-.5.5\" />\n <path d=\"M14 10a3.5 3.5 0 0 0-5 0l-4 4a3.5 3.5 0 0 0 5 5l.5-.5\" />\n </TablerIcon>\n)\n\n/**\n * Block Quote\n */\n\nexport const Blockquote = () => (\n <TablerIcon>\n <path d=\"M6 15h15M21 19H6M15 11h6M21 7h-6M9 9h1a1 1 0 1 1-1 1V7.5a2 2 0 0 1 2-2M3 9h1a1 1 0 1 1-1 1V7.5a2 2 0 0 1 2-2\" />\n </TablerIcon>\n)\n\nexport const Quote = () => (\n <TablerIcon>\n <path d=\"M10 11H6a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v6c0 2.667-1.333 4.333-4 5M19 11h-4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v6c0 2.667-1.333 4.333-4 5\" />\n </TablerIcon>\n)\n\nexport const DoubleQuote = () => (\n <TablerIcon>\n <path d=\"M10 9l4 3-4 3\" />\n <path d=\"M16 9l4 3-4 3\" />\n </TablerIcon>\n)\n\nexport const QuoteOff = () => (\n <TablerIcon>\n <path d=\"M10 11H6a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1m4 4v3c0 2.667-1.333 4.333-4 5M19 11h-4m-1-1V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v6c0 .66-.082 1.26-.245 1.798m-1.653 2.29c-.571.4-1.272.704-2.102.912M3 3l18 18\" />\n </TablerIcon>\n)\n\n/**\n * List\n */\n\nexport const BulletList = () => (\n <TablerIcon>\n <path d=\"M9 6h11M9 12h11M9 18h11M5 6v.01M5 12v.01M5 18v.01\" />\n </TablerIcon>\n)\n\n/**\n * Table\n */\n\nexport const Table = () => (\n <TablerIcon>\n <rect x={4} y={4} width={16} height={16} rx={2} />\n <path d=\"M4 10h16M10 4v16\" />\n </TablerIcon>\n)\n\n/**\n * Code\n */\n\nexport const Code = () => (\n <TablerIcon>\n <path d=\"m7 8-4 4 4 4M17 8l4 4-4 4M14 4l-4 16\" />\n </TablerIcon>\n)\n\nexport const CodeBlock = () => (\n <TablerIcon>\n <path d=\"M9 8L5 12L9 16M15 8L19 12L15 16\" />\n </TablerIcon>\n)\n\n/**\n * Media and Files\n */\n\nexport const Image = () => (\n <TablerIcon>\n <path d=\"M15 8h.01\" />\n <rect x={4} y={4} width={16} height={16} rx={3} />\n <path d=\"m4 15 4-4a3 5 0 0 1 3 0l5 5\" />\n <path d=\"m14 14 1-1a3 5 0 0 1 3 0l2 2\" />\n </TablerIcon>\n)\n\nexport const Attachment = () => (\n <TablerIcon>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2zM12 11v6M9 14h6\" />\n </TablerIcon>\n)\n\nexport const FileUpload = () => (\n <TablerIcon>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2zM12 11v6\" />\n <path d=\"M9.5 13.5 12 11l2.5 2.5\" />\n </TablerIcon>\n)\n\nexport const PhotoUp = () => (\n <TablerIcon>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" />\n <path d=\"M15 8h.01M12.5 21H6a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v6.5\" />\n <path d=\"m3 16 5-5c.928-.893 2.072-.893 3 0l3.5 3.5\" />\n <path d=\"m14 14 1-1c.679-.653 1.473-.829 2.214-.526M19 22v-6M22 19l-3-3-3 3\" />\n </TablerIcon>\n)\n\n/**\n * Text Styles\n */\n\nexport const Plus = () => (\n <TablerIcon>\n <path d=\"M12 5v14M5 12h14\" />\n </TablerIcon>\n)\n\nexport const Strikethrough = () => (\n <TablerIcon>\n <path d=\"M5 12h14M16 6.5A4 2 0 0 0 12 5h-1a3.5 3.5 0 0 0 0 7h2a3.5 3.5 0 0 1 0 7h-1.5a4 2 0 0 1-4-1.5\" />\n </TablerIcon>\n)\n\nexport const Underline = () => (\n <TablerIcon>\n <path d=\"M7 5v5a5 5 0 0 0 10 0V5M5 19h14\" />\n </TablerIcon>\n)\n\nexport const RemoveStyles = () => (\n <TablerIcon>\n <path d=\"m14 6 7 7-2 2M10 10l-4.172 4.172a2.828 2.828 0 1 0 4 4L14 14\" />\n <path d=\"m16 12 4.414-4.414a2 2 0 0 0 0-2.829l-1.171-1.171a2 2 0 0 0-2.829 0L12 8M4 20l1.768-1.768M3 3l18 18\" />\n </TablerIcon>\n)\n\nexport const ListCheck = () => (\n <TablerIcon>\n <path d=\"m9 11 3 3 8-8\" />\n <path d=\"M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h9\" />\n </TablerIcon>\n)\n\nexport const ListNumbers = () => (\n <TablerIcon>\n <path d=\"M11 6h9M11 12h9M12 18h8M4 16a2 2 0 1 1 4 0c0 .591-.5 1-1 1.5L4 20h4M6 10V4L4 6\" />\n </TablerIcon>\n)\n\nexport const IncreaseDepth = () => (\n <TablerIcon>\n <path d=\"M4 6h16M8 12h12M12 18h8M7 12l-3-3M7 12l-3 3\" />\n </TablerIcon>\n)\n\nexport const DecreaseDepth = () => (\n <TablerIcon>\n <path d=\"M4 6h16M8 12h12M12 18h8M4 12l3-3M4 12l3 3\" />\n </TablerIcon>\n)\n\n/**\n * Markdown\n */\nexport const Markdown = () => (\n <TablerIcon>\n <path d=\"M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z\" />\n <path d=\"M7 15V9l2 2 2-2v6M14 9v6h4M14 13h2\" />\n </TablerIcon>\n)\n\n/**\n * Visual Editor\n */\nexport const VisualEditor = () => (\n <TablerIcon>\n <path d=\"M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z\" />\n <path d=\"M8 8h8M8 12h8M8 16h5\" />\n <path d=\"M16 16h1\" />\n </TablerIcon>\n)\n\nexport const Close = () => (\n <TablerIcon>\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </TablerIcon>\n)\n\nexport const Highlight = () => (\n <TablerIcon>\n <path d=\"M4 20h4l10.5-10.5a2.828 2.828 0 1 0-4-4L4 16v4\" />\n <path d=\"M13.5 6.5l4 4\" />\n <path d=\"m14 19 6-6M18 15l2 2M5 21h4\" />\n </TablerIcon>\n)\n","import { MenuItemData } from \"../../shared-overlays/types\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"../../utils/translations\"\n\nconst listDepthItems: MenuItemData[] = [\n {\n icon: Icon.IncreaseDepth,\n title: t(\"increaseDepth\"),\n hotkey: \"tab\",\n action: (editor) => editor.list.increaseDepth(),\n active: (editor) => editor.list.canIncreaseDepth(),\n },\n {\n icon: Icon.DecreaseDepth,\n title: t(\"decreaseDepth\"),\n hotkey: \"shift+tab\",\n action: (editor) => editor.list.decreaseDepth(),\n active: (editor) => editor.list.canDecreaseDepth(),\n },\n]\n\nconst blockItems: MenuItemData[] = [\n {\n icon: Icon.Normal,\n title: t(\"normal\"),\n hotkey: \"super+0\",\n action: (editor) => {\n editor.collapsibleParagraph.convertParagraph()\n },\n },\n {\n icon: Icon.H1,\n title: t(\"heading1\"),\n hotkey: \"super+1\",\n action: (editor) => editor.heading.convertHeading(1, true),\n active: (editor) => editor.heading.isHeadingActive(1),\n },\n {\n icon: Icon.H2,\n title: t(\"heading2\"),\n hotkey: \"super+2\",\n action: (editor) => editor.heading.convertHeading(2, true),\n active: (editor) => editor.heading.isHeadingActive(2),\n },\n {\n icon: Icon.H3,\n title: t(\"heading3\"),\n hotkey: \"super+3\",\n action: (editor) => editor.heading.convertHeading(3, true),\n active: (editor) => editor.heading.isHeadingActive(3),\n },\n]\n\nexport const expandedBlockItems: MenuItemData[] = [...blockItems]\n\nexport const compactBlockItems: MenuItemData[] = [\n {\n icon: Icon.H,\n title: t(\"paragraphStyle\"),\n more: true,\n children: blockItems,\n }\n]\n\n// Export listDepthItems so they can be used in list-items.tsx\nexport { listDepthItems }\n","import { useState, useRef, CSSProperties, useEffect, useCallback } from \"react\"\nimport { useSlateStatic } from \"slate-react\"\n\nimport { CloseMask } from \"../../../shared-overlays\"\nimport { positionInside, useAbsoluteReposition } from \"../../../use-reposition\"\nimport { t } from \"../../../utils/translations\"\n\nimport { $FileDialog } from \"../../styles/file-dialog-styles\"\nimport { DraggableHeader } from \"./DraggableHeader\"\n\ntype ImageSource = \"url\" | \"file\"\n\nexport function ImageUrlDialog({\n dest,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n}) {\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(undefined) as unknown as HTMLDivElement\n const fileInputRef = useRef<HTMLInputElement>(null)\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })\n\n const handleDrag = useCallback((deltaX: number, deltaY: number) => {\n setDragOffset(prev => ({ x: prev.x + deltaX, y: prev.y + deltaY }))\n }, [])\n\n // Persist dialog values in editor.wysimark so they survive dialog close/reopen\n const savedState = editor.wysimark?.imageDialogState\n const hasOnImageChange = !!editor.wysimark?.onImageChange\n\n const [url, setUrl] = useState(savedState?.url ?? \"\")\n const [alt, setAlt] = useState(savedState?.alt ?? \"\")\n const [title, setTitle] = useState(savedState?.title ?? \"\")\n const [titleManuallyEdited, setTitleManuallyEdited] = useState(false)\n const [imageSource, setImageSource] = useState<ImageSource>(savedState?.imageSource ?? (hasOnImageChange ? \"file\" : \"url\"))\n const [isUploading, setIsUploading] = useState(false)\n const [uploadedUrl, setUploadedUrl] = useState(savedState?.uploadedUrl ?? \"\")\n const [uploadedFileName, setUploadedFileName] = useState(\"\")\n\n // Handlers for alt and title with sync\n const handleAltChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const newAlt = e.target.value\n setAlt(newAlt)\n // Sync title with alt if title hasn't been manually edited\n if (!titleManuallyEdited) {\n setTitle(newAlt)\n }\n }, [titleManuallyEdited])\n\n const handleTitleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setTitle(e.target.value)\n setTitleManuallyEdited(true)\n }, [])\n\n // Save state to editor when values change\n useEffect(() => {\n if (editor.wysimark) {\n editor.wysimark.imageDialogState = { url, alt, title, imageSource, uploadedUrl }\n }\n }, [url, alt, title, imageSource, uploadedUrl])\n\n // Clear state on successful submit or cancel\n const clearState = () => {\n if (editor.wysimark) {\n editor.wysimark.imageDialogState = undefined\n }\n }\n\n const baseStyle = useAbsoluteReposition(\n { src: ref, dest },\n ({ src, dest }, viewport) => {\n return positionInside(\n src,\n viewport,\n {\n left: dest.left - 16,\n top: dest.top + dest.height,\n },\n { margin: 16 }\n )\n }\n ) as CSSProperties\n\n const style = {\n ...baseStyle,\n left: (baseStyle.left as number) + dragOffset.x,\n top: (baseStyle.top as number) + dragOffset.y,\n }\n\n function handleSubmit(e: React.FormEvent) {\n e.preventDefault()\n const finalUrl = imageSource === \"file\" ? uploadedUrl : url\n if (finalUrl.trim() === \"\") return\n\n editor.image.insertImageFromUrl(finalUrl, alt, title)\n clearState()\n close()\n }\n\n function handleCancel() {\n clearState()\n close()\n }\n\n async function handleFileSelect(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0]\n if (!file || !editor.wysimark?.onImageChange) return\n\n setUploadedFileName(file.name)\n setIsUploading(true)\n try {\n const resultUrl = await editor.wysimark.onImageChange(file)\n setUploadedUrl(resultUrl)\n } catch (error) {\n console.error(\"Failed to upload image:\", error)\n } finally {\n setIsUploading(false)\n }\n }\n\n function handleSelectFileClick() {\n fileInputRef.current?.click()\n }\n\n const isSubmitDisabled = imageSource === \"file\"\n ? uploadedUrl.trim() === \"\" || isUploading\n : url.trim() === \"\"\n\n return (\n <>\n <CloseMask close={close} />\n <$FileDialog ref={ref as unknown as React.RefObject<HTMLDivElement>} style={style}>\n <DraggableHeader onDrag={handleDrag} />\n <form onSubmit={(e) => void handleSubmit(e)} style={{ padding: \"8px\" }}>\n {hasOnImageChange && (\n <div style={{ marginBottom: \"12px\" }}>\n <label style={{ display: \"inline-flex\", alignItems: \"center\", marginRight: \"16px\", cursor: \"pointer\" }}>\n <input\n type=\"radio\"\n name=\"imageSource\"\n value=\"file\"\n checked={imageSource === \"file\"}\n onChange={() => setImageSource(\"file\")}\n style={{ marginRight: \"4px\" }}\n />\n {t(\"imageSourceFile\")}\n </label>\n <label style={{ display: \"inline-flex\", alignItems: \"center\", cursor: \"pointer\" }}>\n <input\n type=\"radio\"\n name=\"imageSource\"\n value=\"url\"\n checked={imageSource === \"url\"}\n onChange={() => setImageSource(\"url\")}\n style={{ marginRight: \"4px\" }}\n />\n {t(\"imageSourceUrl\")}\n </label>\n </div>\n )}\n\n {imageSource === \"url\" ? (\n <div style={{ marginBottom: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"imageUrlRequired\")}\n </label>\n <input\n type=\"text\"\n value={url}\n onChange={(e) => setUrl(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid var(--shade-300)\",\n borderRadius: \"4px\",\n backgroundColor: \"var(--shade-50)\",\n color: \"var(--shade-700)\"\n }}\n placeholder=\"https://example.com/image.jpg\"\n />\n </div>\n ) : (\n <div style={{ marginBottom: \"8px\" }}>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={(e) => void handleFileSelect(e)}\n style={{ display: \"none\" }}\n />\n <button\n type=\"button\"\n onClick={handleSelectFileClick}\n disabled={isUploading}\n style={{\n padding: \"8px 16px\",\n backgroundColor: isUploading ? \"#ccc\" : \"#0078d4\",\n color: isUploading ? \"#666\" : \"white\",\n border: \"none\",\n borderRadius: \"4px\",\n cursor: isUploading ? \"not-allowed\" : \"pointer\",\n marginBottom: \"8px\",\n fontWeight: \"bold\"\n }}\n >\n {isUploading ? t(\"uploading\") : t(\"selectFile\")}\n </button>\n\n {uploadedUrl && (\n <div style={{ marginTop: \"8px\", padding: \"8px\", backgroundColor: \"var(--shade-100)\", borderRadius: \"4px\" }}>\n <div style={{ color: \"green\", marginBottom: \"4px\" }}>✓ {t(\"uploadComplete\")}</div>\n {uploadedFileName && (\n <div style={{ fontSize: \"12px\", color: \"var(--shade-500)\" }}>{uploadedFileName}</div>\n )}\n </div>\n )}\n </div>\n )}\n\n <div style={{ marginBottom: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"altText\")}\n </label>\n <input\n type=\"text\"\n value={alt}\n onChange={handleAltChange}\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid var(--shade-300)\",\n borderRadius: \"4px\",\n backgroundColor: \"var(--shade-50)\",\n color: \"var(--shade-700)\"\n }}\n placeholder={t(\"imageDescription\")}\n />\n </div>\n\n <div style={{ marginBottom: \"8px\" }}>\n <label style={{ display: \"block\", marginBottom: \"4px\" }}>\n {t(\"title\")}\n </label>\n <input\n type=\"text\"\n value={title}\n onChange={handleTitleChange}\n style={{\n width: \"100%\",\n padding: \"6px\",\n boxSizing: \"border-box\",\n border: \"1px solid var(--shade-300)\",\n borderRadius: \"4px\",\n backgroundColor: \"var(--shade-50)\",\n color: \"var(--shade-700)\"\n }}\n placeholder={t(\"imageTitle\")}\n />\n </div>\n\n <div style={{ display: \"flex\", gap: \"8px\" }}>\n <button\n type=\"submit\"\n disabled={isSubmitDisabled}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px 16px\",\n backgroundColor: isSubmitDisabled ? \"#ccc\" : \"#0078d4\",\n color: \"white\",\n border: \"none\",\n borderRadius: \"4px\",\n cursor: isSubmitDisabled ? \"not-allowed\" : \"pointer\",\n fontWeight: \"bold\"\n }}\n >\n {t(\"register\")}\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n style={{\n padding: \"8px 16px\",\n backgroundColor: \"var(--shade-100)\",\n color: \"var(--shade-700)\",\n border: \"1px solid var(--shade-300)\",\n borderRadius: \"4px\",\n cursor: \"pointer\"\n }}\n >\n {t(\"cancel\")}\n </button>\n </div>\n </form>\n </$FileDialog>\n </>\n )\n}\n","import styled from \"@emotion/styled\"\n\nimport { $Panel } from \"../../shared-overlays/styles/$Panel\"\n\nexport const $FileDialog = styled($Panel)`\n width: 18em;\n padding: 0;\n overflow: hidden;\n`\n","import { isHotkey } from \"is-hotkey\"\nimport {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\"\nimport { Editor, Range } from \"slate\"\nimport { ReactEditor, useSlateStatic } from \"slate-react\"\n\nimport { positionInside, useAbsoluteReposition } from \"../../../use-reposition\"\n\nimport { CloseMask } from \"../../../shared-overlays/components/CloseMask\"\nimport { t } from \"../../../utils/translations\"\nimport * as Icon from \"../../icons\"\nimport {\n $AnchorDialog,\n $AnchorDialogInput,\n $AnchorDialogInputLine,\n} from \"../../styles\"\nimport { $DialogButton, $DialogHint } from \"../../styles/dialog-shared-styles\"\nimport { DraggableHeader } from \"./DraggableHeader\"\n\nconst isEnter = isHotkey(\"enter\")\n\nexport function AnchorDialog({\n dest,\n close,\n}: {\n dest: HTMLElement\n close: () => void\n}) {\n const editor = useSlateStatic()\n const ref = useRef<HTMLDivElement>(null)\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })\n\n const handleDrag = useCallback((deltaX: number, deltaY: number) => {\n setDragOffset(prev => ({ x: prev.x + deltaX, y: prev.y + deltaY }))\n }, [])\n\n const baseStyle = useAbsoluteReposition(\n { src: ref, dest },\n ({ src, dest }, viewport) => {\n return positionInside(\n src,\n viewport,\n {\n left: dest.left - 12,\n top: dest.top + dest.height,\n },\n { margin: 16 }\n )\n }\n )\n\n const style = {\n ...baseStyle,\n left: (baseStyle.left as number) + dragOffset.x,\n top: (baseStyle.top as number) + dragOffset.y,\n }\n\n // Get selected text as initial value for link text\n const initialText = useMemo(() => {\n const { selection } = editor\n if (selection && !Range.isCollapsed(selection)) {\n return Editor.string(editor, selection)\n }\n return \"\"\n }, [])\n\n const [url, setUrl] = useState(\"\")\n const [text, setText] = useState(initialText)\n const [title, setTitle] = useState(initialText)\n const [titleManuallyEdited, setTitleManuallyEdited] = useState(false)\n\n const insertLink = () => {\n const linkText = text.trim() || url\n const linkTitle = title.trim() || undefined\n editor.anchor.insertLink(url, linkText, { select: true, title: linkTitle })\n ReactEditor.focus(editor)\n close()\n }\n\n const onChangeUrl = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setUrl(e.currentTarget.value)\n },\n [setUrl]\n )\n\n const onChangeText = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const newText = e.currentTarget.value\n setText(newText)\n // Sync title with text if title hasn't been manually edited\n if (!titleManuallyEdited) {\n setTitle(newText)\n }\n },\n [setText, setTitle, titleManuallyEdited]\n )\n\n const onChangeTitle = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setTitle(e.currentTarget.value)\n setTitleManuallyEdited(true)\n },\n [setTitle]\n )\n\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (!isEnter(e)) return\n e.preventDefault()\n e.stopPropagation()\n insertLink()\n }\n\n return (\n <>\n <CloseMask close={close} />\n <$AnchorDialog ref={ref} style={style}>\n <DraggableHeader onDrag={handleDrag} />\n <div style={{ padding: \"0.75em\" }}>\n <$AnchorDialogInputLine>\n <$AnchorDialogInput\n type=\"text\"\n value={url}\n autoFocus\n placeholder={t(\"linkUrl\")}\n onChange={onChangeUrl}\n onKeyDown={onKeyDown}\n />\n </$AnchorDialogInputLine>\n <$AnchorDialogInputLine style={{ marginTop: \"0.5em\" }}>\n <$AnchorDialogInput\n type=\"text\"\n value={text}\n placeholder={t(\"linkText\")}\n onChange={onChangeText}\n onKeyDown={onKeyDown}\n />\n </$AnchorDialogInputLine>\n <$AnchorDialogInputLine style={{ marginTop: \"0.5em\" }}>\n <$AnchorDialogInput\n type=\"text\"\n value={title}\n placeholder={t(\"tooltipText\")}\n onChange={onChangeTitle}\n onKeyDown={onKeyDown}\n />\n <$DialogButton onClick={insertLink}>\n <Icon.Link />\n <Icon.LinkPlus />\n </$DialogButton>\n <$DialogButton onClick={close} style={{ marginLeft: \"0.25em\", background: \"var(--shade-400)\" }}>\n <Icon.Close />\n </$DialogButton>\n </$AnchorDialogInputLine>\n <$DialogHint>{t(\"tooltipHint\")}</$DialogHint>\n </div>\n </$AnchorDialog>\n </>\n )\n}\n","import styled from \"@emotion/styled\"\n\nexport const $DialogButton = styled(\"div\")`\n /* Center vertically and horizontally */\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n /* font-size: 1.25em; */\n padding: 0.25em 0.75em;\n text-align: center;\n color: var(--blue-100);\n color: white;\n background: var(--blue-500);\n transition: all 100ms;\n &:hover {\n color: var(--blue-50);\n background: var(--blue-600);\n outline: 2px solid var(--blue-200);\n }\n border-radius: 0.25em;\n svg {\n color: var(--blue-200);\n font-size: 1.25em;\n stroke-width: 2px;\n }\n`\n\nexport const $DialogHint = styled(\"div\")`\n font-size: 0.875em;\n margin-top: 0.5em;\n color: var(--shade-500);\n line-height: 1.375;\n`\n","import { MenuItemData } from \"../../shared-overlays\"\n\nimport { TableDialog } from \"../components\"\nimport { ImageUrlDialog } from \"../components/dialog/image-url-dialog\"\nimport { AnchorDialog } from \"../components/dialog/anchor-dialog\"\nimport * as Icon from \"../icons\"\nimport { t } from \"../../utils/translations\"\n\nexport const dialogItems: MenuItemData[] = [\n {\n icon: Icon.Link,\n title: t(\"insertLink\"),\n more: true,\n hotkey: \"mod+k\",\n Component: AnchorDialog,\n },\n {\n icon: Icon.Image,\n title: t(\"insertImageFromUrl\"),\n more: true,\n Component: ImageUrlDialog,\n },\n {\n icon: Icon.Table,\n title: t(\"insertTable\"),\n more: true,\n Component: TableDialog,\n },\n]\n\nexport const expandedDialogItems: MenuItemData[] = dialogItems\n\nexport const compactDialogItems: MenuItemData[] = dialogItems\n\nexport const smallDialogItems: MenuItemData[] = [\n {\n icon: Icon.Plus,\n title: t(\"insert\"),\n more: true,\n children: dialogItems,\n },\n]\n","import { Editor } from \"slate\"\nimport { MenuItemData } from \"../../shared-overlays\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"../../utils/translations\"\n\nfunction getMarks(editor: Editor) {\n const marks = Editor.marks(editor)\n return {\n bold: marks?.bold || false,\n italic: marks?.italic || false,\n strike: marks?.strike || false,\n code: marks?.code || false,\n underline: marks?.underline || false,\n highlight: marks?.highlight || false,\n }\n}\n\nconst primaryMarkItems: MenuItemData[] = [\n {\n icon: Icon.Bold,\n title: t(\"bold\"),\n hotkey: \"mod+b\",\n action: (editor) => editor.marksPlugin.toggleBold(),\n active: (editor) => getMarks(editor).bold,\n },\n {\n icon: Icon.Italic,\n title: t(\"italic\"),\n hotkey: \"mod+i\",\n action: (editor) => editor.marksPlugin.toggleItalic(),\n active: (editor) => getMarks(editor).italic,\n },\n {\n icon: Icon.Strikethrough,\n title: t(\"strike\"),\n hotkey: \"super+k\",\n action: (editor) => editor.marksPlugin.toggleStrike(),\n active: (editor) => getMarks(editor).strike,\n },\n {\n icon: Icon.Code,\n title: t(\"inlineCode\"),\n hotkey: \"mod+j\",\n action: (editor) => editor.inlineCode.toggleInlineCode(),\n active: (editor) => getMarks(editor).code,\n },\n {\n icon: Icon.Underline,\n title: t(\"underline\"),\n hotkey: \"mod+u\",\n action: (editor) => editor.marksPlugin.toggleUnderline(),\n active: (editor) => getMarks(editor).underline,\n },\n {\n icon: Icon.Highlight,\n title: t(\"highlight\"),\n hotkey: \"mod+h\",\n action: (editor) => editor.marksPlugin.toggleHighlight(),\n active: (editor) => getMarks(editor).highlight,\n show: (editor) => !editor.wysimark.disableHighlight,\n },\n]\n\nexport const expandedMarkItems: MenuItemData[] = primaryMarkItems\nexport const compactMarkItems: MenuItemData[] = [\n {\n icon: Icon.Bold,\n title: t(\"format\"),\n more: true,\n children: primaryMarkItems,\n },\n]\n","import { MenuItemData } from \"../../shared-overlays\"\n\nimport * as Icon from \"../icons\"\nimport { t } from \"../../utils/translations\"\nimport { listDepthItems } from \"./block-items\"\n\nexport const listItems: MenuItemData[] = [\n {\n icon: Icon.BulletList,\n title: t(\"bulletList\"),\n hotkey: \"super+8\",\n action: (editor) => editor.list.convertUnorderedList(true),\n },\n {\n icon: Icon.ListNumbers,\n title: t(\"numberedList\"),\n hotkey: \"super+7\",\n action: (editor) => editor.list.convertOrderedList(true),\n },\n {\n icon: Icon.ListCheck,\n title: t(\"checkList\"),\n hotkey: \"super+9\",\n action: (editor) => editor.list.convertTaskList(true),\n show: (editor) => !editor.wysimark.disableTaskList,\n },\n]\n\nexport const expandedListItems: MenuItemData[] = [...listItems, \"divider\", ...listDepthItems]\n\nexport const compactListItems: MenuItemData[] = [\n {\n icon: Icon.ListNumbers,\n title: t(\"list\"),\n more: true,\n children: [...listItems, \"divider\", ...listDepthItems],\n },\n]\n","import { MenuItemData } from \"../../shared-overlays\"\nimport { Editor, Transforms } from \"slate\"\nimport { findElementUp } from \"../../sink\"\nimport * as Icon from \"../icons\"\nimport { t } from \"../../utils/translations\"\n\nconst quoteItemsList: MenuItemData[] = [\n {\n icon: Icon.Quote,\n title: t(\"quote\"),\n hotkey: \"super+.\",\n action: (editor) => {\n if (editor.blockQuotePlugin.isActive()) {\n editor.blockQuotePlugin.outdent()\n } else {\n editor.blockQuotePlugin.indent()\n }\n },\n active: (editor) => editor.blockQuotePlugin.isActive(),\n },\n {\n icon: Icon.DoubleQuote,\n title: t(\"increaseQuoteDepth\"),\n action: (editor) => editor.blockQuotePlugin.increaseDepth(),\n active: (editor) => editor.blockQuotePlugin.canIncreaseDepth(),\n },\n {\n icon: Icon.CodeBlock,\n title: t(\"codeBlock\"),\n action: (editor) => {\n const { selection } = editor;\n const codeBlockEntry = findElementUp(editor, \"code-block\");\n\n // Case 1: If a code block is already active, convert it to a paragraph\n if (codeBlockEntry) {\n const [, path] = codeBlockEntry;\n\n // Extract text content from the code block\n const textContent = Editor.string(editor, path);\n\n // Remove the code block\n Transforms.removeNodes(editor, { at: path });\n\n // Insert a paragraph with the extracted text\n Transforms.insertNodes(\n editor,\n {\n type: \"paragraph\",\n children: [{ text: textContent }]\n },\n { at: path }\n );\n return;\n }\n\n // Case 2: If text is selected, convert it to a code block\n if (selection && JSON.stringify(selection.anchor.path) !== JSON.stringify(selection.focus.path)) {\n // Handle multi-paragraph selection\n // This is more complex and would require custom handling\n // For simplicity, we'll just create a code block with default behavior\n editor.codeBlock.createCodeBlock({ language: \"text\" });\n return;\n }\n\n if (selection && (selection.anchor.offset !== selection.focus.offset ||\n JSON.stringify(selection.anchor.path) !== JSON.stringify(selection.focus.path))) {\n // Get the selected text\n const selectedText = Editor.string(editor, selection);\n\n // Delete the selected text\n Transforms.delete(editor);\n\n // Insert a code block with the selected text\n Transforms.insertNodes(\n editor,\n {\n type: \"code-block\",\n language: \"text\",\n children: [\n {\n type: \"code-block-line\",\n children: [{ text: selectedText }]\n }\n ]\n }\n );\n return;\n }\n\n // Case 3: Default case - create a new empty code block\n editor.codeBlock.createCodeBlock({ language: \"text\" });\n },\n active: (editor) => !!findElementUp(editor, \"code-block\"),\n show: (editor) => !editor.wysimark.disableCodeBlock,\n },\n]\n\nexport const expandedQuoteItems: MenuItemData[] = quoteItemsList\n\nexport const compactQuoteItems: MenuItemData[] = [\n {\n icon: Icon.Quote,\n title: t(\"quote\"),\n more: true,\n children: quoteItemsList,\n },\n]\n\n// For backward compatibility\nexport const quoteItems = expandedQuoteItems\n","import { MenuItemData } from \"../../shared-overlays\"\n\nimport { expandedBlockItems, compactBlockItems } from \"./block-items\"\nimport { compactDialogItems, expandedDialogItems, smallDialogItems } from \"./dialogItems\"\nimport { compactMarkItems, expandedMarkItems } from \"./mark-items\"\nimport { expandedListItems, compactListItems } from \"./list-items\"\nimport { expandedQuoteItems, compactQuoteItems } from \"./quote-items\"\n\n/**\n * A collection of `Item` objects that describe either\n *\n * - A Button in the toolbar\n * - A Menu Item in a drop down of the toolbar\n *\n * An `Item` is described in the same way whether it is a button or a menu\n * item making them interchangeable.\n */\n\nexport const largeItems: MenuItemData[] = [\n ...expandedBlockItems,\n \"divider\",\n ...expandedListItems,\n \"divider\",\n ...expandedMarkItems,\n \"divider\",\n ...expandedDialogItems,\n \"divider\",\n ...expandedQuoteItems,\n]\n\nexport const mediumItems: MenuItemData[] = [\n ...compactBlockItems,\n \"divider\",\n ...expandedListItems,\n \"divider\",\n ...expandedMarkItems,\n \"divider\",\n ...compactDialogItems,\n \"divider\",\n ...expandedQuoteItems,\n]\n\nexport const smallItems: MenuItemData[] = [\n ...compactBlockItems,\n \"divider\",\n ...compactListItems,\n \"divider\",\n ...compactMarkItems,\n \"divider\",\n ...smallDialogItems,\n \"divider\",\n ...compactQuoteItems,\n]\n\nexport const initialItems: MenuItemData[] = smallItems\n\nexport const items = mediumItems\n\nexport const itemSets: MenuItemData[][] = [largeItems, mediumItems, smallItems]\n","import { clsx } from \"clsx\"\nimport { MouseEvent, useCallback, useRef } from \"react\"\nimport { ReactEditor, useSlate, useSlateStatic } from \"slate-react\"\n\nimport { formatHotkey, Menu, MenuItemData } from \"../../../shared-overlays\"\nimport { useLayer } from \"../../../use-layer\"\nimport { useTooltip } from \"../../../use-tooltip\"\nimport { r } from \"../../../utils/translations\"\n\nimport * as Icon from \"../../icons\"\nimport { $ToolbarButton } from \"../../styles\"\n\nexport function ToolbarButton({\n item,\n}: {\n item: Exclude<MenuItemData, \"divider\">\n}) {\n const staticEditor = useSlateStatic()\n const editor = useSlate() // エディタの状態変更を検知\n const isActive = item.active ? item.active(editor) : false\n const ref = useRef<HTMLDivElement>(null)\n const tooltip = useTooltip({\n title: item.title,\n hotkey: () => (item.hotkey ? formatHotkey(item.hotkey) : undefined),\n })\n const menuLayer = useLayer(\"menu\")\n\n const openMenu = useCallback(() => {\n const dest = ref.current\n const items = item.children\n const Component = item.Component\n if (!dest) return\n if (items) {\n menuLayer.open(() => (\n <Menu dest={dest} items={items} close={menuLayer.close} />\n ))\n } else if (Component) {\n menuLayer.open(() => <Component dest={dest} close={menuLayer.close} />)\n }\n }, [item])\n\n const onClick = useCallback(() => {\n if (item.action) {\n item.action(staticEditor)\n ReactEditor.focus(staticEditor)\n return\n }\n if (menuLayer.layer) {\n menuLayer.close()\n } else {\n openMenu()\n }\n }, [menuLayer.layer, item])\n\n /**\n * On hover\n */\n const onMouseEnter = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n tooltip.onMouseEnter(e)\n /**\n * If any `menu` is already open, then we open up the currently hovered\n * `menu` automatically. This replicates behavior in menus in windowing\n * systems.\n */\n if (menuLayer.layer) openMenu()\n },\n [menuLayer.layer]\n )\n\n return (\n <$ToolbarButton\n data-item-type=\"button\"\n ref={ref}\n onMouseEnter={onMouseEnter}\n onMouseLeave={tooltip.onMouseLeave}\n onClick={onClick}\n className={clsx({\n \"--active\": isActive && !r(item?.title)?.includes('Depth'),\n \"--more\": item.more,\n \"--disabled\": !isActive && r(item?.title)?.includes('Depth')\n })}\n >\n <item.icon />\n {item.more ? <Icon.More /> : null}\n </$ToolbarButton>\n )\n}\n","import { createPlugin, TypedPlugin } from \"../sink\"\n\nimport { renderEditable } from \"./render-editable\"\n\nexport type ToolbarEditor = {\n toolbar: {\n height?: string | number\n minHeight?: string | number\n maxHeight?: string | number\n showUploadButtons?: boolean\n }\n}\n\nexport type ToolbarOptions = {\n toolbar: {\n height?: string | number\n minHeight?: string | number\n maxHeight?: string | number\n showUploadButtons?: boolean\n }\n}\n\nexport type ToolbarPluginCustomTypes = {\n Name: \"toolbar\"\n Editor: ToolbarEditor\n Options: ToolbarOptions\n}\n\nexport const ToolbarPlugin = createPlugin<ToolbarPluginCustomTypes>(\n (editor, options) => {\n editor.toolbar = {\n height: options.toolbar?.height,\n minHeight: options.toolbar?.minHeight,\n maxHeight: options.toolbar?.maxHeight,\n showUploadButtons: options.toolbar?.showUploadButtons ?? true,\n }\n return {\n name: \"toolbar\",\n editor: {},\n renderEditable,\n editableProps: {},\n }\n }\n) as TypedPlugin<ToolbarPluginCustomTypes>\n","import { Editor, Element, Node, Path, Transforms } from \"slate\"\n\nimport { createPlugin, TypedPlugin } from \"../sink\"\n\ntype TrailingBlockPluginCustomType = {\n Name: \"trailing-block\"\n Editor: { allowTrailingBlock: true }\n}\n\nexport const TrailingBlockPlugin = createPlugin<TrailingBlockPluginCustomType>(\n (editor) => {\n editor.allowTrailingBlock = true\n return {\n name: \"trailing-block\",\n editor: {\n normalizeNode: (entry) => {\n if (!Editor.isEditor(entry[0])) return false\n const lastPath = [editor.children.length - 1]\n /**\n * We expect the last node of the Editor to be an `Element` because\n * the children of an `Editor` are `Element` objects.\n */\n const lastElement = Node.child(\n editor,\n editor.children.length - 1\n ) as Element\n /**\n * We need to add a trailing block when it is not easy for us to\n * start typing at the end of the document. This happens in these\n * conditions:\n *\n * - The last Element is a `void` block that we can't type into\n * - The last Element is an Element that contains child elements\n * like a `table` or a nested `list`.\n */\n if (\n Editor.hasBlocks(editor, lastElement) ||\n Editor.isVoid(editor, lastElement)\n ) {\n Transforms.insertNodes(\n editor,\n { type: \"paragraph\", children: [{ text: \"\" }] },\n {\n at: Path.next(lastPath),\n }\n )\n }\n return true\n },\n },\n }\n }\n) as TypedPlugin<TrailingBlockPluginCustomType>\n","import { Editor, Transforms } from \"slate\"\n\nimport { curryOne } from \"../../sink\"\n\nimport { parse, escapeUrlSlashes } from \"../../convert\"\n\nfunction pasteMarkdown(editor: Editor, markdown: string) {\n // Escape forward slashes in URLs before parsing\n const escapedMarkdown = escapeUrlSlashes(markdown);\n const fragment = parse(escapedMarkdown)\n Transforms.insertNodes(editor, fragment)\n}\n\nexport function createPasteMarkdownMethods(editor: Editor) {\n return {\n pasteMarkdown: curryOne(pasteMarkdown, editor),\n }\n}\n","import { createPlugin, stopEvent, TypedPlugin } from \"../sink\"\n\nimport { createPasteMarkdownMethods } from \"./methods\"\n\ntype PasteMarkdownMethods = ReturnType<typeof createPasteMarkdownMethods>\n\nexport type PasteMarkdownEditor = {\n pasteMarkdown: PasteMarkdownMethods\n}\n\nexport type PasteMarkdownPluginCustomTypes = {\n Name: \"paste-markdown\"\n Editor: PasteMarkdownEditor\n}\n\nexport const PasteMarkdownPlugin = createPlugin<PasteMarkdownPluginCustomTypes>(\n (editor) => {\n editor.pasteMarkdown = createPasteMarkdownMethods(editor)\n return {\n name: \"paste-markdown\",\n editor: {},\n editableProps: {\n onPaste(e) {\n const { types } = e.clipboardData\n if (types.length !== 1 || types[0] !== \"text/plain\") {\n return false\n }\n const markdown = e.clipboardData.getData(\"text/plain\")\n editor.pasteMarkdown.pasteMarkdown(markdown)\n stopEvent(e)\n return true\n },\n },\n }\n }\n) as TypedPlugin<PasteMarkdownPluginCustomTypes>\n","import { RenderPlaceholderProps } from \"slate-react\"\n\nimport { createPlugin, TypedPlugin } from \"../sink\"\n\nexport type PlaceholderEditor = {\n placeholder: Record<string, never>\n}\n\nexport type PlaceholderPluginCustomTypes = {\n Name: \"placeholder\"\n Editor: PlaceholderEditor\n}\n\n/**\n * To have the placeholder work properly, it cannot have `width: 100%` and\n * `max-width: 100%` set or it creates horizontal scrollbars.\n *\n * The default `renderPlaceholder` adds these styles so we override them.\n */\nfunction renderPlaceholder(props: RenderPlaceholderProps) {\n const nextAttributes: RenderPlaceholderProps[\"attributes\"] = {\n ...props.attributes,\n style: {\n ...props.attributes.style,\n width: undefined,\n maxWidth: undefined,\n },\n }\n return <span {...nextAttributes}>{props.children}</span>\n}\n\nexport const PlaceholderPlugin = createPlugin<PlaceholderPluginCustomTypes>(\n (editor, _options, { createPolicy }) => {\n editor.placeholder = {}\n return createPolicy({\n name: \"placeholder\",\n editableProps: {\n renderPlaceholder,\n },\n })\n }\n) as TypedPlugin<PlaceholderPluginCustomTypes>\n","import { BaseEditor, BaseText } from \"slate\"\nimport { HistoryEditor } from \"slate-history\"\nimport { ReactEditor } from \"slate-react\"\n\nimport { AnchorPlugin } from \"../anchor-plugin\"\nimport { AtomicDeletePlugin } from \"../atomic-delete-plugin\"\nimport { ImagePlugin } from \"../image-plugin\"\nimport { BlockQuotePlugin } from \"../block-quote-plugin\"\nimport { CodeBlockPlugin } from \"../code-block-plugin\"\nimport { HtmlBlockPlugin } from \"../html-block-plugin\"\nimport { CollapsibleParagraphPlugin } from \"../collapsible-paragraph-plugin\"\nimport { ConvertElementPlugin } from \"../convert-element-plugin\"\nimport { HeadingPlugin } from \"../heading-plugin\"\nimport { HorizontalRulePlugin } from \"../horizontal-rule-plugin\"\nimport { InlineCodePlugin } from \"../inline-code-plugin\"\nimport { ListPlugin } from \"../list-plugin\"\nimport { MarksPlugin } from \"../marks-plugin\"\nimport { NormalizeAfterDeletePlugin } from \"../normalize-after-delete-plugin\"\nimport { ExtractCustomTypes } from \"../sink\"\nimport { TablePlugin } from \"../table-plugin\"\nimport { ThemePlugin } from \"../theme-plugin\"\nimport { ToolbarPlugin } from \"../toolbar-plugin\"\nimport { TrailingBlockPlugin } from \"../trailing-block-plugin\"\nimport { PasteMarkdownPlugin } from \"../paste-markdown-plugin\"\nimport { PlaceholderPlugin } from \"../placeholder-plugin\"\nimport { WysimarkEditor } from \"./types\"\n\nexport const plugins = [\n PasteMarkdownPlugin,\n ConvertElementPlugin,\n AnchorPlugin,\n HeadingPlugin,\n MarksPlugin,\n InlineCodePlugin,\n BlockQuotePlugin,\n CodeBlockPlugin,\n HtmlBlockPlugin,\n TablePlugin,\n HorizontalRulePlugin,\n TrailingBlockPlugin,\n ListPlugin,\n AtomicDeletePlugin,\n NormalizeAfterDeletePlugin,\n CollapsibleParagraphPlugin,\n ThemePlugin,\n ToolbarPlugin,\n ImagePlugin,\n PlaceholderPlugin,\n]\n\nexport type PluginTypes = ExtractCustomTypes<typeof plugins>\n\ntype CustomEditor = PluginTypes[\"Editor\"]\ntype CustomElement = PluginTypes[\"Element\"]\ntype CustomText = PluginTypes[\"Text\"]\n\nexport type OptionsType = PluginTypes[\"Options\"]\nexport type Element = CustomElement\nexport type Text = CustomText\n\ndeclare module \"slate\" {\n interface CustomTypes {\n Editor: BaseEditor &\n ReactEditor &\n HistoryEditor &\n CustomEditor &\n WysimarkEditor\n Element: CustomElement\n Text: BaseText & CustomText\n }\n}\n","import { createSink } from \"../sink\"\n\nimport { plugins, PluginTypes } from \"./plugins\"\n\nconst Sink = createSink<PluginTypes>(plugins)\n\nconst { withSink, SinkEditable } = Sink\nexport { SinkEditable, withSink }\n","import { useState } from \"react\"\nimport { createEditor, Editor, Transforms } from \"slate\"\nimport { withHistory } from \"slate-history\"\nimport { ReactEditor, withReact } from \"slate-react\"\n\nimport { parse, serialize, escapeUrlSlashes } from \"../convert\"\nimport { Element } from \"./plugins\"\nimport { withSink } from \"./SinkEditable\"\nimport { WysimarkEditor } from \"./types\"\n\nexport type UseEditorOptions = {\n authToken?: string\n height?: string | number\n minHeight?: string | number\n maxHeight?: string | number\n /**\n * Disable raw Markdown editing mode.\n * When true, the raw mode toggle button will be hidden from the toolbar.\n * Defaults to true (raw mode is disabled by default).\n */\n disableRawMode?: boolean\n /**\n * Disable task list (checklist) functionality.\n * When true, the task list button will be hidden from the toolbar.\n */\n disableTaskList?: boolean\n /**\n * Disable code block functionality.\n * When true, the code block button will be hidden from the toolbar.\n */\n disableCodeBlock?: boolean\n /**\n * Disable highlight mark functionality.\n * When true, the highlight button will be hidden from the toolbar.\n * Defaults to true (highlight is disabled by default).\n */\n disableHighlight?: boolean\n}\n\nexport function useEditor({\n authToken,\n height,\n minHeight,\n maxHeight,\n disableRawMode,\n disableTaskList,\n disableCodeBlock,\n disableHighlight,\n}: UseEditorOptions = {}): Editor & ReactEditor & WysimarkEditor {\n const [editor] = useState(() => {\n const editor = createEditor()\n const nextEditor = withSink(withReact(withHistory(editor)), {\n toolbar: {\n height,\n minHeight,\n maxHeight,\n /**\n * If `authToken` is provided then show upload buttons.\n */\n showUploadButtons: !!authToken,\n },\n image: {}\n })\n nextEditor.convertElement.addConvertElementType(\"paragraph\")\n editor.wysimark = {\n // Disable raw mode (defaults to true)\n disableRawMode: disableRawMode ?? true,\n // Disable task list if specified\n disableTaskList,\n // Disable code block if specified\n disableCodeBlock,\n // Disable highlight (defaults to true)\n disableHighlight: disableHighlight ?? true,\n }\n editor.getMarkdown = () => {\n return serialize(editor.children as Element[])\n }\n editor.setMarkdown = (markdown: string) => {\n // Escape forward slashes in URLs before parsing\n const escapedMarkdown = escapeUrlSlashes(markdown);\n const documentValue = parse(escapedMarkdown)\n editor.children = documentValue\n editor.selection = null\n Transforms.select(editor, Editor.start(editor, [0]))\n }\n return nextEditor\n })\n\n return editor\n}\n"],"mappings":"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","names":["useCallback","useRef","useState","throttle","useCallback","useRef","useState","Editor","Transforms","ReactEditor","Slate","key","SlateText","SlateText","s","SlateText","SlateText","SlateText","Element","Element","SlateText","SlateText","SlateText","indent","key","plugins","plugins","plugins","key","plugins","renderElement","plugins","plugins","jsx","plugins","plugins","plugins","plugins","withSink","Element","Editor","Element","Editor","jsx","Element","Element","Editor","Editor","Editor","Editor","Editor","Editor","SlateElement","Range","Range","SlateElement","Editor","isHotkey","isHotkey","Editor","Transforms","Editor","Editor","Transforms","Editor","Element","Path","Transforms","Element","Editor","Transforms","Path","Editor","Transforms","Editor","Transforms","Editor","Transforms","Editor","Node","Transforms","Transforms","Node","Editor","Editor","Range","Text","Transforms","Transforms","Transforms","Element","Transforms","useEffect","useRef","jsx","layers","styled","styled","useCallback","useState","useSlateStatic","styled","jsx","key","useRef","useSlateStatic","key","useEffect","useState","counter","useEffect","styled","styled","styled","styled","styled","styled","styled","styled","styled","styled","styled","ReactEditor","jsx","jsxs","ReactEditor","Fragment","jsx","jsxs","useSlateStatic","useRef","dest","useCallback","styled","jsx","jsxs","styled","jsx","styled","jsx","useCallback","styled","useCallback","useRef","useState","Node","useSlateStatic","styled","useRef","useCallback","styled","jsx","e","jsx","jsxs","styled","useState","useCallback","destAnchor","destStartEdge","useSlateStatic","Node","useRef","href","text","title","jsx","jsx","jsxs","$AnchorDialog","styled","parseUrl","useSlateStatic","useState","useCallback","destAnchor","destStartEdge","removeLink","jsx","jsxs","useRef","useEffect","jsx","Editor","Transforms","Element","Path","Path","Element","Editor","Transforms","Transforms","ReactEditor","Editor","Transforms","ReactEditor","Transforms","Editor","ReactEditor","normalizeNode","useSlateStatic","styled","clsx","useState","useSelected","styled","clsx","useCallback","Transforms","ReactEditor","useSlateStatic","useEffect","useEffect","styled","ReactEditor","Fragment","jsx","jsxs","ReactEditor","useSlateStatic","useCallback","e","size","Transforms","clsx","styled","jsxs","styled","styled","clsx","useCallback","Transforms","ReactEditor","useSlateStatic","jsx","useSlateStatic","useCallback","ReactEditor","Transforms","clsx","jsx","useCallback","useSlateStatic","jsx","jsxs","jsxs","jsx","Editor","Transforms","ReactEditor","ReactEditor","Editor","Transforms","jsx","useSlateStatic","useCallback","useCallback","useSlateStatic","Editor","Text","Transforms","ReactEditor","ReactEditor","Editor","Transforms","Text","jsx","useSlateStatic","useCallback","jsx","jsxs","jsx","jsxs","jsx","jsxs","useSelected","useState","clsx","jsx","jsxs","useSlateStatic","useSlateStatic","styled","jsx","jsxs","useSlateStatic","jsx","createOnDrop","ReactEditor","Transforms","normalizeNode","Editor","Element","Transforms","styled","jsx","Element","Transforms","Editor","Editor","Element","Transforms","Element","Node","node","offset","Element","Transforms","Element","Transforms","Element","Node","Transforms","normalizeNode","useCallback","useRef","useSelected","jsx","styled","jsx","jsxs","useRef","useSelected","useCallback","useSelected","jsx","useSelected","jsx","renderElement","jsx","Editor","Transforms","normalizeNode","Element","renderElement","Transforms","styled","jsx","jsxs","jsx","Transforms","Editor","Element","Element","Transforms","Element","Transforms","Element","Transforms","Element","Transforms","normalizeNode","Element","clsx","useSelected","styled","Node","jsx","useSelected","clsx","jsx","insertBreak","Editor","normalizeNode","Editor","Element","Node","Range","Transforms","Editor","Node","Element","Transforms","isCollapsed","Range","Editor","Path","Range","Transforms","Range","Editor","Path","Transforms","Editor","Editor","styled","jsx","useSelected","styled","jsx","jsxs","useSelected","jsx","styled","jsx","jsxs","Editor","Path","MAX_DEPTH","Editor","Transforms","insertBreak","Editor","Transforms","Editor","Editor","Transforms","Transforms","insertBreak","Element","Transforms","Element","Transforms","normalizeNode","clsx","useEffect","ReactEditor","useSlateStatic","styled","styled","jsx","useSlateStatic","useEffect","ReactEditor","clsx","useCallback","useSlateStatic","jsx","jsxs","jsx","jsxs","useSlateStatic","useCallback","jsx","jsxs","jsx","renderElement","normalizeNode","Path","Editor","renderElement","clsx","Editor","Point","Range","Editor","Text","Transforms","key","Editor","Point","Range","styled","jsx","removeMarks","Range","Point","Editor","clsx","Editor","Point","Editor","Point","Element","Editor","Path","Transforms","Editor","Path","Editor","Path","range","Editor","Path","Transforms","Transforms","Editor","Transforms","t","Editor","Transforms","Transforms","t","Transforms","Editor","Element","Path","Transforms","createRow","insertRootElement","Element","Editor","Transforms","Path","Path","t","Path","ReactEditor","t","Editor","Transforms","Transforms","t","t","Editor","Transforms","rowIndex","Editor","Transforms","t","Editor","Transforms","Transforms","t","Transforms","Path","Transforms","t","Path","Transforms","t","Transforms","Transforms","Editor","Transforms","useEffect","ReactEditor","useSelected","useSlateStatic","styled","styled","styled","createContext","jsx","useSlateStatic","useSelected","useEffect","ReactEditor","useContext","useSelected","useCallback","useRef","useState","useSlateStatic","jsx","Fragment","jsx","jsxs","useSlateStatic","useRef","useState","useCallback","useState","useSlateStatic","Fragment","jsx","jsxs","useSlateStatic","useState","styled","jsx","jsx","jsxs","useContext","useSelected","jsx","jsx","jsx","renderElement","Element","renderElement","css","Fragment","jsx","jsxs","Editable","clsx","useCallback","useRef","Editor","Transforms","ReactEditor","useSlateStatic","clsx","useCallback","useRef","useState","ReactEditor","useSlateStatic","styled","styled","Fragment","jsx","jsxs","createRange","useState","useSlateStatic","useRef","dest","useCallback","createTable","ReactEditor","clsx","throttle","useEffect","useRef","useState","useSlateStatic","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","Table","jsxs","CodeBlock","jsx","jsxs","jsx","jsx","jsxs","useState","useRef","useEffect","useCallback","useSlateStatic","styled","styled","Fragment","jsx","jsxs","useSlateStatic","useRef","useState","useCallback","useEffect","dest","isHotkey","useCallback","useMemo","useRef","useState","Editor","Range","ReactEditor","useSlateStatic","styled","Fragment","jsx","jsxs","isHotkey","AnchorDialog","useSlateStatic","useRef","useState","useCallback","dest","useMemo","Range","Editor","insertLink","ReactEditor","AnchorDialog","Table","Editor","Editor","Editor","Transforms","CodeBlock","Editor","Transforms","clsx","useCallback","useRef","ReactEditor","useSlate","useSlateStatic","jsx","jsxs","useSlateStatic","useSlate","useRef","useCallback","ReactEditor","clsx","jsx","useSlateStatic","useRef","useState","useEffect","throttle","jsx","jsxs","Editable","useRef","useSlateStatic","useCallback","Transforms","Editor","ReactEditor","clsx","Editor","Node","Path","Transforms","Editor","Node","Transforms","Path","Transforms","Transforms","jsx","SinkEditable","useState","Editor","Transforms","useState","editor","Transforms","Editor","jsx","jsxs","jsx","Editable","useState","useRef","useCallback","throttle","Transforms","Editor","ReactEditor","jsxs","Slate","SinkEditable","jsx","useState","useRef","markdown","useCallback","jsx","Editable"]}
|