@tiptap/core 2.0.0-beta.98 → 2.0.0-rc.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/README.md +3 -3
- package/dist/index.cjs +4360 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{tiptap-core.esm.js → index.js} +2349 -1447
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +4358 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/packages/core/src/CommandManager.d.ts +14 -7
- package/dist/packages/core/src/Editor.d.ts +25 -11
- package/dist/packages/core/src/EventEmitter.d.ts +8 -4
- package/dist/packages/core/src/Extension.d.ts +63 -29
- package/dist/packages/core/src/ExtensionManager.d.ts +3 -4
- package/dist/packages/core/src/InputRule.d.ts +42 -0
- package/dist/packages/core/src/Mark.d.ts +94 -36
- package/dist/packages/core/src/Node.d.ts +104 -45
- package/dist/packages/core/src/NodeView.d.ts +8 -8
- package/dist/packages/core/src/PasteRule.d.ts +42 -0
- package/dist/packages/core/src/Tracker.d.ts +1 -1
- package/dist/packages/core/src/commands/deleteCurrentNode.d.ts +12 -0
- package/dist/packages/core/src/commands/deleteNode.d.ts +1 -1
- package/dist/packages/core/src/commands/deleteRange.d.ts +1 -1
- package/dist/packages/core/src/commands/extendMarkRange.d.ts +1 -1
- package/dist/packages/core/src/commands/focus.d.ts +4 -2
- package/dist/packages/core/src/commands/index.d.ts +50 -0
- package/dist/packages/core/src/commands/insertContent.d.ts +6 -3
- package/dist/packages/core/src/commands/insertContentAt.d.ts +6 -3
- package/dist/packages/core/src/commands/join.d.ts +33 -0
- package/dist/packages/core/src/commands/lift.d.ts +1 -1
- package/dist/packages/core/src/commands/liftListItem.d.ts +1 -1
- package/dist/packages/core/src/commands/resetAttributes.d.ts +1 -1
- package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +12 -0
- package/dist/packages/core/src/commands/selectTextblockStart.d.ts +12 -0
- package/dist/packages/core/src/commands/setContent.d.ts +2 -2
- package/dist/packages/core/src/commands/setMark.d.ts +1 -1
- package/dist/packages/core/src/commands/setNode.d.ts +1 -1
- package/dist/packages/core/src/commands/setTextSelection.d.ts +1 -1
- package/dist/packages/core/src/commands/sinkListItem.d.ts +1 -1
- package/dist/packages/core/src/commands/splitListItem.d.ts +1 -1
- package/dist/packages/core/src/commands/toggleList.d.ts +2 -2
- package/dist/packages/core/src/commands/toggleMark.d.ts +7 -2
- package/dist/packages/core/src/commands/toggleNode.d.ts +1 -1
- package/dist/packages/core/src/commands/toggleWrap.d.ts +1 -1
- package/dist/packages/core/src/commands/unsetMark.d.ts +7 -2
- package/dist/packages/core/src/commands/updateAttributes.d.ts +1 -1
- package/dist/packages/core/src/commands/wrapIn.d.ts +1 -1
- package/dist/packages/core/src/commands/wrapInList.d.ts +1 -1
- package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +1 -1
- package/dist/packages/core/src/extensions/commands.d.ts +2 -97
- package/dist/packages/core/src/extensions/editable.d.ts +1 -1
- package/dist/packages/core/src/extensions/focusEvents.d.ts +1 -1
- package/dist/packages/core/src/extensions/index.d.ts +1 -0
- package/dist/packages/core/src/extensions/keymap.d.ts +1 -1
- package/dist/packages/core/src/extensions/tabindex.d.ts +2 -0
- package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +7 -0
- package/dist/packages/core/src/helpers/createChainableState.d.ts +5 -0
- package/dist/packages/core/src/helpers/createDocument.d.ts +2 -2
- package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +2 -2
- package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +2 -0
- package/dist/packages/core/src/helpers/findChildren.d.ts +3 -3
- package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +3 -3
- package/dist/packages/core/src/helpers/findParentNode.d.ts +3 -4
- package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +3 -3
- package/dist/packages/core/src/helpers/generateHTML.d.ts +1 -1
- package/dist/packages/core/src/helpers/generateJSON.d.ts +1 -1
- package/dist/packages/core/src/helpers/generateText.d.ts +5 -0
- package/dist/packages/core/src/helpers/getAttributes.d.ts +3 -3
- package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +2 -2
- package/dist/packages/core/src/helpers/getChangedRanges.d.ts +11 -0
- package/dist/packages/core/src/helpers/getDebugJSON.d.ts +2 -5
- package/dist/packages/core/src/helpers/getExtensionField.d.ts +2 -2
- package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +2 -2
- package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +3 -3
- package/dist/packages/core/src/helpers/getMarkRange.d.ts +2 -2
- package/dist/packages/core/src/helpers/getMarkType.d.ts +2 -2
- package/dist/packages/core/src/helpers/getMarksBetween.d.ts +2 -2
- package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +3 -3
- package/dist/packages/core/src/helpers/getNodeType.d.ts +2 -2
- package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +2 -2
- package/dist/packages/core/src/helpers/getSchema.d.ts +2 -2
- package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +2 -2
- package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +2 -2
- package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +2 -2
- package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +1 -1
- package/dist/packages/core/src/helpers/getText.d.ts +6 -0
- package/dist/packages/core/src/helpers/getTextBetween.d.ts +6 -0
- package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +2 -0
- package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +3 -0
- package/dist/packages/core/src/helpers/index.d.ts +47 -0
- package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +2 -2
- package/dist/packages/core/src/helpers/isActive.d.ts +2 -2
- package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +2 -0
- package/dist/packages/core/src/helpers/isList.d.ts +1 -1
- package/dist/packages/core/src/helpers/isMarkActive.d.ts +3 -3
- package/dist/packages/core/src/helpers/isNodeActive.d.ts +3 -3
- package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +2 -2
- package/dist/packages/core/src/helpers/isNodeSelection.d.ts +2 -2
- package/dist/packages/core/src/helpers/isTextSelection.d.ts +2 -2
- package/dist/packages/core/src/helpers/posToDOMRect.d.ts +2 -2
- package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +4 -0
- package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +2 -2
- package/dist/packages/core/src/helpers/splitExtensions.d.ts +6 -6
- package/dist/packages/core/src/index.d.ts +12 -34
- package/dist/packages/core/src/inputRules/index.d.ts +5 -0
- package/dist/packages/core/src/inputRules/markInputRule.d.ts +12 -3
- package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +12 -3
- package/dist/packages/core/src/inputRules/textInputRule.d.ts +9 -0
- package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +14 -0
- package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +27 -0
- package/dist/packages/core/src/pasteRules/index.d.ts +3 -0
- package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +12 -3
- package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +12 -0
- package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +9 -0
- package/dist/packages/core/src/style.d.ts +1 -2
- package/dist/packages/core/src/types.d.ts +70 -40
- package/dist/packages/core/src/utilities/callOrReturn.d.ts +1 -1
- package/dist/packages/core/src/utilities/createStyleTag.d.ts +1 -1
- package/dist/packages/core/src/utilities/deleteProps.d.ts +1 -1
- package/dist/packages/core/src/utilities/elementFromString.d.ts +1 -1
- package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +1 -0
- package/dist/packages/core/src/utilities/findDuplicates.d.ts +1 -0
- package/dist/packages/core/src/utilities/fromString.d.ts +1 -1
- package/dist/packages/core/src/utilities/index.d.ts +20 -0
- package/dist/packages/core/src/utilities/isEmptyObject.d.ts +1 -1
- package/dist/packages/core/src/utilities/isFunction.d.ts +1 -0
- package/dist/packages/core/src/utilities/isMacOS.d.ts +1 -0
- package/dist/packages/core/src/utilities/isNumber.d.ts +1 -0
- package/dist/packages/core/src/utilities/isPlainObject.d.ts +1 -1
- package/dist/packages/core/src/utilities/isRegExp.d.ts +1 -0
- package/dist/packages/core/src/utilities/isString.d.ts +1 -0
- package/dist/packages/core/src/utilities/isiOS.d.ts +1 -1
- package/dist/packages/core/src/utilities/mergeAttributes.d.ts +1 -1
- package/dist/packages/core/src/utilities/mergeDeep.d.ts +1 -1
- package/dist/packages/core/src/utilities/minMax.d.ts +1 -1
- package/dist/packages/core/src/utilities/objectIncludes.d.ts +3 -1
- package/dist/packages/core/src/utilities/removeDuplicates.d.ts +8 -0
- package/package.json +25 -24
- package/src/CommandManager.ts +73 -83
- package/src/Editor.ts +101 -53
- package/src/EventEmitter.ts +14 -4
- package/src/Extension.ts +244 -138
- package/src/ExtensionManager.ts +153 -152
- package/src/InputRule.ts +260 -0
- package/src/Mark.ts +365 -204
- package/src/Node.ts +406 -253
- package/src/NodeView.ts +59 -38
- package/src/PasteRule.ts +240 -0
- package/src/Tracker.ts +4 -8
- package/src/commands/blur.ts +4 -0
- package/src/commands/clearNodes.ts +15 -9
- package/src/commands/createParagraphNear.ts +3 -2
- package/src/commands/deleteCurrentNode.ts +41 -0
- package/src/commands/deleteNode.ts +3 -2
- package/src/commands/deleteRange.ts +1 -1
- package/src/commands/deleteSelection.ts +3 -2
- package/src/commands/exitCode.ts +3 -2
- package/src/commands/extendMarkRange.ts +9 -5
- package/src/commands/focus.ts +31 -42
- package/src/commands/index.ts +50 -0
- package/src/commands/insertContent.ts +15 -4
- package/src/commands/insertContentAt.ts +71 -14
- package/src/commands/join.ts +53 -0
- package/src/commands/keyboardShortcut.ts +3 -3
- package/src/commands/lift.ts +6 -5
- package/src/commands/liftEmptyBlock.ts +2 -1
- package/src/commands/liftListItem.ts +5 -4
- package/src/commands/newlineInCode.ts +3 -2
- package/src/commands/resetAttributes.ts +16 -10
- package/src/commands/selectAll.ts +5 -3
- package/src/commands/selectNodeBackward.ts +3 -2
- package/src/commands/selectNodeForward.ts +3 -2
- package/src/commands/selectParentNode.ts +3 -2
- package/src/commands/selectTextblockEnd.ts +20 -0
- package/src/commands/selectTextblockStart.ts +20 -0
- package/src/commands/setContent.ts +6 -9
- package/src/commands/setMark.ts +66 -13
- package/src/commands/setNode.ts +30 -6
- package/src/commands/setNodeSelection.ts +6 -7
- package/src/commands/setTextSelection.ts +8 -9
- package/src/commands/sinkListItem.ts +5 -4
- package/src/commands/splitBlock.ts +23 -38
- package/src/commands/splitListItem.ts +30 -27
- package/src/commands/toggleList.ts +108 -19
- package/src/commands/toggleMark.ts +17 -6
- package/src/commands/toggleNode.ts +9 -4
- package/src/commands/toggleWrap.ts +8 -8
- package/src/commands/undoInputRule.ts +31 -2
- package/src/commands/unsetAllMarks.ts +4 -8
- package/src/commands/unsetMark.ts +34 -21
- package/src/commands/updateAttributes.ts +18 -12
- package/src/commands/wrapIn.ts +5 -10
- package/src/commands/wrapInList.ts +5 -4
- package/src/extensions/clipboardTextSerializer.ts +15 -36
- package/src/extensions/commands.ts +3 -144
- package/src/extensions/editable.ts +2 -1
- package/src/extensions/focusEvents.ts +4 -6
- package/src/extensions/index.ts +1 -0
- package/src/extensions/keymap.ts +111 -13
- package/src/extensions/tabindex.ts +18 -0
- package/src/helpers/combineTransactionSteps.ts +21 -0
- package/src/helpers/createChainableState.ts +38 -0
- package/src/helpers/createDocument.ts +4 -3
- package/src/helpers/createNodeFromContent.ts +10 -15
- package/src/helpers/defaultBlockAt.ts +13 -0
- package/src/helpers/findChildren.ts +4 -3
- package/src/helpers/findChildrenInRange.ts +8 -3
- package/src/helpers/findParentNode.ts +4 -3
- package/src/helpers/findParentNodeClosestToPos.ts +13 -7
- package/src/helpers/generateHTML.ts +6 -5
- package/src/helpers/generateJSON.ts +6 -7
- package/src/helpers/generateText.ts +27 -0
- package/src/helpers/getAttributes.ts +8 -9
- package/src/helpers/getAttributesFromExtensions.ts +25 -12
- package/src/helpers/getChangedRanges.ts +83 -0
- package/src/helpers/getDebugJSON.ts +42 -38
- package/src/helpers/getExtensionField.ts +3 -3
- package/src/helpers/getHTMLFromFragment.ts +5 -6
- package/src/helpers/getMarkAttributes.ts +18 -10
- package/src/helpers/getMarkRange.ts +13 -8
- package/src/helpers/getMarkType.ts +5 -3
- package/src/helpers/getMarksBetween.ts +34 -10
- package/src/helpers/getNodeAttributes.ts +14 -12
- package/src/helpers/getNodeType.ts +5 -3
- package/src/helpers/getRenderedAttributes.ts +8 -6
- package/src/helpers/getSchema.ts +5 -4
- package/src/helpers/getSchemaByResolvedExtensions.ts +165 -111
- package/src/helpers/getSchemaTypeByName.ts +3 -11
- package/src/helpers/getSchemaTypeNameByName.ts +2 -2
- package/src/helpers/getSplittedAttributes.ts +1 -1
- package/src/helpers/getText.ts +19 -0
- package/src/helpers/getTextBetween.ts +46 -0
- package/src/helpers/getTextContentFromNodes.ts +26 -0
- package/src/helpers/getTextSerializersFromSchema.ts +11 -0
- package/src/helpers/index.ts +47 -0
- package/src/helpers/injectExtensionAttributesToParseRule.ts +22 -23
- package/src/helpers/isActive.ts +10 -5
- package/src/helpers/isExtensionRulesEnabled.ts +15 -0
- package/src/helpers/isList.ts +6 -5
- package/src/helpers/isMarkActive.ts +32 -35
- package/src/helpers/isNodeActive.ts +27 -37
- package/src/helpers/isNodeEmpty.ts +2 -2
- package/src/helpers/isNodeSelection.ts +3 -4
- package/src/helpers/isTextSelection.ts +3 -4
- package/src/helpers/posToDOMRect.ts +10 -4
- package/src/helpers/resolveFocusPosition.ts +42 -0
- package/src/helpers/selectionToInsertionEnd.ts +3 -3
- package/src/helpers/splitExtensions.ts +3 -3
- package/src/index.ts +12 -37
- package/src/inputRules/index.ts +5 -0
- package/src/inputRules/markInputRule.ts +59 -40
- package/src/inputRules/nodeInputRule.ts +45 -12
- package/src/inputRules/textInputRule.ts +35 -0
- package/src/inputRules/textblockTypeInputRule.ts +37 -0
- package/src/inputRules/wrappingInputRule.ts +84 -0
- package/src/pasteRules/index.ts +3 -0
- package/src/pasteRules/markPasteRule.ts +49 -56
- package/src/pasteRules/nodePasteRule.ts +37 -0
- package/src/pasteRules/textPasteRule.ts +35 -0
- package/src/style.ts +12 -3
- package/src/types.ts +140 -106
- package/src/utilities/callOrReturn.ts +3 -2
- package/src/utilities/createStyleTag.ts +8 -4
- package/src/utilities/deleteProps.ts +1 -1
- package/src/utilities/elementFromString.ts +1 -1
- package/src/utilities/escapeForRegEx.ts +4 -0
- package/src/utilities/findDuplicates.ts +5 -0
- package/src/utilities/fromString.ts +2 -2
- package/src/utilities/index.ts +20 -0
- package/src/utilities/isEmptyObject.ts +2 -2
- package/src/utilities/isFunction.ts +3 -0
- package/src/utilities/isMacOS.ts +5 -0
- package/src/utilities/isNumber.ts +3 -0
- package/src/utilities/isPlainObject.ts +8 -5
- package/src/utilities/isRegExp.ts +3 -0
- package/src/utilities/isString.ts +3 -0
- package/src/utilities/isiOS.ts +1 -1
- package/src/utilities/mergeAttributes.ts +2 -1
- package/src/utilities/mergeDeep.ts +2 -2
- package/src/utilities/minMax.ts +1 -1
- package/src/utilities/objectIncludes.ts +18 -4
- package/src/utilities/removeDuplicates.ts +15 -0
- package/CHANGELOG.md +0 -1182
- package/LICENSE.md +0 -21
- package/dist/packages/core/src/commands/joinBackward.d.ts +0 -12
- package/dist/packages/core/src/commands/joinForward.d.ts +0 -12
- package/dist/packages/core/src/utilities/isClass.d.ts +0 -1
- package/dist/packages/core/src/utilities/isObject.d.ts +0 -1
- package/dist/packages/core/src/utilities/removeElement.d.ts +0 -1
- package/dist/tiptap-core.cjs.js +0 -3408
- package/dist/tiptap-core.cjs.js.map +0 -1
- package/dist/tiptap-core.esm.js.map +0 -1
- package/dist/tiptap-core.umd.js +0 -3405
- package/dist/tiptap-core.umd.js.map +0 -1
- package/src/commands/joinBackward.ts +0 -17
- package/src/commands/joinForward.ts +0 -17
- package/src/utilities/isClass.ts +0 -7
- package/src/utilities/isObject.ts +0 -10
- package/src/utilities/removeElement.ts +0 -5
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import getMarkType from './getMarkType'
|
|
1
|
+
import { MarkType } from '@tiptap/pm/model'
|
|
2
|
+
import { EditorState } from '@tiptap/pm/state'
|
|
3
|
+
|
|
5
4
|
import { MarkRange } from '../types'
|
|
5
|
+
import { objectIncludes } from '../utilities/objectIncludes'
|
|
6
|
+
import { getMarkType } from './getMarkType'
|
|
6
7
|
|
|
7
|
-
export
|
|
8
|
+
export function isMarkActive(
|
|
8
9
|
state: EditorState,
|
|
9
10
|
typeOrName: MarkType | string | null,
|
|
10
11
|
attributes: Record<string, any> = {},
|
|
11
12
|
): boolean {
|
|
12
|
-
const {
|
|
13
|
-
const type = typeOrName
|
|
14
|
-
? getMarkType(typeOrName, state.schema)
|
|
15
|
-
: null
|
|
13
|
+
const { empty, ranges } = state.selection
|
|
14
|
+
const type = typeOrName ? getMarkType(typeOrName, state.schema) : null
|
|
16
15
|
|
|
17
16
|
if (empty) {
|
|
18
17
|
return !!(state.storedMarks || state.selection.$from.marks())
|
|
@@ -23,26 +22,35 @@ export default function isMarkActive(
|
|
|
23
22
|
|
|
24
23
|
return type.name === mark.type.name
|
|
25
24
|
})
|
|
26
|
-
.find(mark => objectIncludes(mark.attrs, attributes))
|
|
25
|
+
.find(mark => objectIncludes(mark.attrs, attributes, { strict: false }))
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
let selectionRange = 0
|
|
30
|
-
|
|
29
|
+
const markRanges: MarkRange[] = []
|
|
30
|
+
|
|
31
|
+
ranges.forEach(({ $from, $to }) => {
|
|
32
|
+
const from = $from.pos
|
|
33
|
+
const to = $to.pos
|
|
34
|
+
|
|
35
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
36
|
+
if (!node.isText && !node.marks.length) {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
31
39
|
|
|
32
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
33
|
-
if (node.isText) {
|
|
34
40
|
const relativeFrom = Math.max(from, pos)
|
|
35
41
|
const relativeTo = Math.min(to, pos + node.nodeSize)
|
|
36
42
|
const range = relativeTo - relativeFrom
|
|
37
43
|
|
|
38
44
|
selectionRange += range
|
|
39
45
|
|
|
40
|
-
markRanges
|
|
41
|
-
mark
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
markRanges.push(
|
|
47
|
+
...node.marks.map(mark => ({
|
|
48
|
+
mark,
|
|
49
|
+
from: relativeFrom,
|
|
50
|
+
to: relativeTo,
|
|
51
|
+
})),
|
|
52
|
+
)
|
|
53
|
+
})
|
|
46
54
|
})
|
|
47
55
|
|
|
48
56
|
if (selectionRange === 0) {
|
|
@@ -58,12 +66,8 @@ export default function isMarkActive(
|
|
|
58
66
|
|
|
59
67
|
return type.name === markRange.mark.type.name
|
|
60
68
|
})
|
|
61
|
-
.filter(markRange => objectIncludes(markRange.mark.attrs, attributes))
|
|
62
|
-
.reduce((sum, markRange) =>
|
|
63
|
-
const size = markRange.to - markRange.from
|
|
64
|
-
|
|
65
|
-
return sum + size
|
|
66
|
-
}, 0)
|
|
69
|
+
.filter(markRange => objectIncludes(markRange.mark.attrs, attributes, { strict: false }))
|
|
70
|
+
.reduce((sum, markRange) => sum + markRange.to - markRange.from, 0)
|
|
67
71
|
|
|
68
72
|
// calculate range of marks that excludes the searched mark
|
|
69
73
|
// for example `code` doesn’t allow any other marks
|
|
@@ -73,20 +77,13 @@ export default function isMarkActive(
|
|
|
73
77
|
return true
|
|
74
78
|
}
|
|
75
79
|
|
|
76
|
-
return markRange.mark.type !== type
|
|
77
|
-
&& markRange.mark.type.excludes(type)
|
|
80
|
+
return markRange.mark.type !== type && markRange.mark.type.excludes(type)
|
|
78
81
|
})
|
|
79
|
-
.reduce((sum, markRange) =>
|
|
80
|
-
const size = markRange.to - markRange.from
|
|
81
|
-
|
|
82
|
-
return sum + size
|
|
83
|
-
}, 0)
|
|
82
|
+
.reduce((sum, markRange) => sum + markRange.to - markRange.from, 0)
|
|
84
83
|
|
|
85
84
|
// we only include the result of `excludedRange`
|
|
86
85
|
// if there is a match at all
|
|
87
|
-
const range = matchedRange > 0
|
|
88
|
-
? matchedRange + excludedRange
|
|
89
|
-
: matchedRange
|
|
86
|
+
const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange
|
|
90
87
|
|
|
91
88
|
return range >= selectionRange
|
|
92
89
|
}
|
|
@@ -1,49 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import getNodeType from './getNodeType'
|
|
1
|
+
import { NodeType } from '@tiptap/pm/model'
|
|
2
|
+
import { EditorState } from '@tiptap/pm/state'
|
|
3
|
+
|
|
5
4
|
import { NodeRange } from '../types'
|
|
5
|
+
import { objectIncludes } from '../utilities/objectIncludes'
|
|
6
|
+
import { getNodeType } from './getNodeType'
|
|
6
7
|
|
|
7
|
-
export
|
|
8
|
+
export function isNodeActive(
|
|
8
9
|
state: EditorState,
|
|
9
10
|
typeOrName: NodeType | string | null,
|
|
10
11
|
attributes: Record<string, any> = {},
|
|
11
12
|
): boolean {
|
|
12
13
|
const { from, to, empty } = state.selection
|
|
13
|
-
const type = typeOrName
|
|
14
|
-
? getNodeType(typeOrName, state.schema)
|
|
15
|
-
: null
|
|
14
|
+
const type = typeOrName ? getNodeType(typeOrName, state.schema) : null
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
const nodeRanges: NodeRange[] = []
|
|
18
17
|
|
|
19
18
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
const relativeTo = Math.min(to, pos + node.nodeSize)
|
|
23
|
-
|
|
24
|
-
nodeRanges = [...nodeRanges, {
|
|
25
|
-
node,
|
|
26
|
-
from: relativeFrom,
|
|
27
|
-
to: relativeTo,
|
|
28
|
-
}]
|
|
19
|
+
if (node.isText) {
|
|
20
|
+
return
|
|
29
21
|
}
|
|
30
|
-
})
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.filter(nodeRange => {
|
|
35
|
-
if (!type) {
|
|
36
|
-
return true
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return type.name === nodeRange.node.type.name
|
|
40
|
-
})
|
|
41
|
-
.find(nodeRange => objectIncludes(nodeRange.node.attrs, attributes))
|
|
42
|
-
}
|
|
23
|
+
const relativeFrom = Math.max(from, pos)
|
|
24
|
+
const relativeTo = Math.min(to, pos + node.nodeSize)
|
|
43
25
|
|
|
44
|
-
|
|
26
|
+
nodeRanges.push({
|
|
27
|
+
node,
|
|
28
|
+
from: relativeFrom,
|
|
29
|
+
to: relativeTo,
|
|
30
|
+
})
|
|
31
|
+
})
|
|
45
32
|
|
|
46
|
-
const
|
|
33
|
+
const selectionRange = to - from
|
|
34
|
+
const matchedNodeRanges = nodeRanges
|
|
47
35
|
.filter(nodeRange => {
|
|
48
36
|
if (!type) {
|
|
49
37
|
return true
|
|
@@ -51,11 +39,13 @@ export default function isNodeActive(
|
|
|
51
39
|
|
|
52
40
|
return type.name === nodeRange.node.type.name
|
|
53
41
|
})
|
|
54
|
-
.filter(nodeRange => objectIncludes(nodeRange.node.attrs, attributes))
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
.filter(nodeRange => objectIncludes(nodeRange.node.attrs, attributes, { strict: false }))
|
|
43
|
+
|
|
44
|
+
if (empty) {
|
|
45
|
+
return !!matchedNodeRanges.length
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0)
|
|
59
49
|
|
|
60
50
|
return range >= selectionRange
|
|
61
51
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Node as ProseMirrorNode } from '
|
|
1
|
+
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export function isNodeEmpty(node: ProseMirrorNode): boolean {
|
|
4
4
|
const defaultContent = node.type.createAndFill()?.toJSON()
|
|
5
5
|
const content = node.toJSON()
|
|
6
6
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { NodeSelection } from '
|
|
2
|
-
import isObject from '../utilities/isObject'
|
|
1
|
+
import { NodeSelection } from '@tiptap/pm/state'
|
|
3
2
|
|
|
4
|
-
export
|
|
5
|
-
return
|
|
3
|
+
export function isNodeSelection(value: unknown): value is NodeSelection {
|
|
4
|
+
return value instanceof NodeSelection
|
|
6
5
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { TextSelection } from '
|
|
2
|
-
import isObject from '../utilities/isObject'
|
|
1
|
+
import { TextSelection } from '@tiptap/pm/state'
|
|
3
2
|
|
|
4
|
-
export
|
|
5
|
-
return
|
|
3
|
+
export function isTextSelection(value: unknown): value is TextSelection {
|
|
4
|
+
return value instanceof TextSelection
|
|
6
5
|
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { EditorView } from '
|
|
1
|
+
import { EditorView } from '@tiptap/pm/view'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { minMax } from '../utilities/minMax'
|
|
4
|
+
|
|
5
|
+
export function posToDOMRect(view: EditorView, from: number, to: number): DOMRect {
|
|
6
|
+
const minPos = 0
|
|
7
|
+
const maxPos = view.state.doc.content.size
|
|
8
|
+
const resolvedFrom = minMax(from, minPos, maxPos)
|
|
9
|
+
const resolvedEnd = minMax(to, minPos, maxPos)
|
|
10
|
+
const start = view.coordsAtPos(resolvedFrom)
|
|
11
|
+
const end = view.coordsAtPos(resolvedEnd, -1)
|
|
6
12
|
const top = Math.min(start.top, end.top)
|
|
7
13
|
const bottom = Math.max(start.bottom, end.bottom)
|
|
8
14
|
const left = Math.min(start.left, end.left)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
2
|
+
import { Selection, TextSelection } from '@tiptap/pm/state'
|
|
3
|
+
|
|
4
|
+
import { FocusPosition } from '../types'
|
|
5
|
+
import { minMax } from '../utilities/minMax'
|
|
6
|
+
|
|
7
|
+
export function resolveFocusPosition(
|
|
8
|
+
doc: ProseMirrorNode,
|
|
9
|
+
position: FocusPosition = null,
|
|
10
|
+
): Selection | null {
|
|
11
|
+
if (!position) {
|
|
12
|
+
return null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const selectionAtStart = Selection.atStart(doc)
|
|
16
|
+
const selectionAtEnd = Selection.atEnd(doc)
|
|
17
|
+
|
|
18
|
+
if (position === 'start' || position === true) {
|
|
19
|
+
return selectionAtStart
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (position === 'end') {
|
|
23
|
+
return selectionAtEnd
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const minPos = selectionAtStart.from
|
|
27
|
+
const maxPos = selectionAtEnd.to
|
|
28
|
+
|
|
29
|
+
if (position === 'all') {
|
|
30
|
+
return TextSelection.create(
|
|
31
|
+
doc,
|
|
32
|
+
minMax(0, minPos, maxPos),
|
|
33
|
+
minMax(doc.content.size, minPos, maxPos),
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return TextSelection.create(
|
|
38
|
+
doc,
|
|
39
|
+
minMax(position, minPos, maxPos),
|
|
40
|
+
minMax(position, minPos, maxPos),
|
|
41
|
+
)
|
|
42
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Selection, Transaction } from '
|
|
2
|
-
import {
|
|
1
|
+
import { Selection, Transaction } from '@tiptap/pm/state'
|
|
2
|
+
import { ReplaceAroundStep, ReplaceStep } from '@tiptap/pm/transform'
|
|
3
3
|
|
|
4
4
|
// source: https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.js#L466
|
|
5
|
-
export
|
|
5
|
+
export function selectionToInsertionEnd(tr: Transaction, startLen: number, bias: number) {
|
|
6
6
|
const last = tr.steps.length - 1
|
|
7
7
|
|
|
8
8
|
if (last < startLen) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Extensions } from '../types'
|
|
2
1
|
import { Extension } from '../Extension'
|
|
3
|
-
import { Node } from '../Node'
|
|
4
2
|
import { Mark } from '../Mark'
|
|
3
|
+
import { Node } from '../Node'
|
|
4
|
+
import { Extensions } from '../types'
|
|
5
5
|
|
|
6
|
-
export
|
|
6
|
+
export function splitExtensions(extensions: Extensions) {
|
|
7
7
|
const baseExtensions = extensions.filter(extension => extension.type === 'extension') as Extension[]
|
|
8
8
|
const nodeExtensions = extensions.filter(extension => extension.type === 'node') as Node[]
|
|
9
9
|
const markExtensions = extensions.filter(extension => extension.type === 'mark') as Mark[]
|
package/src/index.ts
CHANGED
|
@@ -1,52 +1,27 @@
|
|
|
1
|
+
export * from './CommandManager'
|
|
1
2
|
export * from './Editor'
|
|
2
3
|
export * from './Extension'
|
|
3
|
-
export * from './
|
|
4
|
+
export * as extensions from './extensions'
|
|
5
|
+
export * from './helpers'
|
|
6
|
+
export * from './InputRule'
|
|
7
|
+
export * from './inputRules'
|
|
4
8
|
export * from './Mark'
|
|
9
|
+
export * from './Node'
|
|
5
10
|
export * from './NodeView'
|
|
11
|
+
export * from './PasteRule'
|
|
12
|
+
export * from './pasteRules'
|
|
6
13
|
export * from './Tracker'
|
|
7
14
|
export * from './types'
|
|
8
|
-
|
|
9
|
-
export { default as nodeInputRule } from './inputRules/nodeInputRule'
|
|
10
|
-
export { default as markInputRule } from './inputRules/markInputRule'
|
|
11
|
-
export { default as markPasteRule } from './pasteRules/markPasteRule'
|
|
12
|
-
|
|
13
|
-
export { default as callOrReturn } from './utilities/callOrReturn'
|
|
14
|
-
export { default as mergeAttributes } from './utilities/mergeAttributes'
|
|
15
|
-
|
|
16
|
-
export { default as getExtensionField } from './helpers/getExtensionField'
|
|
17
|
-
export { default as findChildren } from './helpers/findChildren'
|
|
18
|
-
export { default as findChildrenInRange } from './helpers/findChildrenInRange'
|
|
19
|
-
export { default as findParentNode } from './helpers/findParentNode'
|
|
20
|
-
export { default as findParentNodeClosestToPos } from './helpers/findParentNodeClosestToPos'
|
|
21
|
-
export { default as generateHTML } from './helpers/generateHTML'
|
|
22
|
-
export { default as generateJSON } from './helpers/generateJSON'
|
|
23
|
-
export { default as getSchema } from './helpers/getSchema'
|
|
24
|
-
export { default as getHTMLFromFragment } from './helpers/getHTMLFromFragment'
|
|
25
|
-
export { default as getDebugJSON } from './helpers/getDebugJSON'
|
|
26
|
-
export { default as getAttributes } from './helpers/getAttributes'
|
|
27
|
-
export { default as getMarkAttributes } from './helpers/getMarkAttributes'
|
|
28
|
-
export { default as getMarkRange } from './helpers/getMarkRange'
|
|
29
|
-
export { default as getMarkType } from './helpers/getMarkType'
|
|
30
|
-
export { default as getMarksBetween } from './helpers/getMarksBetween'
|
|
31
|
-
export { default as getNodeAttributes } from './helpers/getNodeAttributes'
|
|
32
|
-
export { default as getNodeType } from './helpers/getNodeType'
|
|
33
|
-
export { default as isActive } from './helpers/isActive'
|
|
34
|
-
export { default as isList } from './helpers/isList'
|
|
35
|
-
export { default as isMarkActive } from './helpers/isMarkActive'
|
|
36
|
-
export { default as isNodeActive } from './helpers/isNodeActive'
|
|
37
|
-
export { default as isNodeEmpty } from './helpers/isNodeEmpty'
|
|
38
|
-
export { default as isNodeSelection } from './helpers/isNodeSelection'
|
|
39
|
-
export { default as isTextSelection } from './helpers/isTextSelection'
|
|
40
|
-
export { default as posToDOMRect } from './helpers/posToDOMRect'
|
|
15
|
+
export * from './utilities'
|
|
41
16
|
|
|
42
17
|
// eslint-disable-next-line
|
|
43
18
|
export interface Commands<ReturnType = any> {}
|
|
44
19
|
|
|
45
20
|
// eslint-disable-next-line
|
|
46
|
-
export interface ExtensionConfig<Options = any> {}
|
|
21
|
+
export interface ExtensionConfig<Options = any, Storage = any> {}
|
|
47
22
|
|
|
48
23
|
// eslint-disable-next-line
|
|
49
|
-
export interface NodeConfig<Options = any> {}
|
|
24
|
+
export interface NodeConfig<Options = any, Storage = any> {}
|
|
50
25
|
|
|
51
26
|
// eslint-disable-next-line
|
|
52
|
-
export interface MarkConfig<Options = any> {}
|
|
27
|
+
export interface MarkConfig<Options = any, Storage = any> {}
|
|
@@ -1,50 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import getMarksBetween from '../helpers/getMarksBetween'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.filter(item => item.to > textStart)
|
|
28
|
-
|
|
29
|
-
if (excludedMarks.length) {
|
|
1
|
+
import { MarkType } from '@tiptap/pm/model'
|
|
2
|
+
|
|
3
|
+
import { getMarksBetween } from '../helpers/getMarksBetween'
|
|
4
|
+
import { InputRule, InputRuleFinder } from '../InputRule'
|
|
5
|
+
import { ExtendedRegExpMatchArray } from '../types'
|
|
6
|
+
import { callOrReturn } from '../utilities/callOrReturn'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Build an input rule that adds a mark when the
|
|
10
|
+
* matched text is typed into it.
|
|
11
|
+
*/
|
|
12
|
+
export function markInputRule(config: {
|
|
13
|
+
find: InputRuleFinder
|
|
14
|
+
type: MarkType
|
|
15
|
+
getAttributes?:
|
|
16
|
+
| Record<string, any>
|
|
17
|
+
| ((match: ExtendedRegExpMatchArray) => Record<string, any>)
|
|
18
|
+
| false
|
|
19
|
+
| null
|
|
20
|
+
}) {
|
|
21
|
+
return new InputRule({
|
|
22
|
+
find: config.find,
|
|
23
|
+
handler: ({ state, range, match }) => {
|
|
24
|
+
const attributes = callOrReturn(config.getAttributes, undefined, match)
|
|
25
|
+
|
|
26
|
+
if (attributes === false || attributes === null) {
|
|
30
27
|
return null
|
|
31
28
|
}
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
const { tr } = state
|
|
31
|
+
const captureGroup = match[match.length - 1]
|
|
32
|
+
const fullMatch = match[0]
|
|
33
|
+
let markEnd = range.to
|
|
36
34
|
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
if (captureGroup) {
|
|
36
|
+
const startSpaces = fullMatch.search(/\S/)
|
|
37
|
+
const textStart = range.from + fullMatch.indexOf(captureGroup)
|
|
38
|
+
const textEnd = textStart + captureGroup.length
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
const excludedMarks = getMarksBetween(range.from, range.to, state.doc)
|
|
41
|
+
.filter(item => {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
const excluded = item.mark.type.excluded as MarkType[]
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
return excluded.find(type => type === config.type && type !== item.mark.type)
|
|
46
|
+
})
|
|
47
|
+
.filter(item => item.to > textStart)
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
if (excludedMarks.length) {
|
|
50
|
+
return null
|
|
51
|
+
}
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
if (textEnd < range.to) {
|
|
54
|
+
tr.delete(textEnd, range.to)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (textStart > range.from) {
|
|
58
|
+
tr.delete(range.from + startSpaces, textStart)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
markEnd = range.from + startSpaces + captureGroup.length
|
|
62
|
+
|
|
63
|
+
tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}))
|
|
64
|
+
|
|
65
|
+
tr.removeStoredMark(config.type)
|
|
66
|
+
}
|
|
67
|
+
},
|
|
49
68
|
})
|
|
50
69
|
}
|
|
@@ -1,17 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { NodeType } from 'prosemirror-model'
|
|
1
|
+
import { NodeType } from '@tiptap/pm/model'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
? getAttributes(match)
|
|
8
|
-
: getAttributes
|
|
9
|
-
const { tr } = state
|
|
3
|
+
import { InputRule, InputRuleFinder } from '../InputRule'
|
|
4
|
+
import { ExtendedRegExpMatchArray } from '../types'
|
|
5
|
+
import { callOrReturn } from '../utilities/callOrReturn'
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Build an input rule that adds a node when the
|
|
9
|
+
* matched text is typed into it.
|
|
10
|
+
*/
|
|
11
|
+
export function nodeInputRule(config: {
|
|
12
|
+
find: InputRuleFinder
|
|
13
|
+
type: NodeType
|
|
14
|
+
getAttributes?:
|
|
15
|
+
| Record<string, any>
|
|
16
|
+
| ((match: ExtendedRegExpMatchArray) => Record<string, any>)
|
|
17
|
+
| false
|
|
18
|
+
| null
|
|
19
|
+
}) {
|
|
20
|
+
return new InputRule({
|
|
21
|
+
find: config.find,
|
|
22
|
+
handler: ({ state, range, match }) => {
|
|
23
|
+
const attributes = callOrReturn(config.getAttributes, undefined, match) || {}
|
|
24
|
+
const { tr } = state
|
|
25
|
+
const start = range.from
|
|
26
|
+
let end = range.to
|
|
14
27
|
|
|
15
|
-
|
|
28
|
+
if (match[1]) {
|
|
29
|
+
const offset = match[0].lastIndexOf(match[1])
|
|
30
|
+
let matchStart = start + offset
|
|
31
|
+
|
|
32
|
+
if (matchStart > end) {
|
|
33
|
+
matchStart = end
|
|
34
|
+
} else {
|
|
35
|
+
end = matchStart + match[1].length
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// insert last typed character
|
|
39
|
+
const lastChar = match[0][match[0].length - 1]
|
|
40
|
+
|
|
41
|
+
tr.insertText(lastChar, start + match[0].length - 1)
|
|
42
|
+
|
|
43
|
+
// insert node from input rule
|
|
44
|
+
tr.replaceWith(matchStart, end, config.type.create(attributes))
|
|
45
|
+
} else if (match[0]) {
|
|
46
|
+
tr.replaceWith(start, end, config.type.create(attributes))
|
|
47
|
+
}
|
|
48
|
+
},
|
|
16
49
|
})
|
|
17
50
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InputRule, InputRuleFinder } from '../InputRule'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Build an input rule that replaces text when the
|
|
5
|
+
* matched text is typed into it.
|
|
6
|
+
*/
|
|
7
|
+
export function textInputRule(config: {
|
|
8
|
+
find: InputRuleFinder,
|
|
9
|
+
replace: string,
|
|
10
|
+
}) {
|
|
11
|
+
return new InputRule({
|
|
12
|
+
find: config.find,
|
|
13
|
+
handler: ({ state, range, match }) => {
|
|
14
|
+
let insert = config.replace
|
|
15
|
+
let start = range.from
|
|
16
|
+
const end = range.to
|
|
17
|
+
|
|
18
|
+
if (match[1]) {
|
|
19
|
+
const offset = match[0].lastIndexOf(match[1])
|
|
20
|
+
|
|
21
|
+
insert += match[0].slice(offset + match[1].length)
|
|
22
|
+
start += offset
|
|
23
|
+
|
|
24
|
+
const cutOff = start - end
|
|
25
|
+
|
|
26
|
+
if (cutOff > 0) {
|
|
27
|
+
insert = match[0].slice(offset - cutOff, offset) + insert
|
|
28
|
+
start = end
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
state.tr.insertText(insert, start, end)
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { NodeType } from '@tiptap/pm/model'
|
|
2
|
+
|
|
3
|
+
import { InputRule, InputRuleFinder } from '../InputRule'
|
|
4
|
+
import { ExtendedRegExpMatchArray } from '../types'
|
|
5
|
+
import { callOrReturn } from '../utilities/callOrReturn'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Build an input rule that changes the type of a textblock when the
|
|
9
|
+
* matched text is typed into it. When using a regular expresion you’ll
|
|
10
|
+
* probably want the regexp to start with `^`, so that the pattern can
|
|
11
|
+
* only occur at the start of a textblock.
|
|
12
|
+
*/
|
|
13
|
+
export function textblockTypeInputRule(config: {
|
|
14
|
+
find: InputRuleFinder
|
|
15
|
+
type: NodeType
|
|
16
|
+
getAttributes?:
|
|
17
|
+
| Record<string, any>
|
|
18
|
+
| ((match: ExtendedRegExpMatchArray) => Record<string, any>)
|
|
19
|
+
| false
|
|
20
|
+
| null
|
|
21
|
+
}) {
|
|
22
|
+
return new InputRule({
|
|
23
|
+
find: config.find,
|
|
24
|
+
handler: ({ state, range, match }) => {
|
|
25
|
+
const $start = state.doc.resolve(range.from)
|
|
26
|
+
const attributes = callOrReturn(config.getAttributes, undefined, match) || {}
|
|
27
|
+
|
|
28
|
+
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), config.type)) {
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
state.tr
|
|
33
|
+
.delete(range.from, range.to)
|
|
34
|
+
.setBlockType(range.from, range.from, config.type, attributes)
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
}
|