@axure/y-prosemirror 1.3.7-fork.2
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 +21 -0
- package/README.md +205 -0
- package/dist/src/lib.d.ts +114 -0
- package/dist/src/plugins/cursor-plugin.d.ts +17 -0
- package/dist/src/plugins/keys.d.ts +20 -0
- package/dist/src/plugins/sync-plugin.d.ts +148 -0
- package/dist/src/plugins/undo-plugin.d.ts +33 -0
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/y-prosemirror.d.ts +5 -0
- package/dist/y-prosemirror.cjs +2268 -0
- package/dist/y-prosemirror.cjs.map +1 -0
- package/package.json +89 -0
- package/src/lib.js +440 -0
- package/src/plugins/cursor-plugin.js +267 -0
- package/src/plugins/keys.js +23 -0
- package/src/plugins/sync-plugin.js +1350 -0
- package/src/plugins/undo-plugin.js +126 -0
- package/src/utils.js +20 -0
- package/src/y-prosemirror.js +11 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Plugin } from 'prosemirror-state'
|
|
2
|
+
|
|
3
|
+
import { createRecoverableSelection } from './sync-plugin.js'
|
|
4
|
+
import { UndoManager, Item, ContentType, XmlElement, Text } from 'yjs'
|
|
5
|
+
import { yUndoPluginKey, ySyncPluginKey } from './keys.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {Object} UndoPluginState
|
|
9
|
+
* @property {import('yjs').UndoManager} undoManager
|
|
10
|
+
* @property {ReturnType<typeof createRecoverableSelection> | null} prevSel
|
|
11
|
+
* @property {boolean} hasUndoOps
|
|
12
|
+
* @property {boolean} hasRedoOps
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Undo the last user action
|
|
17
|
+
*
|
|
18
|
+
* @param {import('prosemirror-state').EditorState} state
|
|
19
|
+
* @return {boolean} whether a change was undone
|
|
20
|
+
*/
|
|
21
|
+
export const undo = state => yUndoPluginKey.getState(state)?.undoManager?.undo() != null
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Redo the last user action
|
|
25
|
+
*
|
|
26
|
+
* @param {import('prosemirror-state').EditorState} state
|
|
27
|
+
* @return {boolean} whether a change was undone
|
|
28
|
+
*/
|
|
29
|
+
export const redo = state => yUndoPluginKey.getState(state)?.undoManager?.redo() != null
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Undo the last user action if there are undo operations available
|
|
33
|
+
* @type {import('prosemirror-state').Command}
|
|
34
|
+
*/
|
|
35
|
+
export const undoCommand = (state, dispatch) => dispatch == null ? yUndoPluginKey.getState(state)?.undoManager?.canUndo() : undo(state)
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Redo the last user action if there are redo operations available
|
|
39
|
+
* @type {import('prosemirror-state').Command}
|
|
40
|
+
*/
|
|
41
|
+
export const redoCommand = (state, dispatch) => dispatch == null ? yUndoPluginKey.getState(state)?.undoManager?.canRedo() : redo(state)
|
|
42
|
+
|
|
43
|
+
export const defaultProtectedNodes = new Set(['paragraph'])
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {import('yjs').Item} item
|
|
47
|
+
* @param {Set<string>} protectedNodes
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
export const defaultDeleteFilter = (item, protectedNodes) => !(item instanceof Item) ||
|
|
51
|
+
!(item.content instanceof ContentType) ||
|
|
52
|
+
!(item.content.type instanceof Text ||
|
|
53
|
+
(item.content.type instanceof XmlElement && protectedNodes.has(item.content.type.nodeName))) ||
|
|
54
|
+
item.content.type._length === 0
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {object} [options]
|
|
58
|
+
* @param {Set<string>} [options.protectedNodes]
|
|
59
|
+
* @param {any[]} [options.trackedOrigins]
|
|
60
|
+
* @param {import('yjs').UndoManager | null} [options.undoManager]
|
|
61
|
+
*/
|
|
62
|
+
export const yUndoPlugin = ({ protectedNodes = defaultProtectedNodes, trackedOrigins = [], undoManager = null } = {}) => new Plugin({
|
|
63
|
+
key: yUndoPluginKey,
|
|
64
|
+
state: {
|
|
65
|
+
init: (initargs, state) => {
|
|
66
|
+
// TODO: check if plugin order matches and fix
|
|
67
|
+
const ystate = ySyncPluginKey.getState(state)
|
|
68
|
+
const _undoManager = undoManager || new UndoManager(ystate.type, {
|
|
69
|
+
trackedOrigins: new Set([ySyncPluginKey].concat(trackedOrigins)),
|
|
70
|
+
deleteFilter: (item) => defaultDeleteFilter(item, protectedNodes),
|
|
71
|
+
captureTransaction: tr => tr.meta.get('addToHistory') !== false
|
|
72
|
+
})
|
|
73
|
+
return {
|
|
74
|
+
undoManager: _undoManager,
|
|
75
|
+
prevSel: null,
|
|
76
|
+
hasUndoOps: _undoManager.undoStack.length > 0,
|
|
77
|
+
hasRedoOps: _undoManager.redoStack.length > 0
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
apply: (tr, val, oldState, state) => {
|
|
81
|
+
const binding = ySyncPluginKey.getState(state).binding
|
|
82
|
+
const undoManager = val.undoManager
|
|
83
|
+
const hasUndoOps = undoManager.undoStack.length > 0
|
|
84
|
+
const hasRedoOps = undoManager.redoStack.length > 0
|
|
85
|
+
if (binding) {
|
|
86
|
+
return {
|
|
87
|
+
undoManager,
|
|
88
|
+
prevSel: createRecoverableSelection(binding, oldState),
|
|
89
|
+
hasUndoOps,
|
|
90
|
+
hasRedoOps
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
if (hasUndoOps !== val.hasUndoOps || hasRedoOps !== val.hasRedoOps) {
|
|
94
|
+
return Object.assign({}, val, {
|
|
95
|
+
hasUndoOps: undoManager.undoStack.length > 0,
|
|
96
|
+
hasRedoOps: undoManager.redoStack.length > 0
|
|
97
|
+
})
|
|
98
|
+
} else { // nothing changed
|
|
99
|
+
return val
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
view: view => {
|
|
105
|
+
const undoManager = yUndoPluginKey.getState(view.state).undoManager
|
|
106
|
+
undoManager.on('stack-item-added', ({ stackItem }) => {
|
|
107
|
+
const ystate = ySyncPluginKey.getState(view.state)
|
|
108
|
+
const binding = ystate.binding
|
|
109
|
+
if (binding) {
|
|
110
|
+
stackItem.meta.set(binding, binding.beforePatchSelection)
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
undoManager.on('stack-item-pop', ({ stackItem }) => {
|
|
114
|
+
const ystate = ySyncPluginKey.getState(view.state)
|
|
115
|
+
const binding = ystate.binding
|
|
116
|
+
if (binding) {
|
|
117
|
+
binding.beforeTransactionSelection = stackItem.meta.get(binding) || binding.beforeTransactionSelection
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
return {
|
|
121
|
+
destroy: () => {
|
|
122
|
+
undoManager.destroy()
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
})
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as sha256 from 'lib0/hash/sha256'
|
|
2
|
+
import * as buf from 'lib0/buffer'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Custom function to transform sha256 hash to N byte
|
|
6
|
+
*
|
|
7
|
+
* @param {Uint8Array} digest
|
|
8
|
+
*/
|
|
9
|
+
const _convolute = digest => {
|
|
10
|
+
const N = 6
|
|
11
|
+
for (let i = N; i < digest.length; i++) {
|
|
12
|
+
digest[i % N] = digest[i % N] ^ digest[i]
|
|
13
|
+
}
|
|
14
|
+
return digest.slice(0, N)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {any} json
|
|
19
|
+
*/
|
|
20
|
+
export const hashOfJSON = (json) => buf.toBase64(_convolute(sha256.digest(buf.encodeAny(json))))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './plugins/cursor-plugin.js'
|
|
2
|
+
export { ySyncPlugin, isVisible, getRelativeSelection, ProsemirrorBinding, updateYFragment } from './plugins/sync-plugin.js'
|
|
3
|
+
export * from './plugins/undo-plugin.js'
|
|
4
|
+
export * from './plugins/keys.js'
|
|
5
|
+
export {
|
|
6
|
+
absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta,
|
|
7
|
+
prosemirrorJSONToYDoc, yDocToProsemirrorJSON, yDocToProsemirror, prosemirrorToYDoc,
|
|
8
|
+
prosemirrorJSONToYXmlFragment, yXmlFragmentToProsemirrorJSON, yXmlFragmentToProsemirror,
|
|
9
|
+
prosemirrorToYXmlFragment, yXmlFragmentToProseMirrorRootNode, yXmlFragmentToProseMirrorFragment,
|
|
10
|
+
initProseMirrorDoc
|
|
11
|
+
} from './lib.js'
|