@tiptap/extension-unique-id 2.0.0-beta.4 → 2.22.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 +14 -0
- package/dist/helpers/findDuplicates.d.ts +5 -0
- package/dist/helpers/findDuplicates.d.ts.map +1 -0
- package/dist/helpers/removeDuplicates.d.ts +9 -0
- package/dist/helpers/removeDuplicates.d.ts.map +1 -0
- package/dist/{tiptap-extension-unique-id.cjs.js → index.cjs} +253 -282
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/{tiptap-extension-unique-id.esm.js → index.js} +253 -282
- package/dist/index.js.map +1 -0
- package/dist/{tiptap-extension-unique-id.umd.js → index.umd.js} +255 -283
- package/dist/index.umd.js.map +1 -0
- package/dist/{tiptap-pro/packages/extension-unique-id/src/unique-id.d.ts → unique-id.d.ts} +10 -9
- package/dist/unique-id.d.ts.map +1 -0
- package/package.json +31 -13
- package/src/helpers/findDuplicates.ts +2 -2
- package/src/helpers/removeDuplicates.ts +1 -1
- package/src/index.ts +2 -2
- package/src/unique-id.ts +97 -33
- package/dist/tiptap-extension-unique-id.cjs.js.map +0 -1
- package/dist/tiptap-extension-unique-id.esm.js.map +0 -1
- package/dist/tiptap-extension-unique-id.umd.js.map +0 -1
- package/dist/tiptap-pro/packages/extension-unique-id/src/helpers/combineTransactionSteps.d.ts +0 -7
- package/dist/tiptap-pro/packages/extension-unique-id/src/helpers/findDuplicates.d.ts +0 -4
- package/dist/tiptap-pro/packages/extension-unique-id/src/helpers/getChangedRanges.d.ts +0 -12
- package/dist/tiptap-pro/packages/extension-unique-id/src/helpers/removeDuplicates.d.ts +0 -8
- package/dist/tiptap-pro/packages/extension-unique-id/src/index.d.ts +0 -3
- package/src/helpers/arrayDifference.ts +0 -35
- package/src/helpers/combineTransactionSteps.ts +0 -18
- package/src/helpers/getChangedRanges.ts +0 -78
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/helpers/removeDuplicates.ts","../src/helpers/findDuplicates.ts","../src/unique-id.ts"],"sourcesContent":["/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nexport function removeDuplicates<T>(array: T[], by = JSON.stringify): T[] {\n const seen: Record<any, any> = {}\n\n return array.filter(item => {\n const key = by(item)\n\n return Object.prototype.hasOwnProperty.call(seen, key)\n ? false\n : (seen[key] = true)\n })\n}\n","import { removeDuplicates } from './removeDuplicates.js'\n\n/**\n * Returns a list of duplicated items within an array.\n */\nexport function findDuplicates(items: any[]): any[] {\n const filtered = items.filter((el, index) => items.indexOf(el) !== index)\n const duplicates = removeDuplicates(filtered)\n\n return duplicates\n}\n","import {\n combineTransactionSteps,\n Extension,\n findChildren,\n findChildrenInRange,\n getChangedRanges,\n} from '@tiptap/core'\nimport { Fragment, Node as ProseMirrorNode, Slice } from '@tiptap/pm/model'\nimport { Plugin, PluginKey, Transaction } from '@tiptap/pm/state'\nimport { v4 as uuidv4 } from 'uuid'\n\nimport { findDuplicates } from './helpers/findDuplicates.js'\n\nexport interface UniqueIDOptions {\n attributeName: string,\n types: string[],\n generateID: () => any,\n filterTransaction: ((transaction: Transaction) => boolean) | null,\n}\n\nexport const UniqueID = Extension.create<UniqueIDOptions>({\n name: 'uniqueID',\n\n // we’ll set a very high priority to make sure this runs first\n // and is compatible with `appendTransaction` hooks of other extensions\n priority: 10000,\n\n addOptions() {\n return {\n attributeName: 'id',\n types: [],\n generateID: () => uuidv4(),\n filterTransaction: null,\n }\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n [this.options.attributeName]: {\n default: null,\n parseHTML: element => element.getAttribute(`data-${this.options.attributeName}`),\n renderHTML: attributes => {\n if (!attributes[this.options.attributeName]) {\n return {}\n }\n\n return {\n [`data-${this.options.attributeName}`]: attributes[this.options.attributeName],\n }\n },\n },\n },\n },\n ]\n },\n\n // check initial content for missing ids\n onCreate() {\n const collab = this.editor.extensionManager.extensions.find(ext => ext.name === 'collaboration')\n const provider = collab?.options ? collab.options.provider : undefined\n\n const createIds = () => {\n const { view, state } = this.editor\n const { tr, doc } = state\n const { types, attributeName, generateID } = this.options\n const nodesWithoutId = findChildren(doc, node => {\n return types.includes(node.type.name) && node.attrs[attributeName] === null\n })\n\n nodesWithoutId.forEach(({ node, pos }) => {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n })\n\n tr.setMeta('addToHistory', false)\n\n view.dispatch(tr)\n\n if (provider) {\n provider.off('synced', createIds)\n }\n }\n\n /**\n * We need to handle collaboration a bit different here\n * because we can't automatically add IDs when the provider is not yet synced\n * otherwise we end up with empty paragraphs\n */\n if (collab) {\n if (!provider) {\n return createIds()\n }\n\n provider.on('synced', createIds)\n } else {\n return createIds()\n }\n },\n\n addProseMirrorPlugins() {\n let dragSourceElement: Element | null = null\n let transformPasted = false\n\n return [\n new Plugin({\n key: new PluginKey('uniqueID'),\n\n appendTransaction: (transactions, oldState, newState) => {\n const hasDocChanges = transactions.some(transaction => transaction.docChanged)\n && !oldState.doc.eq(newState.doc)\n const filterTransactions = this.options.filterTransaction\n && transactions.some(tr => !this.options.filterTransaction?.(tr))\n\n const isCollabTransaction = transactions.find(tr => tr.getMeta('y-sync$'))\n\n if (isCollabTransaction) {\n return\n }\n\n if (!hasDocChanges || filterTransactions) {\n return\n }\n\n const { tr } = newState\n\n const { types, attributeName, generateID } = this.options\n const transform = combineTransactionSteps(oldState.doc, transactions as Transaction[])\n const { mapping } = transform\n\n // get changed ranges based on the old state\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n const newNodes = findChildrenInRange(newState.doc, newRange, node => {\n return types.includes(node.type.name)\n })\n\n const newIds = newNodes\n .map(({ node }) => node.attrs[attributeName])\n .filter(id => id !== null)\n\n newNodes.forEach(({ node, pos }, i) => {\n // instead of checking `node.attrs[attributeName]` directly\n // we look at the current state of the node within `tr.doc`.\n // this helps to prevent adding new ids to the same node\n // if the node changed multiple times within one transaction\n const id = tr.doc.nodeAt(pos)?.attrs[attributeName]\n\n if (id === null) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n\n return\n }\n\n const nextNode = newNodes[i + 1]\n\n if (nextNode && node.content.size === 0) {\n tr.setNodeMarkup(nextNode.pos, undefined, {\n ...nextNode.node.attrs,\n [attributeName]: id,\n })\n newIds[i + 1] = id\n\n if (nextNode.node.attrs[attributeName]) {\n return\n }\n\n const generatedId = generateID()\n\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generatedId,\n })\n newIds[i] = generatedId\n\n return tr\n }\n\n const duplicatedNewIds = findDuplicates(newIds)\n\n // check if the node doesn’t exist in the old state\n const { deleted } = mapping.invert().mapResult(pos)\n\n const newNode = deleted && duplicatedNewIds.includes(id)\n\n if (newNode) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n }\n })\n\n })\n\n if (!tr.steps.length) {\n return\n }\n\n // `tr.setNodeMarkup` resets the stored marks\n // so we’ll restore them if they exist\n tr.setStoredMarks(newState.tr.storedMarks)\n\n return tr\n },\n\n // we register a global drag handler to track the current drag source element\n view(view) {\n const handleDragstart = (event: DragEvent) => {\n dragSourceElement = view.dom.parentElement?.contains(event.target as Element)\n ? view.dom.parentElement\n : null\n }\n\n window.addEventListener('dragstart', handleDragstart)\n\n return {\n destroy() {\n window.removeEventListener('dragstart', handleDragstart)\n },\n }\n },\n\n props: {\n // `handleDOMEvents` is called before `transformPasted`\n // so we can do some checks before\n handleDOMEvents: {\n // only create new ids for dropped content\n // or dropped content while holding `alt`\n // or content is dragged from another editor\n drop: (view, event) => {\n if (\n dragSourceElement !== view.dom.parentElement\n || event.dataTransfer?.effectAllowed === 'copyMove'\n || event.dataTransfer?.effectAllowed === 'copy'\n ) {\n dragSourceElement = null\n transformPasted = true\n }\n\n return false\n },\n // always create new ids on pasted content\n paste: () => {\n transformPasted = true\n\n return false\n },\n },\n\n // we’ll remove ids for every pasted node\n // so we can create a new one within `appendTransaction`\n transformPasted: slice => {\n if (!transformPasted) {\n return slice\n }\n\n const { types, attributeName } = this.options\n const removeId = (fragment: Fragment): Fragment => {\n const list: ProseMirrorNode[] = []\n\n fragment.forEach(node => {\n // don’t touch text nodes\n if (node.isText) {\n list.push(node)\n\n return\n }\n\n // check for any other child nodes\n if (!types.includes(node.type.name)) {\n list.push(node.copy(removeId(node.content)))\n\n return\n }\n\n // remove id\n const nodeWithoutId = node.type.create(\n {\n ...node.attrs,\n [attributeName]: null,\n },\n removeId(node.content),\n node.marks,\n )\n\n list.push(nodeWithoutId)\n })\n\n return Fragment.from(list)\n }\n\n // reset check\n transformPasted = false\n\n return new Slice(removeId(slice.content), slice.openStart, slice.openEnd)\n },\n },\n }),\n ]\n },\n\n})\n"],"names":["Extension","uuidv4","findChildren","Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","Fragment","Slice"],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Extension } from '@tiptap/core';
|
|
2
|
-
import { Transaction } from '
|
|
3
|
-
export interface UniqueIDOptions {
|
|
4
|
-
attributeName: string;
|
|
5
|
-
types: string[];
|
|
6
|
-
generateID: () => any;
|
|
7
|
-
filterTransaction: ((transaction: Transaction) => boolean) | null;
|
|
8
|
-
}
|
|
9
|
-
export declare const UniqueID: Extension<UniqueIDOptions, any>;
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import { Transaction } from '@tiptap/pm/state';
|
|
3
|
+
export interface UniqueIDOptions {
|
|
4
|
+
attributeName: string;
|
|
5
|
+
types: string[];
|
|
6
|
+
generateID: () => any;
|
|
7
|
+
filterTransaction: ((transaction: Transaction) => boolean) | null;
|
|
8
|
+
}
|
|
9
|
+
export declare const UniqueID: Extension<UniqueIDOptions, any>;
|
|
10
|
+
//# sourceMappingURL=unique-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unique-id.d.ts","sourceRoot":"","sources":["../src/unique-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EAIV,MAAM,cAAc,CAAA;AAErB,OAAO,EAAqB,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKjE,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,CAAC;IACtB,iBAAiB,EAAE,CAAC,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,GAAG,IAAI,CAAC;CACnE;AAED,eAAO,MAAM,QAAQ,iCAkSnB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/extension-unique-id",
|
|
3
3
|
"description": "unique id extension for tiptap",
|
|
4
|
-
"version": "2.
|
|
5
|
-
"homepage": "https://tiptap.dev",
|
|
4
|
+
"version": "2.22.1",
|
|
5
|
+
"homepage": "https://tiptap.dev/api/extensions/unique-id",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
8
8
|
"tiptap extension"
|
|
@@ -12,23 +12,41 @@
|
|
|
12
12
|
"type": "github",
|
|
13
13
|
"url": "https://github.com/sponsors/ueberdosis"
|
|
14
14
|
},
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
"type": "module",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"require": "./dist/index.cjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"main": "dist/index.cjs",
|
|
24
|
+
"module": "dist/index.js",
|
|
25
|
+
"umd": "dist/index.umd.js",
|
|
26
|
+
"types": "dist/index.d.ts",
|
|
19
27
|
"files": [
|
|
20
28
|
"src",
|
|
21
29
|
"dist"
|
|
22
30
|
],
|
|
23
31
|
"peerDependencies": {
|
|
24
|
-
"@tiptap/core": "^2.
|
|
32
|
+
"@tiptap/core": "^2.7.0",
|
|
33
|
+
"@tiptap/pm": "^2.7.0"
|
|
25
34
|
},
|
|
26
35
|
"dependencies": {
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
36
|
+
"uuid": "^10.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@tiptap/core": "^2.22.1",
|
|
40
|
+
"@tiptap/pm": "^2.22.1",
|
|
41
|
+
"@types/uuid": "^10.0.0"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/ueberdosis/tiptap",
|
|
46
|
+
"directory": "packages/extension-unique-id"
|
|
32
47
|
},
|
|
33
|
-
"
|
|
48
|
+
"scripts": {
|
|
49
|
+
"clean": "rm -rf dist",
|
|
50
|
+
"build": "npm run clean && rollup -c"
|
|
51
|
+
}
|
|
34
52
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import removeDuplicates from './removeDuplicates'
|
|
1
|
+
import { removeDuplicates } from './removeDuplicates.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns a list of duplicated items within an array.
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
6
|
+
export function findDuplicates(items: any[]): any[] {
|
|
7
7
|
const filtered = items.filter((el, index) => items.indexOf(el) !== index)
|
|
8
8
|
const duplicates = removeDuplicates(filtered)
|
|
9
9
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Removes duplicated values within an array.
|
|
3
3
|
* Supports numbers, strings and objects.
|
|
4
4
|
*/
|
|
5
|
-
export
|
|
5
|
+
export function removeDuplicates<T>(array: T[], by = JSON.stringify): T[] {
|
|
6
6
|
const seen: Record<any, any> = {}
|
|
7
7
|
|
|
8
8
|
return array.filter(item => {
|
package/src/index.ts
CHANGED
package/src/unique-id.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
combineTransactionSteps,
|
|
3
|
+
Extension,
|
|
4
|
+
findChildren,
|
|
5
|
+
findChildrenInRange,
|
|
6
|
+
getChangedRanges,
|
|
7
|
+
} from '@tiptap/core'
|
|
8
|
+
import { Fragment, Node as ProseMirrorNode, Slice } from '@tiptap/pm/model'
|
|
9
|
+
import { Plugin, PluginKey, Transaction } from '@tiptap/pm/state'
|
|
4
10
|
import { v4 as uuidv4 } from 'uuid'
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import findDuplicates from './helpers/findDuplicates'
|
|
11
|
+
|
|
12
|
+
import { findDuplicates } from './helpers/findDuplicates.js'
|
|
8
13
|
|
|
9
14
|
export interface UniqueIDOptions {
|
|
10
15
|
attributeName: string,
|
|
@@ -54,22 +59,47 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
54
59
|
|
|
55
60
|
// check initial content for missing ids
|
|
56
61
|
onCreate() {
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const collab = this.editor.extensionManager.extensions.find(ext => ext.name === 'collaboration')
|
|
63
|
+
const provider = collab?.options ? collab.options.provider : undefined
|
|
64
|
+
|
|
65
|
+
const createIds = () => {
|
|
66
|
+
const { view, state } = this.editor
|
|
67
|
+
const { tr, doc } = state
|
|
68
|
+
const { types, attributeName, generateID } = this.options
|
|
69
|
+
const nodesWithoutId = findChildren(doc, node => {
|
|
70
|
+
return types.includes(node.type.name) && node.attrs[attributeName] === null
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
nodesWithoutId.forEach(({ node, pos }) => {
|
|
74
|
+
tr.setNodeMarkup(pos, undefined, {
|
|
75
|
+
...node.attrs,
|
|
76
|
+
[attributeName]: generateID(),
|
|
77
|
+
})
|
|
69
78
|
})
|
|
70
|
-
})
|
|
71
79
|
|
|
72
|
-
|
|
80
|
+
tr.setMeta('addToHistory', false)
|
|
81
|
+
|
|
82
|
+
view.dispatch(tr)
|
|
83
|
+
|
|
84
|
+
if (provider) {
|
|
85
|
+
provider.off('synced', createIds)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* We need to handle collaboration a bit different here
|
|
91
|
+
* because we can't automatically add IDs when the provider is not yet synced
|
|
92
|
+
* otherwise we end up with empty paragraphs
|
|
93
|
+
*/
|
|
94
|
+
if (collab) {
|
|
95
|
+
if (!provider) {
|
|
96
|
+
return createIds()
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
provider.on('synced', createIds)
|
|
100
|
+
} else {
|
|
101
|
+
return createIds()
|
|
102
|
+
}
|
|
73
103
|
},
|
|
74
104
|
|
|
75
105
|
addProseMirrorPlugins() {
|
|
@@ -81,29 +111,31 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
81
111
|
key: new PluginKey('uniqueID'),
|
|
82
112
|
|
|
83
113
|
appendTransaction: (transactions, oldState, newState) => {
|
|
84
|
-
const
|
|
114
|
+
const hasDocChanges = transactions.some(transaction => transaction.docChanged)
|
|
85
115
|
&& !oldState.doc.eq(newState.doc)
|
|
86
116
|
const filterTransactions = this.options.filterTransaction
|
|
87
117
|
&& transactions.some(tr => !this.options.filterTransaction?.(tr))
|
|
88
118
|
|
|
89
|
-
|
|
119
|
+
const isCollabTransaction = transactions.find(tr => tr.getMeta('y-sync$'))
|
|
120
|
+
|
|
121
|
+
if (isCollabTransaction) {
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!hasDocChanges || filterTransactions) {
|
|
90
126
|
return
|
|
91
127
|
}
|
|
92
128
|
|
|
93
129
|
const { tr } = newState
|
|
130
|
+
|
|
94
131
|
const { types, attributeName, generateID } = this.options
|
|
95
|
-
const transform = combineTransactionSteps(oldState.doc, transactions)
|
|
132
|
+
const transform = combineTransactionSteps(oldState.doc, transactions as Transaction[])
|
|
96
133
|
const { mapping } = transform
|
|
97
134
|
|
|
98
135
|
// get changed ranges based on the old state
|
|
99
136
|
const changes = getChangedRanges(transform)
|
|
100
137
|
|
|
101
|
-
changes.forEach(
|
|
102
|
-
const newRange = {
|
|
103
|
-
from: change.newStart,
|
|
104
|
-
to: change.newEnd,
|
|
105
|
-
}
|
|
106
|
-
|
|
138
|
+
changes.forEach(({ newRange }) => {
|
|
107
139
|
const newNodes = findChildrenInRange(newState.doc, newRange, node => {
|
|
108
140
|
return types.includes(node.type.name)
|
|
109
141
|
})
|
|
@@ -112,9 +144,7 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
112
144
|
.map(({ node }) => node.attrs[attributeName])
|
|
113
145
|
.filter(id => id !== null)
|
|
114
146
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
newNodes.forEach(({ node, pos }) => {
|
|
147
|
+
newNodes.forEach(({ node, pos }, i) => {
|
|
118
148
|
// instead of checking `node.attrs[attributeName]` directly
|
|
119
149
|
// we look at the current state of the node within `tr.doc`.
|
|
120
150
|
// this helps to prevent adding new ids to the same node
|
|
@@ -130,8 +160,35 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
130
160
|
return
|
|
131
161
|
}
|
|
132
162
|
|
|
163
|
+
const nextNode = newNodes[i + 1]
|
|
164
|
+
|
|
165
|
+
if (nextNode && node.content.size === 0) {
|
|
166
|
+
tr.setNodeMarkup(nextNode.pos, undefined, {
|
|
167
|
+
...nextNode.node.attrs,
|
|
168
|
+
[attributeName]: id,
|
|
169
|
+
})
|
|
170
|
+
newIds[i + 1] = id
|
|
171
|
+
|
|
172
|
+
if (nextNode.node.attrs[attributeName]) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const generatedId = generateID()
|
|
177
|
+
|
|
178
|
+
tr.setNodeMarkup(pos, undefined, {
|
|
179
|
+
...node.attrs,
|
|
180
|
+
[attributeName]: generatedId,
|
|
181
|
+
})
|
|
182
|
+
newIds[i] = generatedId
|
|
183
|
+
|
|
184
|
+
return tr
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const duplicatedNewIds = findDuplicates(newIds)
|
|
188
|
+
|
|
133
189
|
// check if the node doesn’t exist in the old state
|
|
134
190
|
const { deleted } = mapping.invert().mapResult(pos)
|
|
191
|
+
|
|
135
192
|
const newNode = deleted && duplicatedNewIds.includes(id)
|
|
136
193
|
|
|
137
194
|
if (newNode) {
|
|
@@ -148,6 +205,10 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
148
205
|
return
|
|
149
206
|
}
|
|
150
207
|
|
|
208
|
+
// `tr.setNodeMarkup` resets the stored marks
|
|
209
|
+
// so we’ll restore them if they exist
|
|
210
|
+
tr.setStoredMarks(newState.tr.storedMarks)
|
|
211
|
+
|
|
151
212
|
return tr
|
|
152
213
|
},
|
|
153
214
|
|
|
@@ -172,11 +233,13 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
172
233
|
// `handleDOMEvents` is called before `transformPasted`
|
|
173
234
|
// so we can do some checks before
|
|
174
235
|
handleDOMEvents: {
|
|
175
|
-
// only create new ids for dropped content
|
|
236
|
+
// only create new ids for dropped content
|
|
237
|
+
// or dropped content while holding `alt`
|
|
176
238
|
// or content is dragged from another editor
|
|
177
239
|
drop: (view, event) => {
|
|
178
240
|
if (
|
|
179
241
|
dragSourceElement !== view.dom.parentElement
|
|
242
|
+
|| event.dataTransfer?.effectAllowed === 'copyMove'
|
|
180
243
|
|| event.dataTransfer?.effectAllowed === 'copy'
|
|
181
244
|
) {
|
|
182
245
|
dragSourceElement = null
|
|
@@ -228,6 +291,7 @@ export const UniqueID = Extension.create<UniqueIDOptions>({
|
|
|
228
291
|
removeId(node.content),
|
|
229
292
|
node.marks,
|
|
230
293
|
)
|
|
294
|
+
|
|
231
295
|
list.push(nodeWithoutId)
|
|
232
296
|
})
|
|
233
297
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-unique-id.cjs.js","sources":["../src/helpers/combineTransactionSteps.ts","../src/helpers/removeDuplicates.ts","../src/helpers/getChangedRanges.ts","../src/helpers/findDuplicates.ts","../src/unique-id.ts"],"sourcesContent":["import { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { Transaction } from 'prosemirror-state'\nimport { Transform } from 'prosemirror-transform'\n\n/**\n * Returns a new `Transform` based on all steps of the passed transactions.\n */\nexport default function combineTransactionSteps(oldDoc: ProseMirrorNode, transactions: Transaction[]): Transform {\n const transform = new Transform(oldDoc)\n\n transactions.forEach(transaction => {\n transaction.steps.forEach(step => {\n transform.step(step)\n })\n })\n\n return transform\n}\n","/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nexport default function removeDuplicates<T>(array: T[], by = JSON.stringify): T[] {\n const seen: Record<any, any> = {}\n\n return array.filter(item => {\n const key = by(item)\n\n return Object.prototype.hasOwnProperty.call(seen, key)\n ? false\n : (seen[key] = true)\n })\n}\n","import { Transform, Step } from 'prosemirror-transform'\nimport removeDuplicates from './removeDuplicates'\n\nexport type ChangedRange = {\n oldStart: number,\n oldEnd: number,\n newStart: number,\n newEnd: number,\n}\n\n/**\n * Removes duplicated ranges and ranges that are\n * fully captured by other ranges.\n */\nfunction simplifyChangedRanges(changes: ChangedRange[]): ChangedRange[] {\n const uniqueChanges = removeDuplicates(changes)\n\n return uniqueChanges.length === 1\n ? uniqueChanges\n : uniqueChanges.filter((change, index) => {\n const rest = uniqueChanges.filter((_, i) => i !== index)\n\n return !rest.some(otherChange => {\n return change.oldStart >= otherChange.oldStart\n && change.oldEnd <= otherChange.oldEnd\n && change.newStart >= otherChange.newStart\n && change.newEnd <= otherChange.newEnd\n })\n })\n}\n\n/**\n * Returns a list of changed ranges\n * based on the first and last state of all steps.\n */\nexport default function getChangedRanges(transform: Transform): ChangedRange[] {\n const { mapping, steps } = transform\n const changes: ChangedRange[] = []\n\n mapping.maps.forEach((stepMap, index) => {\n // This accounts for step changes where no range was actually altered\n // e.g. when setting a mark, node attribute, etc.\n // @ts-ignore\n if (!stepMap.ranges.length) {\n const step = steps[index] as Step & {\n from?: number,\n to?: number,\n }\n\n if (step.from === undefined || step.to === undefined) {\n return\n }\n\n changes.push({\n oldStart: step.from,\n oldEnd: step.to,\n newStart: step.from,\n newEnd: step.to,\n })\n } else {\n stepMap.forEach((from, to) => {\n const newStart = mapping.slice(index).map(from, -1)\n const newEnd = mapping.slice(index).map(to)\n const oldStart = mapping.invert().map(newStart, -1)\n const oldEnd = mapping.invert().map(newEnd)\n\n changes.push({\n oldStart,\n oldEnd,\n newStart,\n newEnd,\n })\n })\n }\n })\n\n return simplifyChangedRanges(changes)\n}\n","import removeDuplicates from './removeDuplicates'\n\n/**\n * Returns a list of duplicated items within an array.\n */\nexport default function findDuplicates(items: any[]): any[] {\n const filtered = items.filter((el, index) => items.indexOf(el) !== index)\n const duplicates = removeDuplicates(filtered)\n\n return duplicates\n}\n","import { Extension, findChildren, findChildrenInRange } from '@tiptap/core'\nimport { Plugin, PluginKey, Transaction } from 'prosemirror-state'\nimport { Slice, Fragment, Node as ProseMirrorNode } from 'prosemirror-model'\nimport { v4 as uuidv4 } from 'uuid'\nimport combineTransactionSteps from './helpers/combineTransactionSteps'\nimport getChangedRanges from './helpers/getChangedRanges'\nimport findDuplicates from './helpers/findDuplicates'\n\nexport interface UniqueIDOptions {\n attributeName: string,\n types: string[],\n generateID: () => any,\n filterTransaction: ((transaction: Transaction) => boolean) | null,\n}\n\nexport const UniqueID = Extension.create<UniqueIDOptions>({\n name: 'uniqueID',\n\n // we’ll set a very high priority to make sure this runs first\n // and is compatible with `appendTransaction` hooks of other extensions\n priority: 10000,\n\n addOptions() {\n return {\n attributeName: 'id',\n types: [],\n generateID: () => uuidv4(),\n filterTransaction: null,\n }\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n [this.options.attributeName]: {\n default: null,\n parseHTML: element => element.getAttribute(`data-${this.options.attributeName}`),\n renderHTML: attributes => {\n if (!attributes[this.options.attributeName]) {\n return {}\n }\n\n return {\n [`data-${this.options.attributeName}`]: attributes[this.options.attributeName],\n }\n },\n },\n },\n },\n ]\n },\n\n // check initial content for missing ids\n onCreate() {\n const { view, state } = this.editor\n const { tr, doc } = state\n const { types, attributeName, generateID } = this.options\n const nodesWithoutId = findChildren(doc, node => {\n return types.includes(node.type.name)\n && node.attrs[attributeName] === null\n })\n\n nodesWithoutId.forEach(({ node, pos }) => {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n })\n\n view.dispatch(tr)\n },\n\n addProseMirrorPlugins() {\n let dragSourceElement: Element | null = null\n let transformPasted = false\n\n return [\n new Plugin({\n key: new PluginKey('uniqueID'),\n\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged)\n && !oldState.doc.eq(newState.doc)\n const filterTransactions = this.options.filterTransaction\n && transactions.some(tr => !this.options.filterTransaction?.(tr))\n\n if (!docChanges || filterTransactions) {\n return\n }\n\n const { tr } = newState\n const { types, attributeName, generateID } = this.options\n const transform = combineTransactionSteps(oldState.doc, transactions)\n const { mapping } = transform\n\n // get changed ranges based on the old state\n const changes = getChangedRanges(transform)\n\n changes.forEach(change => {\n const newRange = {\n from: change.newStart,\n to: change.newEnd,\n }\n\n const newNodes = findChildrenInRange(newState.doc, newRange, node => {\n return types.includes(node.type.name)\n })\n\n const newIds = newNodes\n .map(({ node }) => node.attrs[attributeName])\n .filter(id => id !== null)\n\n const duplicatedNewIds = findDuplicates(newIds)\n\n newNodes.forEach(({ node, pos }) => {\n // instead of checking `node.attrs[attributeName]` directly\n // we look at the current state of the node within `tr.doc`.\n // this helps to prevent adding new ids to the same node\n // if the node changed multiple times within one transaction\n const id = tr.doc.nodeAt(pos)?.attrs[attributeName]\n\n if (id === null) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n\n return\n }\n\n // check if the node doesn’t exist in the old state\n const { deleted } = mapping.invert().mapResult(pos)\n const newNode = deleted && duplicatedNewIds.includes(id)\n\n if (newNode) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n }\n })\n\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n\n // we register a global drag handler to track the current drag source element\n view(view) {\n const handleDragstart = (event: DragEvent) => {\n dragSourceElement = view.dom.parentElement?.contains(event.target as Element)\n ? view.dom.parentElement\n : null\n }\n\n window.addEventListener('dragstart', handleDragstart)\n\n return {\n destroy() {\n window.removeEventListener('dragstart', handleDragstart)\n },\n }\n },\n\n props: {\n // `handleDOMEvents` is called before `transformPasted`\n // so we can do some checks before\n handleDOMEvents: {\n // only create new ids for dropped content while holding `alt`\n // or content is dragged from another editor\n drop: (view, event) => {\n if (\n dragSourceElement !== view.dom.parentElement\n || event.dataTransfer?.effectAllowed === 'copy'\n ) {\n dragSourceElement = null\n transformPasted = true\n }\n\n return false\n },\n // always create new ids on pasted content\n paste: () => {\n transformPasted = true\n\n return false\n },\n },\n\n // we’ll remove ids for every pasted node\n // so we can create a new one within `appendTransaction`\n transformPasted: slice => {\n if (!transformPasted) {\n return slice\n }\n\n const { types, attributeName } = this.options\n const removeId = (fragment: Fragment): Fragment => {\n const list: ProseMirrorNode[] = []\n\n fragment.forEach(node => {\n // don’t touch text nodes\n if (node.isText) {\n list.push(node)\n\n return\n }\n\n // check for any other child nodes\n if (!types.includes(node.type.name)) {\n list.push(node.copy(removeId(node.content)))\n\n return\n }\n\n // remove id\n const nodeWithoutId = node.type.create(\n {\n ...node.attrs,\n [attributeName]: null,\n },\n removeId(node.content),\n node.marks,\n )\n list.push(nodeWithoutId)\n })\n\n return Fragment.from(list)\n }\n\n // reset check\n transformPasted = false\n\n return new Slice(removeId(slice.content), slice.openStart, slice.openEnd)\n },\n },\n }),\n ]\n },\n\n})\n"],"names":["Transform","Extension","uuidv4","findChildren","Plugin","PluginKey","findChildrenInRange","Fragment","Slice"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-unique-id.esm.js","sources":["../src/helpers/combineTransactionSteps.ts","../src/helpers/removeDuplicates.ts","../src/helpers/getChangedRanges.ts","../src/helpers/findDuplicates.ts","../src/unique-id.ts"],"sourcesContent":["import { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { Transaction } from 'prosemirror-state'\nimport { Transform } from 'prosemirror-transform'\n\n/**\n * Returns a new `Transform` based on all steps of the passed transactions.\n */\nexport default function combineTransactionSteps(oldDoc: ProseMirrorNode, transactions: Transaction[]): Transform {\n const transform = new Transform(oldDoc)\n\n transactions.forEach(transaction => {\n transaction.steps.forEach(step => {\n transform.step(step)\n })\n })\n\n return transform\n}\n","/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nexport default function removeDuplicates<T>(array: T[], by = JSON.stringify): T[] {\n const seen: Record<any, any> = {}\n\n return array.filter(item => {\n const key = by(item)\n\n return Object.prototype.hasOwnProperty.call(seen, key)\n ? false\n : (seen[key] = true)\n })\n}\n","import { Transform, Step } from 'prosemirror-transform'\nimport removeDuplicates from './removeDuplicates'\n\nexport type ChangedRange = {\n oldStart: number,\n oldEnd: number,\n newStart: number,\n newEnd: number,\n}\n\n/**\n * Removes duplicated ranges and ranges that are\n * fully captured by other ranges.\n */\nfunction simplifyChangedRanges(changes: ChangedRange[]): ChangedRange[] {\n const uniqueChanges = removeDuplicates(changes)\n\n return uniqueChanges.length === 1\n ? uniqueChanges\n : uniqueChanges.filter((change, index) => {\n const rest = uniqueChanges.filter((_, i) => i !== index)\n\n return !rest.some(otherChange => {\n return change.oldStart >= otherChange.oldStart\n && change.oldEnd <= otherChange.oldEnd\n && change.newStart >= otherChange.newStart\n && change.newEnd <= otherChange.newEnd\n })\n })\n}\n\n/**\n * Returns a list of changed ranges\n * based on the first and last state of all steps.\n */\nexport default function getChangedRanges(transform: Transform): ChangedRange[] {\n const { mapping, steps } = transform\n const changes: ChangedRange[] = []\n\n mapping.maps.forEach((stepMap, index) => {\n // This accounts for step changes where no range was actually altered\n // e.g. when setting a mark, node attribute, etc.\n // @ts-ignore\n if (!stepMap.ranges.length) {\n const step = steps[index] as Step & {\n from?: number,\n to?: number,\n }\n\n if (step.from === undefined || step.to === undefined) {\n return\n }\n\n changes.push({\n oldStart: step.from,\n oldEnd: step.to,\n newStart: step.from,\n newEnd: step.to,\n })\n } else {\n stepMap.forEach((from, to) => {\n const newStart = mapping.slice(index).map(from, -1)\n const newEnd = mapping.slice(index).map(to)\n const oldStart = mapping.invert().map(newStart, -1)\n const oldEnd = mapping.invert().map(newEnd)\n\n changes.push({\n oldStart,\n oldEnd,\n newStart,\n newEnd,\n })\n })\n }\n })\n\n return simplifyChangedRanges(changes)\n}\n","import removeDuplicates from './removeDuplicates'\n\n/**\n * Returns a list of duplicated items within an array.\n */\nexport default function findDuplicates(items: any[]): any[] {\n const filtered = items.filter((el, index) => items.indexOf(el) !== index)\n const duplicates = removeDuplicates(filtered)\n\n return duplicates\n}\n","import { Extension, findChildren, findChildrenInRange } from '@tiptap/core'\nimport { Plugin, PluginKey, Transaction } from 'prosemirror-state'\nimport { Slice, Fragment, Node as ProseMirrorNode } from 'prosemirror-model'\nimport { v4 as uuidv4 } from 'uuid'\nimport combineTransactionSteps from './helpers/combineTransactionSteps'\nimport getChangedRanges from './helpers/getChangedRanges'\nimport findDuplicates from './helpers/findDuplicates'\n\nexport interface UniqueIDOptions {\n attributeName: string,\n types: string[],\n generateID: () => any,\n filterTransaction: ((transaction: Transaction) => boolean) | null,\n}\n\nexport const UniqueID = Extension.create<UniqueIDOptions>({\n name: 'uniqueID',\n\n // we’ll set a very high priority to make sure this runs first\n // and is compatible with `appendTransaction` hooks of other extensions\n priority: 10000,\n\n addOptions() {\n return {\n attributeName: 'id',\n types: [],\n generateID: () => uuidv4(),\n filterTransaction: null,\n }\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n [this.options.attributeName]: {\n default: null,\n parseHTML: element => element.getAttribute(`data-${this.options.attributeName}`),\n renderHTML: attributes => {\n if (!attributes[this.options.attributeName]) {\n return {}\n }\n\n return {\n [`data-${this.options.attributeName}`]: attributes[this.options.attributeName],\n }\n },\n },\n },\n },\n ]\n },\n\n // check initial content for missing ids\n onCreate() {\n const { view, state } = this.editor\n const { tr, doc } = state\n const { types, attributeName, generateID } = this.options\n const nodesWithoutId = findChildren(doc, node => {\n return types.includes(node.type.name)\n && node.attrs[attributeName] === null\n })\n\n nodesWithoutId.forEach(({ node, pos }) => {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n })\n\n view.dispatch(tr)\n },\n\n addProseMirrorPlugins() {\n let dragSourceElement: Element | null = null\n let transformPasted = false\n\n return [\n new Plugin({\n key: new PluginKey('uniqueID'),\n\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged)\n && !oldState.doc.eq(newState.doc)\n const filterTransactions = this.options.filterTransaction\n && transactions.some(tr => !this.options.filterTransaction?.(tr))\n\n if (!docChanges || filterTransactions) {\n return\n }\n\n const { tr } = newState\n const { types, attributeName, generateID } = this.options\n const transform = combineTransactionSteps(oldState.doc, transactions)\n const { mapping } = transform\n\n // get changed ranges based on the old state\n const changes = getChangedRanges(transform)\n\n changes.forEach(change => {\n const newRange = {\n from: change.newStart,\n to: change.newEnd,\n }\n\n const newNodes = findChildrenInRange(newState.doc, newRange, node => {\n return types.includes(node.type.name)\n })\n\n const newIds = newNodes\n .map(({ node }) => node.attrs[attributeName])\n .filter(id => id !== null)\n\n const duplicatedNewIds = findDuplicates(newIds)\n\n newNodes.forEach(({ node, pos }) => {\n // instead of checking `node.attrs[attributeName]` directly\n // we look at the current state of the node within `tr.doc`.\n // this helps to prevent adding new ids to the same node\n // if the node changed multiple times within one transaction\n const id = tr.doc.nodeAt(pos)?.attrs[attributeName]\n\n if (id === null) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n\n return\n }\n\n // check if the node doesn’t exist in the old state\n const { deleted } = mapping.invert().mapResult(pos)\n const newNode = deleted && duplicatedNewIds.includes(id)\n\n if (newNode) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n }\n })\n\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n\n // we register a global drag handler to track the current drag source element\n view(view) {\n const handleDragstart = (event: DragEvent) => {\n dragSourceElement = view.dom.parentElement?.contains(event.target as Element)\n ? view.dom.parentElement\n : null\n }\n\n window.addEventListener('dragstart', handleDragstart)\n\n return {\n destroy() {\n window.removeEventListener('dragstart', handleDragstart)\n },\n }\n },\n\n props: {\n // `handleDOMEvents` is called before `transformPasted`\n // so we can do some checks before\n handleDOMEvents: {\n // only create new ids for dropped content while holding `alt`\n // or content is dragged from another editor\n drop: (view, event) => {\n if (\n dragSourceElement !== view.dom.parentElement\n || event.dataTransfer?.effectAllowed === 'copy'\n ) {\n dragSourceElement = null\n transformPasted = true\n }\n\n return false\n },\n // always create new ids on pasted content\n paste: () => {\n transformPasted = true\n\n return false\n },\n },\n\n // we’ll remove ids for every pasted node\n // so we can create a new one within `appendTransaction`\n transformPasted: slice => {\n if (!transformPasted) {\n return slice\n }\n\n const { types, attributeName } = this.options\n const removeId = (fragment: Fragment): Fragment => {\n const list: ProseMirrorNode[] = []\n\n fragment.forEach(node => {\n // don’t touch text nodes\n if (node.isText) {\n list.push(node)\n\n return\n }\n\n // check for any other child nodes\n if (!types.includes(node.type.name)) {\n list.push(node.copy(removeId(node.content)))\n\n return\n }\n\n // remove id\n const nodeWithoutId = node.type.create(\n {\n ...node.attrs,\n [attributeName]: null,\n },\n removeId(node.content),\n node.marks,\n )\n list.push(nodeWithoutId)\n })\n\n return Fragment.from(list)\n }\n\n // reset check\n transformPasted = false\n\n return new Slice(removeId(slice.content), slice.openStart, slice.openEnd)\n },\n },\n }),\n ]\n },\n\n})\n"],"names":["uuidv4"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-unique-id.umd.js","sources":["../src/helpers/combineTransactionSteps.ts","../src/helpers/removeDuplicates.ts","../src/helpers/getChangedRanges.ts","../src/helpers/findDuplicates.ts","../src/unique-id.ts"],"sourcesContent":["import { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { Transaction } from 'prosemirror-state'\nimport { Transform } from 'prosemirror-transform'\n\n/**\n * Returns a new `Transform` based on all steps of the passed transactions.\n */\nexport default function combineTransactionSteps(oldDoc: ProseMirrorNode, transactions: Transaction[]): Transform {\n const transform = new Transform(oldDoc)\n\n transactions.forEach(transaction => {\n transaction.steps.forEach(step => {\n transform.step(step)\n })\n })\n\n return transform\n}\n","/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nexport default function removeDuplicates<T>(array: T[], by = JSON.stringify): T[] {\n const seen: Record<any, any> = {}\n\n return array.filter(item => {\n const key = by(item)\n\n return Object.prototype.hasOwnProperty.call(seen, key)\n ? false\n : (seen[key] = true)\n })\n}\n","import { Transform, Step } from 'prosemirror-transform'\nimport removeDuplicates from './removeDuplicates'\n\nexport type ChangedRange = {\n oldStart: number,\n oldEnd: number,\n newStart: number,\n newEnd: number,\n}\n\n/**\n * Removes duplicated ranges and ranges that are\n * fully captured by other ranges.\n */\nfunction simplifyChangedRanges(changes: ChangedRange[]): ChangedRange[] {\n const uniqueChanges = removeDuplicates(changes)\n\n return uniqueChanges.length === 1\n ? uniqueChanges\n : uniqueChanges.filter((change, index) => {\n const rest = uniqueChanges.filter((_, i) => i !== index)\n\n return !rest.some(otherChange => {\n return change.oldStart >= otherChange.oldStart\n && change.oldEnd <= otherChange.oldEnd\n && change.newStart >= otherChange.newStart\n && change.newEnd <= otherChange.newEnd\n })\n })\n}\n\n/**\n * Returns a list of changed ranges\n * based on the first and last state of all steps.\n */\nexport default function getChangedRanges(transform: Transform): ChangedRange[] {\n const { mapping, steps } = transform\n const changes: ChangedRange[] = []\n\n mapping.maps.forEach((stepMap, index) => {\n // This accounts for step changes where no range was actually altered\n // e.g. when setting a mark, node attribute, etc.\n // @ts-ignore\n if (!stepMap.ranges.length) {\n const step = steps[index] as Step & {\n from?: number,\n to?: number,\n }\n\n if (step.from === undefined || step.to === undefined) {\n return\n }\n\n changes.push({\n oldStart: step.from,\n oldEnd: step.to,\n newStart: step.from,\n newEnd: step.to,\n })\n } else {\n stepMap.forEach((from, to) => {\n const newStart = mapping.slice(index).map(from, -1)\n const newEnd = mapping.slice(index).map(to)\n const oldStart = mapping.invert().map(newStart, -1)\n const oldEnd = mapping.invert().map(newEnd)\n\n changes.push({\n oldStart,\n oldEnd,\n newStart,\n newEnd,\n })\n })\n }\n })\n\n return simplifyChangedRanges(changes)\n}\n","import removeDuplicates from './removeDuplicates'\n\n/**\n * Returns a list of duplicated items within an array.\n */\nexport default function findDuplicates(items: any[]): any[] {\n const filtered = items.filter((el, index) => items.indexOf(el) !== index)\n const duplicates = removeDuplicates(filtered)\n\n return duplicates\n}\n","import { Extension, findChildren, findChildrenInRange } from '@tiptap/core'\nimport { Plugin, PluginKey, Transaction } from 'prosemirror-state'\nimport { Slice, Fragment, Node as ProseMirrorNode } from 'prosemirror-model'\nimport { v4 as uuidv4 } from 'uuid'\nimport combineTransactionSteps from './helpers/combineTransactionSteps'\nimport getChangedRanges from './helpers/getChangedRanges'\nimport findDuplicates from './helpers/findDuplicates'\n\nexport interface UniqueIDOptions {\n attributeName: string,\n types: string[],\n generateID: () => any,\n filterTransaction: ((transaction: Transaction) => boolean) | null,\n}\n\nexport const UniqueID = Extension.create<UniqueIDOptions>({\n name: 'uniqueID',\n\n // we’ll set a very high priority to make sure this runs first\n // and is compatible with `appendTransaction` hooks of other extensions\n priority: 10000,\n\n addOptions() {\n return {\n attributeName: 'id',\n types: [],\n generateID: () => uuidv4(),\n filterTransaction: null,\n }\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n [this.options.attributeName]: {\n default: null,\n parseHTML: element => element.getAttribute(`data-${this.options.attributeName}`),\n renderHTML: attributes => {\n if (!attributes[this.options.attributeName]) {\n return {}\n }\n\n return {\n [`data-${this.options.attributeName}`]: attributes[this.options.attributeName],\n }\n },\n },\n },\n },\n ]\n },\n\n // check initial content for missing ids\n onCreate() {\n const { view, state } = this.editor\n const { tr, doc } = state\n const { types, attributeName, generateID } = this.options\n const nodesWithoutId = findChildren(doc, node => {\n return types.includes(node.type.name)\n && node.attrs[attributeName] === null\n })\n\n nodesWithoutId.forEach(({ node, pos }) => {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n })\n\n view.dispatch(tr)\n },\n\n addProseMirrorPlugins() {\n let dragSourceElement: Element | null = null\n let transformPasted = false\n\n return [\n new Plugin({\n key: new PluginKey('uniqueID'),\n\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged)\n && !oldState.doc.eq(newState.doc)\n const filterTransactions = this.options.filterTransaction\n && transactions.some(tr => !this.options.filterTransaction?.(tr))\n\n if (!docChanges || filterTransactions) {\n return\n }\n\n const { tr } = newState\n const { types, attributeName, generateID } = this.options\n const transform = combineTransactionSteps(oldState.doc, transactions)\n const { mapping } = transform\n\n // get changed ranges based on the old state\n const changes = getChangedRanges(transform)\n\n changes.forEach(change => {\n const newRange = {\n from: change.newStart,\n to: change.newEnd,\n }\n\n const newNodes = findChildrenInRange(newState.doc, newRange, node => {\n return types.includes(node.type.name)\n })\n\n const newIds = newNodes\n .map(({ node }) => node.attrs[attributeName])\n .filter(id => id !== null)\n\n const duplicatedNewIds = findDuplicates(newIds)\n\n newNodes.forEach(({ node, pos }) => {\n // instead of checking `node.attrs[attributeName]` directly\n // we look at the current state of the node within `tr.doc`.\n // this helps to prevent adding new ids to the same node\n // if the node changed multiple times within one transaction\n const id = tr.doc.nodeAt(pos)?.attrs[attributeName]\n\n if (id === null) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n\n return\n }\n\n // check if the node doesn’t exist in the old state\n const { deleted } = mapping.invert().mapResult(pos)\n const newNode = deleted && duplicatedNewIds.includes(id)\n\n if (newNode) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n })\n }\n })\n\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n\n // we register a global drag handler to track the current drag source element\n view(view) {\n const handleDragstart = (event: DragEvent) => {\n dragSourceElement = view.dom.parentElement?.contains(event.target as Element)\n ? view.dom.parentElement\n : null\n }\n\n window.addEventListener('dragstart', handleDragstart)\n\n return {\n destroy() {\n window.removeEventListener('dragstart', handleDragstart)\n },\n }\n },\n\n props: {\n // `handleDOMEvents` is called before `transformPasted`\n // so we can do some checks before\n handleDOMEvents: {\n // only create new ids for dropped content while holding `alt`\n // or content is dragged from another editor\n drop: (view, event) => {\n if (\n dragSourceElement !== view.dom.parentElement\n || event.dataTransfer?.effectAllowed === 'copy'\n ) {\n dragSourceElement = null\n transformPasted = true\n }\n\n return false\n },\n // always create new ids on pasted content\n paste: () => {\n transformPasted = true\n\n return false\n },\n },\n\n // we’ll remove ids for every pasted node\n // so we can create a new one within `appendTransaction`\n transformPasted: slice => {\n if (!transformPasted) {\n return slice\n }\n\n const { types, attributeName } = this.options\n const removeId = (fragment: Fragment): Fragment => {\n const list: ProseMirrorNode[] = []\n\n fragment.forEach(node => {\n // don’t touch text nodes\n if (node.isText) {\n list.push(node)\n\n return\n }\n\n // check for any other child nodes\n if (!types.includes(node.type.name)) {\n list.push(node.copy(removeId(node.content)))\n\n return\n }\n\n // remove id\n const nodeWithoutId = node.type.create(\n {\n ...node.attrs,\n [attributeName]: null,\n },\n removeId(node.content),\n node.marks,\n )\n list.push(nodeWithoutId)\n })\n\n return Fragment.from(list)\n }\n\n // reset check\n transformPasted = false\n\n return new Slice(removeId(slice.content), slice.openStart, slice.openEnd)\n },\n },\n }),\n ]\n },\n\n})\n"],"names":["Transform","Extension","uuidv4","findChildren","Plugin","PluginKey","findChildrenInRange","Fragment","Slice"],"mappings":";;;;;;EAIA;;;WAGwB,uBAAuB,CAAC,MAAuB,EAAE,YAA2B;MAClG,MAAM,SAAS,GAAG,IAAIA,8BAAS,CAAC,MAAM,CAAC,CAAA;MAEvC,YAAY,CAAC,OAAO,CAAC,WAAW;UAC9B,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI;cAC5B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;WACrB,CAAC,CAAA;OACH,CAAC,CAAA;MAEF,OAAO,SAAS,CAAA;EAClB;;ECjBA;;;;WAIwB,gBAAgB,CAAI,KAAU,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS;MACzE,MAAM,IAAI,GAAqB,EAAE,CAAA;MAEjC,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI;UACtB,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;UAEpB,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC;gBAClD,KAAK;iBACJ,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;OACvB,CAAC,CAAA;EACJ;;ECJA;;;;EAIA,SAAS,qBAAqB,CAAC,OAAuB;MACpD,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;MAE/C,OAAO,aAAa,CAAC,MAAM,KAAK,CAAC;YAC7B,aAAa;YACb,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK;cACnC,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAA;cAExD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW;kBAC3B,OAAO,MAAM,CAAC,QAAQ,IAAI,WAAW,CAAC,QAAQ;yBACzC,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM;yBACnC,MAAM,CAAC,QAAQ,IAAI,WAAW,CAAC,QAAQ;yBACvC,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,CAAA;eACzC,CAAC,CAAA;WACH,CAAC,CAAA;EACN,CAAC;EAED;;;;WAIwB,gBAAgB,CAAC,SAAoB;MAC3D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,SAAS,CAAA;MACpC,MAAM,OAAO,GAAmB,EAAE,CAAA;MAElC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK;;;;UAIlC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;cAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAGvB,CAAA;cAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS,EAAE;kBACpD,OAAM;eACP;cAED,OAAO,CAAC,IAAI,CAAC;kBACX,QAAQ,EAAE,IAAI,CAAC,IAAI;kBACnB,MAAM,EAAE,IAAI,CAAC,EAAE;kBACf,QAAQ,EAAE,IAAI,CAAC,IAAI;kBACnB,MAAM,EAAE,IAAI,CAAC,EAAE;eAChB,CAAC,CAAA;WACH;eAAM;cACL,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;kBACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;kBACnD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;kBAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;kBACnD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;kBAE3C,OAAO,CAAC,IAAI,CAAC;sBACX,QAAQ;sBACR,MAAM;sBACN,QAAQ;sBACR,MAAM;mBACP,CAAC,CAAA;eACH,CAAC,CAAA;WACH;OACF,CAAC,CAAA;MAEF,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAA;EACvC;;EC3EA;;;WAGwB,cAAc,CAAC,KAAY;MACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,CAAA;MACzE,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;MAE7C,OAAO,UAAU,CAAA;EACnB;;QCKa,QAAQ,GAAGC,cAAS,CAAC,MAAM,CAAkB;MACxD,IAAI,EAAE,UAAU;;;MAIhB,QAAQ,EAAE,KAAK;MAEf,UAAU;UACR,OAAO;cACL,aAAa,EAAE,IAAI;cACnB,KAAK,EAAE,EAAE;cACT,UAAU,EAAE,MAAMC,OAAM,EAAE;cAC1B,iBAAiB,EAAE,IAAI;WACxB,CAAA;OACF;MAED,mBAAmB;UACjB,OAAO;cACL;kBACE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;kBACzB,UAAU,EAAE;sBACV,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG;0BAC5B,OAAO,EAAE,IAAI;0BACb,SAAS,EAAE,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;0BAChF,UAAU,EAAE,UAAU;8BACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;kCAC3C,OAAO,EAAE,CAAA;+BACV;8BAED,OAAO;kCACL,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;+BAC/E,CAAA;2BACF;uBACF;mBACF;eACF;WACF,CAAA;OACF;;MAGD,QAAQ;UACN,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;UACnC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;UACzB,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;UACzD,MAAM,cAAc,GAAGC,iBAAY,CAAC,GAAG,EAAE,IAAI;cAC3C,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;qBAChC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;WACxC,CAAC,CAAA;UAEF,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE;cACnC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE;kBAC/B,GAAG,IAAI,CAAC,KAAK;kBACb,CAAC,aAAa,GAAG,UAAU,EAAE;eAC9B,CAAC,CAAA;WACH,CAAC,CAAA;UAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;OAClB;MAED,qBAAqB;UACnB,IAAI,iBAAiB,GAAmB,IAAI,CAAA;UAC5C,IAAI,eAAe,GAAG,KAAK,CAAA;UAE3B,OAAO;cACL,IAAIC,uBAAM,CAAC;kBACT,GAAG,EAAE,IAAIC,0BAAS,CAAC,UAAU,CAAC;kBAE9B,iBAAiB,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ;sBAClD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,UAAU,CAAC;6BACtE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;sBACnC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB;6BACpD,YAAY,CAAC,IAAI,CAAC,EAAE,kBAAI,OAAA,EAAC,MAAA,MAAA,IAAI,CAAC,OAAO,EAAC,iBAAiB,mDAAG,EAAE,CAAC,CAAA,CAAA,EAAA,CAAC,CAAA;sBAEnE,IAAI,CAAC,UAAU,IAAI,kBAAkB,EAAE;0BACrC,OAAM;uBACP;sBAED,MAAM,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAA;sBACvB,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;sBACzD,MAAM,SAAS,GAAG,uBAAuB,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;sBACrE,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;;sBAG7B,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAA;sBAE3C,OAAO,CAAC,OAAO,CAAC,MAAM;0BACpB,MAAM,QAAQ,GAAG;8BACf,IAAI,EAAE,MAAM,CAAC,QAAQ;8BACrB,EAAE,EAAE,MAAM,CAAC,MAAM;2BAClB,CAAA;0BAED,MAAM,QAAQ,GAAGC,wBAAmB,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI;8BAC/D,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;2BACtC,CAAC,CAAA;0BAEF,MAAM,MAAM,GAAG,QAAQ;+BACpB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;+BAC5C,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,CAAA;0BAE5B,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;0BAE/C,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE;;;;;;8BAK7B,MAAM,EAAE,GAAG,MAAA,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,0CAAE,KAAK,CAAC,aAAa,CAAC,CAAA;8BAEnD,IAAI,EAAE,KAAK,IAAI,EAAE;kCACf,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE;sCAC/B,GAAG,IAAI,CAAC,KAAK;sCACb,CAAC,aAAa,GAAG,UAAU,EAAE;mCAC9B,CAAC,CAAA;kCAEF,OAAM;+BACP;;8BAGD,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;8BACnD,MAAM,OAAO,GAAG,OAAO,IAAI,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;8BAExD,IAAI,OAAO,EAAE;kCACX,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE;sCAC/B,GAAG,IAAI,CAAC,KAAK;sCACb,CAAC,aAAa,GAAG,UAAU,EAAE;mCAC9B,CAAC,CAAA;+BACH;2BACF,CAAC,CAAA;uBAEH,CAAC,CAAA;sBAEF,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE;0BACpB,OAAM;uBACP;sBAED,OAAO,EAAE,CAAA;mBACV;;kBAGD,IAAI,CAAC,IAAI;sBACP,MAAM,eAAe,GAAG,CAAC,KAAgB;;0BACvC,iBAAiB,GAAG,CAAA,MAAA,IAAI,CAAC,GAAG,CAAC,aAAa,0CAAE,QAAQ,CAAC,KAAK,CAAC,MAAiB,CAAC;gCACzE,IAAI,CAAC,GAAG,CAAC,aAAa;gCACtB,IAAI,CAAA;uBACT,CAAA;sBAED,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;sBAErD,OAAO;0BACL,OAAO;8BACL,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;2BACzD;uBACF,CAAA;mBACF;kBAED,KAAK,EAAE;;;sBAGL,eAAe,EAAE;;;0BAGf,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK;;8BAChB,IACE,iBAAiB,KAAK,IAAI,CAAC,GAAG,CAAC,aAAa;qCACzC,CAAA,MAAA,KAAK,CAAC,YAAY,0CAAE,aAAa,MAAK,MAAM,EAC/C;kCACA,iBAAiB,GAAG,IAAI,CAAA;kCACxB,eAAe,GAAG,IAAI,CAAA;+BACvB;8BAED,OAAO,KAAK,CAAA;2BACb;;0BAED,KAAK,EAAE;8BACL,eAAe,GAAG,IAAI,CAAA;8BAEtB,OAAO,KAAK,CAAA;2BACb;uBACF;;;sBAID,eAAe,EAAE,KAAK;0BACpB,IAAI,CAAC,eAAe,EAAE;8BACpB,OAAO,KAAK,CAAA;2BACb;0BAED,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;0BAC7C,MAAM,QAAQ,GAAG,CAAC,QAAkB;8BAClC,MAAM,IAAI,GAAsB,EAAE,CAAA;8BAElC,QAAQ,CAAC,OAAO,CAAC,IAAI;;kCAEnB,IAAI,IAAI,CAAC,MAAM,EAAE;sCACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;sCAEf,OAAM;mCACP;;kCAGD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;sCACnC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;sCAE5C,OAAM;mCACP;;kCAGD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CACpC;sCACE,GAAG,IAAI,CAAC,KAAK;sCACb,CAAC,aAAa,GAAG,IAAI;mCACtB,EACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EACtB,IAAI,CAAC,KAAK,CACX,CAAA;kCACD,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;+BACzB,CAAC,CAAA;8BAEF,OAAOC,yBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;2BAC3B,CAAA;;0BAGD,eAAe,GAAG,KAAK,CAAA;0BAEvB,OAAO,IAAIC,sBAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;uBAC1E;mBACF;eACF,CAAC;WACH,CAAA;OACF;GAEF;;;;;;;;;;;"}
|
package/dist/tiptap-pro/packages/extension-unique-id/src/helpers/combineTransactionSteps.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Node as ProseMirrorNode } from 'prosemirror-model';
|
|
2
|
-
import { Transaction } from 'prosemirror-state';
|
|
3
|
-
import { Transform } from 'prosemirror-transform';
|
|
4
|
-
/**
|
|
5
|
-
* Returns a new `Transform` based on all steps of the passed transactions.
|
|
6
|
-
*/
|
|
7
|
-
export default function combineTransactionSteps(oldDoc: ProseMirrorNode, transactions: Transaction[]): Transform;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Transform } from 'prosemirror-transform';
|
|
2
|
-
export declare type ChangedRange = {
|
|
3
|
-
oldStart: number;
|
|
4
|
-
oldEnd: number;
|
|
5
|
-
newStart: number;
|
|
6
|
-
newEnd: number;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Returns a list of changed ranges
|
|
10
|
-
* based on the first and last state of all steps.
|
|
11
|
-
*/
|
|
12
|
-
export default function getChangedRanges(transform: Transform): ChangedRange[];
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Removes duplicated values within an array.
|
|
3
|
-
* Supports numbers, strings and objects.
|
|
4
|
-
*/
|
|
5
|
-
export default function removeDuplicates<T>(array: T[], by?: {
|
|
6
|
-
(value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string;
|
|
7
|
-
(value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string;
|
|
8
|
-
}): T[];
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import removeDuplicates from './removeDuplicates'
|
|
2
|
-
|
|
3
|
-
export interface ArrayDifference {
|
|
4
|
-
added: any[],
|
|
5
|
-
removed: any[],
|
|
6
|
-
common: any[],
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Checks for added, removed and common items between two arrays.
|
|
11
|
-
*/
|
|
12
|
-
export default function arrayDifference(array1: any[], array2: any[]): ArrayDifference {
|
|
13
|
-
const uniqueCombinedArray = removeDuplicates([...array1, ...array2])
|
|
14
|
-
const data: ArrayDifference = {
|
|
15
|
-
added: [],
|
|
16
|
-
removed: [],
|
|
17
|
-
common: [],
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
uniqueCombinedArray.forEach(item => {
|
|
21
|
-
if (!array1.includes(item) && array2.includes(item)) {
|
|
22
|
-
data.added.push(item)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (array1.includes(item) && !array2.includes(item)) {
|
|
26
|
-
data.removed.push(item)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (array1.includes(item) && array2.includes(item)) {
|
|
30
|
-
data.common.push(item)
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
return data
|
|
35
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Node as ProseMirrorNode } from 'prosemirror-model'
|
|
2
|
-
import { Transaction } from 'prosemirror-state'
|
|
3
|
-
import { Transform } from 'prosemirror-transform'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns a new `Transform` based on all steps of the passed transactions.
|
|
7
|
-
*/
|
|
8
|
-
export default function combineTransactionSteps(oldDoc: ProseMirrorNode, transactions: Transaction[]): Transform {
|
|
9
|
-
const transform = new Transform(oldDoc)
|
|
10
|
-
|
|
11
|
-
transactions.forEach(transaction => {
|
|
12
|
-
transaction.steps.forEach(step => {
|
|
13
|
-
transform.step(step)
|
|
14
|
-
})
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
return transform
|
|
18
|
-
}
|