@doist/typist 1.0.0

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.
Files changed (147) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/CODE_OF_CONDUCT.md +83 -0
  3. package/CONTRIBUTING.md +123 -0
  4. package/LICENSE +21 -0
  5. package/README.md +74 -0
  6. package/dist/components/typist-editor.d.ts +173 -0
  7. package/dist/components/typist-editor.d.ts.map +1 -0
  8. package/dist/components/typist-editor.helper.d.ts +22 -0
  9. package/dist/components/typist-editor.helper.d.ts.map +1 -0
  10. package/dist/components/typist-editor.helper.js +26 -0
  11. package/dist/components/typist-editor.js +160 -0
  12. package/dist/constants/common.d.ts +10 -0
  13. package/dist/constants/common.d.ts.map +1 -0
  14. package/dist/constants/common.js +9 -0
  15. package/dist/constants/extension-priorities.d.ts +26 -0
  16. package/dist/constants/extension-priorities.d.ts.map +1 -0
  17. package/dist/constants/extension-priorities.js +25 -0
  18. package/dist/constants/regular-expressions.d.ts +6 -0
  19. package/dist/constants/regular-expressions.d.ts.map +1 -0
  20. package/dist/constants/regular-expressions.js +5 -0
  21. package/dist/extensions/core/extra-editor-commands/commands/extend-word-range.d.ts +24 -0
  22. package/dist/extensions/core/extra-editor-commands/commands/extend-word-range.d.ts.map +1 -0
  23. package/dist/extensions/core/extra-editor-commands/commands/extend-word-range.js +32 -0
  24. package/dist/extensions/core/extra-editor-commands/commands/insert-markdown-content.d.ts +28 -0
  25. package/dist/extensions/core/extra-editor-commands/commands/insert-markdown-content.d.ts.map +1 -0
  26. package/dist/extensions/core/extra-editor-commands/commands/insert-markdown-content.js +25 -0
  27. package/dist/extensions/core/extra-editor-commands/extra-editor-commands.d.ts +9 -0
  28. package/dist/extensions/core/extra-editor-commands/extra-editor-commands.d.ts.map +1 -0
  29. package/dist/extensions/core/extra-editor-commands/extra-editor-commands.js +18 -0
  30. package/dist/extensions/core/view-event-handlers.d.ts +33 -0
  31. package/dist/extensions/core/view-event-handlers.d.ts.map +1 -0
  32. package/dist/extensions/core/view-event-handlers.js +35 -0
  33. package/dist/extensions/plain-text/paste-multiline-text.d.ts +10 -0
  34. package/dist/extensions/plain-text/paste-multiline-text.d.ts.map +1 -0
  35. package/dist/extensions/plain-text/paste-multiline-text.js +66 -0
  36. package/dist/extensions/plain-text/plain-text-document.d.ts +17 -0
  37. package/dist/extensions/plain-text/plain-text-document.d.ts.map +1 -0
  38. package/dist/extensions/plain-text/plain-text-document.js +17 -0
  39. package/dist/extensions/plain-text/plain-text-kit.d.ts +42 -0
  40. package/dist/extensions/plain-text/plain-text-kit.d.ts.map +1 -0
  41. package/dist/extensions/plain-text/plain-text-kit.js +47 -0
  42. package/dist/extensions/plain-text/plain-text-paragraph.d.ts +9 -0
  43. package/dist/extensions/plain-text/plain-text-paragraph.d.ts.map +1 -0
  44. package/dist/extensions/plain-text/plain-text-paragraph.js +13 -0
  45. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-lists.d.ts +9 -0
  46. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-lists.d.ts.map +1 -0
  47. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-lists.js +89 -0
  48. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-select-wrap.d.ts +9 -0
  49. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-select-wrap.d.ts.map +1 -0
  50. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-select-wrap.js +49 -0
  51. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-url-pasting.d.ts +9 -0
  52. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-url-pasting.d.ts.map +1 -0
  53. package/dist/extensions/plain-text/smart-markdown-typing/plugins/smart-url-pasting.js +43 -0
  54. package/dist/extensions/plain-text/smart-markdown-typing/smart-markdown-typing.d.ts +8 -0
  55. package/dist/extensions/plain-text/smart-markdown-typing/smart-markdown-typing.d.ts.map +1 -0
  56. package/dist/extensions/plain-text/smart-markdown-typing/smart-markdown-typing.js +17 -0
  57. package/dist/extensions/rich-text/bold-and-italics.d.ts +8 -0
  58. package/dist/extensions/rich-text/bold-and-italics.d.ts.map +1 -0
  59. package/dist/extensions/rich-text/bold-and-italics.js +40 -0
  60. package/dist/extensions/rich-text/curvenote-codemark.d.ts +11 -0
  61. package/dist/extensions/rich-text/curvenote-codemark.d.ts.map +1 -0
  62. package/dist/extensions/rich-text/curvenote-codemark.js +18 -0
  63. package/dist/extensions/rich-text/paste-emojis.d.ts +9 -0
  64. package/dist/extensions/rich-text/paste-emojis.d.ts.map +1 -0
  65. package/dist/extensions/rich-text/paste-emojis.js +28 -0
  66. package/dist/extensions/rich-text/paste-markdown.d.ts +11 -0
  67. package/dist/extensions/rich-text/paste-markdown.d.ts.map +1 -0
  68. package/dist/extensions/rich-text/paste-markdown.js +68 -0
  69. package/dist/extensions/rich-text/rich-text-document.d.ts +17 -0
  70. package/dist/extensions/rich-text/rich-text-document.d.ts.map +1 -0
  71. package/dist/extensions/rich-text/rich-text-document.js +17 -0
  72. package/dist/extensions/rich-text/rich-text-image.d.ts +80 -0
  73. package/dist/extensions/rich-text/rich-text-image.d.ts.map +1 -0
  74. package/dist/extensions/rich-text/rich-text-image.js +109 -0
  75. package/dist/extensions/rich-text/rich-text-kit.d.ts +129 -0
  76. package/dist/extensions/rich-text/rich-text-kit.d.ts.map +1 -0
  77. package/dist/extensions/rich-text/rich-text-kit.js +130 -0
  78. package/dist/extensions/rich-text/rich-text-link.d.ts +10 -0
  79. package/dist/extensions/rich-text/rich-text-link.d.ts.map +1 -0
  80. package/dist/extensions/rich-text/rich-text-link.js +102 -0
  81. package/dist/extensions/shared/copy-markdown-source.d.ts +20 -0
  82. package/dist/extensions/shared/copy-markdown-source.d.ts.map +1 -0
  83. package/dist/extensions/shared/copy-markdown-source.js +35 -0
  84. package/dist/extensions/shared/paste-singleline-text.d.ts +10 -0
  85. package/dist/extensions/shared/paste-singleline-text.d.ts.map +1 -0
  86. package/dist/extensions/shared/paste-singleline-text.js +43 -0
  87. package/dist/factories/create-suggestion-extension.d.ts +121 -0
  88. package/dist/factories/create-suggestion-extension.d.ts.map +1 -0
  89. package/dist/factories/create-suggestion-extension.js +149 -0
  90. package/dist/helpers/dom.d.ts +8 -0
  91. package/dist/helpers/dom.d.ts.map +1 -0
  92. package/dist/helpers/dom.js +9 -0
  93. package/dist/helpers/schema.d.ts +19 -0
  94. package/dist/helpers/schema.d.ts.map +1 -0
  95. package/dist/helpers/schema.js +21 -0
  96. package/dist/helpers/serializer.d.ts +11 -0
  97. package/dist/helpers/serializer.d.ts.map +1 -0
  98. package/dist/helpers/serializer.js +16 -0
  99. package/dist/hooks/use-editor.d.ts +19 -0
  100. package/dist/hooks/use-editor.d.ts.map +1 -0
  101. package/dist/hooks/use-editor.js +46 -0
  102. package/dist/index.d.ts +26 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +17 -0
  105. package/dist/serializers/html/extensions/checkbox.d.ts +8 -0
  106. package/dist/serializers/html/extensions/checkbox.d.ts.map +1 -0
  107. package/dist/serializers/html/extensions/checkbox.js +12 -0
  108. package/dist/serializers/html/extensions/code.d.ts +9 -0
  109. package/dist/serializers/html/extensions/code.d.ts.map +1 -0
  110. package/dist/serializers/html/extensions/code.js +20 -0
  111. package/dist/serializers/html/extensions/html.d.ts +10 -0
  112. package/dist/serializers/html/extensions/html.d.ts.map +1 -0
  113. package/dist/serializers/html/extensions/html.js +15 -0
  114. package/dist/serializers/html/extensions/link.d.ts +11 -0
  115. package/dist/serializers/html/extensions/link.d.ts.map +1 -0
  116. package/dist/serializers/html/extensions/link.js +28 -0
  117. package/dist/serializers/html/extensions/paragraph.d.ts +12 -0
  118. package/dist/serializers/html/extensions/paragraph.d.ts.map +1 -0
  119. package/dist/serializers/html/extensions/paragraph.js +51 -0
  120. package/dist/serializers/html/extensions/task-list.d.ts +9 -0
  121. package/dist/serializers/html/extensions/task-list.d.ts.map +1 -0
  122. package/dist/serializers/html/extensions/task-list.js +31 -0
  123. package/dist/serializers/html/html.d.ts +27 -0
  124. package/dist/serializers/html/html.d.ts.map +1 -0
  125. package/dist/serializers/html/html.js +129 -0
  126. package/dist/serializers/markdown/markdown.d.ts +40 -0
  127. package/dist/serializers/markdown/markdown.d.ts.map +1 -0
  128. package/dist/serializers/markdown/markdown.js +126 -0
  129. package/dist/serializers/markdown/plugins/image.d.ts +12 -0
  130. package/dist/serializers/markdown/plugins/image.d.ts.map +1 -0
  131. package/dist/serializers/markdown/plugins/image.js +31 -0
  132. package/dist/serializers/markdown/plugins/list-item.d.ts +14 -0
  133. package/dist/serializers/markdown/plugins/list-item.d.ts.map +1 -0
  134. package/dist/serializers/markdown/plugins/list-item.js +41 -0
  135. package/dist/serializers/markdown/plugins/paragraph.d.ts +12 -0
  136. package/dist/serializers/markdown/plugins/paragraph.d.ts.map +1 -0
  137. package/dist/serializers/markdown/plugins/paragraph.js +18 -0
  138. package/dist/serializers/markdown/plugins/strikethrough.d.ts +13 -0
  139. package/dist/serializers/markdown/plugins/strikethrough.d.ts.map +1 -0
  140. package/dist/serializers/markdown/plugins/strikethrough.js +23 -0
  141. package/dist/serializers/markdown/plugins/suggestion.d.ts +11 -0
  142. package/dist/serializers/markdown/plugins/suggestion.d.ts.map +1 -0
  143. package/dist/serializers/markdown/plugins/suggestion.js +21 -0
  144. package/dist/serializers/markdown/plugins/task-item.d.ts +14 -0
  145. package/dist/serializers/markdown/plugins/task-item.d.ts.map +1 -0
  146. package/dist/serializers/markdown/plugins/task-item.js +39 -0
  147. package/package.json +146 -0
@@ -0,0 +1,160 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useImperativeHandle, useMemo } from 'react';
3
+ import { useEvent } from 'react-use-event-hook';
4
+ import { getSchema } from '@tiptap/core';
5
+ import { Placeholder } from '@tiptap/extension-placeholder';
6
+ import { EditorContent } from '@tiptap/react';
7
+ import { ExtraEditorCommands } from '../extensions/core/extra-editor-commands/extra-editor-commands';
8
+ import { ViewEventHandlers } from '../extensions/core/view-event-handlers';
9
+ import { isMultilineDocument, isPlainTextDocument } from '../helpers/schema';
10
+ import { useEditor } from '../hooks/use-editor';
11
+ import { createHTMLSerializer } from '../serializers/html/html';
12
+ import { createMarkdownSerializer } from '../serializers/markdown/markdown';
13
+ import { getAllNodesAttributesByType, resolveContentSelection } from './typist-editor.helper';
14
+ /**
15
+ * The `TypistEditor` component represents a plain-text or a rich-text editing control, built on
16
+ * top of the amazing [Tiptap](https://tiptap.dev/) library.
17
+ */
18
+ const TypistEditor = forwardRef(function TypistEditor({ autoFocus, className, content = '', contentSelection, editable = true, extensions, placeholder, onBeforeCreate, onCreate, onUpdate, onSelectionUpdate, onTransaction, onFocus, onBlur, onDestroy, 'aria-describedby': ariaDescribedBy, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, onClick, onKeyDown, }, ref) {
19
+ const allExtensions = useMemo(function initializeExtensions() {
20
+ return [
21
+ // Custom core extensions
22
+ ...(placeholder
23
+ ? [
24
+ Placeholder.configure({
25
+ placeholder,
26
+ }),
27
+ ]
28
+ : []),
29
+ ExtraEditorCommands,
30
+ ViewEventHandlers.configure({
31
+ onClick,
32
+ onKeyDown,
33
+ }),
34
+ // Always register external extensions at the end so they get a higher priority and
35
+ // are loaded earlier (necessary to override behaviors from built-in extensions)
36
+ ...extensions,
37
+ ];
38
+ }, [extensions, onClick, onKeyDown, placeholder]);
39
+ const schema = useMemo(function generateProseMirrorSchema() {
40
+ return getSchema(allExtensions);
41
+ }, [allExtensions]);
42
+ const htmlSerializer = useMemo(function initializeHTMLSerializer() {
43
+ return createHTMLSerializer(schema);
44
+ }, [schema]);
45
+ const markdownSerializer = useMemo(function initializeMarkdownSerializer() {
46
+ return createMarkdownSerializer(schema);
47
+ }, [schema]);
48
+ const htmlContent = useMemo(function generateHTMLContent() {
49
+ return htmlSerializer.serialize(content);
50
+ }, [content, htmlSerializer]);
51
+ const ariaAttributes = useMemo(function initializeAriaAttributes() {
52
+ return {
53
+ 'aria-readonly': String(!editable),
54
+ 'aria-multiline': String(isMultilineDocument(schema)),
55
+ ...(ariaDescribedBy ? { 'aria-describedby': ariaDescribedBy } : {}),
56
+ ...(ariaLabel ? { 'aria-label': ariaLabel } : {}),
57
+ ...(ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),
58
+ };
59
+ }, [ariaDescribedBy, ariaLabel, ariaLabelledBy, editable, schema]);
60
+ const handleCreate = useEvent(function handleCreate(props) {
61
+ const { view } = props.editor;
62
+ // Apply a selection to the document if one was given and `autoFocus` is `true`
63
+ if (autoFocus && contentSelection) {
64
+ view.dispatch(view.state.tr
65
+ .setSelection(resolveContentSelection(view.state.doc, contentSelection))
66
+ .scrollIntoView());
67
+ }
68
+ // Move the suggestion plugins to the top of the plugins list so they have a higher priority
69
+ // than all input rules (such as the ones used for Markdown shortcuts)
70
+ // ref: https://github.com/ueberdosis/tiptap/issues/2570
71
+ if (view.state.plugins.length > 0) {
72
+ const restOfPlugins = [];
73
+ const suggestionPlugins = [];
74
+ view.state.plugins.forEach((plugin) => {
75
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
76
+ // @ts-ignore: The `Plugin` type does not include `key`
77
+ if (plugin.key.includes('Suggestion')) {
78
+ suggestionPlugins.push(plugin);
79
+ }
80
+ else {
81
+ restOfPlugins.push(plugin);
82
+ }
83
+ });
84
+ view.updateState(view.state.reconfigure({
85
+ plugins: [...suggestionPlugins, ...restOfPlugins],
86
+ }));
87
+ }
88
+ // Invoke the user `onCreate` handle after all internal initializations
89
+ onCreate?.(props);
90
+ });
91
+ const editor = useEditor({
92
+ autofocus: autoFocus ? 'end' : false,
93
+ content: htmlContent,
94
+ editable,
95
+ editorProps: {
96
+ attributes: {
97
+ 'data-typist-editor': 'true',
98
+ ...(isPlainTextDocument(schema)
99
+ ? { 'data-plain-text': 'true' }
100
+ : { 'data-rich-text': 'true' }),
101
+ role: 'textbox',
102
+ ...ariaAttributes,
103
+ },
104
+ },
105
+ extensions: allExtensions,
106
+ parseOptions: {
107
+ preserveWhitespace: isPlainTextDocument(schema),
108
+ },
109
+ ...(onBeforeCreate ? { onBeforeCreate } : {}),
110
+ onCreate: handleCreate,
111
+ ...(onUpdate
112
+ ? {
113
+ onUpdate(props) {
114
+ onUpdate({
115
+ ...props,
116
+ getMarkdown() {
117
+ return markdownSerializer.serialize(props.editor.getHTML());
118
+ },
119
+ });
120
+ },
121
+ }
122
+ : {}),
123
+ ...(onSelectionUpdate ? { onSelectionUpdate } : {}),
124
+ ...(onTransaction ? { onTransaction } : {}),
125
+ ...(onFocus ? { onFocus } : {}),
126
+ ...(onBlur ? { onBlur } : {}),
127
+ ...(onDestroy ? { onDestroy } : {}),
128
+ }, [
129
+ allExtensions,
130
+ ariaAttributes,
131
+ autoFocus,
132
+ editable,
133
+ handleCreate,
134
+ htmlContent,
135
+ markdownSerializer,
136
+ onBeforeCreate,
137
+ onBlur,
138
+ onDestroy,
139
+ onFocus,
140
+ onSelectionUpdate,
141
+ onTransaction,
142
+ onUpdate,
143
+ schema,
144
+ ]);
145
+ useImperativeHandle(ref, function exposeHelperFunctionsToParent() {
146
+ return {
147
+ getEditor() {
148
+ return editor;
149
+ },
150
+ getMarkdown() {
151
+ return markdownSerializer.serialize(editor.getHTML());
152
+ },
153
+ getAllNodesAttributesByType(nodeType) {
154
+ return getAllNodesAttributesByType(editor.state.doc, nodeType);
155
+ },
156
+ };
157
+ }, [editor, markdownSerializer]);
158
+ return _jsx(EditorContent, { className: className, editor: editor });
159
+ });
160
+ export { TypistEditor };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * An enum-like constant for clipboard `DataTransfer.types` that are supported by the editor.
3
+ */
4
+ declare const ClipboardDataType: {
5
+ readonly Text: "text/plain";
6
+ readonly HTML: "text/html";
7
+ readonly VSCode: "vscode-editor-data";
8
+ };
9
+ export { ClipboardDataType };
10
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/constants/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,QAAA,MAAM,iBAAiB;;;;CAIb,CAAA;AAEV,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * An enum-like constant for clipboard `DataTransfer.types` that are supported by the editor.
3
+ */
4
+ const ClipboardDataType = {
5
+ Text: 'text/plain',
6
+ HTML: 'text/html',
7
+ VSCode: 'vscode-editor-data',
8
+ };
9
+ export { ClipboardDataType };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Priority for the extensions created by the suggestion extension factory function. This needs to
3
+ * be higher than most extensions, so that event handlers from the dropdown render function can take
4
+ * precedence over all other event handlers in the chain.
5
+ */
6
+ declare const SUGGESTION_EXTENSION_PRIORITY = 1000;
7
+ /**
8
+ * Priority for the `SmartMarkdownTyping` extension. This needs to be higher than the
9
+ * `ViewEventHandlers` extension, so that event handlers from the ProseMirror plugins built into the
10
+ * extension can take precedence over the `ViewEventHandlers` extension event handlers.
11
+ */
12
+ declare const SMART_MARKDOWN_TYPING_PRIORITY = 110;
13
+ /**
14
+ * Priority for the `ViewEventHandlers` extension. This needs to be higher than the default for most
15
+ * of the built-in and official extensions (i.e. `100`), so that the event handlers from the
16
+ * extension can take precedence over the built-in and official extensions event handlers.
17
+ */
18
+ declare const VIEW_EVENT_HANDLERS_PRIORITY = 105;
19
+ /**
20
+ * Priority for the official `Blockquote` extension. This needs to be higher than the default for
21
+ * most built-in and official extensions (i.e. `100`), so that the keyboard shortcut can take
22
+ * precedence over the `Bold` extension keyboard shortcut.
23
+ */
24
+ declare const BLOCKQUOTE_EXTENSION_PRIORITY = 101;
25
+ export { BLOCKQUOTE_EXTENSION_PRIORITY, SMART_MARKDOWN_TYPING_PRIORITY, SUGGESTION_EXTENSION_PRIORITY, VIEW_EVENT_HANDLERS_PRIORITY, };
26
+ //# sourceMappingURL=extension-priorities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-priorities.d.ts","sourceRoot":"","sources":["../../src/constants/extension-priorities.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,QAAA,MAAM,6BAA6B,OAAO,CAAA;AAE1C;;;;GAIG;AACH,QAAA,MAAM,8BAA8B,MAAM,CAAA;AAE1C;;;;GAIG;AACH,QAAA,MAAM,4BAA4B,MAAM,CAAA;AAExC;;;;GAIG;AACH,QAAA,MAAM,6BAA6B,MAAM,CAAA;AAEzC,OAAO,EACH,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,4BAA4B,GAC/B,CAAA"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Priority for the extensions created by the suggestion extension factory function. This needs to
3
+ * be higher than most extensions, so that event handlers from the dropdown render function can take
4
+ * precedence over all other event handlers in the chain.
5
+ */
6
+ const SUGGESTION_EXTENSION_PRIORITY = 1000;
7
+ /**
8
+ * Priority for the `SmartMarkdownTyping` extension. This needs to be higher than the
9
+ * `ViewEventHandlers` extension, so that event handlers from the ProseMirror plugins built into the
10
+ * extension can take precedence over the `ViewEventHandlers` extension event handlers.
11
+ */
12
+ const SMART_MARKDOWN_TYPING_PRIORITY = 110;
13
+ /**
14
+ * Priority for the `ViewEventHandlers` extension. This needs to be higher than the default for most
15
+ * of the built-in and official extensions (i.e. `100`), so that the event handlers from the
16
+ * extension can take precedence over the built-in and official extensions event handlers.
17
+ */
18
+ const VIEW_EVENT_HANDLERS_PRIORITY = 105;
19
+ /**
20
+ * Priority for the official `Blockquote` extension. This needs to be higher than the default for
21
+ * most built-in and official extensions (i.e. `100`), so that the keyboard shortcut can take
22
+ * precedence over the `Bold` extension keyboard shortcut.
23
+ */
24
+ const BLOCKQUOTE_EXTENSION_PRIORITY = 101;
25
+ export { BLOCKQUOTE_EXTENSION_PRIORITY, SMART_MARKDOWN_TYPING_PRIORITY, SUGGESTION_EXTENSION_PRIORITY, VIEW_EVENT_HANDLERS_PRIORITY, };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * A common regex for all line termination conventions.
3
+ */
4
+ declare const REGEX_LINE_BREAKS: RegExp;
5
+ export { REGEX_LINE_BREAKS };
6
+ //# sourceMappingURL=regular-expressions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regular-expressions.d.ts","sourceRoot":"","sources":["../../src/constants/regular-expressions.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,QAAA,MAAM,iBAAiB,QAAoB,CAAA;AAE3C,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * A common regex for all line termination conventions.
3
+ */
4
+ const REGEX_LINE_BREAKS = /(?:\r\n|\r|\n)/g;
5
+ export { REGEX_LINE_BREAKS };
@@ -0,0 +1,24 @@
1
+ import { RawCommands } from '@tiptap/core';
2
+ /**
3
+ * Augment the official `@tiptap/core` module with extra commands so that the compiler knows about
4
+ * them. For this to work externally, a wildcard export needs to be added to the root `index.ts`.
5
+ */
6
+ declare module '@tiptap/core' {
7
+ interface Commands<ReturnType> {
8
+ extendWordRange: {
9
+ /**
10
+ * Extends the text selection to the current word.
11
+ */
12
+ extendWordRange: () => ReturnType;
13
+ };
14
+ }
15
+ }
16
+ /**
17
+ * Extends the text selection to the current word.
18
+ *
19
+ * The solution for this function was inspired by the official `extendMarkRange` and
20
+ * `setTextSelection` commands.
21
+ */
22
+ declare function extendWordRange(): ReturnType<RawCommands['extendWordRange']>;
23
+ export { extendWordRange };
24
+ //# sourceMappingURL=extend-word-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend-word-range.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/core/extra-editor-commands/commands/extend-word-range.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,WAAW,EAAE,MAAM,cAAc,CAAA;AAIrE;;;GAGG;AACH,OAAO,QAAQ,cAAc,CAAC;IAC1B,UAAU,QAAQ,CAAC,UAAU;QACzB,eAAe,EAAE;YACb;;eAEG;YACH,eAAe,EAAE,MAAM,UAAU,CAAA;SACpC,CAAA;KACJ;CACJ;AAED;;;;;GAKG;AACH,iBAAS,eAAe,IAAI,UAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAkCrE;AAED,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { isActive, isTextSelection } from '@tiptap/core';
2
+ import { clamp } from 'lodash-es';
3
+ import { TextSelection } from 'prosemirror-state';
4
+ /**
5
+ * Extends the text selection to the current word.
6
+ *
7
+ * The solution for this function was inspired by the official `extendMarkRange` and
8
+ * `setTextSelection` commands.
9
+ */
10
+ function extendWordRange() {
11
+ return ({ state, tr, dispatch }) => {
12
+ const { doc, selection } = tr;
13
+ const { $head } = selection;
14
+ // Do nothing if cursor position is not valid for a text selection
15
+ if (!isTextSelection(selection) ||
16
+ isActive(state, 'code') ||
17
+ isActive(state, 'codeBlock')) {
18
+ return false;
19
+ }
20
+ // Check if the transaction should be dispatched
21
+ // ref: https://tiptap.dev/api/commands#dry-run-for-commands
22
+ if (dispatch) {
23
+ const textBefore = $head.nodeBefore?.text?.match(/[^\s]+$/)?.[0] || '';
24
+ const textAfter = $head.nodeAfter?.text?.match(/^[^\s]+/)?.[0] || '';
25
+ const minPos = TextSelection.atStart(doc).from;
26
+ const maxPos = TextSelection.atEnd(doc).to;
27
+ tr.setSelection(TextSelection.create(doc, clamp(selection.head - textBefore.length, minPos, maxPos), clamp(selection.head + textAfter.length, minPos, maxPos)));
28
+ }
29
+ return true;
30
+ };
31
+ }
32
+ export { extendWordRange };
@@ -0,0 +1,28 @@
1
+ import { RawCommands } from '@tiptap/core';
2
+ import type { ParseOptions } from 'prosemirror-model';
3
+ /**
4
+ * Augment the official `@tiptap/core` module with extra commands so that the compiler knows about
5
+ * them. For this to work externally, a wildcard export needs to be added to the root `index.ts`.
6
+ */
7
+ declare module '@tiptap/core' {
8
+ interface Commands<ReturnType> {
9
+ insertMarkdownContent: {
10
+ /**
11
+ * Inserts the provided Markdown as HTML into the editor.
12
+ *
13
+ * @param markdown The Markdown to parse and insert as HTML.
14
+ * @param parseOptions The parse options for ProseMirror's DOMParser.
15
+ */
16
+ insertMarkdownContent: (markdown: string, parseOptions?: ParseOptions) => ReturnType;
17
+ };
18
+ }
19
+ }
20
+ /**
21
+ * Inserts the provided Markdown as HTML into the editor.
22
+ *
23
+ * The solution for this function was inspired how ProseMirror pastes content from the clipboard,
24
+ * and how Tiptap inserts content with the `insertContentAt` command.
25
+ */
26
+ declare function insertMarkdownContent(markdown: string, parseOptions?: ParseOptions): ReturnType<RawCommands['insertMarkdownContent']>;
27
+ export { insertMarkdownContent };
28
+ //# sourceMappingURL=insert-markdown-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insert-markdown-content.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/core/extra-editor-commands/commands/insert-markdown-content.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAO1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD;;;GAGG;AACH,OAAO,QAAQ,cAAc,CAAC;IAC1B,UAAU,QAAQ,CAAC,UAAU;QACzB,qBAAqB,EAAE;YACnB;;;;;eAKG;YACH,qBAAqB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,KAAK,UAAU,CAAA;SACvF,CAAA;KACJ;CACJ;AAED;;;;;GAKG;AACH,iBAAS,qBAAqB,CAC1B,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,YAAY,GAC5B,UAAU,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC,CAoBlD;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAA"}
@@ -0,0 +1,25 @@
1
+ import { DOMParser } from 'prosemirror-model';
2
+ import { parseHtmlToElement } from '../../../../helpers/dom';
3
+ import { isPlainTextDocument } from '../../../../helpers/schema';
4
+ import { createHTMLSerializer } from '../../../../serializers/html/html';
5
+ /**
6
+ * Inserts the provided Markdown as HTML into the editor.
7
+ *
8
+ * The solution for this function was inspired how ProseMirror pastes content from the clipboard,
9
+ * and how Tiptap inserts content with the `insertContentAt` command.
10
+ */
11
+ function insertMarkdownContent(markdown, parseOptions) {
12
+ return ({ dispatch, editor, tr }) => {
13
+ // Check if the transaction should be dispatched
14
+ // ref: https://tiptap.dev/api/commands#dry-run-for-commands
15
+ if (dispatch) {
16
+ const htmlContent = !isPlainTextDocument(editor.schema)
17
+ ? createHTMLSerializer(editor.schema).serialize(markdown)
18
+ : markdown;
19
+ // Inserts the HTML content into the editor while preserving the current selection
20
+ tr.replaceSelection(DOMParser.fromSchema(editor.schema).parseSlice(parseHtmlToElement(htmlContent), parseOptions));
21
+ }
22
+ return true;
23
+ };
24
+ }
25
+ export { insertMarkdownContent };
@@ -0,0 +1,9 @@
1
+ import { Extension } from '@tiptap/core';
2
+ /**
3
+ * The `ExtraEditorCommands` extension is a collection of editor commands that provide additional
4
+ * helper commands not available with the built-in commands. This extension was built similarly to
5
+ * the official `Commands` extension.
6
+ */
7
+ declare const ExtraEditorCommands: Extension<any, any>;
8
+ export { ExtraEditorCommands };
9
+ //# sourceMappingURL=extra-editor-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extra-editor-commands.d.ts","sourceRoot":"","sources":["../../../../src/extensions/core/extra-editor-commands/extra-editor-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAKxC;;;;GAIG;AACH,QAAA,MAAM,mBAAmB,qBAQvB,CAAA;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { extendWordRange } from './commands/extend-word-range';
3
+ import { insertMarkdownContent } from './commands/insert-markdown-content';
4
+ /**
5
+ * The `ExtraEditorCommands` extension is a collection of editor commands that provide additional
6
+ * helper commands not available with the built-in commands. This extension was built similarly to
7
+ * the official `Commands` extension.
8
+ */
9
+ const ExtraEditorCommands = Extension.create({
10
+ name: 'extraEditorCommands',
11
+ addCommands() {
12
+ return {
13
+ extendWordRange,
14
+ insertMarkdownContent,
15
+ };
16
+ },
17
+ });
18
+ export { ExtraEditorCommands };
@@ -0,0 +1,33 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import type { EditorView } from 'prosemirror-view';
3
+ /**
4
+ * The options available to customize the `ViewEventHandlers` extension.
5
+ *
6
+ * If more view handlers are needed, please look into the available event handlers in
7
+ * [`prosemirror-view`](https://prosemirror.net/docs/ref/#view.Props), and add them below.
8
+ */
9
+ declare type ViewEventHandlersOptions = {
10
+ /**
11
+ * Called when the editor is clicked, after `handleClickOn` handlers have been called.
12
+ */
13
+ onClick?: (event: MouseEvent, view: EditorView, pos: number) => boolean | void;
14
+ /**
15
+ * Called when the editor receives a `keydown` event.
16
+ */
17
+ onKeyDown?: (event: KeyboardEvent, view: EditorView) => boolean | void;
18
+ };
19
+ /**
20
+ * The `ViewEventHandlers` extension allows handling of various ProseMirror view events.
21
+ *
22
+ * The various event-handling functions may all return `true` to indicate that they handled the
23
+ * given event. The view will then take care to call `preventDefault` on the event, except with
24
+ * `handleDOMEvents`, where the handler itself is responsible for that. Return `false` or
25
+ * `undefined` for the default event handler to be called.
26
+ *
27
+ * These event handlers should be used sparingly, please consider if a reusable extension would be
28
+ * more appropriate for your use case.
29
+ */
30
+ declare const ViewEventHandlers: Extension<ViewEventHandlersOptions, any>;
31
+ export { ViewEventHandlers };
32
+ export type { ViewEventHandlersOptions };
33
+ //# sourceMappingURL=view-event-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-event-handlers.d.ts","sourceRoot":"","sources":["../../../src/extensions/core/view-event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAKxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD;;;;;GAKG;AACH,aAAK,wBAAwB,GAAG;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAA;IAE9E;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,KAAK,OAAO,GAAG,IAAI,CAAA;CACzE,CAAA;AAED;;;;;;;;;;GAUG;AACH,QAAA,MAAM,iBAAiB,0CAoBrB,CAAA;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAA;AAE5B,YAAY,EAAE,wBAAwB,EAAE,CAAA"}
@@ -0,0 +1,35 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
3
+ import { VIEW_EVENT_HANDLERS_PRIORITY } from '../../constants/extension-priorities';
4
+ /**
5
+ * The `ViewEventHandlers` extension allows handling of various ProseMirror view events.
6
+ *
7
+ * The various event-handling functions may all return `true` to indicate that they handled the
8
+ * given event. The view will then take care to call `preventDefault` on the event, except with
9
+ * `handleDOMEvents`, where the handler itself is responsible for that. Return `false` or
10
+ * `undefined` for the default event handler to be called.
11
+ *
12
+ * These event handlers should be used sparingly, please consider if a reusable extension would be
13
+ * more appropriate for your use case.
14
+ */
15
+ const ViewEventHandlers = Extension.create({
16
+ name: 'viewEventHandlers',
17
+ priority: VIEW_EVENT_HANDLERS_PRIORITY,
18
+ addProseMirrorPlugins() {
19
+ const { options } = this;
20
+ return [
21
+ new Plugin({
22
+ key: new PluginKey('viewEventHandlers'),
23
+ props: {
24
+ handleClick(view, pos, event) {
25
+ return options.onClick?.(event, view, pos) || false;
26
+ },
27
+ handleKeyDown(view, event) {
28
+ return options.onKeyDown?.(event, view) || false;
29
+ },
30
+ },
31
+ }),
32
+ ];
33
+ },
34
+ });
35
+ export { ViewEventHandlers };
@@ -0,0 +1,10 @@
1
+ import { Extension } from '@tiptap/core';
2
+ /**
3
+ * The `MultilineDocumentPaste` extension preserves paragraphs (including empty ones) when
4
+ * copying-and-pasting text into the editor, or when inputting multiline text with some sort of
5
+ * automatic text insertion shortcut. This custom extension is required for a plain-text editor
6
+ * configured with `multiline: true`, so that multiline clipboard text is pasted correctly.
7
+ */
8
+ declare const PasteMultilineText: Extension<any, any>;
9
+ export { PasteMultilineText };
10
+ //# sourceMappingURL=paste-multiline-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-multiline-text.d.ts","sourceRoot":"","sources":["../../../src/extensions/plain-text/paste-multiline-text.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AA+CxC;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,qBA0BtB,CAAA;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -0,0 +1,66 @@
1
+ /* eslint-disable no-console */
2
+ import { Extension } from '@tiptap/core';
3
+ import { Fragment, Slice } from 'prosemirror-model';
4
+ import { Plugin, PluginKey } from 'prosemirror-state';
5
+ import { ClipboardDataType } from '../../constants/common';
6
+ import { REGEX_LINE_BREAKS } from '../../constants/regular-expressions';
7
+ /**
8
+ * Handles a text input or paste event, and replaces all found line breaks with paragraph nodes.
9
+ *
10
+ * @param view The current editor view to process.
11
+ * @param text The multiline text input to parse.
12
+ */
13
+ function handleTextInputOrPaste(view, text) {
14
+ const { schema } = view.state;
15
+ const { tr } = view.state;
16
+ const textLines = text.split(REGEX_LINE_BREAKS);
17
+ // Do not handle the event without a multiline input
18
+ // (i.e. when the user is only typing)
19
+ if (textLines.length === 1) {
20
+ return false;
21
+ }
22
+ // Build an array of paragraphs nodes (including empty ones)
23
+ const paragraphNodes = textLines.map((textLine) => {
24
+ if (textLine.length === 0) {
25
+ return schema.nodes.paragraph.create();
26
+ }
27
+ return schema.nodes.paragraph.create(null, schema.text(textLine));
28
+ });
29
+ // Inserts the new paragraph nodes at the current cursor position
30
+ // (takes into account if a selection needs to be replaced)
31
+ view.dispatch(tr.replaceSelection(Slice.maxOpen(Fragment.fromArray(paragraphNodes))).scrollIntoView());
32
+ // Suppress the default handling behaviour
33
+ return true;
34
+ }
35
+ /**
36
+ * The `MultilineDocumentPaste` extension preserves paragraphs (including empty ones) when
37
+ * copying-and-pasting text into the editor, or when inputting multiline text with some sort of
38
+ * automatic text insertion shortcut. This custom extension is required for a plain-text editor
39
+ * configured with `multiline: true`, so that multiline clipboard text is pasted correctly.
40
+ */
41
+ const PasteMultilineText = Extension.create({
42
+ name: 'pasteMultilineText',
43
+ addProseMirrorPlugins() {
44
+ return [
45
+ new Plugin({
46
+ key: new PluginKey('pasteMultilineText'),
47
+ props: {
48
+ handleTextInput(view, _, __, inputText) {
49
+ return handleTextInputOrPaste(view, inputText);
50
+ },
51
+ handlePaste(view, event) {
52
+ const clipboardText = event.clipboardData
53
+ ?.getData(ClipboardDataType.Text)
54
+ .trim();
55
+ // Do not handle the event if the clipboard doesn't contain text
56
+ if (!clipboardText) {
57
+ return false;
58
+ }
59
+ return handleTextInputOrPaste(view, clipboardText);
60
+ },
61
+ },
62
+ }),
63
+ ];
64
+ },
65
+ });
66
+ export { PasteMultilineText };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The options available to customize the `PlainTextDocument` extension.
3
+ */
4
+ declare type PlainTextDocumentOptions = {
5
+ /**
6
+ * Indicates whether the document accepts multiple lines of input or only a single line.
7
+ */
8
+ multiline: boolean;
9
+ };
10
+ /**
11
+ * Custom extension that extends the built-in `Document` extension to define a schema for multiline
12
+ * or singleline plain-text documents (as opposed to the multiple block nodes by default).
13
+ */
14
+ declare const PlainTextDocument: import("@tiptap/core").Node<PlainTextDocumentOptions, any>;
15
+ export { PlainTextDocument };
16
+ export type { PlainTextDocumentOptions };
17
+ //# sourceMappingURL=plain-text-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plain-text-document.d.ts","sourceRoot":"","sources":["../../../src/extensions/plain-text/plain-text-document.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,aAAK,wBAAwB,GAAG;IAC5B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAA;CACrB,CAAA;AAED;;;GAGG;AACH,QAAA,MAAM,iBAAiB,4DAUrB,CAAA;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAA;AAE5B,YAAY,EAAE,wBAAwB,EAAE,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { Document } from '@tiptap/extension-document';
2
+ /**
3
+ * Custom extension that extends the built-in `Document` extension to define a schema for multiline
4
+ * or singleline plain-text documents (as opposed to the multiple block nodes by default).
5
+ */
6
+ const PlainTextDocument = Document.extend({
7
+ addOptions() {
8
+ return {
9
+ multiline: true,
10
+ };
11
+ },
12
+ content() {
13
+ // ref: https://tiptap.dev/api/schema#content
14
+ return `paragraph${this.options.multiline ? '+' : ''}`;
15
+ },
16
+ });
17
+ export { PlainTextDocument };