@tiptap/core 2.0.0-beta.14 → 2.0.0-beta.143
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/LICENSE.md +1 -1
- package/README.md +2 -2
- package/dist/packages/core/src/CommandManager.d.ts +12 -5
- package/dist/packages/core/src/Editor.d.ts +19 -20
- package/dist/packages/core/src/EventEmitter.d.ts +8 -4
- package/dist/packages/core/src/Extension.d.ts +102 -26
- package/dist/packages/core/src/ExtensionManager.d.ts +6 -11
- package/dist/packages/core/src/InputRule.d.ts +42 -0
- package/dist/packages/core/src/Mark.d.ts +134 -30
- package/dist/packages/core/src/Node.d.ts +151 -32
- package/dist/packages/core/src/NodeView.d.ts +5 -9
- package/dist/packages/core/src/PasteRule.d.ts +42 -0
- package/dist/packages/core/src/Tracker.d.ts +11 -0
- package/dist/packages/core/src/commands/blur.d.ts +3 -3
- package/dist/packages/core/src/commands/clearContent.d.ts +3 -3
- package/dist/packages/core/src/commands/clearNodes.d.ts +3 -3
- package/dist/packages/core/src/commands/command.d.ts +2 -2
- package/dist/packages/core/src/commands/createParagraphNear.d.ts +3 -3
- package/dist/packages/core/src/commands/deleteNode.d.ts +13 -0
- package/dist/packages/core/src/commands/deleteRange.d.ts +3 -3
- package/dist/packages/core/src/commands/deleteSelection.d.ts +3 -3
- package/dist/packages/core/src/commands/enter.d.ts +3 -3
- package/dist/packages/core/src/commands/exitCode.d.ts +3 -3
- package/dist/packages/core/src/commands/extendMarkRange.d.ts +3 -3
- package/dist/packages/core/src/commands/first.d.ts +3 -3
- package/dist/packages/core/src/commands/focus.d.ts +5 -3
- package/dist/packages/core/src/commands/forEach.d.ts +14 -0
- package/dist/packages/core/src/commands/insertContent.d.ts +16 -0
- package/dist/packages/core/src/commands/insertContentAt.d.ts +16 -0
- package/dist/packages/core/src/commands/joinBackward.d.ts +3 -3
- package/dist/packages/core/src/commands/joinForward.d.ts +3 -3
- package/dist/packages/core/src/commands/keyboardShortcut.d.ts +3 -3
- package/dist/packages/core/src/commands/lift.d.ts +3 -3
- package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +3 -3
- package/dist/packages/core/src/commands/liftListItem.d.ts +3 -3
- package/dist/packages/core/src/commands/newlineInCode.d.ts +3 -3
- package/dist/packages/core/src/commands/resetAttributes.d.ts +13 -0
- package/dist/packages/core/src/commands/scrollIntoView.d.ts +3 -3
- package/dist/packages/core/src/commands/selectAll.d.ts +3 -3
- package/dist/packages/core/src/commands/selectNodeBackward.d.ts +3 -3
- package/dist/packages/core/src/commands/selectNodeForward.d.ts +3 -3
- package/dist/packages/core/src/commands/selectParentNode.d.ts +3 -3
- package/dist/packages/core/src/commands/setContent.d.ts +4 -3
- package/dist/packages/core/src/commands/setMark.d.ts +3 -3
- package/dist/packages/core/src/commands/setMeta.d.ts +12 -0
- package/dist/packages/core/src/commands/setNode.d.ts +3 -3
- package/dist/packages/core/src/commands/setNodeSelection.d.ts +12 -0
- package/dist/packages/core/src/commands/setTextSelection.d.ts +12 -0
- package/dist/packages/core/src/commands/sinkListItem.d.ts +3 -3
- package/dist/packages/core/src/commands/splitBlock.d.ts +3 -3
- package/dist/packages/core/src/commands/splitListItem.d.ts +3 -3
- package/dist/packages/core/src/commands/toggleList.d.ts +3 -3
- package/dist/packages/core/src/commands/toggleMark.d.ts +8 -3
- package/dist/packages/core/src/commands/toggleNode.d.ts +3 -3
- package/dist/packages/core/src/commands/toggleWrap.d.ts +3 -3
- package/dist/packages/core/src/commands/undoInputRule.d.ts +3 -3
- package/dist/packages/core/src/commands/unsetAllMarks.d.ts +3 -3
- package/dist/packages/core/src/commands/unsetMark.d.ts +8 -3
- package/dist/packages/core/src/commands/updateAttributes.d.ts +13 -0
- package/dist/packages/core/src/commands/wrapIn.d.ts +3 -3
- package/dist/packages/core/src/commands/wrapInList.d.ts +3 -3
- package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +1 -1
- package/dist/packages/core/src/extensions/commands.d.ts +19 -15
- 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/createChainableState.d.ts +5 -0
- package/dist/packages/core/src/helpers/createDocument.d.ts +3 -0
- package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +7 -0
- package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +2 -0
- package/dist/packages/core/src/helpers/findChildren.d.ts +3 -0
- package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +6 -0
- package/dist/packages/core/src/helpers/generateHTML.d.ts +2 -2
- package/dist/packages/core/src/helpers/generateJSON.d.ts +2 -0
- package/dist/packages/core/src/helpers/generateText.d.ts +5 -0
- package/dist/packages/core/src/helpers/getAttributes.d.ts +3 -0
- package/dist/packages/core/src/helpers/getDebugJSON.d.ts +8 -0
- package/dist/packages/core/src/helpers/getExtensionField.d.ts +2 -0
- package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +2 -2
- package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +1 -2
- package/dist/packages/core/src/helpers/getMarkRange.d.ts +1 -1
- package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +1 -2
- package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +2 -2
- package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +3 -0
- package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +2 -2
- 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/getTextSeralizersFromSchema.d.ts +3 -0
- package/dist/packages/core/src/helpers/isActive.d.ts +1 -2
- package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +2 -0
- package/dist/packages/core/src/helpers/isMarkActive.d.ts +1 -2
- package/dist/packages/core/src/helpers/isNodeActive.d.ts +1 -2
- package/dist/packages/core/src/helpers/posToDOMRect.d.ts +2 -0
- package/dist/packages/core/src/helpers/splitExtensions.d.ts +3 -3
- package/dist/packages/core/src/index.d.ts +33 -5
- package/dist/packages/core/src/inputRules/markInputRule.d.ts +11 -2
- package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +11 -2
- 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 +23 -0
- package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +11 -2
- package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +9 -0
- package/dist/packages/core/src/style.d.ts +1 -1
- package/dist/packages/core/src/types.d.ts +105 -52
- package/dist/packages/core/src/utilities/callOrReturn.d.ts +2 -1
- package/dist/packages/core/src/utilities/deleteProps.d.ts +1 -2
- package/dist/packages/core/src/utilities/findDuplicates.d.ts +1 -0
- package/dist/packages/core/src/utilities/isClass.d.ts +1 -1
- 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/isNumber.d.ts +1 -0
- package/dist/packages/core/src/utilities/isObject.d.ts +1 -1
- 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/isiOS.d.ts +1 -0
- package/dist/packages/core/src/utilities/mergeAttributes.d.ts +1 -2
- package/dist/packages/core/src/utilities/mergeDeep.d.ts +1 -2
- package/dist/packages/core/src/utilities/objectIncludes.d.ts +3 -2
- package/dist/tiptap-core.cjs.js +2723 -1455
- package/dist/tiptap-core.cjs.js.map +1 -1
- package/dist/tiptap-core.esm.js +3172 -1931
- package/dist/tiptap-core.esm.js.map +1 -1
- package/dist/tiptap-core.umd.js +3292 -2023
- package/dist/tiptap-core.umd.js.map +1 -1
- package/package.json +19 -16
- package/src/CommandManager.ts +59 -61
- package/src/Editor.ts +91 -95
- package/src/EventEmitter.ts +14 -4
- package/src/Extension.ts +202 -40
- package/src/ExtensionManager.ts +234 -70
- package/src/InputRule.ts +268 -0
- package/src/Mark.ts +248 -46
- package/src/Node.ts +275 -51
- package/src/NodeView.ts +105 -42
- package/src/PasteRule.ts +215 -0
- package/src/Tracker.ts +42 -0
- package/src/commands/blur.ts +9 -7
- package/src/commands/clearContent.ts +3 -3
- package/src/commands/clearNodes.ts +25 -19
- package/src/commands/command.ts +2 -2
- package/src/commands/createParagraphNear.ts +3 -3
- package/src/commands/deleteNode.ts +36 -0
- package/src/commands/deleteRange.ts +3 -3
- package/src/commands/deleteSelection.ts +3 -3
- package/src/commands/enter.ts +3 -3
- package/src/commands/exitCode.ts +3 -3
- package/src/commands/extendMarkRange.ts +8 -8
- package/src/commands/first.ts +3 -3
- package/src/commands/focus.ts +54 -12
- package/src/commands/forEach.ts +24 -0
- package/src/commands/insertContent.ts +23 -0
- package/src/commands/insertContentAt.ts +93 -0
- package/src/commands/joinBackward.ts +3 -3
- package/src/commands/joinForward.ts +3 -3
- package/src/commands/keyboardShortcut.ts +3 -3
- package/src/commands/lift.ts +3 -3
- package/src/commands/liftEmptyBlock.ts +3 -3
- package/src/commands/liftListItem.ts +3 -3
- package/src/commands/newlineInCode.ts +3 -3
- package/src/commands/resetAttributes.ts +61 -0
- package/src/commands/scrollIntoView.ts +3 -3
- package/src/commands/selectAll.ts +8 -6
- package/src/commands/selectNodeBackward.ts +3 -3
- package/src/commands/selectNodeForward.ts +3 -3
- package/src/commands/selectParentNode.ts +3 -3
- package/src/commands/setContent.ts +10 -5
- package/src/commands/setMark.ts +33 -10
- package/src/commands/setMeta.ts +18 -0
- package/src/commands/setNode.ts +3 -3
- package/src/commands/setNodeSelection.ts +28 -0
- package/src/commands/setTextSelection.ts +32 -0
- package/src/commands/sinkListItem.ts +3 -3
- package/src/commands/splitBlock.ts +13 -8
- package/src/commands/splitListItem.ts +39 -13
- package/src/commands/toggleList.ts +4 -4
- package/src/commands/toggleMark.ts +15 -5
- package/src/commands/toggleNode.ts +3 -3
- package/src/commands/toggleWrap.ts +3 -3
- package/src/commands/undoInputRule.ts +33 -5
- package/src/commands/unsetAllMarks.ts +3 -3
- package/src/commands/unsetMark.ts +32 -20
- package/src/commands/updateAttributes.ts +72 -0
- package/src/commands/wrapIn.ts +3 -3
- package/src/commands/wrapInList.ts +3 -3
- package/src/extensions/clipboardTextSerializer.ts +11 -35
- package/src/extensions/commands.ts +27 -21
- package/src/extensions/focusEvents.ts +0 -3
- package/src/extensions/index.ts +1 -0
- package/src/extensions/keymap.ts +6 -6
- package/src/extensions/tabindex.ts +19 -0
- package/src/helpers/createChainableState.ts +37 -0
- package/src/helpers/createDocument.ts +11 -0
- package/src/helpers/createNodeFromContent.ts +56 -0
- package/src/helpers/defaultBlockAt.ts +13 -0
- package/src/helpers/findChildren.ts +17 -0
- package/src/helpers/findChildrenInRange.ts +31 -0
- package/src/helpers/generateHTML.ts +3 -3
- package/src/helpers/generateJSON.ts +13 -0
- package/src/helpers/generateText.ts +29 -0
- package/src/helpers/getAttributes.ts +27 -0
- package/src/helpers/getAttributesFromExtensions.ts +26 -5
- package/src/helpers/getDebugJSON.ts +46 -0
- package/src/helpers/getExtensionField.ts +25 -0
- package/src/helpers/getHTMLFromFragment.ts +5 -5
- package/src/helpers/getMarkAttributes.ts +11 -8
- package/src/helpers/getMarkRange.ts +34 -6
- package/src/helpers/getMarkType.ts +4 -0
- package/src/helpers/getMarksBetween.ts +3 -3
- package/src/helpers/getNodeAttributes.ts +6 -7
- package/src/helpers/getNodeType.ts +4 -0
- package/src/helpers/getRenderedAttributes.ts +3 -5
- package/src/helpers/getSchema.ts +5 -132
- package/src/helpers/getSchemaByResolvedExtensions.ts +147 -0
- package/src/helpers/getSchemaTypeByName.ts +1 -9
- package/src/helpers/getSplittedAttributes.ts +3 -3
- package/src/helpers/getText.ts +18 -0
- package/src/helpers/getTextBetween.ts +45 -0
- package/src/helpers/getTextSeralizersFromSchema.ts +9 -0
- package/src/helpers/injectExtensionAttributesToParseRule.ts +12 -8
- package/src/helpers/isActive.ts +1 -2
- package/src/helpers/isExtensionRulesEnabled.ts +15 -0
- package/src/helpers/isList.ts +11 -4
- package/src/helpers/isMarkActive.ts +40 -16
- package/src/helpers/isNodeActive.ts +23 -31
- package/src/helpers/posToDOMRect.ts +34 -0
- package/src/index.ts +35 -5
- package/src/inputRules/markInputRule.ts +57 -38
- package/src/inputRules/nodeInputRule.ts +43 -11
- package/src/inputRules/textInputRule.ts +35 -0
- package/src/inputRules/textblockTypeInputRule.ts +37 -0
- package/src/inputRules/wrappingInputRule.ts +59 -0
- package/src/pasteRules/markPasteRule.ts +61 -53
- package/src/pasteRules/textPasteRule.ts +35 -0
- package/src/style.ts +15 -0
- package/src/types.ts +119 -37
- package/src/utilities/callOrReturn.ts +6 -3
- package/src/utilities/createStyleTag.ts +7 -0
- package/src/utilities/deleteProps.ts +2 -4
- package/src/utilities/elementFromString.ts +3 -4
- package/src/utilities/findDuplicates.ts +5 -0
- package/src/utilities/fromString.ts +1 -1
- package/src/utilities/isClass.ts +2 -2
- package/src/utilities/isEmptyObject.ts +2 -2
- package/src/utilities/isFunction.ts +3 -0
- package/src/utilities/isNumber.ts +3 -0
- package/src/utilities/isObject.ts +5 -5
- package/src/utilities/isPlainObject.ts +5 -5
- package/src/utilities/isRegExp.ts +3 -0
- package/src/utilities/isString.ts +3 -0
- package/src/utilities/isiOS.ts +12 -0
- package/src/utilities/mergeAttributes.ts +2 -3
- package/src/utilities/mergeDeep.ts +1 -2
- package/src/utilities/objectIncludes.ts +17 -5
- package/CHANGELOG.md +0 -294
- package/dist/packages/core/src/commands/insertHTML.d.ts +0 -12
- package/dist/packages/core/src/commands/insertNode.d.ts +0 -13
- package/dist/packages/core/src/commands/insertText.d.ts +0 -12
- package/dist/packages/core/src/commands/replace.d.ts +0 -13
- package/dist/packages/core/src/commands/replaceRange.d.ts +0 -13
- package/dist/packages/core/src/commands/resetNodeAttributes.d.ts +0 -13
- package/dist/packages/core/src/commands/updateNodeAttributes.d.ts +0 -13
- package/dist/packages/core/src/utilities/removeElement.d.ts +0 -1
- package/dist/tiptap-core.bundle.umd.min.js +0 -17
- package/dist/tiptap-core.bundle.umd.min.js.map +0 -1
- package/src/commands/insertHTML.ts +0 -28
- package/src/commands/insertNode.ts +0 -31
- package/src/commands/insertText.ts +0 -20
- package/src/commands/replace.ts +0 -20
- package/src/commands/replaceRange.ts +0 -36
- package/src/commands/resetNodeAttributes.ts +0 -31
- package/src/commands/updateNodeAttributes.ts +0 -33
- package/src/utilities/removeElement.ts +0 -5
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import { TextSelection } from 'prosemirror-state'
|
|
2
|
-
import {
|
|
2
|
+
import { ParseOptions } from 'prosemirror-model'
|
|
3
|
+
import createDocument from '../helpers/createDocument'
|
|
4
|
+
import { RawCommands, Content } from '../types'
|
|
3
5
|
|
|
4
6
|
declare module '@tiptap/core' {
|
|
5
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
6
8
|
setContent: {
|
|
7
9
|
/**
|
|
8
10
|
* Replace the whole document with new content.
|
|
9
11
|
*/
|
|
10
|
-
setContent: (
|
|
12
|
+
setContent: (
|
|
13
|
+
content: Content,
|
|
14
|
+
emitUpdate?: boolean,
|
|
15
|
+
parseOptions?: ParseOptions,
|
|
16
|
+
) => ReturnType,
|
|
11
17
|
}
|
|
12
18
|
}
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
export const setContent: RawCommands['setContent'] = (content, emitUpdate = false, parseOptions = {}) => ({ tr, editor, dispatch }) => {
|
|
16
|
-
const { createDocument } = editor
|
|
17
22
|
const { doc } = tr
|
|
18
|
-
const document = createDocument(content, parseOptions)
|
|
23
|
+
const document = createDocument(content, editor.schema, parseOptions)
|
|
19
24
|
const selection = TextSelection.create(doc, 0, doc.content.size)
|
|
20
25
|
|
|
21
26
|
if (dispatch) {
|
package/src/commands/setMark.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { MarkType } from 'prosemirror-model'
|
|
2
|
-
import {
|
|
2
|
+
import { RawCommands } from '../types'
|
|
3
3
|
import getMarkType from '../helpers/getMarkType'
|
|
4
4
|
import getMarkAttributes from '../helpers/getMarkAttributes'
|
|
5
5
|
|
|
6
6
|
declare module '@tiptap/core' {
|
|
7
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
8
|
setMark: {
|
|
9
9
|
/**
|
|
10
10
|
* Add a mark with new attributes.
|
|
11
11
|
*/
|
|
12
|
-
setMark: (typeOrName: string | MarkType, attributes?:
|
|
12
|
+
setMark: (typeOrName: string | MarkType, attributes?: Record<string, any>) => ReturnType,
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -18,18 +18,41 @@ export const setMark: RawCommands['setMark'] = (typeOrName, attributes = {}) =>
|
|
|
18
18
|
const { selection } = tr
|
|
19
19
|
const { empty, ranges } = selection
|
|
20
20
|
const type = getMarkType(typeOrName, state.schema)
|
|
21
|
-
const oldAttributes = getMarkAttributes(state, type)
|
|
22
|
-
const newAttributes = {
|
|
23
|
-
...oldAttributes,
|
|
24
|
-
...attributes,
|
|
25
|
-
}
|
|
26
21
|
|
|
27
22
|
if (dispatch) {
|
|
28
23
|
if (empty) {
|
|
29
|
-
|
|
24
|
+
const oldAttributes = getMarkAttributes(state, type)
|
|
25
|
+
|
|
26
|
+
tr.addStoredMark(type.create({
|
|
27
|
+
...oldAttributes,
|
|
28
|
+
...attributes,
|
|
29
|
+
}))
|
|
30
30
|
} else {
|
|
31
31
|
ranges.forEach(range => {
|
|
32
|
-
|
|
32
|
+
const from = range.$from.pos
|
|
33
|
+
const to = range.$to.pos
|
|
34
|
+
|
|
35
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
36
|
+
const trimmedFrom = Math.max(pos, from)
|
|
37
|
+
const trimmedTo = Math.min(pos + node.nodeSize, to)
|
|
38
|
+
const someHasMark = node.marks.find(mark => mark.type === type)
|
|
39
|
+
|
|
40
|
+
// if there is already a mark of this type
|
|
41
|
+
// we know that we have to merge its attributes
|
|
42
|
+
// otherwise we add a fresh new mark
|
|
43
|
+
if (someHasMark) {
|
|
44
|
+
node.marks.forEach(mark => {
|
|
45
|
+
if (type === mark.type) {
|
|
46
|
+
tr.addMark(trimmedFrom, trimmedTo, type.create({
|
|
47
|
+
...mark.attrs,
|
|
48
|
+
...attributes,
|
|
49
|
+
}))
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
} else {
|
|
53
|
+
tr.addMark(trimmedFrom, trimmedTo, type.create(attributes))
|
|
54
|
+
}
|
|
55
|
+
})
|
|
33
56
|
})
|
|
34
57
|
}
|
|
35
58
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RawCommands } from '../types'
|
|
2
|
+
|
|
3
|
+
declare module '@tiptap/core' {
|
|
4
|
+
interface Commands<ReturnType> {
|
|
5
|
+
setMeta: {
|
|
6
|
+
/**
|
|
7
|
+
* Store a metadata property in the current transaction.
|
|
8
|
+
*/
|
|
9
|
+
setMeta: (key: string, value: any) => ReturnType,
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const setMeta: RawCommands['setMeta'] = (key, value) => ({ tr }) => {
|
|
15
|
+
tr.setMeta(key, value)
|
|
16
|
+
|
|
17
|
+
return true
|
|
18
|
+
}
|
package/src/commands/setNode.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { NodeType } from 'prosemirror-model'
|
|
2
2
|
import { setBlockType } from 'prosemirror-commands'
|
|
3
|
-
import {
|
|
3
|
+
import { RawCommands } from '../types'
|
|
4
4
|
import getNodeType from '../helpers/getNodeType'
|
|
5
5
|
|
|
6
6
|
declare module '@tiptap/core' {
|
|
7
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
8
|
setNode: {
|
|
9
9
|
/**
|
|
10
10
|
* Replace a given range with a node.
|
|
11
11
|
*/
|
|
12
|
-
setNode: (typeOrName: string | NodeType, attributes?:
|
|
12
|
+
setNode: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType,
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Selection, NodeSelection } from 'prosemirror-state'
|
|
2
|
+
import minMax from '../utilities/minMax'
|
|
3
|
+
import { RawCommands } from '../types'
|
|
4
|
+
|
|
5
|
+
declare module '@tiptap/core' {
|
|
6
|
+
interface Commands<ReturnType> {
|
|
7
|
+
setNodeSelection: {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a NodeSelection.
|
|
10
|
+
*/
|
|
11
|
+
setNodeSelection: (position: number) => ReturnType,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const setNodeSelection: RawCommands['setNodeSelection'] = position => ({ tr, dispatch }) => {
|
|
17
|
+
if (dispatch) {
|
|
18
|
+
const { doc } = tr
|
|
19
|
+
const minPos = Selection.atStart(doc).from
|
|
20
|
+
const maxPos = Selection.atEnd(doc).to
|
|
21
|
+
const resolvedPos = minMax(position, minPos, maxPos)
|
|
22
|
+
const selection = NodeSelection.create(doc, resolvedPos)
|
|
23
|
+
|
|
24
|
+
tr.setSelection(selection)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return true
|
|
28
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Selection, TextSelection } from 'prosemirror-state'
|
|
2
|
+
import minMax from '../utilities/minMax'
|
|
3
|
+
import { RawCommands, Range } from '../types'
|
|
4
|
+
|
|
5
|
+
declare module '@tiptap/core' {
|
|
6
|
+
interface Commands<ReturnType> {
|
|
7
|
+
setTextSelection: {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a TextSelection.
|
|
10
|
+
*/
|
|
11
|
+
setTextSelection: (position: number | Range) => ReturnType,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const setTextSelection: RawCommands['setTextSelection'] = position => ({ tr, dispatch }) => {
|
|
17
|
+
if (dispatch) {
|
|
18
|
+
const { doc } = tr
|
|
19
|
+
const { from, to } = typeof position === 'number'
|
|
20
|
+
? { from: position, to: position }
|
|
21
|
+
: position
|
|
22
|
+
const minPos = Selection.atStart(doc).from
|
|
23
|
+
const maxPos = Selection.atEnd(doc).to
|
|
24
|
+
const resolvedFrom = minMax(from, minPos, maxPos)
|
|
25
|
+
const resolvedEnd = minMax(to, minPos, maxPos)
|
|
26
|
+
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
|
|
27
|
+
|
|
28
|
+
tr.setSelection(selection)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
|
|
2
2
|
import { NodeType } from 'prosemirror-model'
|
|
3
|
-
import {
|
|
3
|
+
import { RawCommands } from '../types'
|
|
4
4
|
import getNodeType from '../helpers/getNodeType'
|
|
5
5
|
|
|
6
6
|
declare module '@tiptap/core' {
|
|
7
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
8
|
sinkListItem: {
|
|
9
9
|
/**
|
|
10
10
|
* Sink the list item down into an inner list.
|
|
11
11
|
*/
|
|
12
|
-
sinkListItem: (typeOrName: string | NodeType) =>
|
|
12
|
+
sinkListItem: (typeOrName: string | NodeType) => ReturnType,
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { canSplit } from 'prosemirror-transform'
|
|
2
|
-
import { ContentMatch
|
|
2
|
+
import { ContentMatch } from 'prosemirror-model'
|
|
3
3
|
import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state'
|
|
4
|
-
import {
|
|
4
|
+
import { RawCommands } from '../types'
|
|
5
5
|
import getSplittedAttributes from '../helpers/getSplittedAttributes'
|
|
6
6
|
|
|
7
7
|
function defaultBlockAt(match: ContentMatch) {
|
|
8
|
-
for (let i = 0; i < match.edgeCount; i
|
|
8
|
+
for (let i = 0; i < match.edgeCount; i += 1) {
|
|
9
9
|
const { type } = match.edge(i)
|
|
10
10
|
|
|
11
11
|
if (type.isTextblock && !type.hasRequiredAttrs()) {
|
|
@@ -27,12 +27,12 @@ function ensureMarks(state: EditorState, splittableMarks?: string[]) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
declare module '@tiptap/core' {
|
|
30
|
-
interface Commands {
|
|
30
|
+
interface Commands<ReturnType> {
|
|
31
31
|
splitBlock: {
|
|
32
32
|
/**
|
|
33
33
|
* Forks a new node from an existing node.
|
|
34
34
|
*/
|
|
35
|
-
splitBlock: (options?: { keepMarks?: boolean }) =>
|
|
35
|
+
splitBlock: (options?: { keepMarks?: boolean }) => ReturnType,
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -110,12 +110,17 @@ export const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {})
|
|
|
110
110
|
tr.split(tr.mapping.map($from.pos), 1, types)
|
|
111
111
|
|
|
112
112
|
if (
|
|
113
|
-
|
|
113
|
+
deflt
|
|
114
|
+
&& !atEnd
|
|
114
115
|
&& !$from.parentOffset
|
|
115
116
|
&& $from.parent.type !== deflt
|
|
116
|
-
&& $from.node(-1).canReplace($from.index(-1), $from.indexAfter(-1), Fragment.from(deflt?.create()))
|
|
117
117
|
) {
|
|
118
|
-
tr.
|
|
118
|
+
const first = tr.mapping.map($from.before())
|
|
119
|
+
const $first = tr.doc.resolve(first)
|
|
120
|
+
|
|
121
|
+
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) {
|
|
122
|
+
tr.setNodeMarkup(tr.mapping.map($from.before()), deflt)
|
|
123
|
+
}
|
|
119
124
|
}
|
|
120
125
|
}
|
|
121
126
|
|
|
@@ -6,17 +6,17 @@ import {
|
|
|
6
6
|
} from 'prosemirror-model'
|
|
7
7
|
import { canSplit } from 'prosemirror-transform'
|
|
8
8
|
import { TextSelection } from 'prosemirror-state'
|
|
9
|
-
import {
|
|
9
|
+
import { RawCommands } from '../types'
|
|
10
10
|
import getNodeType from '../helpers/getNodeType'
|
|
11
11
|
import getSplittedAttributes from '../helpers/getSplittedAttributes'
|
|
12
12
|
|
|
13
13
|
declare module '@tiptap/core' {
|
|
14
|
-
interface Commands {
|
|
14
|
+
interface Commands<ReturnType> {
|
|
15
15
|
splitListItem: {
|
|
16
16
|
/**
|
|
17
17
|
* Splits one list item into two list items.
|
|
18
18
|
*/
|
|
19
|
-
splitListItem: (typeOrName: string | NodeType) =>
|
|
19
|
+
splitListItem: (typeOrName: string | NodeType) => ReturnType,
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -57,14 +57,26 @@ export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
|
|
|
57
57
|
|
|
58
58
|
if (dispatch) {
|
|
59
59
|
let wrap = Fragment.empty
|
|
60
|
-
|
|
60
|
+
// eslint-disable-next-line
|
|
61
|
+
const depthBefore = $from.index(-1)
|
|
62
|
+
? 1
|
|
63
|
+
: $from.index(-2)
|
|
64
|
+
? 2
|
|
65
|
+
: 3
|
|
61
66
|
|
|
62
67
|
// Build a fragment containing empty versions of the structure
|
|
63
68
|
// from the outer list item to the parent node of the cursor
|
|
64
|
-
for (let d = $from.depth -
|
|
69
|
+
for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) {
|
|
65
70
|
wrap = Fragment.from($from.node(d).copy(wrap))
|
|
66
71
|
}
|
|
67
72
|
|
|
73
|
+
// eslint-disable-next-line
|
|
74
|
+
const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount
|
|
75
|
+
? 1
|
|
76
|
+
: $from.indexAfter(-2) < $from.node(-3).childCount
|
|
77
|
+
? 2
|
|
78
|
+
: 3
|
|
79
|
+
|
|
68
80
|
// Add a second list item with an empty default start node
|
|
69
81
|
const newNextTypeAttributes = getSplittedAttributes(
|
|
70
82
|
extensionAttributes,
|
|
@@ -72,16 +84,30 @@ export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
|
|
|
72
84
|
$from.node().attrs,
|
|
73
85
|
)
|
|
74
86
|
const nextType = type.contentMatch.defaultType?.createAndFill(newNextTypeAttributes) || undefined
|
|
87
|
+
|
|
75
88
|
wrap = wrap.append(Fragment.from(type.createAndFill(null, nextType) || undefined))
|
|
76
89
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
const start = $from.before($from.depth - (depthBefore - 1))
|
|
91
|
+
|
|
92
|
+
tr.replace(start, $from.after(-depthAfter), new Slice(wrap, 4 - depthBefore, 0))
|
|
93
|
+
|
|
94
|
+
let sel = -1
|
|
95
|
+
|
|
96
|
+
tr.doc.nodesBetween(start, tr.doc.content.size, (n, pos) => {
|
|
97
|
+
if (sel > -1) {
|
|
98
|
+
return false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (n.isTextblock && n.content.size === 0) {
|
|
102
|
+
sel = pos + 1
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
if (sel > -1) {
|
|
107
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve(sel)))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
tr.scrollIntoView()
|
|
85
111
|
}
|
|
86
112
|
|
|
87
113
|
return true
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { NodeType } from 'prosemirror-model'
|
|
2
|
-
import {
|
|
2
|
+
import { RawCommands } from '../types'
|
|
3
3
|
import getNodeType from '../helpers/getNodeType'
|
|
4
4
|
import findParentNode from '../helpers/findParentNode'
|
|
5
5
|
import isList from '../helpers/isList'
|
|
6
6
|
|
|
7
7
|
declare module '@tiptap/core' {
|
|
8
|
-
interface Commands {
|
|
8
|
+
interface Commands<ReturnType> {
|
|
9
9
|
toggleList: {
|
|
10
10
|
/**
|
|
11
11
|
* Toggle between different list types.
|
|
12
12
|
*/
|
|
13
|
-
toggleList: (listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType) =>
|
|
13
|
+
toggleList: (listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType) => ReturnType,
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -18,7 +18,7 @@ declare module '@tiptap/core' {
|
|
|
18
18
|
export const toggleList: RawCommands['toggleList'] = (listTypeOrName, itemTypeOrName) => ({
|
|
19
19
|
editor, tr, state, dispatch, chain, commands, can,
|
|
20
20
|
}) => {
|
|
21
|
-
const { extensions } = editor.
|
|
21
|
+
const { extensions } = editor.extensionManager
|
|
22
22
|
const listType = getNodeType(listTypeOrName, state.schema)
|
|
23
23
|
const itemType = getNodeType(itemTypeOrName, state.schema)
|
|
24
24
|
const { selection } = state
|
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
import { MarkType } from 'prosemirror-model'
|
|
2
|
-
import {
|
|
2
|
+
import { RawCommands } from '../types'
|
|
3
3
|
import getMarkType from '../helpers/getMarkType'
|
|
4
4
|
import isMarkActive from '../helpers/isMarkActive'
|
|
5
5
|
|
|
6
6
|
declare module '@tiptap/core' {
|
|
7
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
8
|
toggleMark: {
|
|
9
9
|
/**
|
|
10
10
|
* Toggle a mark on and off.
|
|
11
11
|
*/
|
|
12
|
-
toggleMark: (
|
|
12
|
+
toggleMark: (
|
|
13
|
+
typeOrName: string | MarkType,
|
|
14
|
+
attributes?: Record<string, any>,
|
|
15
|
+
options?: {
|
|
16
|
+
/**
|
|
17
|
+
* Removes the mark even across the current selection. Defaults to `false`.
|
|
18
|
+
*/
|
|
19
|
+
extendEmptyMarkRange?: boolean,
|
|
20
|
+
},
|
|
21
|
+
) => ReturnType,
|
|
13
22
|
}
|
|
14
23
|
}
|
|
15
24
|
}
|
|
16
25
|
|
|
17
|
-
export const toggleMark: RawCommands['toggleMark'] = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
|
26
|
+
export const toggleMark: RawCommands['toggleMark'] = (typeOrName, attributes = {}, options = {}) => ({ state, commands }) => {
|
|
27
|
+
const { extendEmptyMarkRange = false } = options
|
|
18
28
|
const type = getMarkType(typeOrName, state.schema)
|
|
19
29
|
const isActive = isMarkActive(state, type, attributes)
|
|
20
30
|
|
|
21
31
|
if (isActive) {
|
|
22
|
-
return commands.unsetMark(type)
|
|
32
|
+
return commands.unsetMark(type, { extendEmptyMarkRange })
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
return commands.setMark(type, attributes)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { NodeType } from 'prosemirror-model'
|
|
2
|
-
import {
|
|
2
|
+
import { RawCommands } from '../types'
|
|
3
3
|
import isNodeActive from '../helpers/isNodeActive'
|
|
4
4
|
import getNodeType from '../helpers/getNodeType'
|
|
5
5
|
|
|
6
6
|
declare module '@tiptap/core' {
|
|
7
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
8
|
toggleNode: {
|
|
9
9
|
/**
|
|
10
10
|
* Toggle a node with another node.
|
|
11
11
|
*/
|
|
12
|
-
toggleNode: (typeOrName: string | NodeType, toggleTypeOrName: string | NodeType, attributes?:
|
|
12
|
+
toggleNode: (typeOrName: string | NodeType, toggleTypeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType,
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { wrapIn, lift } from 'prosemirror-commands'
|
|
2
2
|
import { NodeType } from 'prosemirror-model'
|
|
3
|
-
import {
|
|
3
|
+
import { RawCommands } from '../types'
|
|
4
4
|
import isNodeActive from '../helpers/isNodeActive'
|
|
5
5
|
import getNodeType from '../helpers/getNodeType'
|
|
6
6
|
|
|
7
7
|
declare module '@tiptap/core' {
|
|
8
|
-
interface Commands {
|
|
8
|
+
interface Commands<ReturnType> {
|
|
9
9
|
toggleWrap: {
|
|
10
10
|
/**
|
|
11
11
|
* Wraps nodes in another node, or removes an existing wrap.
|
|
12
12
|
*/
|
|
13
|
-
toggleWrap: (typeOrName: string | NodeType, attributes?:
|
|
13
|
+
toggleWrap: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType,
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,17 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Command, RawCommands } from '../types'
|
|
1
|
+
import { RawCommands } from '../types'
|
|
3
2
|
|
|
4
3
|
declare module '@tiptap/core' {
|
|
5
|
-
interface Commands {
|
|
4
|
+
interface Commands<ReturnType> {
|
|
6
5
|
undoInputRule: {
|
|
7
6
|
/**
|
|
8
7
|
* Undo an input rule.
|
|
9
8
|
*/
|
|
10
|
-
undoInputRule: () =>
|
|
9
|
+
undoInputRule: () => ReturnType,
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export const undoInputRule: RawCommands['undoInputRule'] = () => ({ state, dispatch }) => {
|
|
16
|
-
|
|
15
|
+
const plugins = state.plugins
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < plugins.length; i += 1) {
|
|
18
|
+
const plugin = plugins[i]
|
|
19
|
+
let undoable
|
|
20
|
+
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
// eslint-disable-next-line
|
|
23
|
+
if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
|
|
24
|
+
if (dispatch) {
|
|
25
|
+
const tr = state.tr
|
|
26
|
+
const toUndo = undoable.transform
|
|
27
|
+
|
|
28
|
+
for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
|
|
29
|
+
tr.step(toUndo.steps[j].invert(toUndo.docs[j]))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (undoable.text) {
|
|
33
|
+
const marks = tr.doc.resolve(undoable.from).marks()
|
|
34
|
+
tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks))
|
|
35
|
+
} else {
|
|
36
|
+
tr.delete(undoable.from, undoable.to)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return false
|
|
17
45
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RawCommands } from '../types'
|
|
2
2
|
|
|
3
3
|
declare module '@tiptap/core' {
|
|
4
|
-
interface Commands {
|
|
4
|
+
interface Commands<ReturnType> {
|
|
5
5
|
unsetAllMarks: {
|
|
6
6
|
/**
|
|
7
7
|
* Remove all marks in the current selection.
|
|
8
8
|
*/
|
|
9
|
-
unsetAllMarks: () =>
|
|
9
|
+
unsetAllMarks: () => ReturnType,
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -1,43 +1,55 @@
|
|
|
1
1
|
import { MarkType } from 'prosemirror-model'
|
|
2
|
-
import {
|
|
2
|
+
import { RawCommands } from '../types'
|
|
3
3
|
import getMarkType from '../helpers/getMarkType'
|
|
4
4
|
import getMarkRange from '../helpers/getMarkRange'
|
|
5
5
|
|
|
6
6
|
declare module '@tiptap/core' {
|
|
7
|
-
interface Commands {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
8
|
unsetMark: {
|
|
9
9
|
/**
|
|
10
10
|
* Remove all marks in the current selection.
|
|
11
11
|
*/
|
|
12
|
-
unsetMark: (
|
|
12
|
+
unsetMark: (
|
|
13
|
+
typeOrName: string | MarkType,
|
|
14
|
+
options?: {
|
|
15
|
+
/**
|
|
16
|
+
* Removes the mark even across the current selection. Defaults to `false`.
|
|
17
|
+
*/
|
|
18
|
+
extendEmptyMarkRange?: boolean,
|
|
19
|
+
},
|
|
20
|
+
) => ReturnType,
|
|
13
21
|
}
|
|
14
22
|
}
|
|
15
23
|
}
|
|
16
24
|
|
|
17
|
-
export const unsetMark: RawCommands['unsetMark'] = typeOrName => ({ tr, state, dispatch }) => {
|
|
25
|
+
export const unsetMark: RawCommands['unsetMark'] = (typeOrName, options = {}) => ({ tr, state, dispatch }) => {
|
|
26
|
+
const { extendEmptyMarkRange = false } = options
|
|
18
27
|
const { selection } = tr
|
|
19
28
|
const type = getMarkType(typeOrName, state.schema)
|
|
20
29
|
const { $from, empty, ranges } = selection
|
|
21
30
|
|
|
22
|
-
if (dispatch) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
ranges.forEach(range => {
|
|
35
|
-
tr.removeMark(range.$from.pos, range.$to.pos, type)
|
|
36
|
-
})
|
|
31
|
+
if (!dispatch) {
|
|
32
|
+
return true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (empty && extendEmptyMarkRange) {
|
|
36
|
+
let { from, to } = selection
|
|
37
|
+
const attrs = $from.marks().find(mark => mark.type === type)?.attrs
|
|
38
|
+
const range = getMarkRange($from, type, attrs)
|
|
39
|
+
|
|
40
|
+
if (range) {
|
|
41
|
+
from = range.from
|
|
42
|
+
to = range.to
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
tr.
|
|
45
|
+
tr.removeMark(from, to, type)
|
|
46
|
+
} else {
|
|
47
|
+
ranges.forEach(range => {
|
|
48
|
+
tr.removeMark(range.$from.pos, range.$to.pos, type)
|
|
49
|
+
})
|
|
40
50
|
}
|
|
41
51
|
|
|
52
|
+
tr.removeStoredMark(type)
|
|
53
|
+
|
|
42
54
|
return true
|
|
43
55
|
}
|