@liveblocks/react-ui
Version:
A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.
1 lines • 5.93 kB
Source Map (JSON)
{"version":3,"file":"auto-formatting.cjs","sources":["../../../src/slate/plugins/auto-formatting.ts"],"sourcesContent":["import type { EditorMarks } from \"slate\";\nimport {\n Editor as SlateEditor,\n Range as SlateRange,\n Transforms as SlateTransforms,\n} from \"slate\";\n\nimport { getCharacterBefore } from \"../utils/get-character\";\nimport { getMatchRange } from \"../utils/get-match-range\";\nimport { isEmptyString } from \"../utils/is-empty-string\";\n\ninterface MarkFormatter {\n type: \"mark\";\n mark: keyof EditorMarks;\n character: string;\n}\n\ntype Formatter = MarkFormatter;\n\nconst formatters: Formatter[] = [\n {\n type: \"mark\",\n mark: \"bold\",\n character: \"*\",\n },\n {\n type: \"mark\",\n mark: \"italic\",\n character: \"_\",\n },\n {\n type: \"mark\",\n mark: \"strikethrough\",\n character: \"~\",\n },\n {\n type: \"mark\",\n mark: \"code\",\n character: \"`\",\n },\n];\nconst markFormattingCharacters = formatters\n .filter((formatter) => formatter.type === \"mark\")\n .map((formatter) => formatter.character);\n\nfunction formatMark<T extends SlateEditor>(\n editor: T,\n text: string,\n formatter: MarkFormatter\n): boolean {\n if (text !== formatter.character) {\n return false;\n }\n\n const match = getMatchRange(editor, editor.selection!, [formatter.character]);\n\n // Check if the match exists and is not empty\n if (!match || SlateRange.isCollapsed(match)) {\n return false;\n }\n\n const formattingCharacter = getCharacterBefore(editor, match);\n\n // Check if the match is preceded by the formatting character\n if (\n !formattingCharacter ||\n formattingCharacter.text !== formatter.character\n ) {\n return false;\n }\n\n const beforeCharacter = getCharacterBefore(editor, formattingCharacter.range);\n\n // Check if the formatting character is preceded by a non-whitespace character (or another formatting character)\n if (\n beforeCharacter &&\n !markFormattingCharacters.includes(beforeCharacter.text) &&\n !isEmptyString(beforeCharacter.text)\n ) {\n return false;\n }\n\n const matchText = SlateEditor.string(editor, match);\n\n // Check if the match has leading/trailing whitespace\n if (matchText.trim() !== matchText) {\n return false;\n }\n\n // Set the match to the expected mark\n SlateTransforms.select(editor, match);\n editor.addMark(formatter.mark, true);\n\n // Set the selection at the end of the match and reset formatting\n SlateTransforms.collapse(editor, { edge: \"end\" });\n editor.removeMark(formatter.mark);\n\n // Delete the formatting character\n SlateTransforms.delete(editor, {\n at: formattingCharacter.range,\n });\n\n return true;\n}\n\nexport function withAutoFormatting<T extends SlateEditor>(editor: T): T {\n const { insertText } = editor;\n\n editor.insertText = (text, options) => {\n if (!editor.selection || !SlateRange.isCollapsed(editor.selection)) {\n return insertText(text, options);\n }\n\n let shouldInsertText = true;\n\n for (const formatter of formatters) {\n if (formatter.type === \"mark\") {\n if (formatMark(editor, text, formatter)) {\n shouldInsertText = false;\n }\n }\n }\n\n if (shouldInsertText) {\n insertText(text, options);\n }\n };\n\n return editor;\n}\n"],"names":["getMatchRange","SlateRange","getCharacterBefore","isEmptyString","SlateEditor","SlateTransforms"],"mappings":"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"}