@kerebron/extension-basic-editor 0.0.6 → 0.0.7
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/esm/editor/src/CoreEditor.d.ts +28 -0
- package/esm/editor/src/CoreEditor.d.ts.map +1 -0
- package/esm/editor/src/CoreEditor.js +170 -0
- package/esm/editor/src/Extension.d.ts +26 -0
- package/esm/editor/src/Extension.d.ts.map +1 -0
- package/esm/editor/src/Extension.js +33 -0
- package/esm/editor/src/ExtensionManager.d.ts +32 -0
- package/esm/editor/src/ExtensionManager.d.ts.map +1 -0
- package/esm/editor/src/ExtensionManager.js +253 -0
- package/esm/editor/src/Mark.d.ts +18 -0
- package/esm/editor/src/Mark.d.ts.map +1 -0
- package/esm/editor/src/Mark.js +34 -0
- package/esm/editor/src/Node.d.ts +27 -0
- package/esm/editor/src/Node.d.ts.map +1 -0
- package/esm/editor/src/Node.js +43 -0
- package/esm/editor/src/commands/CommandManager.d.ts +20 -0
- package/esm/editor/src/commands/CommandManager.d.ts.map +1 -0
- package/esm/editor/src/commands/CommandManager.js +60 -0
- package/esm/editor/src/commands/createChainableState.d.ts +3 -0
- package/esm/editor/src/commands/createChainableState.d.ts.map +1 -0
- package/esm/editor/src/commands/createChainableState.js +29 -0
- package/esm/editor/src/commands/mod.d.ts +49 -0
- package/esm/editor/src/commands/mod.d.ts.map +1 -0
- package/esm/editor/src/commands/mod.js +928 -0
- package/esm/editor/src/mod.d.ts +5 -0
- package/esm/editor/src/mod.d.ts.map +1 -0
- package/esm/editor/src/mod.js +4 -0
- package/esm/editor/src/plugins/input-rules/InputRulesPlugin.d.ts +23 -0
- package/esm/editor/src/plugins/input-rules/InputRulesPlugin.d.ts.map +1 -0
- package/esm/editor/src/plugins/input-rules/InputRulesPlugin.js +163 -0
- package/esm/editor/src/plugins/input-rules/mod.d.ts +3 -0
- package/esm/editor/src/plugins/input-rules/mod.d.ts.map +1 -0
- package/esm/editor/src/plugins/input-rules/mod.js +2 -0
- package/esm/editor/src/plugins/input-rules/rulebuilders.d.ts +5 -0
- package/esm/editor/src/plugins/input-rules/rulebuilders.d.ts.map +1 -0
- package/esm/editor/src/plugins/input-rules/rulebuilders.js +50 -0
- package/esm/editor/src/types.d.ts +29 -0
- package/esm/editor/src/types.d.ts.map +1 -0
- package/esm/editor/src/types.js +1 -0
- package/esm/editor/src/utilities/createNodeFromContent.d.ts +12 -0
- package/esm/editor/src/utilities/createNodeFromContent.d.ts.map +1 -0
- package/esm/editor/src/utilities/createNodeFromContent.js +118 -0
- package/esm/editor/src/utilities/getHtmlAttributes.d.ts +4 -0
- package/esm/editor/src/utilities/getHtmlAttributes.d.ts.map +1 -0
- package/esm/editor/src/utilities/getHtmlAttributes.js +47 -0
- package/esm/editor/src/utilities/mod.d.ts +3 -0
- package/esm/editor/src/utilities/mod.d.ts.map +1 -0
- package/esm/editor/src/utilities/mod.js +2 -0
- package/esm/extension-automerge/src/CursorPlugin.d.ts +16 -0
- package/esm/extension-automerge/src/CursorPlugin.d.ts.map +1 -0
- package/esm/extension-automerge/src/CursorPlugin.js +114 -0
- package/esm/extension-automerge/src/ExtensionAutomerge.d.ts +26 -0
- package/esm/extension-automerge/src/ExtensionAutomerge.d.ts.map +1 -0
- package/esm/extension-automerge/src/ExtensionAutomerge.js +136 -0
- package/esm/extension-automerge/src/MarkUnknown.d.ts +8 -0
- package/esm/extension-automerge/src/MarkUnknown.d.ts.map +1 -0
- package/esm/extension-automerge/src/MarkUnknown.js +26 -0
- package/esm/extension-automerge/src/NodeUnknown.d.ts +8 -0
- package/esm/extension-automerge/src/NodeUnknown.d.ts.map +1 -0
- package/esm/extension-automerge/src/NodeUnknown.js +28 -0
- package/esm/extension-automerge/src/NodeUnknownBlock.d.ts +11 -0
- package/esm/extension-automerge/src/NodeUnknownBlock.d.ts.map +1 -0
- package/esm/extension-automerge/src/NodeUnknownBlock.js +36 -0
- package/esm/extension-automerge/src/SchemaAdapter.d.ts +70 -0
- package/esm/extension-automerge/src/SchemaAdapter.d.ts.map +1 -0
- package/esm/extension-automerge/src/SchemaAdapter.js +188 -0
- package/esm/extension-automerge/src/SyncPlugin.d.ts +16 -0
- package/esm/extension-automerge/src/SyncPlugin.d.ts.map +1 -0
- package/esm/extension-automerge/src/SyncPlugin.js +147 -0
- package/esm/extension-automerge/src/amToPm.d.ts +9 -0
- package/esm/extension-automerge/src/amToPm.d.ts.map +1 -0
- package/esm/extension-automerge/src/amToPm.js +245 -0
- package/esm/extension-automerge/src/amTraversal.d.ts +62 -0
- package/esm/extension-automerge/src/amTraversal.d.ts.map +1 -0
- package/esm/extension-automerge/src/amTraversal.js +688 -0
- package/esm/extension-automerge/src/loader.d.ts +8 -0
- package/esm/extension-automerge/src/loader.d.ts.map +1 -0
- package/esm/extension-automerge/src/loader.js +54 -0
- package/esm/extension-automerge/src/maintainSpans.d.ts +9 -0
- package/esm/extension-automerge/src/maintainSpans.d.ts.map +1 -0
- package/esm/extension-automerge/src/maintainSpans.js +464 -0
- package/esm/extension-automerge/src/pmToAm.d.ts +6 -0
- package/esm/extension-automerge/src/pmToAm.d.ts.map +1 -0
- package/esm/extension-automerge/src/pmToAm.js +183 -0
- package/esm/extension-automerge/src/pmTraversal.d.ts +26 -0
- package/esm/extension-automerge/src/pmTraversal.d.ts.map +1 -0
- package/esm/extension-automerge/src/pmTraversal.js +102 -0
- package/esm/extension-automerge/src/types.d.ts +42 -0
- package/esm/extension-automerge/src/types.d.ts.map +1 -0
- package/esm/extension-automerge/src/types.js +94 -0
- package/esm/extension-automerge/src/utils.d.ts +3 -0
- package/esm/extension-automerge/src/utils.d.ts.map +1 -0
- package/esm/extension-automerge/src/utils.js +18 -0
- package/esm/extension-basic-editor/src/ExtensionBaseKeymap.d.ts +8 -0
- package/esm/extension-basic-editor/src/ExtensionBaseKeymap.d.ts.map +1 -0
- package/esm/{ExtensionBaseKeymap.js → extension-basic-editor/src/ExtensionBaseKeymap.js} +2 -2
- package/esm/{ExtensionBasicEditor.d.ts → extension-basic-editor/src/ExtensionBasicEditor.d.ts} +1 -1
- package/esm/extension-basic-editor/src/ExtensionBasicEditor.d.ts.map +1 -0
- package/esm/{ExtensionBasicEditor.js → extension-basic-editor/src/ExtensionBasicEditor.js} +1 -1
- package/esm/{ExtensionDropcursor.d.ts → extension-basic-editor/src/ExtensionDropcursor.d.ts} +1 -1
- package/esm/extension-basic-editor/src/ExtensionDropcursor.d.ts.map +1 -0
- package/esm/{ExtensionDropcursor.js → extension-basic-editor/src/ExtensionDropcursor.js} +1 -1
- package/esm/{ExtensionGapcursor.d.ts → extension-basic-editor/src/ExtensionGapcursor.d.ts} +1 -1
- package/esm/extension-basic-editor/src/ExtensionGapcursor.d.ts.map +1 -0
- package/esm/{ExtensionGapcursor.js → extension-basic-editor/src/ExtensionGapcursor.js} +1 -1
- package/esm/{ExtensionHistory.d.ts → extension-basic-editor/src/ExtensionHistory.d.ts} +2 -2
- package/esm/extension-basic-editor/src/ExtensionHistory.d.ts.map +1 -0
- package/esm/{ExtensionHistory.js → extension-basic-editor/src/ExtensionHistory.js} +1 -1
- package/esm/{MarkCode.d.ts → extension-basic-editor/src/MarkCode.d.ts} +2 -2
- package/esm/extension-basic-editor/src/MarkCode.d.ts.map +1 -0
- package/esm/{MarkCode.js → extension-basic-editor/src/MarkCode.js} +2 -2
- package/esm/{MarkItalic.d.ts → extension-basic-editor/src/MarkItalic.d.ts} +2 -2
- package/esm/extension-basic-editor/src/MarkItalic.d.ts.map +1 -0
- package/esm/{MarkItalic.js → extension-basic-editor/src/MarkItalic.js} +2 -2
- package/esm/{MarkLink.d.ts → extension-basic-editor/src/MarkLink.d.ts} +1 -1
- package/esm/extension-basic-editor/src/MarkLink.d.ts.map +1 -0
- package/esm/{MarkLink.js → extension-basic-editor/src/MarkLink.js} +1 -1
- package/esm/{MarkStrong.d.ts → extension-basic-editor/src/MarkStrong.d.ts} +2 -2
- package/esm/extension-basic-editor/src/MarkStrong.d.ts.map +1 -0
- package/esm/{MarkStrong.js → extension-basic-editor/src/MarkStrong.js} +2 -2
- package/esm/{MarkUnderline.d.ts → extension-basic-editor/src/MarkUnderline.d.ts} +2 -2
- package/esm/extension-basic-editor/src/MarkUnderline.d.ts.map +1 -0
- package/esm/{MarkUnderline.js → extension-basic-editor/src/MarkUnderline.js} +2 -2
- package/esm/{NodeAside.d.ts → extension-basic-editor/src/NodeAside.d.ts} +1 -1
- package/esm/extension-basic-editor/src/NodeAside.d.ts.map +1 -0
- package/esm/{NodeAside.js → extension-basic-editor/src/NodeAside.js} +1 -1
- package/esm/{NodeBlockquote.d.ts → extension-basic-editor/src/NodeBlockquote.d.ts} +3 -3
- package/esm/extension-basic-editor/src/NodeBlockquote.d.ts.map +1 -0
- package/esm/{NodeBlockquote.js → extension-basic-editor/src/NodeBlockquote.js} +3 -3
- package/esm/{NodeBulletList.d.ts → extension-basic-editor/src/NodeBulletList.d.ts} +3 -3
- package/esm/extension-basic-editor/src/NodeBulletList.d.ts.map +1 -0
- package/esm/{NodeBulletList.js → extension-basic-editor/src/NodeBulletList.js} +3 -3
- package/esm/{NodeDocument.d.ts → extension-basic-editor/src/NodeDocument.d.ts} +1 -1
- package/esm/extension-basic-editor/src/NodeDocument.d.ts.map +1 -0
- package/esm/{NodeDocument.js → extension-basic-editor/src/NodeDocument.js} +1 -1
- package/esm/{NodeHardBreak.d.ts → extension-basic-editor/src/NodeHardBreak.d.ts} +2 -2
- package/esm/extension-basic-editor/src/NodeHardBreak.d.ts.map +1 -0
- package/esm/{NodeHardBreak.js → extension-basic-editor/src/NodeHardBreak.js} +2 -2
- package/esm/{NodeHeading.d.ts → extension-basic-editor/src/NodeHeading.d.ts} +3 -3
- package/esm/extension-basic-editor/src/NodeHeading.d.ts.map +1 -0
- package/esm/{NodeHeading.js → extension-basic-editor/src/NodeHeading.js} +3 -3
- package/esm/{NodeHorizontalRule.d.ts → extension-basic-editor/src/NodeHorizontalRule.d.ts} +2 -2
- package/esm/extension-basic-editor/src/NodeHorizontalRule.d.ts.map +1 -0
- package/esm/{NodeHorizontalRule.js → extension-basic-editor/src/NodeHorizontalRule.js} +1 -1
- package/esm/{NodeImage.d.ts → extension-basic-editor/src/NodeImage.d.ts} +2 -2
- package/esm/extension-basic-editor/src/NodeImage.d.ts.map +1 -0
- package/esm/{NodeImage.js → extension-basic-editor/src/NodeImage.js} +1 -1
- package/esm/{NodeListItem.d.ts → extension-basic-editor/src/NodeListItem.d.ts} +2 -2
- package/esm/extension-basic-editor/src/NodeListItem.d.ts.map +1 -0
- package/esm/{NodeListItem.js → extension-basic-editor/src/NodeListItem.js} +1 -1
- package/esm/{NodeOrderedList.d.ts → extension-basic-editor/src/NodeOrderedList.d.ts} +3 -3
- package/esm/extension-basic-editor/src/NodeOrderedList.d.ts.map +1 -0
- package/esm/{NodeOrderedList.js → extension-basic-editor/src/NodeOrderedList.js} +5 -5
- package/esm/{NodeParagraph.d.ts → extension-basic-editor/src/NodeParagraph.d.ts} +2 -2
- package/esm/extension-basic-editor/src/NodeParagraph.d.ts.map +1 -0
- package/esm/{NodeParagraph.js → extension-basic-editor/src/NodeParagraph.js} +2 -2
- package/esm/{NodeText.d.ts → extension-basic-editor/src/NodeText.d.ts} +1 -1
- package/esm/extension-basic-editor/src/NodeText.d.ts.map +1 -0
- package/esm/{NodeText.js → extension-basic-editor/src/NodeText.js} +1 -1
- package/package.json +31 -25
- package/esm/ExtensionBaseKeymap.d.ts +0 -8
- package/esm/ExtensionBaseKeymap.d.ts.map +0 -1
- package/esm/ExtensionBasicEditor.d.ts.map +0 -1
- package/esm/ExtensionDropcursor.d.ts.map +0 -1
- package/esm/ExtensionGapcursor.d.ts.map +0 -1
- package/esm/ExtensionHistory.d.ts.map +0 -1
- package/esm/MarkCode.d.ts.map +0 -1
- package/esm/MarkItalic.d.ts.map +0 -1
- package/esm/MarkLink.d.ts.map +0 -1
- package/esm/MarkStrong.d.ts.map +0 -1
- package/esm/MarkUnderline.d.ts.map +0 -1
- package/esm/NodeAside.d.ts.map +0 -1
- package/esm/NodeBlockquote.d.ts.map +0 -1
- package/esm/NodeBulletList.d.ts.map +0 -1
- package/esm/NodeDocument.d.ts.map +0 -1
- package/esm/NodeHardBreak.d.ts.map +0 -1
- package/esm/NodeHeading.d.ts.map +0 -1
- package/esm/NodeHorizontalRule.d.ts.map +0 -1
- package/esm/NodeImage.d.ts.map +0 -1
- package/esm/NodeListItem.d.ts.map +0 -1
- package/esm/NodeOrderedList.d.ts.map +0 -1
- package/esm/NodeParagraph.d.ts.map +0 -1
- package/esm/NodeText.d.ts.map +0 -1
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
import { next as automerge } from '@automerge/automerge/slim';
|
|
2
|
+
import { Fragment, } from 'prosemirror-model';
|
|
3
|
+
import { amSpanToSpan, isBlockMarker } from './types.js';
|
|
4
|
+
import { amMarksFromPmMarks, pmMarksFromAmMarks, } from './SchemaAdapter.js';
|
|
5
|
+
/**
|
|
6
|
+
* Convert an array of AutoMerge spans into a ProseMirror doc.
|
|
7
|
+
* @param adapter
|
|
8
|
+
* @param spans
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
export function amSpansToDoc(adapter, spans) {
|
|
12
|
+
const events = traverseSpans(adapter, spans);
|
|
13
|
+
const stack = [
|
|
14
|
+
{
|
|
15
|
+
tag: 'doc',
|
|
16
|
+
attrs: {},
|
|
17
|
+
children: [],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
let nextBlockAmgAttrs = null;
|
|
21
|
+
for (const event of events) {
|
|
22
|
+
if (event.type === 'openTag') {
|
|
23
|
+
const attrs = Object.assign({}, nextBlockAmgAttrs, event.attrs);
|
|
24
|
+
stack.push({
|
|
25
|
+
tag: event.tag,
|
|
26
|
+
attrs,
|
|
27
|
+
children: [],
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (event.type === 'closeTag') {
|
|
31
|
+
//eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
32
|
+
const { children, attrs, tag } = stack.pop();
|
|
33
|
+
const node = constructNode(adapter.schema, tag, attrs, children);
|
|
34
|
+
stack[stack.length - 1].children.push(node);
|
|
35
|
+
}
|
|
36
|
+
else if (event.type === 'leafNode') {
|
|
37
|
+
stack[stack.length - 1].children.push(constructNode(adapter.schema, event.tag, nextBlockAmgAttrs || {}, []));
|
|
38
|
+
}
|
|
39
|
+
else if (event.type === 'text') {
|
|
40
|
+
const pmMarks = pmMarksFromAmMarks(adapter, event.marks);
|
|
41
|
+
stack[stack.length - 1].children.push(adapter.schema.text(event.text, pmMarks));
|
|
42
|
+
}
|
|
43
|
+
if (event.type === 'block') {
|
|
44
|
+
nextBlockAmgAttrs = { isAmgBlock: true, ...event.block.attrs };
|
|
45
|
+
if (event.isUnknown) {
|
|
46
|
+
nextBlockAmgAttrs.unknownBlock = event.block;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
nextBlockAmgAttrs = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (stack.length !== 1) {
|
|
54
|
+
throw new Error('Invalid stack length');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const { children, attrs, tag } = stack[0];
|
|
58
|
+
return constructNode(adapter.schema, tag, attrs, children);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function constructNode(schema, nodeName,
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
attrs, children) {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
|
+
const knownAttrs = {};
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
+
const unknownAttrs = {};
|
|
68
|
+
let hasUnknownAttr = false;
|
|
69
|
+
for (const name of Object.keys(attrs)) {
|
|
70
|
+
if (name === 'isAmgBlock' ||
|
|
71
|
+
name === 'unknownBlock' ||
|
|
72
|
+
name === 'unknownAttrs') {
|
|
73
|
+
knownAttrs[name] = attrs[name];
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const attrSpec = schema.nodes[nodeName]?.spec?.attrs?.[name];
|
|
77
|
+
if (attrSpec != null) {
|
|
78
|
+
knownAttrs[name] = attrs[name];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
hasUnknownAttr = true;
|
|
82
|
+
unknownAttrs[name] = attrs[name];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (hasUnknownAttr) {
|
|
86
|
+
knownAttrs.unknownAttrs = unknownAttrs;
|
|
87
|
+
}
|
|
88
|
+
return schema.node(nodeName, knownAttrs, children);
|
|
89
|
+
}
|
|
90
|
+
export function amSpliceIdxToPmIdx(adapter, spans, target) {
|
|
91
|
+
const events = eventsWithIndexChanges(traverseSpans(adapter, spans));
|
|
92
|
+
let maxInsertableIndex = null;
|
|
93
|
+
for (const state of events) {
|
|
94
|
+
if (state.before.amIdx >= target && maxInsertableIndex != null) {
|
|
95
|
+
return maxInsertableIndex;
|
|
96
|
+
}
|
|
97
|
+
if (state.event.type === 'openTag') {
|
|
98
|
+
if (adapter.schema.nodes[state.event.tag].isTextblock) {
|
|
99
|
+
maxInsertableIndex = state.after.pmIdx;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (state.event.type === 'leafNode') {
|
|
103
|
+
maxInsertableIndex = state.after.pmIdx;
|
|
104
|
+
}
|
|
105
|
+
else if (state.event.type === 'text') {
|
|
106
|
+
maxInsertableIndex = state.after.pmIdx;
|
|
107
|
+
if (state.after.amIdx >= target) {
|
|
108
|
+
if (state.before.amIdx + state.event.text.length >= target) {
|
|
109
|
+
const diff = target - state.before.amIdx;
|
|
110
|
+
return state.before.pmIdx + diff - 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return maxInsertableIndex;
|
|
116
|
+
}
|
|
117
|
+
export function amIdxToPmBlockIdx(adapter, spans, target) {
|
|
118
|
+
const events = eventsWithIndexChanges(traverseSpans(adapter, spans));
|
|
119
|
+
let lastBlockStart = null;
|
|
120
|
+
let isFirstTag = true;
|
|
121
|
+
for (const state of events) {
|
|
122
|
+
if (state.event.type === 'openTag') {
|
|
123
|
+
if (state.event.role === 'explicit') {
|
|
124
|
+
lastBlockStart = state.after.pmIdx;
|
|
125
|
+
}
|
|
126
|
+
else if (adapter.schema.nodes[state.event.tag].isTextblock &&
|
|
127
|
+
isFirstTag) {
|
|
128
|
+
// If there's a render-only opening paragraph then everything before
|
|
129
|
+
// the first block marker should be inside it
|
|
130
|
+
lastBlockStart = state.after.pmIdx;
|
|
131
|
+
}
|
|
132
|
+
isFirstTag = false;
|
|
133
|
+
}
|
|
134
|
+
else if (state.event.type === 'block') {
|
|
135
|
+
if (state.after.amIdx === target) {
|
|
136
|
+
return state.after.pmIdx + 1;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (state.after.amIdx >= target) {
|
|
140
|
+
return lastBlockStart;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return lastBlockStart;
|
|
144
|
+
}
|
|
145
|
+
export function* eventsWithIndexChanges(events) {
|
|
146
|
+
let pmOffset = 0;
|
|
147
|
+
let amOffset = -1;
|
|
148
|
+
while (true) {
|
|
149
|
+
const next = events.next();
|
|
150
|
+
if (next.done) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const event = next.value;
|
|
154
|
+
const before = { amIdx: amOffset, pmIdx: pmOffset };
|
|
155
|
+
if (event.type === 'openTag' && event.tag !== 'doc') {
|
|
156
|
+
pmOffset += 1;
|
|
157
|
+
}
|
|
158
|
+
else if (event.type === 'closeTag' && event.tag !== 'doc') {
|
|
159
|
+
pmOffset += 1;
|
|
160
|
+
}
|
|
161
|
+
else if (event.type === 'leafNode') {
|
|
162
|
+
pmOffset += 1;
|
|
163
|
+
}
|
|
164
|
+
else if (event.type === 'text') {
|
|
165
|
+
amOffset += event.text.length;
|
|
166
|
+
pmOffset += event.text.length;
|
|
167
|
+
}
|
|
168
|
+
else if (event.type === 'block') {
|
|
169
|
+
amOffset += 1;
|
|
170
|
+
}
|
|
171
|
+
const after = { amIdx: amOffset, pmIdx: pmOffset };
|
|
172
|
+
yield { event, before, after };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export function* traverseNode(adapter, node) {
|
|
176
|
+
const toProcess = [
|
|
177
|
+
{
|
|
178
|
+
node,
|
|
179
|
+
parent: null,
|
|
180
|
+
indexInParent: 0,
|
|
181
|
+
numChildrenInParent: node.childCount,
|
|
182
|
+
type: 'node',
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
const nodePath = [];
|
|
186
|
+
while (toProcess.length > 0) {
|
|
187
|
+
const next = toProcess.pop();
|
|
188
|
+
if (next == null) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (next.type === 'node') {
|
|
192
|
+
const cur = next.node;
|
|
193
|
+
if (cur.isText) {
|
|
194
|
+
const marks = amMarksFromPmMarks(adapter, cur.marks);
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
196
|
+
yield { type: 'text', text: cur.text, marks };
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const maybeBlock = blockForNode(adapter, cur, nodePath, next.indexInParent, next.numChildrenInParent);
|
|
200
|
+
const role = maybeBlock != null ? 'explicit' : 'render-only';
|
|
201
|
+
if (maybeBlock != null) {
|
|
202
|
+
const { block, isUnknown } = maybeBlock;
|
|
203
|
+
yield {
|
|
204
|
+
type: 'block',
|
|
205
|
+
isUnknown,
|
|
206
|
+
block,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (cur.isLeaf) {
|
|
210
|
+
yield { type: 'leafNode', tag: cur.type.name, role };
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
yield { type: 'openTag', tag: cur.type.name, role };
|
|
214
|
+
// nodePath.push({ node: cur, idx: 0 });
|
|
215
|
+
nodePath.push(cur);
|
|
216
|
+
toProcess.push({ type: 'closeTag', tag: cur.type.name, role });
|
|
217
|
+
for (let i = cur.childCount - 1; i >= 0; i--) {
|
|
218
|
+
toProcess.push({
|
|
219
|
+
parent: cur,
|
|
220
|
+
indexInParent: i,
|
|
221
|
+
numChildrenInParent: cur.childCount,
|
|
222
|
+
type: 'node',
|
|
223
|
+
node: cur.child(i),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
if (next.type === 'closeTag') {
|
|
231
|
+
nodePath.pop();
|
|
232
|
+
}
|
|
233
|
+
yield next;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function blockForNode(adapter, node, nodePath, indexInParent, numChildrenInParent) {
|
|
238
|
+
// Round trip unknown blocks through the editor
|
|
239
|
+
if (node.attrs.unknownBlock != null) {
|
|
240
|
+
return {
|
|
241
|
+
isUnknown: true,
|
|
242
|
+
block: node.attrs.unknownBlock,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const blockMapping = blockMappingForNode(adapter, node);
|
|
246
|
+
if (blockMapping == null) {
|
|
247
|
+
if (node.attrs.isAmgBlock) {
|
|
248
|
+
throw new Error('no mapping found for node which is marked as a block');
|
|
249
|
+
}
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
const attrs = blockMapping.attrParsers?.fromProsemirror(node) || {};
|
|
253
|
+
// make sure to round trip unknown attributes
|
|
254
|
+
if (node.attrs.unknownAttrs != null) {
|
|
255
|
+
for (const key of Object.keys(node.attrs.unknownAttrs)) {
|
|
256
|
+
attrs[key] = node.attrs.unknownAttrs[key];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// We have a few things to do
|
|
260
|
+
// 1. If this node has `isAmgBlock: true` then we just need to get the block
|
|
261
|
+
// mapping and emit the correct block
|
|
262
|
+
// 2. If this node has `isAmgBlock: false` then we have to decide, based on
|
|
263
|
+
// it's descendants, whether we should emit a block at this point
|
|
264
|
+
if (node.attrs.isAmgBlock) {
|
|
265
|
+
return {
|
|
266
|
+
isUnknown: false,
|
|
267
|
+
block: {
|
|
268
|
+
type: blockMapping.blockName,
|
|
269
|
+
parents: findParents(adapter, nodePath),
|
|
270
|
+
attrs,
|
|
271
|
+
isEmbed: blockMapping.isEmbed || false,
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
else if (blockMapping && blockMapping.isEmbed) {
|
|
276
|
+
return {
|
|
277
|
+
isUnknown: false,
|
|
278
|
+
block: {
|
|
279
|
+
type: blockMapping.blockName,
|
|
280
|
+
parents: findParents(adapter, nodePath),
|
|
281
|
+
attrs,
|
|
282
|
+
isEmbed: true,
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// Two possibilities:
|
|
288
|
+
//
|
|
289
|
+
// 1. The block is a container for an `isAmgBlock: true` block
|
|
290
|
+
// 2. The block is a newly inserted block
|
|
291
|
+
const explicitChildren = findExplicitChildren(node);
|
|
292
|
+
if (explicitChildren != null) {
|
|
293
|
+
// This block has explicit children. So we only need to emit a block
|
|
294
|
+
// marker if the content before the first explicit child is different to
|
|
295
|
+
// that which would be emitted by the default schema
|
|
296
|
+
const defaultContent = blockMapping.content.contentMatch.fillBefore(Fragment.from([explicitChildren.first]), true);
|
|
297
|
+
if (defaultContent == null) {
|
|
298
|
+
throw new Error('schema could not find wrapping');
|
|
299
|
+
}
|
|
300
|
+
if (defaultContent.eq(explicitChildren.contentBeforeFirst)) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
let emitBlock = false;
|
|
305
|
+
if (node.isTextblock) {
|
|
306
|
+
const lastParent = nodePath[nodePath.length - 1];
|
|
307
|
+
const lastParentNode = lastParent;
|
|
308
|
+
// const lastParentNode = lastParent.node;
|
|
309
|
+
if (lastParentNode == null ||
|
|
310
|
+
(lastParentNode.type === adapter.schema.nodes.doc &&
|
|
311
|
+
numChildrenInParent > 1)) {
|
|
312
|
+
// we're at the top level and there are multiple children, so we need to emit a block marker
|
|
313
|
+
emitBlock = true;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// If we're the first node in our parent, and we're the default textblock
|
|
317
|
+
// for that parent then we don't emit a block marker
|
|
318
|
+
const isTextWrapper = lastParentNode.type.contentMatch.defaultType === node.type &&
|
|
319
|
+
indexInParent === 0 &&
|
|
320
|
+
!node.attrs.isAmgBlock;
|
|
321
|
+
if (!isTextWrapper) {
|
|
322
|
+
emitBlock = true;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else if (hasImmediateTextChild(node)) {
|
|
327
|
+
emitBlock = true;
|
|
328
|
+
}
|
|
329
|
+
if (emitBlock) {
|
|
330
|
+
return {
|
|
331
|
+
isUnknown: blockMapping.content === adapter.unknownBlock,
|
|
332
|
+
block: {
|
|
333
|
+
type: blockMapping.blockName,
|
|
334
|
+
parents: findParents(adapter, nodePath),
|
|
335
|
+
attrs,
|
|
336
|
+
isEmbed: blockMapping.isEmbed || false,
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function hasImmediateTextChild(node) {
|
|
346
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
347
|
+
if (node.child(i).isTextblock) {
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Find the first child of this node which either has `isAmgBlock: true` or
|
|
355
|
+
* has a descendant with `isAmgBlock: true`
|
|
356
|
+
*/
|
|
357
|
+
function findExplicitChildren(node) {
|
|
358
|
+
let numExplicitChildren = 0;
|
|
359
|
+
let firstExplicitChild = null;
|
|
360
|
+
const contentBeforeFirst = [];
|
|
361
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
362
|
+
const child = node.child(i);
|
|
363
|
+
let hasExplicitDescendant = false;
|
|
364
|
+
if (child.attrs.isAmgBlock) {
|
|
365
|
+
hasExplicitDescendant = true;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
child.descendants((desc) => {
|
|
369
|
+
if (desc.attrs.isAmgBlock) {
|
|
370
|
+
hasExplicitDescendant = true;
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
return true;
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
if (hasExplicitDescendant) {
|
|
377
|
+
numExplicitChildren++;
|
|
378
|
+
if (firstExplicitChild == null) {
|
|
379
|
+
firstExplicitChild = child;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (firstExplicitChild == null) {
|
|
383
|
+
contentBeforeFirst.push(child);
|
|
384
|
+
}
|
|
385
|
+
if (numExplicitChildren > 1) {
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (numExplicitChildren > 0) {
|
|
390
|
+
return {
|
|
391
|
+
contentBeforeFirst: Fragment.from(contentBeforeFirst),
|
|
392
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
393
|
+
first: firstExplicitChild,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function blockMappingForNode(adapter, node) {
|
|
401
|
+
if (node.type === adapter.unknownBlock && node.attrs.unknownParentBlock) {
|
|
402
|
+
return {
|
|
403
|
+
blockName: node.attrs.unknownParentBlock,
|
|
404
|
+
content: node.type,
|
|
405
|
+
isEmbed: false,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
const possibleMappings = adapter.nodeMappings.filter((m) => m.content === node.type);
|
|
409
|
+
if (possibleMappings.length === 0) {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
return possibleMappings[0];
|
|
413
|
+
}
|
|
414
|
+
function findParents(adapter, parentNodes) {
|
|
415
|
+
const parents = [];
|
|
416
|
+
for (const [index, parent] of parentNodes.entries()) {
|
|
417
|
+
const node = parent; // .node;
|
|
418
|
+
if (index === parentNodes.length - 1 &&
|
|
419
|
+
node.isTextblock &&
|
|
420
|
+
!node.attrs.isAmgBlock) {
|
|
421
|
+
// If the last node is a render-only text block then we don't need to emit it, the
|
|
422
|
+
// schema will take care of inserting it around the content for us
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
const mapping = blockMappingForNode(adapter, node);
|
|
426
|
+
if (mapping == null) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
parents.push(mapping.blockName);
|
|
430
|
+
}
|
|
431
|
+
return parents;
|
|
432
|
+
}
|
|
433
|
+
export function* traverseSpans(adapter, amSpans) {
|
|
434
|
+
const blockSpans = amSpans.map(amSpanToSpan);
|
|
435
|
+
if (blockSpans.length === 0) {
|
|
436
|
+
return yield* [
|
|
437
|
+
{ type: 'openTag', tag: 'paragraph', role: 'render-only' },
|
|
438
|
+
{ type: 'closeTag', tag: 'paragraph', role: 'render-only' },
|
|
439
|
+
];
|
|
440
|
+
}
|
|
441
|
+
const state = new TraverseState(adapter);
|
|
442
|
+
for (const span of blockSpans) {
|
|
443
|
+
if (span.type === 'block') {
|
|
444
|
+
yield* state.newBlock(span.value);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
yield* state.newText(span.value, span.marks || {});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
yield* state.finish();
|
|
451
|
+
}
|
|
452
|
+
class TraverseState {
|
|
453
|
+
constructor(adapter) {
|
|
454
|
+
Object.defineProperty(this, "adapter", {
|
|
455
|
+
enumerable: true,
|
|
456
|
+
configurable: true,
|
|
457
|
+
writable: true,
|
|
458
|
+
value: void 0
|
|
459
|
+
});
|
|
460
|
+
Object.defineProperty(this, "lastBlock", {
|
|
461
|
+
enumerable: true,
|
|
462
|
+
configurable: true,
|
|
463
|
+
writable: true,
|
|
464
|
+
value: null
|
|
465
|
+
});
|
|
466
|
+
Object.defineProperty(this, "stack", {
|
|
467
|
+
enumerable: true,
|
|
468
|
+
configurable: true,
|
|
469
|
+
writable: true,
|
|
470
|
+
value: []
|
|
471
|
+
});
|
|
472
|
+
Object.defineProperty(this, "topMatch", {
|
|
473
|
+
enumerable: true,
|
|
474
|
+
configurable: true,
|
|
475
|
+
writable: true,
|
|
476
|
+
value: void 0
|
|
477
|
+
});
|
|
478
|
+
this.adapter = adapter;
|
|
479
|
+
this.stack = [];
|
|
480
|
+
this.topMatch = this.adapter.schema.nodes.doc.contentMatch;
|
|
481
|
+
}
|
|
482
|
+
set currentMatch(match) {
|
|
483
|
+
if (match === null) {
|
|
484
|
+
throw new Error('Match cannot be null');
|
|
485
|
+
}
|
|
486
|
+
if (this.stack.length > 0) {
|
|
487
|
+
this.stack[this.stack.length - 1].lastMatch = match;
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
this.topMatch = match;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
get currentMatch() {
|
|
494
|
+
if (this.stack.length > 0) {
|
|
495
|
+
return this.stack[this.stack.length - 1].lastMatch;
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
return this.topMatch;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
*newBlock(block) {
|
|
502
|
+
if (block.isEmbed) {
|
|
503
|
+
const { content } = nodesForBlock(this.adapter, block.type.val, block.isEmbed);
|
|
504
|
+
const wrapping = this.currentMatch.findWrapping(content);
|
|
505
|
+
if (wrapping) {
|
|
506
|
+
for (let i = 0; i < wrapping.length; i++) {
|
|
507
|
+
yield this.pushNode(wrapping[i], null, 'render-only');
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
511
|
+
this.currentMatch = this.currentMatch.matchType(content);
|
|
512
|
+
yield blockEvent(this.adapter, block);
|
|
513
|
+
yield { type: 'leafNode', tag: content.name, role: 'explicit' };
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const newOuter = outerNodeTypes(this.adapter, block);
|
|
517
|
+
let i = 0;
|
|
518
|
+
while (i < newOuter.length && i < this.stack.length) {
|
|
519
|
+
if (this.stack[i].node !== newOuter[i].type) {
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
i++;
|
|
523
|
+
}
|
|
524
|
+
const toClose = this.stack.splice(i);
|
|
525
|
+
for (const { node, role, lastMatch } of toClose.toReversed()) {
|
|
526
|
+
yield* this.finishStackFrame({ node, role, lastMatch });
|
|
527
|
+
yield { type: 'closeTag', tag: node.name, role };
|
|
528
|
+
}
|
|
529
|
+
for (let j = i; j < newOuter.length; j++) {
|
|
530
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
531
|
+
const { type: next, attrs } = newOuter[j];
|
|
532
|
+
yield* this.fillBefore(next);
|
|
533
|
+
yield this.pushNode(next, attrs, 'render-only');
|
|
534
|
+
}
|
|
535
|
+
yield blockEvent(this.adapter, block);
|
|
536
|
+
const { content } = nodesForBlock(this.adapter, block.type.val, block.isEmbed || false);
|
|
537
|
+
yield this.pushNode(content, null, 'explicit');
|
|
538
|
+
}
|
|
539
|
+
pushNode(node,
|
|
540
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
541
|
+
attrs, role) {
|
|
542
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
543
|
+
this.currentMatch = this.currentMatch.matchType(node);
|
|
544
|
+
this.stack.push({ node, role, lastMatch: node.contentMatch });
|
|
545
|
+
return { type: 'openTag', tag: node.name, role, ...(attrs && { attrs }) };
|
|
546
|
+
}
|
|
547
|
+
*newText(text, marks) {
|
|
548
|
+
const wrapping = this.currentMatch.findWrapping(this.adapter.schema.nodes.text);
|
|
549
|
+
if (wrapping) {
|
|
550
|
+
for (let i = 0; i < wrapping.length; i++) {
|
|
551
|
+
yield this.pushNode(wrapping[i], null, 'render-only');
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
555
|
+
this.currentMatch = this.currentMatch.matchType(this.adapter.schema.nodes.text);
|
|
556
|
+
yield { type: 'text', text, marks };
|
|
557
|
+
}
|
|
558
|
+
*finish() {
|
|
559
|
+
for (const { node, role, lastMatch } of this.stack.toReversed()) {
|
|
560
|
+
yield* this.finishStackFrame({ node, role, lastMatch });
|
|
561
|
+
yield { type: 'closeTag', tag: node.name, role };
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
*fillBefore(node) {
|
|
565
|
+
const fill = this.currentMatch.fillBefore(Fragment.from(node.create()));
|
|
566
|
+
if (fill != null) {
|
|
567
|
+
yield* this.emitFragment(fill);
|
|
568
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
569
|
+
this.currentMatch = this.currentMatch.matchFragment(fill);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
*emitFragment(fragment) {
|
|
573
|
+
const toProcess = [];
|
|
574
|
+
for (let i = fragment.childCount - 1; i >= 0; i--) {
|
|
575
|
+
toProcess.push({ type: 'open', node: fragment.child(i) });
|
|
576
|
+
}
|
|
577
|
+
while (toProcess.length > 0) {
|
|
578
|
+
const next = toProcess.pop();
|
|
579
|
+
if (next == null) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
if (next.type === 'open') {
|
|
583
|
+
yield {
|
|
584
|
+
type: 'openTag',
|
|
585
|
+
tag: next.node.type.name,
|
|
586
|
+
role: 'render-only',
|
|
587
|
+
};
|
|
588
|
+
if (next.node.isText) {
|
|
589
|
+
// TODO: Calculate marks
|
|
590
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
591
|
+
yield { type: 'text', text: next.node.text, marks: {} };
|
|
592
|
+
yield {
|
|
593
|
+
type: 'closeTag',
|
|
594
|
+
tag: next.node.type.name,
|
|
595
|
+
role: 'render-only',
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
toProcess.push({ type: 'close', node: next.node.type });
|
|
600
|
+
for (let i = next.node.childCount - 1; i >= 0; i--) {
|
|
601
|
+
toProcess.push({ type: 'open', node: next.node.child(i) });
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
yield { type: 'closeTag', tag: next.node.name, role: 'render-only' };
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
*finishStackFrame(frame) {
|
|
611
|
+
const fill = frame.lastMatch.fillBefore(Fragment.empty, true);
|
|
612
|
+
if (fill) {
|
|
613
|
+
yield* this.emitFragment(fill);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
function outerNodeTypes(adapter, block) {
|
|
618
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
619
|
+
const result = [];
|
|
620
|
+
for (const parent of block.parents) {
|
|
621
|
+
const { content, attrs } = nodesForBlock(adapter, parent.val, false);
|
|
622
|
+
result.push({ type: content, attrs: attrs || null });
|
|
623
|
+
}
|
|
624
|
+
return result;
|
|
625
|
+
}
|
|
626
|
+
function blockEvent(adapter, block) {
|
|
627
|
+
const mapping = adapter.nodeMappings.find((m) => m.blockName === block.type.val);
|
|
628
|
+
const attrs = { ...block.attrs };
|
|
629
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
630
|
+
if (value instanceof automerge.RawString) {
|
|
631
|
+
attrs[key] = value.val;
|
|
632
|
+
}
|
|
633
|
+
else if ('string' === typeof value?.val) {
|
|
634
|
+
attrs[key] = value?.val;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
type: 'block',
|
|
639
|
+
isUnknown: mapping == null,
|
|
640
|
+
block: {
|
|
641
|
+
attrs,
|
|
642
|
+
parents: block.parents.map((p) => p.val),
|
|
643
|
+
type: block.type.val,
|
|
644
|
+
isEmbed: block.isEmbed || false,
|
|
645
|
+
},
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
export function blockAtIdx(spans, target) {
|
|
649
|
+
let idx = 0;
|
|
650
|
+
let block = null;
|
|
651
|
+
for (const span of spans) {
|
|
652
|
+
if (idx > target) {
|
|
653
|
+
return block;
|
|
654
|
+
}
|
|
655
|
+
if (span.type === 'text') {
|
|
656
|
+
if (idx + span.value.length > target) {
|
|
657
|
+
return block;
|
|
658
|
+
}
|
|
659
|
+
idx += span.value.length;
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
if (isBlockMarker(span.value)) {
|
|
663
|
+
block = { index: idx, block: span.value };
|
|
664
|
+
}
|
|
665
|
+
idx += 1;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return block;
|
|
669
|
+
}
|
|
670
|
+
function nodesForBlock(adapter, blockType, isEmbed) {
|
|
671
|
+
const mapping = adapter.nodeMappings.find((m) => m.blockName === blockType);
|
|
672
|
+
if (mapping == null) {
|
|
673
|
+
if (isEmbed) {
|
|
674
|
+
return {
|
|
675
|
+
content: adapter.unknownLeaf,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
return {
|
|
680
|
+
content: adapter.unknownBlock,
|
|
681
|
+
attrs: { unknownParentBlock: blockType },
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return {
|
|
686
|
+
content: mapping.content,
|
|
687
|
+
};
|
|
688
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { next as automerge } from '@automerge/automerge';
|
|
2
|
+
import type { Node as ProseMirrorNode } from 'prosemirror-model';
|
|
3
|
+
import type { SchemaAdapter } from './SchemaAdapter.js';
|
|
4
|
+
import { DocHandle } from '@automerge/automerge-repo';
|
|
5
|
+
export declare function createEmptyDocFromExisting(doc: ProseMirrorNode): ProseMirrorNode | null;
|
|
6
|
+
export declare function pmDocToAm<T>(basicSchemaAdapter: SchemaAdapter, amDoc: automerge.Doc<T>, docToLoad: ProseMirrorNode, pathToTextField?: string[]): automerge.Doc<T>;
|
|
7
|
+
export declare function pmDocToAmHandle<T>(basicSchemaAdapter: SchemaAdapter, handle: DocHandle<T>, docToLoad: ProseMirrorNode, pathToTextField?: string[]): void;
|
|
8
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/extension-automerge/src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,IAAI,eAAe,EAAU,MAAM,mBAAmB,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAkCtD,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,eAAe,0BAE9D;AAED,wBAAgB,SAAS,CAAC,CAAC,EACzB,kBAAkB,EAAE,aAAa,EACjC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EACvB,SAAS,EAAE,eAAe,EAC1B,eAAe,WAAW,GACzB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAYlB;AAED,wBAAgB,eAAe,CAAC,CAAC,EAC/B,kBAAkB,EAAE,aAAa,EACjC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EACpB,SAAS,EAAE,eAAe,EAC1B,eAAe,WAAW,QAc3B"}
|