@liveblocks/node-prosemirror 2.18.3 → 2.18.4-uns2
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/dist/index.cjs +249 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +33 -3102
- package/dist/index.js.map +1 -1
- package/package.json +13 -12
- package/dist/index.mjs +0 -3318
- package/dist/index.mjs.map +0 -1
- /package/dist/{index.d.mts → index.d.cts} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3091 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// src/version.ts
|
|
5
|
-
var PKG_NAME = "@liveblocks/node-prosemirror";
|
|
6
|
-
var PKG_VERSION = "2.18.3";
|
|
7
|
-
var PKG_FORMAT = "cjs";
|
|
8
|
-
|
|
9
|
-
// ../../node_modules/@tiptap/core/dist/index.js
|
|
10
|
-
var _state = require('@tiptap/pm/state');
|
|
11
|
-
var _view2 = require('@tiptap/pm/view');
|
|
12
|
-
var _keymap = require('@tiptap/pm/keymap');
|
|
13
|
-
var _model = require('@tiptap/pm/model');
|
|
14
|
-
var _transform = require('@tiptap/pm/transform');
|
|
15
|
-
var _commands = require('@tiptap/pm/commands');
|
|
16
|
-
var _schemalist = require('@tiptap/pm/schema-list');
|
|
17
|
-
function createChainableState(config) {
|
|
18
|
-
const { state, transaction } = config;
|
|
19
|
-
let { selection } = transaction;
|
|
20
|
-
let { doc } = transaction;
|
|
21
|
-
let { storedMarks } = transaction;
|
|
22
|
-
return {
|
|
23
|
-
...state,
|
|
24
|
-
apply: state.apply.bind(state),
|
|
25
|
-
applyTransaction: state.applyTransaction.bind(state),
|
|
26
|
-
plugins: state.plugins,
|
|
27
|
-
schema: state.schema,
|
|
28
|
-
reconfigure: state.reconfigure.bind(state),
|
|
29
|
-
toJSON: state.toJSON.bind(state),
|
|
30
|
-
get storedMarks() {
|
|
31
|
-
return storedMarks;
|
|
32
|
-
},
|
|
33
|
-
get selection() {
|
|
34
|
-
return selection;
|
|
35
|
-
},
|
|
36
|
-
get doc() {
|
|
37
|
-
return doc;
|
|
38
|
-
},
|
|
39
|
-
get tr() {
|
|
40
|
-
selection = transaction.selection;
|
|
41
|
-
doc = transaction.doc;
|
|
42
|
-
storedMarks = transaction.storedMarks;
|
|
43
|
-
return transaction;
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
var CommandManager = class {
|
|
48
|
-
constructor(props) {
|
|
49
|
-
this.editor = props.editor;
|
|
50
|
-
this.rawCommands = this.editor.extensionManager.commands;
|
|
51
|
-
this.customState = props.state;
|
|
52
|
-
}
|
|
53
|
-
get hasCustomState() {
|
|
54
|
-
return !!this.customState;
|
|
55
|
-
}
|
|
56
|
-
get state() {
|
|
57
|
-
return this.customState || this.editor.state;
|
|
58
|
-
}
|
|
59
|
-
get commands() {
|
|
60
|
-
const { rawCommands, editor, state } = this;
|
|
61
|
-
const { view } = editor;
|
|
62
|
-
const { tr } = state;
|
|
63
|
-
const props = this.buildProps(tr);
|
|
64
|
-
return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
|
|
65
|
-
const method = (...args) => {
|
|
66
|
-
const callback = command2(...args)(props);
|
|
67
|
-
if (!tr.getMeta("preventDispatch") && !this.hasCustomState) {
|
|
68
|
-
view.dispatch(tr);
|
|
69
|
-
}
|
|
70
|
-
return callback;
|
|
71
|
-
};
|
|
72
|
-
return [name, method];
|
|
73
|
-
}));
|
|
74
|
-
}
|
|
75
|
-
get chain() {
|
|
76
|
-
return () => this.createChain();
|
|
77
|
-
}
|
|
78
|
-
get can() {
|
|
79
|
-
return () => this.createCan();
|
|
80
|
-
}
|
|
81
|
-
createChain(startTr, shouldDispatch = true) {
|
|
82
|
-
const { rawCommands, editor, state } = this;
|
|
83
|
-
const { view } = editor;
|
|
84
|
-
const callbacks = [];
|
|
85
|
-
const hasStartTransaction = !!startTr;
|
|
86
|
-
const tr = startTr || state.tr;
|
|
87
|
-
const run2 = () => {
|
|
88
|
-
if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) {
|
|
89
|
-
view.dispatch(tr);
|
|
90
|
-
}
|
|
91
|
-
return callbacks.every((callback) => callback === true);
|
|
92
|
-
};
|
|
93
|
-
const chain = {
|
|
94
|
-
...Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
|
|
95
|
-
const chainedCommand = (...args) => {
|
|
96
|
-
const props = this.buildProps(tr, shouldDispatch);
|
|
97
|
-
const callback = command2(...args)(props);
|
|
98
|
-
callbacks.push(callback);
|
|
99
|
-
return chain;
|
|
100
|
-
};
|
|
101
|
-
return [name, chainedCommand];
|
|
102
|
-
})),
|
|
103
|
-
run: run2
|
|
104
|
-
};
|
|
105
|
-
return chain;
|
|
106
|
-
}
|
|
107
|
-
createCan(startTr) {
|
|
108
|
-
const { rawCommands, state } = this;
|
|
109
|
-
const dispatch = false;
|
|
110
|
-
const tr = startTr || state.tr;
|
|
111
|
-
const props = this.buildProps(tr, dispatch);
|
|
112
|
-
const formattedCommands = Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
|
|
113
|
-
return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
|
|
114
|
-
}));
|
|
115
|
-
return {
|
|
116
|
-
...formattedCommands,
|
|
117
|
-
chain: () => this.createChain(tr, dispatch)
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
buildProps(tr, shouldDispatch = true) {
|
|
121
|
-
const { rawCommands, editor, state } = this;
|
|
122
|
-
const { view } = editor;
|
|
123
|
-
const props = {
|
|
124
|
-
tr,
|
|
125
|
-
editor,
|
|
126
|
-
view,
|
|
127
|
-
state: createChainableState({
|
|
128
|
-
state,
|
|
129
|
-
transaction: tr
|
|
130
|
-
}),
|
|
131
|
-
dispatch: shouldDispatch ? () => void 0 : void 0,
|
|
132
|
-
chain: () => this.createChain(tr, shouldDispatch),
|
|
133
|
-
can: () => this.createCan(tr),
|
|
134
|
-
get commands() {
|
|
135
|
-
return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
|
|
136
|
-
return [name, (...args) => command2(...args)(props)];
|
|
137
|
-
}));
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
return props;
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
function getExtensionField(extension, field, context) {
|
|
144
|
-
if (extension.config[field] === void 0 && extension.parent) {
|
|
145
|
-
return getExtensionField(extension.parent, field, context);
|
|
146
|
-
}
|
|
147
|
-
if (typeof extension.config[field] === "function") {
|
|
148
|
-
const value = extension.config[field].bind({
|
|
149
|
-
...context,
|
|
150
|
-
parent: extension.parent ? getExtensionField(extension.parent, field, context) : null
|
|
151
|
-
});
|
|
152
|
-
return value;
|
|
153
|
-
}
|
|
154
|
-
return extension.config[field];
|
|
155
|
-
}
|
|
156
|
-
function splitExtensions(extensions) {
|
|
157
|
-
const baseExtensions = extensions.filter((extension) => extension.type === "extension");
|
|
158
|
-
const nodeExtensions = extensions.filter((extension) => extension.type === "node");
|
|
159
|
-
const markExtensions = extensions.filter((extension) => extension.type === "mark");
|
|
160
|
-
return {
|
|
161
|
-
baseExtensions,
|
|
162
|
-
nodeExtensions,
|
|
163
|
-
markExtensions
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
function getAttributesFromExtensions(extensions) {
|
|
167
|
-
const extensionAttributes = [];
|
|
168
|
-
const { nodeExtensions, markExtensions } = splitExtensions(extensions);
|
|
169
|
-
const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions];
|
|
170
|
-
const defaultAttribute = {
|
|
171
|
-
default: null,
|
|
172
|
-
rendered: true,
|
|
173
|
-
renderHTML: null,
|
|
174
|
-
parseHTML: null,
|
|
175
|
-
keepOnSplit: true,
|
|
176
|
-
isRequired: false
|
|
177
|
-
};
|
|
178
|
-
extensions.forEach((extension) => {
|
|
179
|
-
const context = {
|
|
180
|
-
name: extension.name,
|
|
181
|
-
options: extension.options,
|
|
182
|
-
storage: extension.storage,
|
|
183
|
-
extensions: nodeAndMarkExtensions
|
|
184
|
-
};
|
|
185
|
-
const addGlobalAttributes = getExtensionField(extension, "addGlobalAttributes", context);
|
|
186
|
-
if (!addGlobalAttributes) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
const globalAttributes = addGlobalAttributes();
|
|
190
|
-
globalAttributes.forEach((globalAttribute) => {
|
|
191
|
-
globalAttribute.types.forEach((type) => {
|
|
192
|
-
Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => {
|
|
193
|
-
extensionAttributes.push({
|
|
194
|
-
type,
|
|
195
|
-
name,
|
|
196
|
-
attribute: {
|
|
197
|
-
...defaultAttribute,
|
|
198
|
-
...attribute
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
nodeAndMarkExtensions.forEach((extension) => {
|
|
206
|
-
const context = {
|
|
207
|
-
name: extension.name,
|
|
208
|
-
options: extension.options,
|
|
209
|
-
storage: extension.storage
|
|
210
|
-
};
|
|
211
|
-
const addAttributes = getExtensionField(extension, "addAttributes", context);
|
|
212
|
-
if (!addAttributes) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const attributes = addAttributes();
|
|
216
|
-
Object.entries(attributes).forEach(([name, attribute]) => {
|
|
217
|
-
const mergedAttr = {
|
|
218
|
-
...defaultAttribute,
|
|
219
|
-
...attribute
|
|
220
|
-
};
|
|
221
|
-
if (typeof (mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.default) === "function") {
|
|
222
|
-
mergedAttr.default = mergedAttr.default();
|
|
223
|
-
}
|
|
224
|
-
if ((mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.isRequired) && (mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.default) === void 0) {
|
|
225
|
-
delete mergedAttr.default;
|
|
226
|
-
}
|
|
227
|
-
extensionAttributes.push({
|
|
228
|
-
type: extension.name,
|
|
229
|
-
name,
|
|
230
|
-
attribute: mergedAttr
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
return extensionAttributes;
|
|
235
|
-
}
|
|
236
|
-
function getNodeType(nameOrType, schema) {
|
|
237
|
-
if (typeof nameOrType === "string") {
|
|
238
|
-
if (!schema.nodes[nameOrType]) {
|
|
239
|
-
throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
240
|
-
}
|
|
241
|
-
return schema.nodes[nameOrType];
|
|
242
|
-
}
|
|
243
|
-
return nameOrType;
|
|
244
|
-
}
|
|
245
|
-
function mergeAttributes(...objects) {
|
|
246
|
-
return objects.filter((item) => !!item).reduce((items, item) => {
|
|
247
|
-
const mergedAttributes = { ...items };
|
|
248
|
-
Object.entries(item).forEach(([key, value]) => {
|
|
249
|
-
const exists = mergedAttributes[key];
|
|
250
|
-
if (!exists) {
|
|
251
|
-
mergedAttributes[key] = value;
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
if (key === "class") {
|
|
255
|
-
const valueClasses = value ? value.split(" ") : [];
|
|
256
|
-
const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : [];
|
|
257
|
-
const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass));
|
|
258
|
-
mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
|
|
259
|
-
} else if (key === "style") {
|
|
260
|
-
const newStyles = value ? value.split(";").map((style) => style.trim()).filter(Boolean) : [];
|
|
261
|
-
const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(";").map((style) => style.trim()).filter(Boolean) : [];
|
|
262
|
-
const styleMap = /* @__PURE__ */ new Map();
|
|
263
|
-
existingStyles.forEach((style) => {
|
|
264
|
-
const [property, val] = style.split(":").map((part) => part.trim());
|
|
265
|
-
styleMap.set(property, val);
|
|
266
|
-
});
|
|
267
|
-
newStyles.forEach((style) => {
|
|
268
|
-
const [property, val] = style.split(":").map((part) => part.trim());
|
|
269
|
-
styleMap.set(property, val);
|
|
270
|
-
});
|
|
271
|
-
mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
|
|
272
|
-
} else {
|
|
273
|
-
mergedAttributes[key] = value;
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
return mergedAttributes;
|
|
277
|
-
}, {});
|
|
278
|
-
}
|
|
279
|
-
function getRenderedAttributes(nodeOrMark, extensionAttributes) {
|
|
280
|
-
return extensionAttributes.filter((attribute) => attribute.type === nodeOrMark.type.name).filter((item) => item.attribute.rendered).map((item) => {
|
|
281
|
-
if (!item.attribute.renderHTML) {
|
|
282
|
-
return {
|
|
283
|
-
[item.name]: nodeOrMark.attrs[item.name]
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
return item.attribute.renderHTML(nodeOrMark.attrs) || {};
|
|
287
|
-
}).reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {});
|
|
288
|
-
}
|
|
289
|
-
function isFunction(value) {
|
|
290
|
-
return typeof value === "function";
|
|
291
|
-
}
|
|
292
|
-
function callOrReturn(value, context = void 0, ...props) {
|
|
293
|
-
if (isFunction(value)) {
|
|
294
|
-
if (context) {
|
|
295
|
-
return value.bind(context)(...props);
|
|
296
|
-
}
|
|
297
|
-
return value(...props);
|
|
298
|
-
}
|
|
299
|
-
return value;
|
|
300
|
-
}
|
|
301
|
-
function isEmptyObject(value = {}) {
|
|
302
|
-
return Object.keys(value).length === 0 && value.constructor === Object;
|
|
303
|
-
}
|
|
304
|
-
function fromString(value) {
|
|
305
|
-
if (typeof value !== "string") {
|
|
306
|
-
return value;
|
|
307
|
-
}
|
|
308
|
-
if (value.match(/^[+-]?(?:\d*\.)?\d+$/)) {
|
|
309
|
-
return Number(value);
|
|
310
|
-
}
|
|
311
|
-
if (value === "true") {
|
|
312
|
-
return true;
|
|
313
|
-
}
|
|
314
|
-
if (value === "false") {
|
|
315
|
-
return false;
|
|
316
|
-
}
|
|
317
|
-
return value;
|
|
318
|
-
}
|
|
319
|
-
function injectExtensionAttributesToParseRule(parseRule, extensionAttributes) {
|
|
320
|
-
if ("style" in parseRule) {
|
|
321
|
-
return parseRule;
|
|
322
|
-
}
|
|
323
|
-
return {
|
|
324
|
-
...parseRule,
|
|
325
|
-
getAttrs: (node) => {
|
|
326
|
-
const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : parseRule.attrs;
|
|
327
|
-
if (oldAttributes === false) {
|
|
328
|
-
return false;
|
|
329
|
-
}
|
|
330
|
-
const newAttributes = extensionAttributes.reduce((items, item) => {
|
|
331
|
-
const value = item.attribute.parseHTML ? item.attribute.parseHTML(node) : fromString(node.getAttribute(item.name));
|
|
332
|
-
if (value === null || value === void 0) {
|
|
333
|
-
return items;
|
|
334
|
-
}
|
|
335
|
-
return {
|
|
336
|
-
...items,
|
|
337
|
-
[item.name]: value
|
|
338
|
-
};
|
|
339
|
-
}, {});
|
|
340
|
-
return { ...oldAttributes, ...newAttributes };
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
function cleanUpSchemaItem(data) {
|
|
345
|
-
return Object.fromEntries(
|
|
346
|
-
// @ts-ignore
|
|
347
|
-
Object.entries(data).filter(([key, value]) => {
|
|
348
|
-
if (key === "attrs" && isEmptyObject(value)) {
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
return value !== null && value !== void 0;
|
|
352
|
-
})
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
function getSchemaByResolvedExtensions(extensions, editor) {
|
|
356
|
-
var _a;
|
|
357
|
-
const allAttributes = getAttributesFromExtensions(extensions);
|
|
358
|
-
const { nodeExtensions, markExtensions } = splitExtensions(extensions);
|
|
359
|
-
const topNode = (_a = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) === null || _a === void 0 ? void 0 : _a.name;
|
|
360
|
-
const nodes = Object.fromEntries(nodeExtensions.map((extension) => {
|
|
361
|
-
const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
|
|
362
|
-
const context = {
|
|
363
|
-
name: extension.name,
|
|
364
|
-
options: extension.options,
|
|
365
|
-
storage: extension.storage,
|
|
366
|
-
editor
|
|
367
|
-
};
|
|
368
|
-
const extraNodeFields = extensions.reduce((fields, e) => {
|
|
369
|
-
const extendNodeSchema = getExtensionField(e, "extendNodeSchema", context);
|
|
370
|
-
return {
|
|
371
|
-
...fields,
|
|
372
|
-
...extendNodeSchema ? extendNodeSchema(extension) : {}
|
|
373
|
-
};
|
|
374
|
-
}, {});
|
|
375
|
-
const schema = cleanUpSchemaItem({
|
|
376
|
-
...extraNodeFields,
|
|
377
|
-
content: callOrReturn(getExtensionField(extension, "content", context)),
|
|
378
|
-
marks: callOrReturn(getExtensionField(extension, "marks", context)),
|
|
379
|
-
group: callOrReturn(getExtensionField(extension, "group", context)),
|
|
380
|
-
inline: callOrReturn(getExtensionField(extension, "inline", context)),
|
|
381
|
-
atom: callOrReturn(getExtensionField(extension, "atom", context)),
|
|
382
|
-
selectable: callOrReturn(getExtensionField(extension, "selectable", context)),
|
|
383
|
-
draggable: callOrReturn(getExtensionField(extension, "draggable", context)),
|
|
384
|
-
code: callOrReturn(getExtensionField(extension, "code", context)),
|
|
385
|
-
whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)),
|
|
386
|
-
linebreakReplacement: callOrReturn(getExtensionField(extension, "linebreakReplacement", context)),
|
|
387
|
-
defining: callOrReturn(getExtensionField(extension, "defining", context)),
|
|
388
|
-
isolating: callOrReturn(getExtensionField(extension, "isolating", context)),
|
|
389
|
-
attrs: Object.fromEntries(extensionAttributes.map((extensionAttribute) => {
|
|
390
|
-
var _a2;
|
|
391
|
-
return [extensionAttribute.name, { default: (_a2 = extensionAttribute === null || extensionAttribute === void 0 ? void 0 : extensionAttribute.attribute) === null || _a2 === void 0 ? void 0 : _a2.default }];
|
|
392
|
-
}))
|
|
393
|
-
});
|
|
394
|
-
const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
|
|
395
|
-
if (parseHTML) {
|
|
396
|
-
schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
|
|
397
|
-
}
|
|
398
|
-
const renderHTML = getExtensionField(extension, "renderHTML", context);
|
|
399
|
-
if (renderHTML) {
|
|
400
|
-
schema.toDOM = (node) => renderHTML({
|
|
401
|
-
node,
|
|
402
|
-
HTMLAttributes: getRenderedAttributes(node, extensionAttributes)
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
const renderText = getExtensionField(extension, "renderText", context);
|
|
406
|
-
if (renderText) {
|
|
407
|
-
schema.toText = renderText;
|
|
408
|
-
}
|
|
409
|
-
return [extension.name, schema];
|
|
410
|
-
}));
|
|
411
|
-
const marks = Object.fromEntries(markExtensions.map((extension) => {
|
|
412
|
-
const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
|
|
413
|
-
const context = {
|
|
414
|
-
name: extension.name,
|
|
415
|
-
options: extension.options,
|
|
416
|
-
storage: extension.storage,
|
|
417
|
-
editor
|
|
418
|
-
};
|
|
419
|
-
const extraMarkFields = extensions.reduce((fields, e) => {
|
|
420
|
-
const extendMarkSchema = getExtensionField(e, "extendMarkSchema", context);
|
|
421
|
-
return {
|
|
422
|
-
...fields,
|
|
423
|
-
...extendMarkSchema ? extendMarkSchema(extension) : {}
|
|
424
|
-
};
|
|
425
|
-
}, {});
|
|
426
|
-
const schema = cleanUpSchemaItem({
|
|
427
|
-
...extraMarkFields,
|
|
428
|
-
inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)),
|
|
429
|
-
excludes: callOrReturn(getExtensionField(extension, "excludes", context)),
|
|
430
|
-
group: callOrReturn(getExtensionField(extension, "group", context)),
|
|
431
|
-
spanning: callOrReturn(getExtensionField(extension, "spanning", context)),
|
|
432
|
-
code: callOrReturn(getExtensionField(extension, "code", context)),
|
|
433
|
-
attrs: Object.fromEntries(extensionAttributes.map((extensionAttribute) => {
|
|
434
|
-
var _a2;
|
|
435
|
-
return [extensionAttribute.name, { default: (_a2 = extensionAttribute === null || extensionAttribute === void 0 ? void 0 : extensionAttribute.attribute) === null || _a2 === void 0 ? void 0 : _a2.default }];
|
|
436
|
-
}))
|
|
437
|
-
});
|
|
438
|
-
const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
|
|
439
|
-
if (parseHTML) {
|
|
440
|
-
schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
|
|
441
|
-
}
|
|
442
|
-
const renderHTML = getExtensionField(extension, "renderHTML", context);
|
|
443
|
-
if (renderHTML) {
|
|
444
|
-
schema.toDOM = (mark) => renderHTML({
|
|
445
|
-
mark,
|
|
446
|
-
HTMLAttributes: getRenderedAttributes(mark, extensionAttributes)
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
return [extension.name, schema];
|
|
450
|
-
}));
|
|
451
|
-
return new (0, _model.Schema)({
|
|
452
|
-
topNode,
|
|
453
|
-
nodes,
|
|
454
|
-
marks
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
function getSchemaTypeByName(name, schema) {
|
|
458
|
-
return schema.nodes[name] || schema.marks[name] || null;
|
|
459
|
-
}
|
|
460
|
-
function isExtensionRulesEnabled(extension, enabled) {
|
|
461
|
-
if (Array.isArray(enabled)) {
|
|
462
|
-
return enabled.some((enabledExtension) => {
|
|
463
|
-
const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name;
|
|
464
|
-
return name === extension.name;
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
return enabled;
|
|
468
|
-
}
|
|
469
|
-
function getHTMLFromFragment(fragment, schema) {
|
|
470
|
-
const documentFragment = _model.DOMSerializer.fromSchema(schema).serializeFragment(fragment);
|
|
471
|
-
const temporaryDocument = document.implementation.createHTMLDocument();
|
|
472
|
-
const container = temporaryDocument.createElement("div");
|
|
473
|
-
container.appendChild(documentFragment);
|
|
474
|
-
return container.innerHTML;
|
|
475
|
-
}
|
|
476
|
-
var getTextContentFromNodes = ($from, maxMatch = 500) => {
|
|
477
|
-
let textBefore = "";
|
|
478
|
-
const sliceEndPos = $from.parentOffset;
|
|
479
|
-
$from.parent.nodesBetween(Math.max(0, sliceEndPos - maxMatch), sliceEndPos, (node, pos, parent, index) => {
|
|
480
|
-
var _a, _b;
|
|
481
|
-
const chunk = ((_b = (_a = node.type.spec).toText) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
|
482
|
-
node,
|
|
483
|
-
pos,
|
|
484
|
-
parent,
|
|
485
|
-
index
|
|
486
|
-
})) || node.textContent || "%leaf%";
|
|
487
|
-
textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
|
|
488
|
-
});
|
|
489
|
-
return textBefore;
|
|
490
|
-
};
|
|
491
|
-
function isRegExp(value) {
|
|
492
|
-
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
493
|
-
}
|
|
494
|
-
var inputRuleMatcherHandler = (text, find) => {
|
|
495
|
-
if (isRegExp(find)) {
|
|
496
|
-
return find.exec(text);
|
|
497
|
-
}
|
|
498
|
-
const inputRuleMatch = find(text);
|
|
499
|
-
if (!inputRuleMatch) {
|
|
500
|
-
return null;
|
|
501
|
-
}
|
|
502
|
-
const result = [inputRuleMatch.text];
|
|
503
|
-
result.index = inputRuleMatch.index;
|
|
504
|
-
result.input = text;
|
|
505
|
-
result.data = inputRuleMatch.data;
|
|
506
|
-
if (inputRuleMatch.replaceWith) {
|
|
507
|
-
if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
|
|
508
|
-
console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".');
|
|
509
|
-
}
|
|
510
|
-
result.push(inputRuleMatch.replaceWith);
|
|
511
|
-
}
|
|
512
|
-
return result;
|
|
513
|
-
};
|
|
514
|
-
function run$1(config) {
|
|
515
|
-
var _a;
|
|
516
|
-
const { editor, from, to, text, rules, plugin } = config;
|
|
517
|
-
const { view } = editor;
|
|
518
|
-
if (view.composing) {
|
|
519
|
-
return false;
|
|
520
|
-
}
|
|
521
|
-
const $from = view.state.doc.resolve(from);
|
|
522
|
-
if (
|
|
523
|
-
// check for code node
|
|
524
|
-
$from.parent.type.spec.code || !!((_a = $from.nodeBefore || $from.nodeAfter) === null || _a === void 0 ? void 0 : _a.marks.find((mark) => mark.type.spec.code))
|
|
525
|
-
) {
|
|
526
|
-
return false;
|
|
527
|
-
}
|
|
528
|
-
let matched = false;
|
|
529
|
-
const textBefore = getTextContentFromNodes($from) + text;
|
|
530
|
-
rules.forEach((rule) => {
|
|
531
|
-
if (matched) {
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
const match = inputRuleMatcherHandler(textBefore, rule.find);
|
|
535
|
-
if (!match) {
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
const tr = view.state.tr;
|
|
539
|
-
const state = createChainableState({
|
|
540
|
-
state: view.state,
|
|
541
|
-
transaction: tr
|
|
542
|
-
});
|
|
543
|
-
const range = {
|
|
544
|
-
from: from - (match[0].length - text.length),
|
|
545
|
-
to
|
|
546
|
-
};
|
|
547
|
-
const { commands: commands2, chain, can } = new CommandManager({
|
|
548
|
-
editor,
|
|
549
|
-
state
|
|
550
|
-
});
|
|
551
|
-
const handler = rule.handler({
|
|
552
|
-
state,
|
|
553
|
-
range,
|
|
554
|
-
match,
|
|
555
|
-
commands: commands2,
|
|
556
|
-
chain,
|
|
557
|
-
can
|
|
558
|
-
});
|
|
559
|
-
if (handler === null || !tr.steps.length) {
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
tr.setMeta(plugin, {
|
|
563
|
-
transform: tr,
|
|
564
|
-
from,
|
|
565
|
-
to,
|
|
566
|
-
text
|
|
567
|
-
});
|
|
568
|
-
view.dispatch(tr);
|
|
569
|
-
matched = true;
|
|
570
|
-
});
|
|
571
|
-
return matched;
|
|
572
|
-
}
|
|
573
|
-
function inputRulesPlugin(props) {
|
|
574
|
-
const { editor, rules } = props;
|
|
575
|
-
const plugin = new (0, _state.Plugin)({
|
|
576
|
-
state: {
|
|
577
|
-
init() {
|
|
578
|
-
return null;
|
|
579
|
-
},
|
|
580
|
-
apply(tr, prev, state) {
|
|
581
|
-
const stored = tr.getMeta(plugin);
|
|
582
|
-
if (stored) {
|
|
583
|
-
return stored;
|
|
584
|
-
}
|
|
585
|
-
const simulatedInputMeta = tr.getMeta("applyInputRules");
|
|
586
|
-
const isSimulatedInput = !!simulatedInputMeta;
|
|
587
|
-
if (isSimulatedInput) {
|
|
588
|
-
setTimeout(() => {
|
|
589
|
-
let { text } = simulatedInputMeta;
|
|
590
|
-
if (typeof text === "string") {
|
|
591
|
-
text = text;
|
|
592
|
-
} else {
|
|
593
|
-
text = getHTMLFromFragment(_model.Fragment.from(text), state.schema);
|
|
594
|
-
}
|
|
595
|
-
const { from } = simulatedInputMeta;
|
|
596
|
-
const to = from + text.length;
|
|
597
|
-
run$1({
|
|
598
|
-
editor,
|
|
599
|
-
from,
|
|
600
|
-
to,
|
|
601
|
-
text,
|
|
602
|
-
rules,
|
|
603
|
-
plugin
|
|
604
|
-
});
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
return tr.selectionSet || tr.docChanged ? null : prev;
|
|
608
|
-
}
|
|
609
|
-
},
|
|
610
|
-
props: {
|
|
611
|
-
handleTextInput(view, from, to, text) {
|
|
612
|
-
return run$1({
|
|
613
|
-
editor,
|
|
614
|
-
from,
|
|
615
|
-
to,
|
|
616
|
-
text,
|
|
617
|
-
rules,
|
|
618
|
-
plugin
|
|
619
|
-
});
|
|
620
|
-
},
|
|
621
|
-
handleDOMEvents: {
|
|
622
|
-
compositionend: (view) => {
|
|
623
|
-
setTimeout(() => {
|
|
624
|
-
const { $cursor } = view.state.selection;
|
|
625
|
-
if ($cursor) {
|
|
626
|
-
run$1({
|
|
627
|
-
editor,
|
|
628
|
-
from: $cursor.pos,
|
|
629
|
-
to: $cursor.pos,
|
|
630
|
-
text: "",
|
|
631
|
-
rules,
|
|
632
|
-
plugin
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
});
|
|
636
|
-
return false;
|
|
637
|
-
}
|
|
638
|
-
},
|
|
639
|
-
// add support for input rules to trigger on enter
|
|
640
|
-
// this is useful for example for code blocks
|
|
641
|
-
handleKeyDown(view, event) {
|
|
642
|
-
if (event.key !== "Enter") {
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
const { $cursor } = view.state.selection;
|
|
646
|
-
if ($cursor) {
|
|
647
|
-
return run$1({
|
|
648
|
-
editor,
|
|
649
|
-
from: $cursor.pos,
|
|
650
|
-
to: $cursor.pos,
|
|
651
|
-
text: "\n",
|
|
652
|
-
rules,
|
|
653
|
-
plugin
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
return false;
|
|
657
|
-
}
|
|
658
|
-
},
|
|
659
|
-
// @ts-ignore
|
|
660
|
-
isInputRules: true
|
|
661
|
-
});
|
|
662
|
-
return plugin;
|
|
663
|
-
}
|
|
664
|
-
function getType(value) {
|
|
665
|
-
return Object.prototype.toString.call(value).slice(8, -1);
|
|
666
|
-
}
|
|
667
|
-
function isPlainObject(value) {
|
|
668
|
-
if (getType(value) !== "Object") {
|
|
669
|
-
return false;
|
|
670
|
-
}
|
|
671
|
-
return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype;
|
|
672
|
-
}
|
|
673
|
-
function mergeDeep(target, source) {
|
|
674
|
-
const output = { ...target };
|
|
675
|
-
if (isPlainObject(target) && isPlainObject(source)) {
|
|
676
|
-
Object.keys(source).forEach((key) => {
|
|
677
|
-
if (isPlainObject(source[key]) && isPlainObject(target[key])) {
|
|
678
|
-
output[key] = mergeDeep(target[key], source[key]);
|
|
679
|
-
} else {
|
|
680
|
-
output[key] = source[key];
|
|
681
|
-
}
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
return output;
|
|
685
|
-
}
|
|
686
|
-
var Mark = class _Mark {
|
|
687
|
-
constructor(config = {}) {
|
|
688
|
-
this.type = "mark";
|
|
689
|
-
this.name = "mark";
|
|
690
|
-
this.parent = null;
|
|
691
|
-
this.child = null;
|
|
692
|
-
this.config = {
|
|
693
|
-
name: this.name,
|
|
694
|
-
defaultOptions: {}
|
|
695
|
-
};
|
|
696
|
-
this.config = {
|
|
697
|
-
...this.config,
|
|
698
|
-
...config
|
|
699
|
-
};
|
|
700
|
-
this.name = this.config.name;
|
|
701
|
-
if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) {
|
|
702
|
-
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`);
|
|
703
|
-
}
|
|
704
|
-
this.options = this.config.defaultOptions;
|
|
705
|
-
if (this.config.addOptions) {
|
|
706
|
-
this.options = callOrReturn(getExtensionField(this, "addOptions", {
|
|
707
|
-
name: this.name
|
|
708
|
-
}));
|
|
709
|
-
}
|
|
710
|
-
this.storage = callOrReturn(getExtensionField(this, "addStorage", {
|
|
711
|
-
name: this.name,
|
|
712
|
-
options: this.options
|
|
713
|
-
})) || {};
|
|
714
|
-
}
|
|
715
|
-
static create(config = {}) {
|
|
716
|
-
return new _Mark(config);
|
|
717
|
-
}
|
|
718
|
-
configure(options = {}) {
|
|
719
|
-
const extension = this.extend({
|
|
720
|
-
...this.config,
|
|
721
|
-
addOptions: () => {
|
|
722
|
-
return mergeDeep(this.options, options);
|
|
723
|
-
}
|
|
724
|
-
});
|
|
725
|
-
extension.name = this.name;
|
|
726
|
-
extension.parent = this.parent;
|
|
727
|
-
return extension;
|
|
728
|
-
}
|
|
729
|
-
extend(extendedConfig = {}) {
|
|
730
|
-
const extension = new _Mark(extendedConfig);
|
|
731
|
-
extension.parent = this;
|
|
732
|
-
this.child = extension;
|
|
733
|
-
extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name;
|
|
734
|
-
if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {
|
|
735
|
-
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`);
|
|
736
|
-
}
|
|
737
|
-
extension.options = callOrReturn(getExtensionField(extension, "addOptions", {
|
|
738
|
-
name: extension.name
|
|
739
|
-
}));
|
|
740
|
-
extension.storage = callOrReturn(getExtensionField(extension, "addStorage", {
|
|
741
|
-
name: extension.name,
|
|
742
|
-
options: extension.options
|
|
743
|
-
}));
|
|
744
|
-
return extension;
|
|
745
|
-
}
|
|
746
|
-
static handleExit({ editor, mark }) {
|
|
747
|
-
const { tr } = editor.state;
|
|
748
|
-
const currentPos = editor.state.selection.$from;
|
|
749
|
-
const isAtEnd = currentPos.pos === currentPos.end();
|
|
750
|
-
if (isAtEnd) {
|
|
751
|
-
const currentMarks = currentPos.marks();
|
|
752
|
-
const isInMark = !!currentMarks.find((m) => (m === null || m === void 0 ? void 0 : m.type.name) === mark.name);
|
|
753
|
-
if (!isInMark) {
|
|
754
|
-
return false;
|
|
755
|
-
}
|
|
756
|
-
const removeMark = currentMarks.find((m) => (m === null || m === void 0 ? void 0 : m.type.name) === mark.name);
|
|
757
|
-
if (removeMark) {
|
|
758
|
-
tr.removeStoredMark(removeMark);
|
|
759
|
-
}
|
|
760
|
-
tr.insertText(" ", currentPos.pos);
|
|
761
|
-
editor.view.dispatch(tr);
|
|
762
|
-
return true;
|
|
763
|
-
}
|
|
764
|
-
return false;
|
|
765
|
-
}
|
|
766
|
-
};
|
|
767
|
-
function isNumber(value) {
|
|
768
|
-
return typeof value === "number";
|
|
769
|
-
}
|
|
770
|
-
var pasteRuleMatcherHandler = (text, find, event) => {
|
|
771
|
-
if (isRegExp(find)) {
|
|
772
|
-
return [...text.matchAll(find)];
|
|
773
|
-
}
|
|
774
|
-
const matches = find(text, event);
|
|
775
|
-
if (!matches) {
|
|
776
|
-
return [];
|
|
777
|
-
}
|
|
778
|
-
return matches.map((pasteRuleMatch) => {
|
|
779
|
-
const result = [pasteRuleMatch.text];
|
|
780
|
-
result.index = pasteRuleMatch.index;
|
|
781
|
-
result.input = text;
|
|
782
|
-
result.data = pasteRuleMatch.data;
|
|
783
|
-
if (pasteRuleMatch.replaceWith) {
|
|
784
|
-
if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {
|
|
785
|
-
console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".');
|
|
786
|
-
}
|
|
787
|
-
result.push(pasteRuleMatch.replaceWith);
|
|
788
|
-
}
|
|
789
|
-
return result;
|
|
790
|
-
});
|
|
791
|
-
};
|
|
792
|
-
function run(config) {
|
|
793
|
-
const { editor, state, from, to, rule, pasteEvent, dropEvent } = config;
|
|
794
|
-
const { commands: commands2, chain, can } = new CommandManager({
|
|
795
|
-
editor,
|
|
796
|
-
state
|
|
797
|
-
});
|
|
798
|
-
const handlers = [];
|
|
799
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
800
|
-
if (!node.isTextblock || node.type.spec.code) {
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
const resolvedFrom = Math.max(from, pos);
|
|
804
|
-
const resolvedTo = Math.min(to, pos + node.content.size);
|
|
805
|
-
const textToMatch = node.textBetween(resolvedFrom - pos, resolvedTo - pos, void 0, "\uFFFC");
|
|
806
|
-
const matches = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent);
|
|
807
|
-
matches.forEach((match) => {
|
|
808
|
-
if (match.index === void 0) {
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
const start = resolvedFrom + match.index + 1;
|
|
812
|
-
const end = start + match[0].length;
|
|
813
|
-
const range = {
|
|
814
|
-
from: state.tr.mapping.map(start),
|
|
815
|
-
to: state.tr.mapping.map(end)
|
|
816
|
-
};
|
|
817
|
-
const handler = rule.handler({
|
|
818
|
-
state,
|
|
819
|
-
range,
|
|
820
|
-
match,
|
|
821
|
-
commands: commands2,
|
|
822
|
-
chain,
|
|
823
|
-
can,
|
|
824
|
-
pasteEvent,
|
|
825
|
-
dropEvent
|
|
826
|
-
});
|
|
827
|
-
handlers.push(handler);
|
|
828
|
-
});
|
|
829
|
-
});
|
|
830
|
-
const success = handlers.every((handler) => handler !== null);
|
|
831
|
-
return success;
|
|
832
|
-
}
|
|
833
|
-
var createClipboardPasteEvent = (text) => {
|
|
834
|
-
var _a;
|
|
835
|
-
const event = new ClipboardEvent("paste", {
|
|
836
|
-
clipboardData: new DataTransfer()
|
|
837
|
-
});
|
|
838
|
-
(_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.setData("text/html", text);
|
|
839
|
-
return event;
|
|
840
|
-
};
|
|
841
|
-
function pasteRulesPlugin(props) {
|
|
842
|
-
const { editor, rules } = props;
|
|
843
|
-
let dragSourceElement = null;
|
|
844
|
-
let isPastedFromProseMirror = false;
|
|
845
|
-
let isDroppedFromProseMirror = false;
|
|
846
|
-
let pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
847
|
-
let dropEvent;
|
|
848
|
-
try {
|
|
849
|
-
dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null;
|
|
850
|
-
} catch (e) {
|
|
851
|
-
dropEvent = null;
|
|
852
|
-
}
|
|
853
|
-
const processEvent = ({ state, from, to, rule, pasteEvt }) => {
|
|
854
|
-
const tr = state.tr;
|
|
855
|
-
const chainableState = createChainableState({
|
|
856
|
-
state,
|
|
857
|
-
transaction: tr
|
|
858
|
-
});
|
|
859
|
-
const handler = run({
|
|
860
|
-
editor,
|
|
861
|
-
state: chainableState,
|
|
862
|
-
from: Math.max(from - 1, 0),
|
|
863
|
-
to: to.b - 1,
|
|
864
|
-
rule,
|
|
865
|
-
pasteEvent: pasteEvt,
|
|
866
|
-
dropEvent
|
|
867
|
-
});
|
|
868
|
-
if (!handler || !tr.steps.length) {
|
|
869
|
-
return;
|
|
870
|
-
}
|
|
871
|
-
try {
|
|
872
|
-
dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null;
|
|
873
|
-
} catch (e) {
|
|
874
|
-
dropEvent = null;
|
|
875
|
-
}
|
|
876
|
-
pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
|
|
877
|
-
return tr;
|
|
878
|
-
};
|
|
879
|
-
const plugins = rules.map((rule) => {
|
|
880
|
-
return new (0, _state.Plugin)({
|
|
881
|
-
// we register a global drag handler to track the current drag source element
|
|
882
|
-
view(view) {
|
|
883
|
-
const handleDragstart = (event) => {
|
|
884
|
-
var _a;
|
|
885
|
-
dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target)) ? view.dom.parentElement : null;
|
|
886
|
-
};
|
|
887
|
-
window.addEventListener("dragstart", handleDragstart);
|
|
888
|
-
return {
|
|
889
|
-
destroy() {
|
|
890
|
-
window.removeEventListener("dragstart", handleDragstart);
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
|
-
},
|
|
894
|
-
props: {
|
|
895
|
-
handleDOMEvents: {
|
|
896
|
-
drop: (view, event) => {
|
|
897
|
-
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
|
|
898
|
-
dropEvent = event;
|
|
899
|
-
return false;
|
|
900
|
-
},
|
|
901
|
-
paste: (_view, event) => {
|
|
902
|
-
var _a;
|
|
903
|
-
const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/html");
|
|
904
|
-
pasteEvent = event;
|
|
905
|
-
isPastedFromProseMirror = !!(html === null || html === void 0 ? void 0 : html.includes("data-pm-slice"));
|
|
906
|
-
return false;
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
},
|
|
910
|
-
appendTransaction: (transactions, oldState, state) => {
|
|
911
|
-
const transaction = transactions[0];
|
|
912
|
-
const isPaste = transaction.getMeta("uiEvent") === "paste" && !isPastedFromProseMirror;
|
|
913
|
-
const isDrop = transaction.getMeta("uiEvent") === "drop" && !isDroppedFromProseMirror;
|
|
914
|
-
const simulatedPasteMeta = transaction.getMeta("applyPasteRules");
|
|
915
|
-
const isSimulatedPaste = !!simulatedPasteMeta;
|
|
916
|
-
if (!isPaste && !isDrop && !isSimulatedPaste) {
|
|
917
|
-
return;
|
|
918
|
-
}
|
|
919
|
-
if (isSimulatedPaste) {
|
|
920
|
-
let { text } = simulatedPasteMeta;
|
|
921
|
-
if (typeof text === "string") {
|
|
922
|
-
text = text;
|
|
923
|
-
} else {
|
|
924
|
-
text = getHTMLFromFragment(_model.Fragment.from(text), state.schema);
|
|
925
|
-
}
|
|
926
|
-
const { from: from2 } = simulatedPasteMeta;
|
|
927
|
-
const to2 = from2 + text.length;
|
|
928
|
-
const pasteEvt = createClipboardPasteEvent(text);
|
|
929
|
-
return processEvent({
|
|
930
|
-
rule,
|
|
931
|
-
state,
|
|
932
|
-
from: from2,
|
|
933
|
-
to: { b: to2 },
|
|
934
|
-
pasteEvt
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
const from = oldState.doc.content.findDiffStart(state.doc.content);
|
|
938
|
-
const to = oldState.doc.content.findDiffEnd(state.doc.content);
|
|
939
|
-
if (!isNumber(from) || !to || from === to.b) {
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
return processEvent({
|
|
943
|
-
rule,
|
|
944
|
-
state,
|
|
945
|
-
from,
|
|
946
|
-
to,
|
|
947
|
-
pasteEvt: pasteEvent
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
});
|
|
951
|
-
});
|
|
952
|
-
return plugins;
|
|
953
|
-
}
|
|
954
|
-
function findDuplicates(items) {
|
|
955
|
-
const filtered = items.filter((el, index) => items.indexOf(el) !== index);
|
|
956
|
-
return Array.from(new Set(filtered));
|
|
957
|
-
}
|
|
958
|
-
var ExtensionManager = class _ExtensionManager {
|
|
959
|
-
constructor(extensions, editor) {
|
|
960
|
-
this.splittableMarks = [];
|
|
961
|
-
this.editor = editor;
|
|
962
|
-
this.extensions = _ExtensionManager.resolve(extensions);
|
|
963
|
-
this.schema = getSchemaByResolvedExtensions(this.extensions, editor);
|
|
964
|
-
this.setupExtensions();
|
|
965
|
-
}
|
|
966
|
-
/**
|
|
967
|
-
* Returns a flattened and sorted extension list while
|
|
968
|
-
* also checking for duplicated extensions and warns the user.
|
|
969
|
-
* @param extensions An array of Tiptap extensions
|
|
970
|
-
* @returns An flattened and sorted array of Tiptap extensions
|
|
971
|
-
*/
|
|
972
|
-
static resolve(extensions) {
|
|
973
|
-
const resolvedExtensions = _ExtensionManager.sort(_ExtensionManager.flatten(extensions));
|
|
974
|
-
const duplicatedNames = findDuplicates(resolvedExtensions.map((extension) => extension.name));
|
|
975
|
-
if (duplicatedNames.length) {
|
|
976
|
-
console.warn(`[tiptap warn]: Duplicate extension names found: [${duplicatedNames.map((item) => `'${item}'`).join(", ")}]. This can lead to issues.`);
|
|
977
|
-
}
|
|
978
|
-
return resolvedExtensions;
|
|
979
|
-
}
|
|
980
|
-
/**
|
|
981
|
-
* Create a flattened array of extensions by traversing the `addExtensions` field.
|
|
982
|
-
* @param extensions An array of Tiptap extensions
|
|
983
|
-
* @returns A flattened array of Tiptap extensions
|
|
984
|
-
*/
|
|
985
|
-
static flatten(extensions) {
|
|
986
|
-
return extensions.map((extension) => {
|
|
987
|
-
const context = {
|
|
988
|
-
name: extension.name,
|
|
989
|
-
options: extension.options,
|
|
990
|
-
storage: extension.storage
|
|
991
|
-
};
|
|
992
|
-
const addExtensions = getExtensionField(extension, "addExtensions", context);
|
|
993
|
-
if (addExtensions) {
|
|
994
|
-
return [extension, ...this.flatten(addExtensions())];
|
|
995
|
-
}
|
|
996
|
-
return extension;
|
|
997
|
-
}).flat(10);
|
|
998
|
-
}
|
|
999
|
-
/**
|
|
1000
|
-
* Sort extensions by priority.
|
|
1001
|
-
* @param extensions An array of Tiptap extensions
|
|
1002
|
-
* @returns A sorted array of Tiptap extensions by priority
|
|
1003
|
-
*/
|
|
1004
|
-
static sort(extensions) {
|
|
1005
|
-
const defaultPriority = 100;
|
|
1006
|
-
return extensions.sort((a, b) => {
|
|
1007
|
-
const priorityA = getExtensionField(a, "priority") || defaultPriority;
|
|
1008
|
-
const priorityB = getExtensionField(b, "priority") || defaultPriority;
|
|
1009
|
-
if (priorityA > priorityB) {
|
|
1010
|
-
return -1;
|
|
1011
|
-
}
|
|
1012
|
-
if (priorityA < priorityB) {
|
|
1013
|
-
return 1;
|
|
1014
|
-
}
|
|
1015
|
-
return 0;
|
|
1016
|
-
});
|
|
1017
|
-
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Get all commands from the extensions.
|
|
1020
|
-
* @returns An object with all commands where the key is the command name and the value is the command function
|
|
1021
|
-
*/
|
|
1022
|
-
get commands() {
|
|
1023
|
-
return this.extensions.reduce((commands2, extension) => {
|
|
1024
|
-
const context = {
|
|
1025
|
-
name: extension.name,
|
|
1026
|
-
options: extension.options,
|
|
1027
|
-
storage: extension.storage,
|
|
1028
|
-
editor: this.editor,
|
|
1029
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
1030
|
-
};
|
|
1031
|
-
const addCommands = getExtensionField(extension, "addCommands", context);
|
|
1032
|
-
if (!addCommands) {
|
|
1033
|
-
return commands2;
|
|
1034
|
-
}
|
|
1035
|
-
return {
|
|
1036
|
-
...commands2,
|
|
1037
|
-
...addCommands()
|
|
1038
|
-
};
|
|
1039
|
-
}, {});
|
|
1040
|
-
}
|
|
1041
|
-
/**
|
|
1042
|
-
* Get all registered Prosemirror plugins from the extensions.
|
|
1043
|
-
* @returns An array of Prosemirror plugins
|
|
1044
|
-
*/
|
|
1045
|
-
get plugins() {
|
|
1046
|
-
const { editor } = this;
|
|
1047
|
-
const extensions = _ExtensionManager.sort([...this.extensions].reverse());
|
|
1048
|
-
const inputRules = [];
|
|
1049
|
-
const pasteRules = [];
|
|
1050
|
-
const allPlugins = extensions.map((extension) => {
|
|
1051
|
-
const context = {
|
|
1052
|
-
name: extension.name,
|
|
1053
|
-
options: extension.options,
|
|
1054
|
-
storage: extension.storage,
|
|
1055
|
-
editor,
|
|
1056
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
1057
|
-
};
|
|
1058
|
-
const plugins = [];
|
|
1059
|
-
const addKeyboardShortcuts = getExtensionField(extension, "addKeyboardShortcuts", context);
|
|
1060
|
-
let defaultBindings = {};
|
|
1061
|
-
if (extension.type === "mark" && getExtensionField(extension, "exitable", context)) {
|
|
1062
|
-
defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: extension });
|
|
1063
|
-
}
|
|
1064
|
-
if (addKeyboardShortcuts) {
|
|
1065
|
-
const bindings = Object.fromEntries(Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => {
|
|
1066
|
-
return [shortcut, () => method({ editor })];
|
|
1067
|
-
}));
|
|
1068
|
-
defaultBindings = { ...defaultBindings, ...bindings };
|
|
1069
|
-
}
|
|
1070
|
-
const keyMapPlugin = _keymap.keymap.call(void 0, defaultBindings);
|
|
1071
|
-
plugins.push(keyMapPlugin);
|
|
1072
|
-
const addInputRules = getExtensionField(extension, "addInputRules", context);
|
|
1073
|
-
if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
|
|
1074
|
-
inputRules.push(...addInputRules());
|
|
1075
|
-
}
|
|
1076
|
-
const addPasteRules = getExtensionField(extension, "addPasteRules", context);
|
|
1077
|
-
if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
|
|
1078
|
-
pasteRules.push(...addPasteRules());
|
|
1079
|
-
}
|
|
1080
|
-
const addProseMirrorPlugins = getExtensionField(extension, "addProseMirrorPlugins", context);
|
|
1081
|
-
if (addProseMirrorPlugins) {
|
|
1082
|
-
const proseMirrorPlugins = addProseMirrorPlugins();
|
|
1083
|
-
plugins.push(...proseMirrorPlugins);
|
|
1084
|
-
}
|
|
1085
|
-
return plugins;
|
|
1086
|
-
}).flat();
|
|
1087
|
-
return [
|
|
1088
|
-
inputRulesPlugin({
|
|
1089
|
-
editor,
|
|
1090
|
-
rules: inputRules
|
|
1091
|
-
}),
|
|
1092
|
-
...pasteRulesPlugin({
|
|
1093
|
-
editor,
|
|
1094
|
-
rules: pasteRules
|
|
1095
|
-
}),
|
|
1096
|
-
...allPlugins
|
|
1097
|
-
];
|
|
1098
|
-
}
|
|
1099
|
-
/**
|
|
1100
|
-
* Get all attributes from the extensions.
|
|
1101
|
-
* @returns An array of attributes
|
|
1102
|
-
*/
|
|
1103
|
-
get attributes() {
|
|
1104
|
-
return getAttributesFromExtensions(this.extensions);
|
|
1105
|
-
}
|
|
1106
|
-
/**
|
|
1107
|
-
* Get all node views from the extensions.
|
|
1108
|
-
* @returns An object with all node views where the key is the node name and the value is the node view function
|
|
1109
|
-
*/
|
|
1110
|
-
get nodeViews() {
|
|
1111
|
-
const { editor } = this;
|
|
1112
|
-
const { nodeExtensions } = splitExtensions(this.extensions);
|
|
1113
|
-
return Object.fromEntries(nodeExtensions.filter((extension) => !!getExtensionField(extension, "addNodeView")).map((extension) => {
|
|
1114
|
-
const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name);
|
|
1115
|
-
const context = {
|
|
1116
|
-
name: extension.name,
|
|
1117
|
-
options: extension.options,
|
|
1118
|
-
storage: extension.storage,
|
|
1119
|
-
editor,
|
|
1120
|
-
type: getNodeType(extension.name, this.schema)
|
|
1121
|
-
};
|
|
1122
|
-
const addNodeView = getExtensionField(extension, "addNodeView", context);
|
|
1123
|
-
if (!addNodeView) {
|
|
1124
|
-
return [];
|
|
1125
|
-
}
|
|
1126
|
-
const nodeview = (node, view, getPos, decorations, innerDecorations) => {
|
|
1127
|
-
const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
|
|
1128
|
-
return addNodeView()({
|
|
1129
|
-
// pass-through
|
|
1130
|
-
node,
|
|
1131
|
-
view,
|
|
1132
|
-
getPos,
|
|
1133
|
-
decorations,
|
|
1134
|
-
innerDecorations,
|
|
1135
|
-
// tiptap-specific
|
|
1136
|
-
editor,
|
|
1137
|
-
extension,
|
|
1138
|
-
HTMLAttributes
|
|
1139
|
-
});
|
|
1140
|
-
};
|
|
1141
|
-
return [extension.name, nodeview];
|
|
1142
|
-
}));
|
|
1143
|
-
}
|
|
1144
|
-
/**
|
|
1145
|
-
* Go through all extensions, create extension storages & setup marks
|
|
1146
|
-
* & bind editor event listener.
|
|
1147
|
-
*/
|
|
1148
|
-
setupExtensions() {
|
|
1149
|
-
this.extensions.forEach((extension) => {
|
|
1150
|
-
var _a;
|
|
1151
|
-
this.editor.extensionStorage[extension.name] = extension.storage;
|
|
1152
|
-
const context = {
|
|
1153
|
-
name: extension.name,
|
|
1154
|
-
options: extension.options,
|
|
1155
|
-
storage: extension.storage,
|
|
1156
|
-
editor: this.editor,
|
|
1157
|
-
type: getSchemaTypeByName(extension.name, this.schema)
|
|
1158
|
-
};
|
|
1159
|
-
if (extension.type === "mark") {
|
|
1160
|
-
const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, "keepOnSplit", context))) !== null && _a !== void 0 ? _a : true;
|
|
1161
|
-
if (keepOnSplit) {
|
|
1162
|
-
this.splittableMarks.push(extension.name);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
const onBeforeCreate = getExtensionField(extension, "onBeforeCreate", context);
|
|
1166
|
-
const onCreate = getExtensionField(extension, "onCreate", context);
|
|
1167
|
-
const onUpdate = getExtensionField(extension, "onUpdate", context);
|
|
1168
|
-
const onSelectionUpdate = getExtensionField(extension, "onSelectionUpdate", context);
|
|
1169
|
-
const onTransaction = getExtensionField(extension, "onTransaction", context);
|
|
1170
|
-
const onFocus = getExtensionField(extension, "onFocus", context);
|
|
1171
|
-
const onBlur = getExtensionField(extension, "onBlur", context);
|
|
1172
|
-
const onDestroy = getExtensionField(extension, "onDestroy", context);
|
|
1173
|
-
if (onBeforeCreate) {
|
|
1174
|
-
this.editor.on("beforeCreate", onBeforeCreate);
|
|
1175
|
-
}
|
|
1176
|
-
if (onCreate) {
|
|
1177
|
-
this.editor.on("create", onCreate);
|
|
1178
|
-
}
|
|
1179
|
-
if (onUpdate) {
|
|
1180
|
-
this.editor.on("update", onUpdate);
|
|
1181
|
-
}
|
|
1182
|
-
if (onSelectionUpdate) {
|
|
1183
|
-
this.editor.on("selectionUpdate", onSelectionUpdate);
|
|
1184
|
-
}
|
|
1185
|
-
if (onTransaction) {
|
|
1186
|
-
this.editor.on("transaction", onTransaction);
|
|
1187
|
-
}
|
|
1188
|
-
if (onFocus) {
|
|
1189
|
-
this.editor.on("focus", onFocus);
|
|
1190
|
-
}
|
|
1191
|
-
if (onBlur) {
|
|
1192
|
-
this.editor.on("blur", onBlur);
|
|
1193
|
-
}
|
|
1194
|
-
if (onDestroy) {
|
|
1195
|
-
this.editor.on("destroy", onDestroy);
|
|
1196
|
-
}
|
|
1197
|
-
});
|
|
1198
|
-
}
|
|
1199
|
-
};
|
|
1200
|
-
var Extension = class _Extension {
|
|
1201
|
-
constructor(config = {}) {
|
|
1202
|
-
this.type = "extension";
|
|
1203
|
-
this.name = "extension";
|
|
1204
|
-
this.parent = null;
|
|
1205
|
-
this.child = null;
|
|
1206
|
-
this.config = {
|
|
1207
|
-
name: this.name,
|
|
1208
|
-
defaultOptions: {}
|
|
1209
|
-
};
|
|
1210
|
-
this.config = {
|
|
1211
|
-
...this.config,
|
|
1212
|
-
...config
|
|
1213
|
-
};
|
|
1214
|
-
this.name = this.config.name;
|
|
1215
|
-
if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) {
|
|
1216
|
-
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`);
|
|
1217
|
-
}
|
|
1218
|
-
this.options = this.config.defaultOptions;
|
|
1219
|
-
if (this.config.addOptions) {
|
|
1220
|
-
this.options = callOrReturn(getExtensionField(this, "addOptions", {
|
|
1221
|
-
name: this.name
|
|
1222
|
-
}));
|
|
1223
|
-
}
|
|
1224
|
-
this.storage = callOrReturn(getExtensionField(this, "addStorage", {
|
|
1225
|
-
name: this.name,
|
|
1226
|
-
options: this.options
|
|
1227
|
-
})) || {};
|
|
1228
|
-
}
|
|
1229
|
-
static create(config = {}) {
|
|
1230
|
-
return new _Extension(config);
|
|
1231
|
-
}
|
|
1232
|
-
configure(options = {}) {
|
|
1233
|
-
const extension = this.extend({
|
|
1234
|
-
...this.config,
|
|
1235
|
-
addOptions: () => {
|
|
1236
|
-
return mergeDeep(this.options, options);
|
|
1237
|
-
}
|
|
1238
|
-
});
|
|
1239
|
-
extension.name = this.name;
|
|
1240
|
-
extension.parent = this.parent;
|
|
1241
|
-
return extension;
|
|
1242
|
-
}
|
|
1243
|
-
extend(extendedConfig = {}) {
|
|
1244
|
-
const extension = new _Extension({ ...this.config, ...extendedConfig });
|
|
1245
|
-
extension.parent = this;
|
|
1246
|
-
this.child = extension;
|
|
1247
|
-
extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name;
|
|
1248
|
-
if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {
|
|
1249
|
-
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`);
|
|
1250
|
-
}
|
|
1251
|
-
extension.options = callOrReturn(getExtensionField(extension, "addOptions", {
|
|
1252
|
-
name: extension.name
|
|
1253
|
-
}));
|
|
1254
|
-
extension.storage = callOrReturn(getExtensionField(extension, "addStorage", {
|
|
1255
|
-
name: extension.name,
|
|
1256
|
-
options: extension.options
|
|
1257
|
-
}));
|
|
1258
|
-
return extension;
|
|
1259
|
-
}
|
|
1260
|
-
};
|
|
1261
|
-
function getTextBetween(startNode, range, options) {
|
|
1262
|
-
const { from, to } = range;
|
|
1263
|
-
const { blockSeparator = "\n\n", textSerializers = {} } = options || {};
|
|
1264
|
-
let text = "";
|
|
1265
|
-
startNode.nodesBetween(from, to, (node, pos, parent, index) => {
|
|
1266
|
-
var _a;
|
|
1267
|
-
if (node.isBlock && pos > from) {
|
|
1268
|
-
text += blockSeparator;
|
|
1269
|
-
}
|
|
1270
|
-
const textSerializer = textSerializers === null || textSerializers === void 0 ? void 0 : textSerializers[node.type.name];
|
|
1271
|
-
if (textSerializer) {
|
|
1272
|
-
if (parent) {
|
|
1273
|
-
text += textSerializer({
|
|
1274
|
-
node,
|
|
1275
|
-
pos,
|
|
1276
|
-
parent,
|
|
1277
|
-
index,
|
|
1278
|
-
range
|
|
1279
|
-
});
|
|
1280
|
-
}
|
|
1281
|
-
return false;
|
|
1282
|
-
}
|
|
1283
|
-
if (node.isText) {
|
|
1284
|
-
text += (_a = node === null || node === void 0 ? void 0 : node.text) === null || _a === void 0 ? void 0 : _a.slice(Math.max(from, pos) - pos, to - pos);
|
|
1285
|
-
}
|
|
1286
|
-
});
|
|
1287
|
-
return text;
|
|
1288
|
-
}
|
|
1289
|
-
function getTextSerializersFromSchema(schema) {
|
|
1290
|
-
return Object.fromEntries(Object.entries(schema.nodes).filter(([, node]) => node.spec.toText).map(([name, node]) => [name, node.spec.toText]));
|
|
1291
|
-
}
|
|
1292
|
-
var ClipboardTextSerializer = Extension.create({
|
|
1293
|
-
name: "clipboardTextSerializer",
|
|
1294
|
-
addOptions() {
|
|
1295
|
-
return {
|
|
1296
|
-
blockSeparator: void 0
|
|
1297
|
-
};
|
|
1298
|
-
},
|
|
1299
|
-
addProseMirrorPlugins() {
|
|
1300
|
-
return [
|
|
1301
|
-
new (0, _state.Plugin)({
|
|
1302
|
-
key: new (0, _state.PluginKey)("clipboardTextSerializer"),
|
|
1303
|
-
props: {
|
|
1304
|
-
clipboardTextSerializer: () => {
|
|
1305
|
-
const { editor } = this;
|
|
1306
|
-
const { state, schema } = editor;
|
|
1307
|
-
const { doc, selection } = state;
|
|
1308
|
-
const { ranges } = selection;
|
|
1309
|
-
const from = Math.min(...ranges.map((range2) => range2.$from.pos));
|
|
1310
|
-
const to = Math.max(...ranges.map((range2) => range2.$to.pos));
|
|
1311
|
-
const textSerializers = getTextSerializersFromSchema(schema);
|
|
1312
|
-
const range = { from, to };
|
|
1313
|
-
return getTextBetween(doc, range, {
|
|
1314
|
-
...this.options.blockSeparator !== void 0 ? { blockSeparator: this.options.blockSeparator } : {},
|
|
1315
|
-
textSerializers
|
|
1316
|
-
});
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
})
|
|
1320
|
-
];
|
|
1321
|
-
}
|
|
1322
|
-
});
|
|
1323
|
-
var blur = () => ({ editor, view }) => {
|
|
1324
|
-
requestAnimationFrame(() => {
|
|
1325
|
-
var _a;
|
|
1326
|
-
if (!editor.isDestroyed) {
|
|
1327
|
-
view.dom.blur();
|
|
1328
|
-
(_a = window === null || window === void 0 ? void 0 : window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
|
|
1329
|
-
}
|
|
1330
|
-
});
|
|
1331
|
-
return true;
|
|
1332
|
-
};
|
|
1333
|
-
var clearContent = (emitUpdate = false) => ({ commands: commands2 }) => {
|
|
1334
|
-
return commands2.setContent("", emitUpdate);
|
|
1335
|
-
};
|
|
1336
|
-
var clearNodes = () => ({ state, tr, dispatch }) => {
|
|
1337
|
-
const { selection } = tr;
|
|
1338
|
-
const { ranges } = selection;
|
|
1339
|
-
if (!dispatch) {
|
|
1340
|
-
return true;
|
|
1341
|
-
}
|
|
1342
|
-
ranges.forEach(({ $from, $to }) => {
|
|
1343
|
-
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
1344
|
-
if (node.type.isText) {
|
|
1345
|
-
return;
|
|
1346
|
-
}
|
|
1347
|
-
const { doc, mapping } = tr;
|
|
1348
|
-
const $mappedFrom = doc.resolve(mapping.map(pos));
|
|
1349
|
-
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
|
|
1350
|
-
const nodeRange = $mappedFrom.blockRange($mappedTo);
|
|
1351
|
-
if (!nodeRange) {
|
|
1352
|
-
return;
|
|
1353
|
-
}
|
|
1354
|
-
const targetLiftDepth = _transform.liftTarget.call(void 0, nodeRange);
|
|
1355
|
-
if (node.type.isTextblock) {
|
|
1356
|
-
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
|
|
1357
|
-
tr.setNodeMarkup(nodeRange.start, defaultType);
|
|
1358
|
-
}
|
|
1359
|
-
if (targetLiftDepth || targetLiftDepth === 0) {
|
|
1360
|
-
tr.lift(nodeRange, targetLiftDepth);
|
|
1361
|
-
}
|
|
1362
|
-
});
|
|
1363
|
-
});
|
|
1364
|
-
return true;
|
|
1365
|
-
};
|
|
1366
|
-
var command = (fn) => (props) => {
|
|
1367
|
-
return fn(props);
|
|
1368
|
-
};
|
|
1369
|
-
var createParagraphNear = () => ({ state, dispatch }) => {
|
|
1370
|
-
return _commands.createParagraphNear.call(void 0, state, dispatch);
|
|
1371
|
-
};
|
|
1372
|
-
var cut = (originRange, targetPos) => ({ editor, tr }) => {
|
|
1373
|
-
const { state } = editor;
|
|
1374
|
-
const contentSlice = state.doc.slice(originRange.from, originRange.to);
|
|
1375
|
-
tr.deleteRange(originRange.from, originRange.to);
|
|
1376
|
-
const newPos = tr.mapping.map(targetPos);
|
|
1377
|
-
tr.insert(newPos, contentSlice.content);
|
|
1378
|
-
tr.setSelection(new (0, _state.TextSelection)(tr.doc.resolve(newPos - 1)));
|
|
1379
|
-
return true;
|
|
1380
|
-
};
|
|
1381
|
-
var deleteCurrentNode = () => ({ tr, dispatch }) => {
|
|
1382
|
-
const { selection } = tr;
|
|
1383
|
-
const currentNode = selection.$anchor.node();
|
|
1384
|
-
if (currentNode.content.size > 0) {
|
|
1385
|
-
return false;
|
|
1386
|
-
}
|
|
1387
|
-
const $pos = tr.selection.$anchor;
|
|
1388
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
1389
|
-
const node = $pos.node(depth);
|
|
1390
|
-
if (node.type === currentNode.type) {
|
|
1391
|
-
if (dispatch) {
|
|
1392
|
-
const from = $pos.before(depth);
|
|
1393
|
-
const to = $pos.after(depth);
|
|
1394
|
-
tr.delete(from, to).scrollIntoView();
|
|
1395
|
-
}
|
|
1396
|
-
return true;
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
return false;
|
|
1400
|
-
};
|
|
1401
|
-
var deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
|
|
1402
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
1403
|
-
const $pos = tr.selection.$anchor;
|
|
1404
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
1405
|
-
const node = $pos.node(depth);
|
|
1406
|
-
if (node.type === type) {
|
|
1407
|
-
if (dispatch) {
|
|
1408
|
-
const from = $pos.before(depth);
|
|
1409
|
-
const to = $pos.after(depth);
|
|
1410
|
-
tr.delete(from, to).scrollIntoView();
|
|
1411
|
-
}
|
|
1412
|
-
return true;
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
return false;
|
|
1416
|
-
};
|
|
1417
|
-
var deleteRange = (range) => ({ tr, dispatch }) => {
|
|
1418
|
-
const { from, to } = range;
|
|
1419
|
-
if (dispatch) {
|
|
1420
|
-
tr.delete(from, to);
|
|
1421
|
-
}
|
|
1422
|
-
return true;
|
|
1423
|
-
};
|
|
1424
|
-
var deleteSelection = () => ({ state, dispatch }) => {
|
|
1425
|
-
return _commands.deleteSelection.call(void 0, state, dispatch);
|
|
1426
|
-
};
|
|
1427
|
-
var enter = () => ({ commands: commands2 }) => {
|
|
1428
|
-
return commands2.keyboardShortcut("Enter");
|
|
1429
|
-
};
|
|
1430
|
-
var exitCode = () => ({ state, dispatch }) => {
|
|
1431
|
-
return _commands.exitCode.call(void 0, state, dispatch);
|
|
1432
|
-
};
|
|
1433
|
-
function objectIncludes(object1, object2, options = { strict: true }) {
|
|
1434
|
-
const keys = Object.keys(object2);
|
|
1435
|
-
if (!keys.length) {
|
|
1436
|
-
return true;
|
|
1437
|
-
}
|
|
1438
|
-
return keys.every((key) => {
|
|
1439
|
-
if (options.strict) {
|
|
1440
|
-
return object2[key] === object1[key];
|
|
1441
|
-
}
|
|
1442
|
-
if (isRegExp(object2[key])) {
|
|
1443
|
-
return object2[key].test(object1[key]);
|
|
1444
|
-
}
|
|
1445
|
-
return object2[key] === object1[key];
|
|
1446
|
-
});
|
|
1447
|
-
}
|
|
1448
|
-
function findMarkInSet(marks, type, attributes = {}) {
|
|
1449
|
-
return marks.find((item) => {
|
|
1450
|
-
return item.type === type && objectIncludes(
|
|
1451
|
-
// Only check equality for the attributes that are provided
|
|
1452
|
-
Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])),
|
|
1453
|
-
attributes
|
|
1454
|
-
);
|
|
1455
|
-
});
|
|
1456
|
-
}
|
|
1457
|
-
function isMarkInSet(marks, type, attributes = {}) {
|
|
1458
|
-
return !!findMarkInSet(marks, type, attributes);
|
|
1459
|
-
}
|
|
1460
|
-
function getMarkRange($pos, type, attributes) {
|
|
1461
|
-
var _a;
|
|
1462
|
-
if (!$pos || !type) {
|
|
1463
|
-
return;
|
|
1464
|
-
}
|
|
1465
|
-
let start = $pos.parent.childAfter($pos.parentOffset);
|
|
1466
|
-
if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
|
|
1467
|
-
start = $pos.parent.childBefore($pos.parentOffset);
|
|
1468
|
-
}
|
|
1469
|
-
if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) {
|
|
1470
|
-
return;
|
|
1471
|
-
}
|
|
1472
|
-
attributes = attributes || ((_a = start.node.marks[0]) === null || _a === void 0 ? void 0 : _a.attrs);
|
|
1473
|
-
const mark = findMarkInSet([...start.node.marks], type, attributes);
|
|
1474
|
-
if (!mark) {
|
|
1475
|
-
return;
|
|
1476
|
-
}
|
|
1477
|
-
let startIndex = start.index;
|
|
1478
|
-
let startPos = $pos.start() + start.offset;
|
|
1479
|
-
let endIndex = startIndex + 1;
|
|
1480
|
-
let endPos = startPos + start.node.nodeSize;
|
|
1481
|
-
while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
|
|
1482
|
-
startIndex -= 1;
|
|
1483
|
-
startPos -= $pos.parent.child(startIndex).nodeSize;
|
|
1484
|
-
}
|
|
1485
|
-
while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) {
|
|
1486
|
-
endPos += $pos.parent.child(endIndex).nodeSize;
|
|
1487
|
-
endIndex += 1;
|
|
1488
|
-
}
|
|
1489
|
-
return {
|
|
1490
|
-
from: startPos,
|
|
1491
|
-
to: endPos
|
|
1492
|
-
};
|
|
1493
|
-
}
|
|
1494
|
-
function getMarkType(nameOrType, schema) {
|
|
1495
|
-
if (typeof nameOrType === "string") {
|
|
1496
|
-
if (!schema.marks[nameOrType]) {
|
|
1497
|
-
throw Error(`There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`);
|
|
1498
|
-
}
|
|
1499
|
-
return schema.marks[nameOrType];
|
|
1500
|
-
}
|
|
1501
|
-
return nameOrType;
|
|
1502
|
-
}
|
|
1503
|
-
var extendMarkRange = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
1504
|
-
const type = getMarkType(typeOrName, state.schema);
|
|
1505
|
-
const { doc, selection } = tr;
|
|
1506
|
-
const { $from, from, to } = selection;
|
|
1507
|
-
if (dispatch) {
|
|
1508
|
-
const range = getMarkRange($from, type, attributes);
|
|
1509
|
-
if (range && range.from <= from && range.to >= to) {
|
|
1510
|
-
const newSelection = _state.TextSelection.create(doc, range.from, range.to);
|
|
1511
|
-
tr.setSelection(newSelection);
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
return true;
|
|
1515
|
-
};
|
|
1516
|
-
var first = (commands2) => (props) => {
|
|
1517
|
-
const items = typeof commands2 === "function" ? commands2(props) : commands2;
|
|
1518
|
-
for (let i = 0; i < items.length; i += 1) {
|
|
1519
|
-
if (items[i](props)) {
|
|
1520
|
-
return true;
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
return false;
|
|
1524
|
-
};
|
|
1525
|
-
function isTextSelection(value) {
|
|
1526
|
-
return value instanceof _state.TextSelection;
|
|
1527
|
-
}
|
|
1528
|
-
function minMax(value = 0, min = 0, max = 0) {
|
|
1529
|
-
return Math.min(Math.max(value, min), max);
|
|
1530
|
-
}
|
|
1531
|
-
function resolveFocusPosition(doc, position = null) {
|
|
1532
|
-
if (!position) {
|
|
1533
|
-
return null;
|
|
1534
|
-
}
|
|
1535
|
-
const selectionAtStart = _state.Selection.atStart(doc);
|
|
1536
|
-
const selectionAtEnd = _state.Selection.atEnd(doc);
|
|
1537
|
-
if (position === "start" || position === true) {
|
|
1538
|
-
return selectionAtStart;
|
|
1539
|
-
}
|
|
1540
|
-
if (position === "end") {
|
|
1541
|
-
return selectionAtEnd;
|
|
1542
|
-
}
|
|
1543
|
-
const minPos = selectionAtStart.from;
|
|
1544
|
-
const maxPos = selectionAtEnd.to;
|
|
1545
|
-
if (position === "all") {
|
|
1546
|
-
return _state.TextSelection.create(doc, minMax(0, minPos, maxPos), minMax(doc.content.size, minPos, maxPos));
|
|
1547
|
-
}
|
|
1548
|
-
return _state.TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
|
|
1549
|
-
}
|
|
1550
|
-
function isiOS() {
|
|
1551
|
-
return [
|
|
1552
|
-
"iPad Simulator",
|
|
1553
|
-
"iPhone Simulator",
|
|
1554
|
-
"iPod Simulator",
|
|
1555
|
-
"iPad",
|
|
1556
|
-
"iPhone",
|
|
1557
|
-
"iPod"
|
|
1558
|
-
].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
1559
|
-
}
|
|
1560
|
-
var focus = (position = null, options = {}) => ({ editor, view, tr, dispatch }) => {
|
|
1561
|
-
options = {
|
|
1562
|
-
scrollIntoView: true,
|
|
1563
|
-
...options
|
|
1564
|
-
};
|
|
1565
|
-
const delayedFocus = () => {
|
|
1566
|
-
if (isiOS()) {
|
|
1567
|
-
view.dom.focus();
|
|
1568
|
-
}
|
|
1569
|
-
requestAnimationFrame(() => {
|
|
1570
|
-
if (!editor.isDestroyed) {
|
|
1571
|
-
view.focus();
|
|
1572
|
-
if (options === null || options === void 0 ? void 0 : options.scrollIntoView) {
|
|
1573
|
-
editor.commands.scrollIntoView();
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
});
|
|
1577
|
-
};
|
|
1578
|
-
if (view.hasFocus() && position === null || position === false) {
|
|
1579
|
-
return true;
|
|
1580
|
-
}
|
|
1581
|
-
if (dispatch && position === null && !isTextSelection(editor.state.selection)) {
|
|
1582
|
-
delayedFocus();
|
|
1583
|
-
return true;
|
|
1584
|
-
}
|
|
1585
|
-
const selection = resolveFocusPosition(tr.doc, position) || editor.state.selection;
|
|
1586
|
-
const isSameSelection = editor.state.selection.eq(selection);
|
|
1587
|
-
if (dispatch) {
|
|
1588
|
-
if (!isSameSelection) {
|
|
1589
|
-
tr.setSelection(selection);
|
|
1590
|
-
}
|
|
1591
|
-
if (isSameSelection && tr.storedMarks) {
|
|
1592
|
-
tr.setStoredMarks(tr.storedMarks);
|
|
1593
|
-
}
|
|
1594
|
-
delayedFocus();
|
|
1595
|
-
}
|
|
1596
|
-
return true;
|
|
1597
|
-
};
|
|
1598
|
-
var forEach = (items, fn) => (props) => {
|
|
1599
|
-
return items.every((item, index) => fn(item, { ...props, index }));
|
|
1600
|
-
};
|
|
1601
|
-
var insertContent = (value, options) => ({ tr, commands: commands2 }) => {
|
|
1602
|
-
return commands2.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value, options);
|
|
1603
|
-
};
|
|
1604
|
-
var removeWhitespaces = (node) => {
|
|
1605
|
-
const children = node.childNodes;
|
|
1606
|
-
for (let i = children.length - 1; i >= 0; i -= 1) {
|
|
1607
|
-
const child = children[i];
|
|
1608
|
-
if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) {
|
|
1609
|
-
node.removeChild(child);
|
|
1610
|
-
} else if (child.nodeType === 1) {
|
|
1611
|
-
removeWhitespaces(child);
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
return node;
|
|
1615
|
-
};
|
|
1616
|
-
function elementFromString(value) {
|
|
1617
|
-
const wrappedValue = `<body>${value}</body>`;
|
|
1618
|
-
const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
|
|
1619
|
-
return removeWhitespaces(html);
|
|
1620
|
-
}
|
|
1621
|
-
function createNodeFromContent(content, schema, options) {
|
|
1622
|
-
if (content instanceof _model.Node || content instanceof _model.Fragment) {
|
|
1623
|
-
return content;
|
|
1624
|
-
}
|
|
1625
|
-
options = {
|
|
1626
|
-
slice: true,
|
|
1627
|
-
parseOptions: {},
|
|
1628
|
-
...options
|
|
1629
|
-
};
|
|
1630
|
-
const isJSONContent = typeof content === "object" && content !== null;
|
|
1631
|
-
const isTextContent = typeof content === "string";
|
|
1632
|
-
if (isJSONContent) {
|
|
1633
|
-
try {
|
|
1634
|
-
const isArrayContent = Array.isArray(content) && content.length > 0;
|
|
1635
|
-
if (isArrayContent) {
|
|
1636
|
-
return _model.Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item)));
|
|
1637
|
-
}
|
|
1638
|
-
const node = schema.nodeFromJSON(content);
|
|
1639
|
-
if (options.errorOnInvalidContent) {
|
|
1640
|
-
node.check();
|
|
1641
|
-
}
|
|
1642
|
-
return node;
|
|
1643
|
-
} catch (error) {
|
|
1644
|
-
if (options.errorOnInvalidContent) {
|
|
1645
|
-
throw new Error("[tiptap error]: Invalid JSON content", { cause: error });
|
|
1646
|
-
}
|
|
1647
|
-
console.warn("[tiptap warn]: Invalid content.", "Passed value:", content, "Error:", error);
|
|
1648
|
-
return createNodeFromContent("", schema, options);
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
if (isTextContent) {
|
|
1652
|
-
if (options.errorOnInvalidContent) {
|
|
1653
|
-
let hasInvalidContent = false;
|
|
1654
|
-
let invalidContent = "";
|
|
1655
|
-
const contentCheckSchema = new (0, _model.Schema)({
|
|
1656
|
-
topNode: schema.spec.topNode,
|
|
1657
|
-
marks: schema.spec.marks,
|
|
1658
|
-
// Prosemirror's schemas are executed such that: the last to execute, matches last
|
|
1659
|
-
// This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle
|
|
1660
|
-
nodes: schema.spec.nodes.append({
|
|
1661
|
-
__tiptap__private__unknown__catch__all__node: {
|
|
1662
|
-
content: "inline*",
|
|
1663
|
-
group: "block",
|
|
1664
|
-
parseDOM: [
|
|
1665
|
-
{
|
|
1666
|
-
tag: "*",
|
|
1667
|
-
getAttrs: (e) => {
|
|
1668
|
-
hasInvalidContent = true;
|
|
1669
|
-
invalidContent = typeof e === "string" ? e : e.outerHTML;
|
|
1670
|
-
return null;
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
]
|
|
1674
|
-
}
|
|
1675
|
-
})
|
|
1676
|
-
});
|
|
1677
|
-
if (options.slice) {
|
|
1678
|
-
_model.DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
|
|
1679
|
-
} else {
|
|
1680
|
-
_model.DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
|
|
1681
|
-
}
|
|
1682
|
-
if (options.errorOnInvalidContent && hasInvalidContent) {
|
|
1683
|
-
throw new Error("[tiptap error]: Invalid HTML content", { cause: new Error(`Invalid element found: ${invalidContent}`) });
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
const parser = _model.DOMParser.fromSchema(schema);
|
|
1687
|
-
if (options.slice) {
|
|
1688
|
-
return parser.parseSlice(elementFromString(content), options.parseOptions).content;
|
|
1689
|
-
}
|
|
1690
|
-
return parser.parse(elementFromString(content), options.parseOptions);
|
|
1691
|
-
}
|
|
1692
|
-
return createNodeFromContent("", schema, options);
|
|
1693
|
-
}
|
|
1694
|
-
function selectionToInsertionEnd(tr, startLen, bias) {
|
|
1695
|
-
const last = tr.steps.length - 1;
|
|
1696
|
-
if (last < startLen) {
|
|
1697
|
-
return;
|
|
1698
|
-
}
|
|
1699
|
-
const step = tr.steps[last];
|
|
1700
|
-
if (!(step instanceof _transform.ReplaceStep || step instanceof _transform.ReplaceAroundStep)) {
|
|
1701
|
-
return;
|
|
1702
|
-
}
|
|
1703
|
-
const map = tr.mapping.maps[last];
|
|
1704
|
-
let end = 0;
|
|
1705
|
-
map.forEach((_from, _to, _newFrom, newTo) => {
|
|
1706
|
-
if (end === 0) {
|
|
1707
|
-
end = newTo;
|
|
1708
|
-
}
|
|
1709
|
-
});
|
|
1710
|
-
tr.setSelection(_state.Selection.near(tr.doc.resolve(end), bias));
|
|
1711
|
-
}
|
|
1712
|
-
var isFragment = (nodeOrFragment) => {
|
|
1713
|
-
return !("type" in nodeOrFragment);
|
|
1714
|
-
};
|
|
1715
|
-
var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) => {
|
|
1716
|
-
var _a;
|
|
1717
|
-
if (dispatch) {
|
|
1718
|
-
options = {
|
|
1719
|
-
parseOptions: editor.options.parseOptions,
|
|
1720
|
-
updateSelection: true,
|
|
1721
|
-
applyInputRules: false,
|
|
1722
|
-
applyPasteRules: false,
|
|
1723
|
-
...options
|
|
1724
|
-
};
|
|
1725
|
-
let content;
|
|
1726
|
-
try {
|
|
1727
|
-
content = createNodeFromContent(value, editor.schema, {
|
|
1728
|
-
parseOptions: {
|
|
1729
|
-
preserveWhitespace: "full",
|
|
1730
|
-
...options.parseOptions
|
|
1731
|
-
},
|
|
1732
|
-
errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck
|
|
1733
|
-
});
|
|
1734
|
-
} catch (e) {
|
|
1735
|
-
editor.emit("contentError", {
|
|
1736
|
-
editor,
|
|
1737
|
-
error: e,
|
|
1738
|
-
disableCollaboration: () => {
|
|
1739
|
-
if (editor.storage.collaboration) {
|
|
1740
|
-
editor.storage.collaboration.isDisabled = true;
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
});
|
|
1744
|
-
return false;
|
|
1745
|
-
}
|
|
1746
|
-
let { from, to } = typeof position === "number" ? { from: position, to: position } : { from: position.from, to: position.to };
|
|
1747
|
-
let isOnlyTextContent = true;
|
|
1748
|
-
let isOnlyBlockContent = true;
|
|
1749
|
-
const nodes = isFragment(content) ? content : [content];
|
|
1750
|
-
nodes.forEach((node) => {
|
|
1751
|
-
node.check();
|
|
1752
|
-
isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false;
|
|
1753
|
-
isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false;
|
|
1754
|
-
});
|
|
1755
|
-
if (from === to && isOnlyBlockContent) {
|
|
1756
|
-
const { parent } = tr.doc.resolve(from);
|
|
1757
|
-
const isEmptyTextBlock = parent.isTextblock && !parent.type.spec.code && !parent.childCount;
|
|
1758
|
-
if (isEmptyTextBlock) {
|
|
1759
|
-
from -= 1;
|
|
1760
|
-
to += 1;
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
let newContent;
|
|
1764
|
-
if (isOnlyTextContent) {
|
|
1765
|
-
if (Array.isArray(value)) {
|
|
1766
|
-
newContent = value.map((v) => v.text || "").join("");
|
|
1767
|
-
} else if (value instanceof _model.Fragment) {
|
|
1768
|
-
let text = "";
|
|
1769
|
-
value.forEach((node) => {
|
|
1770
|
-
if (node.text) {
|
|
1771
|
-
text += node.text;
|
|
1772
|
-
}
|
|
1773
|
-
});
|
|
1774
|
-
newContent = text;
|
|
1775
|
-
} else if (typeof value === "object" && !!value && !!value.text) {
|
|
1776
|
-
newContent = value.text;
|
|
1777
|
-
} else {
|
|
1778
|
-
newContent = value;
|
|
1779
|
-
}
|
|
1780
|
-
tr.insertText(newContent, from, to);
|
|
1781
|
-
} else {
|
|
1782
|
-
newContent = content;
|
|
1783
|
-
tr.replaceWith(from, to, newContent);
|
|
1784
|
-
}
|
|
1785
|
-
if (options.updateSelection) {
|
|
1786
|
-
selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
|
|
1787
|
-
}
|
|
1788
|
-
if (options.applyInputRules) {
|
|
1789
|
-
tr.setMeta("applyInputRules", { from, text: newContent });
|
|
1790
|
-
}
|
|
1791
|
-
if (options.applyPasteRules) {
|
|
1792
|
-
tr.setMeta("applyPasteRules", { from, text: newContent });
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
return true;
|
|
1796
|
-
};
|
|
1797
|
-
var joinUp = () => ({ state, dispatch }) => {
|
|
1798
|
-
return _commands.joinUp.call(void 0, state, dispatch);
|
|
1799
|
-
};
|
|
1800
|
-
var joinDown = () => ({ state, dispatch }) => {
|
|
1801
|
-
return _commands.joinDown.call(void 0, state, dispatch);
|
|
1802
|
-
};
|
|
1803
|
-
var joinBackward = () => ({ state, dispatch }) => {
|
|
1804
|
-
return _commands.joinBackward.call(void 0, state, dispatch);
|
|
1805
|
-
};
|
|
1806
|
-
var joinForward = () => ({ state, dispatch }) => {
|
|
1807
|
-
return _commands.joinForward.call(void 0, state, dispatch);
|
|
1808
|
-
};
|
|
1809
|
-
var joinItemBackward = () => ({ state, dispatch, tr }) => {
|
|
1810
|
-
try {
|
|
1811
|
-
const point = _transform.joinPoint.call(void 0, state.doc, state.selection.$from.pos, -1);
|
|
1812
|
-
if (point === null || point === void 0) {
|
|
1813
|
-
return false;
|
|
1814
|
-
}
|
|
1815
|
-
tr.join(point, 2);
|
|
1816
|
-
if (dispatch) {
|
|
1817
|
-
dispatch(tr);
|
|
1818
|
-
}
|
|
1819
|
-
return true;
|
|
1820
|
-
} catch (e) {
|
|
1821
|
-
return false;
|
|
1822
|
-
}
|
|
1823
|
-
};
|
|
1824
|
-
var joinItemForward = () => ({ state, dispatch, tr }) => {
|
|
1825
|
-
try {
|
|
1826
|
-
const point = _transform.joinPoint.call(void 0, state.doc, state.selection.$from.pos, 1);
|
|
1827
|
-
if (point === null || point === void 0) {
|
|
1828
|
-
return false;
|
|
1829
|
-
}
|
|
1830
|
-
tr.join(point, 2);
|
|
1831
|
-
if (dispatch) {
|
|
1832
|
-
dispatch(tr);
|
|
1833
|
-
}
|
|
1834
|
-
return true;
|
|
1835
|
-
} catch (e) {
|
|
1836
|
-
return false;
|
|
1837
|
-
}
|
|
1838
|
-
};
|
|
1839
|
-
var joinTextblockBackward = () => ({ state, dispatch }) => {
|
|
1840
|
-
return _commands.joinTextblockBackward.call(void 0, state, dispatch);
|
|
1841
|
-
};
|
|
1842
|
-
var joinTextblockForward = () => ({ state, dispatch }) => {
|
|
1843
|
-
return _commands.joinTextblockForward.call(void 0, state, dispatch);
|
|
1844
|
-
};
|
|
1845
|
-
function isMacOS() {
|
|
1846
|
-
return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
|
|
1847
|
-
}
|
|
1848
|
-
function normalizeKeyName(name) {
|
|
1849
|
-
const parts = name.split(/-(?!$)/);
|
|
1850
|
-
let result = parts[parts.length - 1];
|
|
1851
|
-
if (result === "Space") {
|
|
1852
|
-
result = " ";
|
|
1853
|
-
}
|
|
1854
|
-
let alt;
|
|
1855
|
-
let ctrl;
|
|
1856
|
-
let shift;
|
|
1857
|
-
let meta;
|
|
1858
|
-
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
1859
|
-
const mod = parts[i];
|
|
1860
|
-
if (/^(cmd|meta|m)$/i.test(mod)) {
|
|
1861
|
-
meta = true;
|
|
1862
|
-
} else if (/^a(lt)?$/i.test(mod)) {
|
|
1863
|
-
alt = true;
|
|
1864
|
-
} else if (/^(c|ctrl|control)$/i.test(mod)) {
|
|
1865
|
-
ctrl = true;
|
|
1866
|
-
} else if (/^s(hift)?$/i.test(mod)) {
|
|
1867
|
-
shift = true;
|
|
1868
|
-
} else if (/^mod$/i.test(mod)) {
|
|
1869
|
-
if (isiOS() || isMacOS()) {
|
|
1870
|
-
meta = true;
|
|
1871
|
-
} else {
|
|
1872
|
-
ctrl = true;
|
|
1873
|
-
}
|
|
1874
|
-
} else {
|
|
1875
|
-
throw new Error(`Unrecognized modifier name: ${mod}`);
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
if (alt) {
|
|
1879
|
-
result = `Alt-${result}`;
|
|
1880
|
-
}
|
|
1881
|
-
if (ctrl) {
|
|
1882
|
-
result = `Ctrl-${result}`;
|
|
1883
|
-
}
|
|
1884
|
-
if (meta) {
|
|
1885
|
-
result = `Meta-${result}`;
|
|
1886
|
-
}
|
|
1887
|
-
if (shift) {
|
|
1888
|
-
result = `Shift-${result}`;
|
|
1889
|
-
}
|
|
1890
|
-
return result;
|
|
1891
|
-
}
|
|
1892
|
-
var keyboardShortcut = (name) => ({ editor, view, tr, dispatch }) => {
|
|
1893
|
-
const keys = normalizeKeyName(name).split(/-(?!$)/);
|
|
1894
|
-
const key = keys.find((item) => !["Alt", "Ctrl", "Meta", "Shift"].includes(item));
|
|
1895
|
-
const event = new KeyboardEvent("keydown", {
|
|
1896
|
-
key: key === "Space" ? " " : key,
|
|
1897
|
-
altKey: keys.includes("Alt"),
|
|
1898
|
-
ctrlKey: keys.includes("Ctrl"),
|
|
1899
|
-
metaKey: keys.includes("Meta"),
|
|
1900
|
-
shiftKey: keys.includes("Shift"),
|
|
1901
|
-
bubbles: true,
|
|
1902
|
-
cancelable: true
|
|
1903
|
-
});
|
|
1904
|
-
const capturedTransaction = editor.captureTransaction(() => {
|
|
1905
|
-
view.someProp("handleKeyDown", (f) => f(view, event));
|
|
1906
|
-
});
|
|
1907
|
-
capturedTransaction === null || capturedTransaction === void 0 ? void 0 : capturedTransaction.steps.forEach((step) => {
|
|
1908
|
-
const newStep = step.map(tr.mapping);
|
|
1909
|
-
if (newStep && dispatch) {
|
|
1910
|
-
tr.maybeStep(newStep);
|
|
1911
|
-
}
|
|
1912
|
-
});
|
|
1913
|
-
return true;
|
|
1914
|
-
};
|
|
1915
|
-
function isNodeActive(state, typeOrName, attributes = {}) {
|
|
1916
|
-
const { from, to, empty } = state.selection;
|
|
1917
|
-
const type = typeOrName ? getNodeType(typeOrName, state.schema) : null;
|
|
1918
|
-
const nodeRanges = [];
|
|
1919
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
1920
|
-
if (node.isText) {
|
|
1921
|
-
return;
|
|
1922
|
-
}
|
|
1923
|
-
const relativeFrom = Math.max(from, pos);
|
|
1924
|
-
const relativeTo = Math.min(to, pos + node.nodeSize);
|
|
1925
|
-
nodeRanges.push({
|
|
1926
|
-
node,
|
|
1927
|
-
from: relativeFrom,
|
|
1928
|
-
to: relativeTo
|
|
1929
|
-
});
|
|
1930
|
-
});
|
|
1931
|
-
const selectionRange = to - from;
|
|
1932
|
-
const matchedNodeRanges = nodeRanges.filter((nodeRange) => {
|
|
1933
|
-
if (!type) {
|
|
1934
|
-
return true;
|
|
1935
|
-
}
|
|
1936
|
-
return type.name === nodeRange.node.type.name;
|
|
1937
|
-
}).filter((nodeRange) => objectIncludes(nodeRange.node.attrs, attributes, { strict: false }));
|
|
1938
|
-
if (empty) {
|
|
1939
|
-
return !!matchedNodeRanges.length;
|
|
1940
|
-
}
|
|
1941
|
-
const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0);
|
|
1942
|
-
return range >= selectionRange;
|
|
1943
|
-
}
|
|
1944
|
-
var lift = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
|
|
1945
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
1946
|
-
const isActive = isNodeActive(state, type, attributes);
|
|
1947
|
-
if (!isActive) {
|
|
1948
|
-
return false;
|
|
1949
|
-
}
|
|
1950
|
-
return _commands.lift.call(void 0, state, dispatch);
|
|
1951
|
-
};
|
|
1952
|
-
var liftEmptyBlock = () => ({ state, dispatch }) => {
|
|
1953
|
-
return _commands.liftEmptyBlock.call(void 0, state, dispatch);
|
|
1954
|
-
};
|
|
1955
|
-
var liftListItem = (typeOrName) => ({ state, dispatch }) => {
|
|
1956
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
1957
|
-
return _schemalist.liftListItem.call(void 0, type)(state, dispatch);
|
|
1958
|
-
};
|
|
1959
|
-
var newlineInCode = () => ({ state, dispatch }) => {
|
|
1960
|
-
return _commands.newlineInCode.call(void 0, state, dispatch);
|
|
1961
|
-
};
|
|
1962
|
-
function getSchemaTypeNameByName(name, schema) {
|
|
1963
|
-
if (schema.nodes[name]) {
|
|
1964
|
-
return "node";
|
|
1965
|
-
}
|
|
1966
|
-
if (schema.marks[name]) {
|
|
1967
|
-
return "mark";
|
|
1968
|
-
}
|
|
1969
|
-
return null;
|
|
1970
|
-
}
|
|
1971
|
-
function deleteProps(obj, propOrProps) {
|
|
1972
|
-
const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
|
|
1973
|
-
return Object.keys(obj).reduce((newObj, prop) => {
|
|
1974
|
-
if (!props.includes(prop)) {
|
|
1975
|
-
newObj[prop] = obj[prop];
|
|
1976
|
-
}
|
|
1977
|
-
return newObj;
|
|
1978
|
-
}, {});
|
|
1979
|
-
}
|
|
1980
|
-
var resetAttributes = (typeOrName, attributes) => ({ tr, state, dispatch }) => {
|
|
1981
|
-
let nodeType = null;
|
|
1982
|
-
let markType = null;
|
|
1983
|
-
const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema);
|
|
1984
|
-
if (!schemaType) {
|
|
1985
|
-
return false;
|
|
1986
|
-
}
|
|
1987
|
-
if (schemaType === "node") {
|
|
1988
|
-
nodeType = getNodeType(typeOrName, state.schema);
|
|
1989
|
-
}
|
|
1990
|
-
if (schemaType === "mark") {
|
|
1991
|
-
markType = getMarkType(typeOrName, state.schema);
|
|
1992
|
-
}
|
|
1993
|
-
if (dispatch) {
|
|
1994
|
-
tr.selection.ranges.forEach((range) => {
|
|
1995
|
-
state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {
|
|
1996
|
-
if (nodeType && nodeType === node.type) {
|
|
1997
|
-
tr.setNodeMarkup(pos, void 0, deleteProps(node.attrs, attributes));
|
|
1998
|
-
}
|
|
1999
|
-
if (markType && node.marks.length) {
|
|
2000
|
-
node.marks.forEach((mark) => {
|
|
2001
|
-
if (markType === mark.type) {
|
|
2002
|
-
tr.addMark(pos, pos + node.nodeSize, markType.create(deleteProps(mark.attrs, attributes)));
|
|
2003
|
-
}
|
|
2004
|
-
});
|
|
2005
|
-
}
|
|
2006
|
-
});
|
|
2007
|
-
});
|
|
2008
|
-
}
|
|
2009
|
-
return true;
|
|
2010
|
-
};
|
|
2011
|
-
var scrollIntoView = () => ({ tr, dispatch }) => {
|
|
2012
|
-
if (dispatch) {
|
|
2013
|
-
tr.scrollIntoView();
|
|
2014
|
-
}
|
|
2015
|
-
return true;
|
|
2016
|
-
};
|
|
2017
|
-
var selectAll = () => ({ tr, commands: commands2 }) => {
|
|
2018
|
-
return commands2.setTextSelection({
|
|
2019
|
-
from: 0,
|
|
2020
|
-
to: tr.doc.content.size
|
|
2021
|
-
});
|
|
2022
|
-
};
|
|
2023
|
-
var selectNodeBackward = () => ({ state, dispatch }) => {
|
|
2024
|
-
return _commands.selectNodeBackward.call(void 0, state, dispatch);
|
|
2025
|
-
};
|
|
2026
|
-
var selectNodeForward = () => ({ state, dispatch }) => {
|
|
2027
|
-
return _commands.selectNodeForward.call(void 0, state, dispatch);
|
|
2028
|
-
};
|
|
2029
|
-
var selectParentNode = () => ({ state, dispatch }) => {
|
|
2030
|
-
return _commands.selectParentNode.call(void 0, state, dispatch);
|
|
2031
|
-
};
|
|
2032
|
-
var selectTextblockEnd = () => ({ state, dispatch }) => {
|
|
2033
|
-
return _commands.selectTextblockEnd.call(void 0, state, dispatch);
|
|
2034
|
-
};
|
|
2035
|
-
var selectTextblockStart = () => ({ state, dispatch }) => {
|
|
2036
|
-
return _commands.selectTextblockStart.call(void 0, state, dispatch);
|
|
2037
|
-
};
|
|
2038
|
-
function createDocument(content, schema, parseOptions = {}, options = {}) {
|
|
2039
|
-
return createNodeFromContent(content, schema, {
|
|
2040
|
-
slice: false,
|
|
2041
|
-
parseOptions,
|
|
2042
|
-
errorOnInvalidContent: options.errorOnInvalidContent
|
|
2043
|
-
});
|
|
2044
|
-
}
|
|
2045
|
-
var setContent = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({ editor, tr, dispatch, commands: commands2 }) => {
|
|
2046
|
-
var _a, _b;
|
|
2047
|
-
const { doc } = tr;
|
|
2048
|
-
if (parseOptions.preserveWhitespace !== "full") {
|
|
2049
|
-
const document2 = createDocument(content, editor.schema, parseOptions, {
|
|
2050
|
-
errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck
|
|
2051
|
-
});
|
|
2052
|
-
if (dispatch) {
|
|
2053
|
-
tr.replaceWith(0, doc.content.size, document2).setMeta("preventUpdate", !emitUpdate);
|
|
2054
|
-
}
|
|
2055
|
-
return true;
|
|
2056
|
-
}
|
|
2057
|
-
if (dispatch) {
|
|
2058
|
-
tr.setMeta("preventUpdate", !emitUpdate);
|
|
2059
|
-
}
|
|
2060
|
-
return commands2.insertContentAt({ from: 0, to: doc.content.size }, content, {
|
|
2061
|
-
parseOptions,
|
|
2062
|
-
errorOnInvalidContent: (_b = options.errorOnInvalidContent) !== null && _b !== void 0 ? _b : editor.options.enableContentCheck
|
|
2063
|
-
});
|
|
2064
|
-
};
|
|
2065
|
-
function getMarkAttributes(state, typeOrName) {
|
|
2066
|
-
const type = getMarkType(typeOrName, state.schema);
|
|
2067
|
-
const { from, to, empty } = state.selection;
|
|
2068
|
-
const marks = [];
|
|
2069
|
-
if (empty) {
|
|
2070
|
-
if (state.storedMarks) {
|
|
2071
|
-
marks.push(...state.storedMarks);
|
|
2072
|
-
}
|
|
2073
|
-
marks.push(...state.selection.$head.marks());
|
|
2074
|
-
} else {
|
|
2075
|
-
state.doc.nodesBetween(from, to, (node) => {
|
|
2076
|
-
marks.push(...node.marks);
|
|
2077
|
-
});
|
|
2078
|
-
}
|
|
2079
|
-
const mark = marks.find((markItem) => markItem.type.name === type.name);
|
|
2080
|
-
if (!mark) {
|
|
2081
|
-
return {};
|
|
2082
|
-
}
|
|
2083
|
-
return { ...mark.attrs };
|
|
2084
|
-
}
|
|
2085
|
-
function defaultBlockAt(match) {
|
|
2086
|
-
for (let i = 0; i < match.edgeCount; i += 1) {
|
|
2087
|
-
const { type } = match.edge(i);
|
|
2088
|
-
if (type.isTextblock && !type.hasRequiredAttrs()) {
|
|
2089
|
-
return type;
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
return null;
|
|
2093
|
-
}
|
|
2094
|
-
function findParentNodeClosestToPos($pos, predicate) {
|
|
2095
|
-
for (let i = $pos.depth; i > 0; i -= 1) {
|
|
2096
|
-
const node = $pos.node(i);
|
|
2097
|
-
if (predicate(node)) {
|
|
2098
|
-
return {
|
|
2099
|
-
pos: i > 0 ? $pos.before(i) : 0,
|
|
2100
|
-
start: $pos.start(i),
|
|
2101
|
-
depth: i,
|
|
2102
|
-
node
|
|
2103
|
-
};
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
function findParentNode(predicate) {
|
|
2108
|
-
return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
|
|
2109
|
-
}
|
|
2110
|
-
function getSchema(extensions, editor) {
|
|
2111
|
-
const resolvedExtensions = ExtensionManager.resolve(extensions);
|
|
2112
|
-
return getSchemaByResolvedExtensions(resolvedExtensions, editor);
|
|
2113
|
-
}
|
|
2114
|
-
function getText(node, options) {
|
|
2115
|
-
const range = {
|
|
2116
|
-
from: 0,
|
|
2117
|
-
to: node.content.size
|
|
2118
|
-
};
|
|
2119
|
-
return getTextBetween(node, range, options);
|
|
2120
|
-
}
|
|
2121
|
-
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
2122
|
-
return Object.fromEntries(Object.entries(attributes).filter(([name]) => {
|
|
2123
|
-
const extensionAttribute = extensionAttributes.find((item) => {
|
|
2124
|
-
return item.type === typeName && item.name === name;
|
|
2125
|
-
});
|
|
2126
|
-
if (!extensionAttribute) {
|
|
2127
|
-
return false;
|
|
2128
|
-
}
|
|
2129
|
-
return extensionAttribute.attribute.keepOnSplit;
|
|
2130
|
-
}));
|
|
2131
|
-
}
|
|
2132
|
-
function isMarkActive(state, typeOrName, attributes = {}) {
|
|
2133
|
-
const { empty, ranges } = state.selection;
|
|
2134
|
-
const type = typeOrName ? getMarkType(typeOrName, state.schema) : null;
|
|
2135
|
-
if (empty) {
|
|
2136
|
-
return !!(state.storedMarks || state.selection.$from.marks()).filter((mark) => {
|
|
2137
|
-
if (!type) {
|
|
2138
|
-
return true;
|
|
2139
|
-
}
|
|
2140
|
-
return type.name === mark.type.name;
|
|
2141
|
-
}).find((mark) => objectIncludes(mark.attrs, attributes, { strict: false }));
|
|
2142
|
-
}
|
|
2143
|
-
let selectionRange = 0;
|
|
2144
|
-
const markRanges = [];
|
|
2145
|
-
ranges.forEach(({ $from, $to }) => {
|
|
2146
|
-
const from = $from.pos;
|
|
2147
|
-
const to = $to.pos;
|
|
2148
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
2149
|
-
if (!node.isText && !node.marks.length) {
|
|
2150
|
-
return;
|
|
2151
|
-
}
|
|
2152
|
-
const relativeFrom = Math.max(from, pos);
|
|
2153
|
-
const relativeTo = Math.min(to, pos + node.nodeSize);
|
|
2154
|
-
const range2 = relativeTo - relativeFrom;
|
|
2155
|
-
selectionRange += range2;
|
|
2156
|
-
markRanges.push(...node.marks.map((mark) => ({
|
|
2157
|
-
mark,
|
|
2158
|
-
from: relativeFrom,
|
|
2159
|
-
to: relativeTo
|
|
2160
|
-
})));
|
|
2161
|
-
});
|
|
2162
|
-
});
|
|
2163
|
-
if (selectionRange === 0) {
|
|
2164
|
-
return false;
|
|
2165
|
-
}
|
|
2166
|
-
const matchedRange = markRanges.filter((markRange) => {
|
|
2167
|
-
if (!type) {
|
|
2168
|
-
return true;
|
|
2169
|
-
}
|
|
2170
|
-
return type.name === markRange.mark.type.name;
|
|
2171
|
-
}).filter((markRange) => objectIncludes(markRange.mark.attrs, attributes, { strict: false })).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0);
|
|
2172
|
-
const excludedRange = markRanges.filter((markRange) => {
|
|
2173
|
-
if (!type) {
|
|
2174
|
-
return true;
|
|
2175
|
-
}
|
|
2176
|
-
return markRange.mark.type !== type && markRange.mark.type.excludes(type);
|
|
2177
|
-
}).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0);
|
|
2178
|
-
const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange;
|
|
2179
|
-
return range >= selectionRange;
|
|
2180
|
-
}
|
|
2181
|
-
function isList(name, extensions) {
|
|
2182
|
-
const { nodeExtensions } = splitExtensions(extensions);
|
|
2183
|
-
const extension = nodeExtensions.find((item) => item.name === name);
|
|
2184
|
-
if (!extension) {
|
|
2185
|
-
return false;
|
|
2186
|
-
}
|
|
2187
|
-
const context = {
|
|
2188
|
-
name: extension.name,
|
|
2189
|
-
options: extension.options,
|
|
2190
|
-
storage: extension.storage
|
|
2191
|
-
};
|
|
2192
|
-
const group = callOrReturn(getExtensionField(extension, "group", context));
|
|
2193
|
-
if (typeof group !== "string") {
|
|
2194
|
-
return false;
|
|
2195
|
-
}
|
|
2196
|
-
return group.split(" ").includes("list");
|
|
2197
|
-
}
|
|
2198
|
-
function isNodeEmpty(node, { checkChildren = true, ignoreWhitespace = false } = {}) {
|
|
2199
|
-
var _a;
|
|
2200
|
-
if (ignoreWhitespace) {
|
|
2201
|
-
if (node.type.name === "hardBreak") {
|
|
2202
|
-
return true;
|
|
2203
|
-
}
|
|
2204
|
-
if (node.isText) {
|
|
2205
|
-
return /^\s*$/m.test((_a = node.text) !== null && _a !== void 0 ? _a : "");
|
|
2206
|
-
}
|
|
2207
|
-
}
|
|
2208
|
-
if (node.isText) {
|
|
2209
|
-
return !node.text;
|
|
2210
|
-
}
|
|
2211
|
-
if (node.isAtom || node.isLeaf) {
|
|
2212
|
-
return false;
|
|
2213
|
-
}
|
|
2214
|
-
if (node.content.childCount === 0) {
|
|
2215
|
-
return true;
|
|
2216
|
-
}
|
|
2217
|
-
if (checkChildren) {
|
|
2218
|
-
let isContentEmpty = true;
|
|
2219
|
-
node.content.forEach((childNode) => {
|
|
2220
|
-
if (isContentEmpty === false) {
|
|
2221
|
-
return;
|
|
2222
|
-
}
|
|
2223
|
-
if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) {
|
|
2224
|
-
isContentEmpty = false;
|
|
2225
|
-
}
|
|
2226
|
-
});
|
|
2227
|
-
return isContentEmpty;
|
|
2228
|
-
}
|
|
2229
|
-
return false;
|
|
2230
|
-
}
|
|
2231
|
-
function canSetMark(state, tr, newMarkType) {
|
|
2232
|
-
var _a;
|
|
2233
|
-
const { selection } = tr;
|
|
2234
|
-
let cursor = null;
|
|
2235
|
-
if (isTextSelection(selection)) {
|
|
2236
|
-
cursor = selection.$cursor;
|
|
2237
|
-
}
|
|
2238
|
-
if (cursor) {
|
|
2239
|
-
const currentMarks = (_a = state.storedMarks) !== null && _a !== void 0 ? _a : cursor.marks();
|
|
2240
|
-
return !!newMarkType.isInSet(currentMarks) || !currentMarks.some((mark) => mark.type.excludes(newMarkType));
|
|
2241
|
-
}
|
|
2242
|
-
const { ranges } = selection;
|
|
2243
|
-
return ranges.some(({ $from, $to }) => {
|
|
2244
|
-
let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false;
|
|
2245
|
-
state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => {
|
|
2246
|
-
if (someNodeSupportsMark) {
|
|
2247
|
-
return false;
|
|
2248
|
-
}
|
|
2249
|
-
if (node.isInline) {
|
|
2250
|
-
const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType);
|
|
2251
|
-
const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some((otherMark) => otherMark.type.excludes(newMarkType));
|
|
2252
|
-
someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType;
|
|
2253
|
-
}
|
|
2254
|
-
return !someNodeSupportsMark;
|
|
2255
|
-
});
|
|
2256
|
-
return someNodeSupportsMark;
|
|
2257
|
-
});
|
|
2258
|
-
}
|
|
2259
|
-
var setMark = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
2260
|
-
const { selection } = tr;
|
|
2261
|
-
const { empty, ranges } = selection;
|
|
2262
|
-
const type = getMarkType(typeOrName, state.schema);
|
|
2263
|
-
if (dispatch) {
|
|
2264
|
-
if (empty) {
|
|
2265
|
-
const oldAttributes = getMarkAttributes(state, type);
|
|
2266
|
-
tr.addStoredMark(type.create({
|
|
2267
|
-
...oldAttributes,
|
|
2268
|
-
...attributes
|
|
2269
|
-
}));
|
|
2270
|
-
} else {
|
|
2271
|
-
ranges.forEach((range) => {
|
|
2272
|
-
const from = range.$from.pos;
|
|
2273
|
-
const to = range.$to.pos;
|
|
2274
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
2275
|
-
const trimmedFrom = Math.max(pos, from);
|
|
2276
|
-
const trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
2277
|
-
const someHasMark = node.marks.find((mark) => mark.type === type);
|
|
2278
|
-
if (someHasMark) {
|
|
2279
|
-
node.marks.forEach((mark) => {
|
|
2280
|
-
if (type === mark.type) {
|
|
2281
|
-
tr.addMark(trimmedFrom, trimmedTo, type.create({
|
|
2282
|
-
...mark.attrs,
|
|
2283
|
-
...attributes
|
|
2284
|
-
}));
|
|
2285
|
-
}
|
|
2286
|
-
});
|
|
2287
|
-
} else {
|
|
2288
|
-
tr.addMark(trimmedFrom, trimmedTo, type.create(attributes));
|
|
2289
|
-
}
|
|
2290
|
-
});
|
|
2291
|
-
});
|
|
2292
|
-
}
|
|
2293
|
-
}
|
|
2294
|
-
return canSetMark(state, tr, type);
|
|
2295
|
-
};
|
|
2296
|
-
var setMeta = (key, value) => ({ tr }) => {
|
|
2297
|
-
tr.setMeta(key, value);
|
|
2298
|
-
return true;
|
|
2299
|
-
};
|
|
2300
|
-
var setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {
|
|
2301
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2302
|
-
let attributesToCopy;
|
|
2303
|
-
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
2304
|
-
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
2305
|
-
}
|
|
2306
|
-
if (!type.isTextblock) {
|
|
2307
|
-
console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.');
|
|
2308
|
-
return false;
|
|
2309
|
-
}
|
|
2310
|
-
return chain().command(({ commands: commands2 }) => {
|
|
2311
|
-
const canSetBlock = _commands.setBlockType.call(void 0, type, { ...attributesToCopy, ...attributes })(state);
|
|
2312
|
-
if (canSetBlock) {
|
|
2313
|
-
return true;
|
|
2314
|
-
}
|
|
2315
|
-
return commands2.clearNodes();
|
|
2316
|
-
}).command(({ state: updatedState }) => {
|
|
2317
|
-
return _commands.setBlockType.call(void 0, type, { ...attributesToCopy, ...attributes })(updatedState, dispatch);
|
|
2318
|
-
}).run();
|
|
2319
|
-
};
|
|
2320
|
-
var setNodeSelection = (position) => ({ tr, dispatch }) => {
|
|
2321
|
-
if (dispatch) {
|
|
2322
|
-
const { doc } = tr;
|
|
2323
|
-
const from = minMax(position, 0, doc.content.size);
|
|
2324
|
-
const selection = _state.NodeSelection.create(doc, from);
|
|
2325
|
-
tr.setSelection(selection);
|
|
2326
|
-
}
|
|
2327
|
-
return true;
|
|
2328
|
-
};
|
|
2329
|
-
var setTextSelection = (position) => ({ tr, dispatch }) => {
|
|
2330
|
-
if (dispatch) {
|
|
2331
|
-
const { doc } = tr;
|
|
2332
|
-
const { from, to } = typeof position === "number" ? { from: position, to: position } : position;
|
|
2333
|
-
const minPos = _state.TextSelection.atStart(doc).from;
|
|
2334
|
-
const maxPos = _state.TextSelection.atEnd(doc).to;
|
|
2335
|
-
const resolvedFrom = minMax(from, minPos, maxPos);
|
|
2336
|
-
const resolvedEnd = minMax(to, minPos, maxPos);
|
|
2337
|
-
const selection = _state.TextSelection.create(doc, resolvedFrom, resolvedEnd);
|
|
2338
|
-
tr.setSelection(selection);
|
|
2339
|
-
}
|
|
2340
|
-
return true;
|
|
2341
|
-
};
|
|
2342
|
-
var sinkListItem = (typeOrName) => ({ state, dispatch }) => {
|
|
2343
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2344
|
-
return _schemalist.sinkListItem.call(void 0, type)(state, dispatch);
|
|
2345
|
-
};
|
|
2346
|
-
function ensureMarks(state, splittableMarks) {
|
|
2347
|
-
const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks();
|
|
2348
|
-
if (marks) {
|
|
2349
|
-
const filteredMarks = marks.filter((mark) => splittableMarks === null || splittableMarks === void 0 ? void 0 : splittableMarks.includes(mark.type.name));
|
|
2350
|
-
state.tr.ensureMarks(filteredMarks);
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
var splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor }) => {
|
|
2354
|
-
const { selection, doc } = tr;
|
|
2355
|
-
const { $from, $to } = selection;
|
|
2356
|
-
const extensionAttributes = editor.extensionManager.attributes;
|
|
2357
|
-
const newAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
|
|
2358
|
-
if (selection instanceof _state.NodeSelection && selection.node.isBlock) {
|
|
2359
|
-
if (!$from.parentOffset || !_transform.canSplit.call(void 0, doc, $from.pos)) {
|
|
2360
|
-
return false;
|
|
2361
|
-
}
|
|
2362
|
-
if (dispatch) {
|
|
2363
|
-
if (keepMarks) {
|
|
2364
|
-
ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
2365
|
-
}
|
|
2366
|
-
tr.split($from.pos).scrollIntoView();
|
|
2367
|
-
}
|
|
2368
|
-
return true;
|
|
2369
|
-
}
|
|
2370
|
-
if (!$from.parent.isBlock) {
|
|
2371
|
-
return false;
|
|
2372
|
-
}
|
|
2373
|
-
const atEnd = $to.parentOffset === $to.parent.content.size;
|
|
2374
|
-
const deflt = $from.depth === 0 ? void 0 : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
|
|
2375
|
-
let types = atEnd && deflt ? [
|
|
2376
|
-
{
|
|
2377
|
-
type: deflt,
|
|
2378
|
-
attrs: newAttributes
|
|
2379
|
-
}
|
|
2380
|
-
] : void 0;
|
|
2381
|
-
let can = _transform.canSplit.call(void 0, tr.doc, tr.mapping.map($from.pos), 1, types);
|
|
2382
|
-
if (!types && !can && _transform.canSplit.call(void 0, tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) {
|
|
2383
|
-
can = true;
|
|
2384
|
-
types = deflt ? [
|
|
2385
|
-
{
|
|
2386
|
-
type: deflt,
|
|
2387
|
-
attrs: newAttributes
|
|
2388
|
-
}
|
|
2389
|
-
] : void 0;
|
|
2390
|
-
}
|
|
2391
|
-
if (dispatch) {
|
|
2392
|
-
if (can) {
|
|
2393
|
-
if (selection instanceof _state.TextSelection) {
|
|
2394
|
-
tr.deleteSelection();
|
|
2395
|
-
}
|
|
2396
|
-
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
2397
|
-
if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
|
|
2398
|
-
const first2 = tr.mapping.map($from.before());
|
|
2399
|
-
const $first = tr.doc.resolve(first2);
|
|
2400
|
-
if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) {
|
|
2401
|
-
tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
|
|
2402
|
-
}
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
if (keepMarks) {
|
|
2406
|
-
ensureMarks(state, editor.extensionManager.splittableMarks);
|
|
2407
|
-
}
|
|
2408
|
-
tr.scrollIntoView();
|
|
2409
|
-
}
|
|
2410
|
-
return can;
|
|
2411
|
-
};
|
|
2412
|
-
var splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr, state, dispatch, editor }) => {
|
|
2413
|
-
var _a;
|
|
2414
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2415
|
-
const { $from, $to } = state.selection;
|
|
2416
|
-
const node = state.selection.node;
|
|
2417
|
-
if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) {
|
|
2418
|
-
return false;
|
|
2419
|
-
}
|
|
2420
|
-
const grandParent = $from.node(-1);
|
|
2421
|
-
if (grandParent.type !== type) {
|
|
2422
|
-
return false;
|
|
2423
|
-
}
|
|
2424
|
-
const extensionAttributes = editor.extensionManager.attributes;
|
|
2425
|
-
if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) {
|
|
2426
|
-
if ($from.depth === 2 || $from.node(-3).type !== type || $from.index(-2) !== $from.node(-2).childCount - 1) {
|
|
2427
|
-
return false;
|
|
2428
|
-
}
|
|
2429
|
-
if (dispatch) {
|
|
2430
|
-
let wrap = _model.Fragment.empty;
|
|
2431
|
-
const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3;
|
|
2432
|
-
for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) {
|
|
2433
|
-
wrap = _model.Fragment.from($from.node(d).copy(wrap));
|
|
2434
|
-
}
|
|
2435
|
-
const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3;
|
|
2436
|
-
const newNextTypeAttributes2 = {
|
|
2437
|
-
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
2438
|
-
...overrideAttrs
|
|
2439
|
-
};
|
|
2440
|
-
const nextType2 = ((_a = type.contentMatch.defaultType) === null || _a === void 0 ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0;
|
|
2441
|
-
wrap = wrap.append(_model.Fragment.from(type.createAndFill(null, nextType2) || void 0));
|
|
2442
|
-
const start = $from.before($from.depth - (depthBefore - 1));
|
|
2443
|
-
tr.replace(start, $from.after(-depthAfter), new (0, _model.Slice)(wrap, 4 - depthBefore, 0));
|
|
2444
|
-
let sel = -1;
|
|
2445
|
-
tr.doc.nodesBetween(start, tr.doc.content.size, (n, pos) => {
|
|
2446
|
-
if (sel > -1) {
|
|
2447
|
-
return false;
|
|
2448
|
-
}
|
|
2449
|
-
if (n.isTextblock && n.content.size === 0) {
|
|
2450
|
-
sel = pos + 1;
|
|
2451
|
-
}
|
|
2452
|
-
});
|
|
2453
|
-
if (sel > -1) {
|
|
2454
|
-
tr.setSelection(_state.TextSelection.near(tr.doc.resolve(sel)));
|
|
2455
|
-
}
|
|
2456
|
-
tr.scrollIntoView();
|
|
2457
|
-
}
|
|
2458
|
-
return true;
|
|
2459
|
-
}
|
|
2460
|
-
const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null;
|
|
2461
|
-
const newTypeAttributes = {
|
|
2462
|
-
...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs),
|
|
2463
|
-
...overrideAttrs
|
|
2464
|
-
};
|
|
2465
|
-
const newNextTypeAttributes = {
|
|
2466
|
-
...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
|
|
2467
|
-
...overrideAttrs
|
|
2468
|
-
};
|
|
2469
|
-
tr.delete($from.pos, $to.pos);
|
|
2470
|
-
const types = nextType ? [
|
|
2471
|
-
{ type, attrs: newTypeAttributes },
|
|
2472
|
-
{ type: nextType, attrs: newNextTypeAttributes }
|
|
2473
|
-
] : [{ type, attrs: newTypeAttributes }];
|
|
2474
|
-
if (!_transform.canSplit.call(void 0, tr.doc, $from.pos, 2)) {
|
|
2475
|
-
return false;
|
|
2476
|
-
}
|
|
2477
|
-
if (dispatch) {
|
|
2478
|
-
const { selection, storedMarks } = state;
|
|
2479
|
-
const { splittableMarks } = editor.extensionManager;
|
|
2480
|
-
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
2481
|
-
tr.split($from.pos, 2, types).scrollIntoView();
|
|
2482
|
-
if (!marks || !dispatch) {
|
|
2483
|
-
return true;
|
|
2484
|
-
}
|
|
2485
|
-
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
2486
|
-
tr.ensureMarks(filteredMarks);
|
|
2487
|
-
}
|
|
2488
|
-
return true;
|
|
2489
|
-
};
|
|
2490
|
-
var joinListBackwards = (tr, listType) => {
|
|
2491
|
-
const list = findParentNode((node) => node.type === listType)(tr.selection);
|
|
2492
|
-
if (!list) {
|
|
2493
|
-
return true;
|
|
2494
|
-
}
|
|
2495
|
-
const before = tr.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth);
|
|
2496
|
-
if (before === void 0) {
|
|
2497
|
-
return true;
|
|
2498
|
-
}
|
|
2499
|
-
const nodeBefore = tr.doc.nodeAt(before);
|
|
2500
|
-
const canJoinBackwards = list.node.type === (nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.type) && _transform.canJoin.call(void 0, tr.doc, list.pos);
|
|
2501
|
-
if (!canJoinBackwards) {
|
|
2502
|
-
return true;
|
|
2503
|
-
}
|
|
2504
|
-
tr.join(list.pos);
|
|
2505
|
-
return true;
|
|
2506
|
-
};
|
|
2507
|
-
var joinListForwards = (tr, listType) => {
|
|
2508
|
-
const list = findParentNode((node) => node.type === listType)(tr.selection);
|
|
2509
|
-
if (!list) {
|
|
2510
|
-
return true;
|
|
2511
|
-
}
|
|
2512
|
-
const after = tr.doc.resolve(list.start).after(list.depth);
|
|
2513
|
-
if (after === void 0) {
|
|
2514
|
-
return true;
|
|
2515
|
-
}
|
|
2516
|
-
const nodeAfter = tr.doc.nodeAt(after);
|
|
2517
|
-
const canJoinForwards = list.node.type === (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.type) && _transform.canJoin.call(void 0, tr.doc, after);
|
|
2518
|
-
if (!canJoinForwards) {
|
|
2519
|
-
return true;
|
|
2520
|
-
}
|
|
2521
|
-
tr.join(after);
|
|
2522
|
-
return true;
|
|
2523
|
-
};
|
|
2524
|
-
var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr, state, dispatch, chain, commands: commands2, can }) => {
|
|
2525
|
-
const { extensions, splittableMarks } = editor.extensionManager;
|
|
2526
|
-
const listType = getNodeType(listTypeOrName, state.schema);
|
|
2527
|
-
const itemType = getNodeType(itemTypeOrName, state.schema);
|
|
2528
|
-
const { selection, storedMarks } = state;
|
|
2529
|
-
const { $from, $to } = selection;
|
|
2530
|
-
const range = $from.blockRange($to);
|
|
2531
|
-
const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
|
|
2532
|
-
if (!range) {
|
|
2533
|
-
return false;
|
|
2534
|
-
}
|
|
2535
|
-
const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection);
|
|
2536
|
-
if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
|
|
2537
|
-
if (parentList.node.type === listType) {
|
|
2538
|
-
return commands2.liftListItem(itemType);
|
|
2539
|
-
}
|
|
2540
|
-
if (isList(parentList.node.type.name, extensions) && listType.validContent(parentList.node.content) && dispatch) {
|
|
2541
|
-
return chain().command(() => {
|
|
2542
|
-
tr.setNodeMarkup(parentList.pos, listType);
|
|
2543
|
-
return true;
|
|
2544
|
-
}).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
|
|
2545
|
-
}
|
|
2546
|
-
}
|
|
2547
|
-
if (!keepMarks || !marks || !dispatch) {
|
|
2548
|
-
return chain().command(() => {
|
|
2549
|
-
const canWrapInList = can().wrapInList(listType, attributes);
|
|
2550
|
-
if (canWrapInList) {
|
|
2551
|
-
return true;
|
|
2552
|
-
}
|
|
2553
|
-
return commands2.clearNodes();
|
|
2554
|
-
}).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
|
|
2555
|
-
}
|
|
2556
|
-
return chain().command(() => {
|
|
2557
|
-
const canWrapInList = can().wrapInList(listType, attributes);
|
|
2558
|
-
const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
|
|
2559
|
-
tr.ensureMarks(filteredMarks);
|
|
2560
|
-
if (canWrapInList) {
|
|
2561
|
-
return true;
|
|
2562
|
-
}
|
|
2563
|
-
return commands2.clearNodes();
|
|
2564
|
-
}).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
|
|
2565
|
-
};
|
|
2566
|
-
var toggleMark = (typeOrName, attributes = {}, options = {}) => ({ state, commands: commands2 }) => {
|
|
2567
|
-
const { extendEmptyMarkRange = false } = options;
|
|
2568
|
-
const type = getMarkType(typeOrName, state.schema);
|
|
2569
|
-
const isActive = isMarkActive(state, type, attributes);
|
|
2570
|
-
if (isActive) {
|
|
2571
|
-
return commands2.unsetMark(type, { extendEmptyMarkRange });
|
|
2572
|
-
}
|
|
2573
|
-
return commands2.setMark(type, attributes);
|
|
2574
|
-
};
|
|
2575
|
-
var toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands: commands2 }) => {
|
|
2576
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2577
|
-
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
2578
|
-
const isActive = isNodeActive(state, type, attributes);
|
|
2579
|
-
let attributesToCopy;
|
|
2580
|
-
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
2581
|
-
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
2582
|
-
}
|
|
2583
|
-
if (isActive) {
|
|
2584
|
-
return commands2.setNode(toggleType, attributesToCopy);
|
|
2585
|
-
}
|
|
2586
|
-
return commands2.setNode(type, { ...attributesToCopy, ...attributes });
|
|
2587
|
-
};
|
|
2588
|
-
var toggleWrap = (typeOrName, attributes = {}) => ({ state, commands: commands2 }) => {
|
|
2589
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2590
|
-
const isActive = isNodeActive(state, type, attributes);
|
|
2591
|
-
if (isActive) {
|
|
2592
|
-
return commands2.lift(type);
|
|
2593
|
-
}
|
|
2594
|
-
return commands2.wrapIn(type, attributes);
|
|
2595
|
-
};
|
|
2596
|
-
var undoInputRule = () => ({ state, dispatch }) => {
|
|
2597
|
-
const plugins = state.plugins;
|
|
2598
|
-
for (let i = 0; i < plugins.length; i += 1) {
|
|
2599
|
-
const plugin = plugins[i];
|
|
2600
|
-
let undoable;
|
|
2601
|
-
if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
|
|
2602
|
-
if (dispatch) {
|
|
2603
|
-
const tr = state.tr;
|
|
2604
|
-
const toUndo = undoable.transform;
|
|
2605
|
-
for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
|
|
2606
|
-
tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
|
|
2607
|
-
}
|
|
2608
|
-
if (undoable.text) {
|
|
2609
|
-
const marks = tr.doc.resolve(undoable.from).marks();
|
|
2610
|
-
tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
|
|
2611
|
-
} else {
|
|
2612
|
-
tr.delete(undoable.from, undoable.to);
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
return true;
|
|
2616
|
-
}
|
|
2617
|
-
}
|
|
2618
|
-
return false;
|
|
2619
|
-
};
|
|
2620
|
-
var unsetAllMarks = () => ({ tr, dispatch }) => {
|
|
2621
|
-
const { selection } = tr;
|
|
2622
|
-
const { empty, ranges } = selection;
|
|
2623
|
-
if (empty) {
|
|
2624
|
-
return true;
|
|
2625
|
-
}
|
|
2626
|
-
if (dispatch) {
|
|
2627
|
-
ranges.forEach((range) => {
|
|
2628
|
-
tr.removeMark(range.$from.pos, range.$to.pos);
|
|
2629
|
-
});
|
|
2630
|
-
}
|
|
2631
|
-
return true;
|
|
2632
|
-
};
|
|
2633
|
-
var unsetMark = (typeOrName, options = {}) => ({ tr, state, dispatch }) => {
|
|
2634
|
-
var _a;
|
|
2635
|
-
const { extendEmptyMarkRange = false } = options;
|
|
2636
|
-
const { selection } = tr;
|
|
2637
|
-
const type = getMarkType(typeOrName, state.schema);
|
|
2638
|
-
const { $from, empty, ranges } = selection;
|
|
2639
|
-
if (!dispatch) {
|
|
2640
|
-
return true;
|
|
2641
|
-
}
|
|
2642
|
-
if (empty && extendEmptyMarkRange) {
|
|
2643
|
-
let { from, to } = selection;
|
|
2644
|
-
const attrs = (_a = $from.marks().find((mark) => mark.type === type)) === null || _a === void 0 ? void 0 : _a.attrs;
|
|
2645
|
-
const range = getMarkRange($from, type, attrs);
|
|
2646
|
-
if (range) {
|
|
2647
|
-
from = range.from;
|
|
2648
|
-
to = range.to;
|
|
2649
|
-
}
|
|
2650
|
-
tr.removeMark(from, to, type);
|
|
2651
|
-
} else {
|
|
2652
|
-
ranges.forEach((range) => {
|
|
2653
|
-
tr.removeMark(range.$from.pos, range.$to.pos, type);
|
|
2654
|
-
});
|
|
2655
|
-
}
|
|
2656
|
-
tr.removeStoredMark(type);
|
|
2657
|
-
return true;
|
|
2658
|
-
};
|
|
2659
|
-
var updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
2660
|
-
let nodeType = null;
|
|
2661
|
-
let markType = null;
|
|
2662
|
-
const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema);
|
|
2663
|
-
if (!schemaType) {
|
|
2664
|
-
return false;
|
|
2665
|
-
}
|
|
2666
|
-
if (schemaType === "node") {
|
|
2667
|
-
nodeType = getNodeType(typeOrName, state.schema);
|
|
2668
|
-
}
|
|
2669
|
-
if (schemaType === "mark") {
|
|
2670
|
-
markType = getMarkType(typeOrName, state.schema);
|
|
2671
|
-
}
|
|
2672
|
-
if (dispatch) {
|
|
2673
|
-
tr.selection.ranges.forEach((range) => {
|
|
2674
|
-
const from = range.$from.pos;
|
|
2675
|
-
const to = range.$to.pos;
|
|
2676
|
-
let lastPos;
|
|
2677
|
-
let lastNode;
|
|
2678
|
-
let trimmedFrom;
|
|
2679
|
-
let trimmedTo;
|
|
2680
|
-
if (tr.selection.empty) {
|
|
2681
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
2682
|
-
if (nodeType && nodeType === node.type) {
|
|
2683
|
-
trimmedFrom = Math.max(pos, from);
|
|
2684
|
-
trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
2685
|
-
lastPos = pos;
|
|
2686
|
-
lastNode = node;
|
|
2687
|
-
}
|
|
2688
|
-
});
|
|
2689
|
-
} else {
|
|
2690
|
-
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
2691
|
-
if (pos < from && nodeType && nodeType === node.type) {
|
|
2692
|
-
trimmedFrom = Math.max(pos, from);
|
|
2693
|
-
trimmedTo = Math.min(pos + node.nodeSize, to);
|
|
2694
|
-
lastPos = pos;
|
|
2695
|
-
lastNode = node;
|
|
2696
|
-
}
|
|
2697
|
-
if (pos >= from && pos <= to) {
|
|
2698
|
-
if (nodeType && nodeType === node.type) {
|
|
2699
|
-
tr.setNodeMarkup(pos, void 0, {
|
|
2700
|
-
...node.attrs,
|
|
2701
|
-
...attributes
|
|
2702
|
-
});
|
|
2703
|
-
}
|
|
2704
|
-
if (markType && node.marks.length) {
|
|
2705
|
-
node.marks.forEach((mark) => {
|
|
2706
|
-
if (markType === mark.type) {
|
|
2707
|
-
const trimmedFrom2 = Math.max(pos, from);
|
|
2708
|
-
const trimmedTo2 = Math.min(pos + node.nodeSize, to);
|
|
2709
|
-
tr.addMark(trimmedFrom2, trimmedTo2, markType.create({
|
|
2710
|
-
...mark.attrs,
|
|
2711
|
-
...attributes
|
|
2712
|
-
}));
|
|
2713
|
-
}
|
|
2714
|
-
});
|
|
2715
|
-
}
|
|
2716
|
-
}
|
|
2717
|
-
});
|
|
2718
|
-
}
|
|
2719
|
-
if (lastNode) {
|
|
2720
|
-
if (lastPos !== void 0) {
|
|
2721
|
-
tr.setNodeMarkup(lastPos, void 0, {
|
|
2722
|
-
...lastNode.attrs,
|
|
2723
|
-
...attributes
|
|
2724
|
-
});
|
|
2725
|
-
}
|
|
2726
|
-
if (markType && lastNode.marks.length) {
|
|
2727
|
-
lastNode.marks.forEach((mark) => {
|
|
2728
|
-
if (markType === mark.type) {
|
|
2729
|
-
tr.addMark(trimmedFrom, trimmedTo, markType.create({
|
|
2730
|
-
...mark.attrs,
|
|
2731
|
-
...attributes
|
|
2732
|
-
}));
|
|
2733
|
-
}
|
|
2734
|
-
});
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
});
|
|
2738
|
-
}
|
|
2739
|
-
return true;
|
|
2740
|
-
};
|
|
2741
|
-
var wrapIn = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
|
|
2742
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2743
|
-
return _commands.wrapIn.call(void 0, type, attributes)(state, dispatch);
|
|
2744
|
-
};
|
|
2745
|
-
var wrapInList = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
|
|
2746
|
-
const type = getNodeType(typeOrName, state.schema);
|
|
2747
|
-
return _schemalist.wrapInList.call(void 0, type, attributes)(state, dispatch);
|
|
2748
|
-
};
|
|
2749
|
-
var commands = /* @__PURE__ */ Object.freeze({
|
|
2750
|
-
__proto__: null,
|
|
2751
|
-
blur,
|
|
2752
|
-
clearContent,
|
|
2753
|
-
clearNodes,
|
|
2754
|
-
command,
|
|
2755
|
-
createParagraphNear,
|
|
2756
|
-
cut,
|
|
2757
|
-
deleteCurrentNode,
|
|
2758
|
-
deleteNode,
|
|
2759
|
-
deleteRange,
|
|
2760
|
-
deleteSelection,
|
|
2761
|
-
enter,
|
|
2762
|
-
exitCode,
|
|
2763
|
-
extendMarkRange,
|
|
2764
|
-
first,
|
|
2765
|
-
focus,
|
|
2766
|
-
forEach,
|
|
2767
|
-
insertContent,
|
|
2768
|
-
insertContentAt,
|
|
2769
|
-
joinBackward,
|
|
2770
|
-
joinDown,
|
|
2771
|
-
joinForward,
|
|
2772
|
-
joinItemBackward,
|
|
2773
|
-
joinItemForward,
|
|
2774
|
-
joinTextblockBackward,
|
|
2775
|
-
joinTextblockForward,
|
|
2776
|
-
joinUp,
|
|
2777
|
-
keyboardShortcut,
|
|
2778
|
-
lift,
|
|
2779
|
-
liftEmptyBlock,
|
|
2780
|
-
liftListItem,
|
|
2781
|
-
newlineInCode,
|
|
2782
|
-
resetAttributes,
|
|
2783
|
-
scrollIntoView,
|
|
2784
|
-
selectAll,
|
|
2785
|
-
selectNodeBackward,
|
|
2786
|
-
selectNodeForward,
|
|
2787
|
-
selectParentNode,
|
|
2788
|
-
selectTextblockEnd,
|
|
2789
|
-
selectTextblockStart,
|
|
2790
|
-
setContent,
|
|
2791
|
-
setMark,
|
|
2792
|
-
setMeta,
|
|
2793
|
-
setNode,
|
|
2794
|
-
setNodeSelection,
|
|
2795
|
-
setTextSelection,
|
|
2796
|
-
sinkListItem,
|
|
2797
|
-
splitBlock,
|
|
2798
|
-
splitListItem,
|
|
2799
|
-
toggleList,
|
|
2800
|
-
toggleMark,
|
|
2801
|
-
toggleNode,
|
|
2802
|
-
toggleWrap,
|
|
2803
|
-
undoInputRule,
|
|
2804
|
-
unsetAllMarks,
|
|
2805
|
-
unsetMark,
|
|
2806
|
-
updateAttributes,
|
|
2807
|
-
wrapIn,
|
|
2808
|
-
wrapInList
|
|
2809
|
-
});
|
|
2810
|
-
var Commands = Extension.create({
|
|
2811
|
-
name: "commands",
|
|
2812
|
-
addCommands() {
|
|
2813
|
-
return {
|
|
2814
|
-
...commands
|
|
2815
|
-
};
|
|
2816
|
-
}
|
|
2817
|
-
});
|
|
2818
|
-
var Drop = Extension.create({
|
|
2819
|
-
name: "drop",
|
|
2820
|
-
addProseMirrorPlugins() {
|
|
2821
|
-
return [
|
|
2822
|
-
new (0, _state.Plugin)({
|
|
2823
|
-
key: new (0, _state.PluginKey)("tiptapDrop"),
|
|
2824
|
-
props: {
|
|
2825
|
-
handleDrop: (_, e, slice, moved) => {
|
|
2826
|
-
this.editor.emit("drop", {
|
|
2827
|
-
editor: this.editor,
|
|
2828
|
-
event: e,
|
|
2829
|
-
slice,
|
|
2830
|
-
moved
|
|
2831
|
-
});
|
|
2832
|
-
}
|
|
2833
|
-
}
|
|
2834
|
-
})
|
|
2835
|
-
];
|
|
2836
|
-
}
|
|
2837
|
-
});
|
|
2838
|
-
var Editable = Extension.create({
|
|
2839
|
-
name: "editable",
|
|
2840
|
-
addProseMirrorPlugins() {
|
|
2841
|
-
return [
|
|
2842
|
-
new (0, _state.Plugin)({
|
|
2843
|
-
key: new (0, _state.PluginKey)("editable"),
|
|
2844
|
-
props: {
|
|
2845
|
-
editable: () => this.editor.options.editable
|
|
2846
|
-
}
|
|
2847
|
-
})
|
|
2848
|
-
];
|
|
2849
|
-
}
|
|
2850
|
-
});
|
|
2851
|
-
var FocusEvents = Extension.create({
|
|
2852
|
-
name: "focusEvents",
|
|
2853
|
-
addProseMirrorPlugins() {
|
|
2854
|
-
const { editor } = this;
|
|
2855
|
-
return [
|
|
2856
|
-
new (0, _state.Plugin)({
|
|
2857
|
-
key: new (0, _state.PluginKey)("focusEvents"),
|
|
2858
|
-
props: {
|
|
2859
|
-
handleDOMEvents: {
|
|
2860
|
-
focus: (view, event) => {
|
|
2861
|
-
editor.isFocused = true;
|
|
2862
|
-
const transaction = editor.state.tr.setMeta("focus", { event }).setMeta("addToHistory", false);
|
|
2863
|
-
view.dispatch(transaction);
|
|
2864
|
-
return false;
|
|
2865
|
-
},
|
|
2866
|
-
blur: (view, event) => {
|
|
2867
|
-
editor.isFocused = false;
|
|
2868
|
-
const transaction = editor.state.tr.setMeta("blur", { event }).setMeta("addToHistory", false);
|
|
2869
|
-
view.dispatch(transaction);
|
|
2870
|
-
return false;
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
})
|
|
2875
|
-
];
|
|
2876
|
-
}
|
|
2877
|
-
});
|
|
2878
|
-
var Keymap = Extension.create({
|
|
2879
|
-
name: "keymap",
|
|
2880
|
-
addKeyboardShortcuts() {
|
|
2881
|
-
const handleBackspace = () => this.editor.commands.first(({ commands: commands2 }) => [
|
|
2882
|
-
() => commands2.undoInputRule(),
|
|
2883
|
-
// maybe convert first text block node to default node
|
|
2884
|
-
() => commands2.command(({ tr }) => {
|
|
2885
|
-
const { selection, doc } = tr;
|
|
2886
|
-
const { empty, $anchor } = selection;
|
|
2887
|
-
const { pos, parent } = $anchor;
|
|
2888
|
-
const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor;
|
|
2889
|
-
const parentIsIsolating = $parentPos.parent.type.spec.isolating;
|
|
2890
|
-
const parentPos = $anchor.pos - $anchor.parentOffset;
|
|
2891
|
-
const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : _state.Selection.atStart(doc).from === pos;
|
|
2892
|
-
if (!empty || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") {
|
|
2893
|
-
return false;
|
|
2894
|
-
}
|
|
2895
|
-
return commands2.clearNodes();
|
|
2896
|
-
}),
|
|
2897
|
-
() => commands2.deleteSelection(),
|
|
2898
|
-
() => commands2.joinBackward(),
|
|
2899
|
-
() => commands2.selectNodeBackward()
|
|
2900
|
-
]);
|
|
2901
|
-
const handleDelete = () => this.editor.commands.first(({ commands: commands2 }) => [
|
|
2902
|
-
() => commands2.deleteSelection(),
|
|
2903
|
-
() => commands2.deleteCurrentNode(),
|
|
2904
|
-
() => commands2.joinForward(),
|
|
2905
|
-
() => commands2.selectNodeForward()
|
|
2906
|
-
]);
|
|
2907
|
-
const handleEnter = () => this.editor.commands.first(({ commands: commands2 }) => [
|
|
2908
|
-
() => commands2.newlineInCode(),
|
|
2909
|
-
() => commands2.createParagraphNear(),
|
|
2910
|
-
() => commands2.liftEmptyBlock(),
|
|
2911
|
-
() => commands2.splitBlock()
|
|
2912
|
-
]);
|
|
2913
|
-
const baseKeymap = {
|
|
2914
|
-
Enter: handleEnter,
|
|
2915
|
-
"Mod-Enter": () => this.editor.commands.exitCode(),
|
|
2916
|
-
Backspace: handleBackspace,
|
|
2917
|
-
"Mod-Backspace": handleBackspace,
|
|
2918
|
-
"Shift-Backspace": handleBackspace,
|
|
2919
|
-
Delete: handleDelete,
|
|
2920
|
-
"Mod-Delete": handleDelete,
|
|
2921
|
-
"Mod-a": () => this.editor.commands.selectAll()
|
|
2922
|
-
};
|
|
2923
|
-
const pcKeymap = {
|
|
2924
|
-
...baseKeymap
|
|
2925
|
-
};
|
|
2926
|
-
const macKeymap = {
|
|
2927
|
-
...baseKeymap,
|
|
2928
|
-
"Ctrl-h": handleBackspace,
|
|
2929
|
-
"Alt-Backspace": handleBackspace,
|
|
2930
|
-
"Ctrl-d": handleDelete,
|
|
2931
|
-
"Ctrl-Alt-Backspace": handleDelete,
|
|
2932
|
-
"Alt-Delete": handleDelete,
|
|
2933
|
-
"Alt-d": handleDelete,
|
|
2934
|
-
"Ctrl-a": () => this.editor.commands.selectTextblockStart(),
|
|
2935
|
-
"Ctrl-e": () => this.editor.commands.selectTextblockEnd()
|
|
2936
|
-
};
|
|
2937
|
-
if (isiOS() || isMacOS()) {
|
|
2938
|
-
return macKeymap;
|
|
2939
|
-
}
|
|
2940
|
-
return pcKeymap;
|
|
2941
|
-
},
|
|
2942
|
-
addProseMirrorPlugins() {
|
|
2943
|
-
return [
|
|
2944
|
-
// With this plugin we check if the whole document was selected and deleted.
|
|
2945
|
-
// In this case we will additionally call `clearNodes()` to convert e.g. a heading
|
|
2946
|
-
// to a paragraph if necessary.
|
|
2947
|
-
// This is an alternative to ProseMirror's `AllSelection`, which doesn’t work well
|
|
2948
|
-
// with many other commands.
|
|
2949
|
-
new (0, _state.Plugin)({
|
|
2950
|
-
key: new (0, _state.PluginKey)("clearDocument"),
|
|
2951
|
-
appendTransaction: (transactions, oldState, newState) => {
|
|
2952
|
-
const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
|
|
2953
|
-
const ignoreTr = transactions.some((transaction) => transaction.getMeta("preventClearDocument"));
|
|
2954
|
-
if (!docChanges || ignoreTr) {
|
|
2955
|
-
return;
|
|
2956
|
-
}
|
|
2957
|
-
const { empty, from, to } = oldState.selection;
|
|
2958
|
-
const allFrom = _state.Selection.atStart(oldState.doc).from;
|
|
2959
|
-
const allEnd = _state.Selection.atEnd(oldState.doc).to;
|
|
2960
|
-
const allWasSelected = from === allFrom && to === allEnd;
|
|
2961
|
-
if (empty || !allWasSelected) {
|
|
2962
|
-
return;
|
|
2963
|
-
}
|
|
2964
|
-
const isEmpty = isNodeEmpty(newState.doc);
|
|
2965
|
-
if (!isEmpty) {
|
|
2966
|
-
return;
|
|
2967
|
-
}
|
|
2968
|
-
const tr = newState.tr;
|
|
2969
|
-
const state = createChainableState({
|
|
2970
|
-
state: newState,
|
|
2971
|
-
transaction: tr
|
|
2972
|
-
});
|
|
2973
|
-
const { commands: commands2 } = new CommandManager({
|
|
2974
|
-
editor: this.editor,
|
|
2975
|
-
state
|
|
2976
|
-
});
|
|
2977
|
-
commands2.clearNodes();
|
|
2978
|
-
if (!tr.steps.length) {
|
|
2979
|
-
return;
|
|
2980
|
-
}
|
|
2981
|
-
return tr;
|
|
2982
|
-
}
|
|
2983
|
-
})
|
|
2984
|
-
];
|
|
2985
|
-
}
|
|
2986
|
-
});
|
|
2987
|
-
var Paste = Extension.create({
|
|
2988
|
-
name: "paste",
|
|
2989
|
-
addProseMirrorPlugins() {
|
|
2990
|
-
return [
|
|
2991
|
-
new (0, _state.Plugin)({
|
|
2992
|
-
key: new (0, _state.PluginKey)("tiptapPaste"),
|
|
2993
|
-
props: {
|
|
2994
|
-
handlePaste: (_view, e, slice) => {
|
|
2995
|
-
this.editor.emit("paste", {
|
|
2996
|
-
editor: this.editor,
|
|
2997
|
-
event: e,
|
|
2998
|
-
slice
|
|
2999
|
-
});
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
})
|
|
3003
|
-
];
|
|
3004
|
-
}
|
|
3005
|
-
});
|
|
3006
|
-
var Tabindex = Extension.create({
|
|
3007
|
-
name: "tabindex",
|
|
3008
|
-
addProseMirrorPlugins() {
|
|
3009
|
-
return [
|
|
3010
|
-
new (0, _state.Plugin)({
|
|
3011
|
-
key: new (0, _state.PluginKey)("tabindex"),
|
|
3012
|
-
props: {
|
|
3013
|
-
attributes: () => this.editor.isEditable ? { tabindex: "0" } : {}
|
|
3014
|
-
}
|
|
3015
|
-
})
|
|
3016
|
-
];
|
|
3017
|
-
}
|
|
3018
|
-
});
|
|
3019
|
-
var Node = class _Node {
|
|
3020
|
-
constructor(config = {}) {
|
|
3021
|
-
this.type = "node";
|
|
3022
|
-
this.name = "node";
|
|
3023
|
-
this.parent = null;
|
|
3024
|
-
this.child = null;
|
|
3025
|
-
this.config = {
|
|
3026
|
-
name: this.name,
|
|
3027
|
-
defaultOptions: {}
|
|
3028
|
-
};
|
|
3029
|
-
this.config = {
|
|
3030
|
-
...this.config,
|
|
3031
|
-
...config
|
|
3032
|
-
};
|
|
3033
|
-
this.name = this.config.name;
|
|
3034
|
-
if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) {
|
|
3035
|
-
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`);
|
|
3036
|
-
}
|
|
3037
|
-
this.options = this.config.defaultOptions;
|
|
3038
|
-
if (this.config.addOptions) {
|
|
3039
|
-
this.options = callOrReturn(getExtensionField(this, "addOptions", {
|
|
3040
|
-
name: this.name
|
|
3041
|
-
}));
|
|
3042
|
-
}
|
|
3043
|
-
this.storage = callOrReturn(getExtensionField(this, "addStorage", {
|
|
3044
|
-
name: this.name,
|
|
3045
|
-
options: this.options
|
|
3046
|
-
})) || {};
|
|
3047
|
-
}
|
|
3048
|
-
static create(config = {}) {
|
|
3049
|
-
return new _Node(config);
|
|
3050
|
-
}
|
|
3051
|
-
configure(options = {}) {
|
|
3052
|
-
const extension = this.extend({
|
|
3053
|
-
...this.config,
|
|
3054
|
-
addOptions: () => {
|
|
3055
|
-
return mergeDeep(this.options, options);
|
|
3056
|
-
}
|
|
3057
|
-
});
|
|
3058
|
-
extension.name = this.name;
|
|
3059
|
-
extension.parent = this.parent;
|
|
3060
|
-
return extension;
|
|
3061
|
-
}
|
|
3062
|
-
extend(extendedConfig = {}) {
|
|
3063
|
-
const extension = new _Node(extendedConfig);
|
|
3064
|
-
extension.parent = this;
|
|
3065
|
-
this.child = extension;
|
|
3066
|
-
extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name;
|
|
3067
|
-
if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {
|
|
3068
|
-
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`);
|
|
3069
|
-
}
|
|
3070
|
-
extension.options = callOrReturn(getExtensionField(extension, "addOptions", {
|
|
3071
|
-
name: extension.name
|
|
3072
|
-
}));
|
|
3073
|
-
extension.storage = callOrReturn(getExtensionField(extension, "addStorage", {
|
|
3074
|
-
name: extension.name,
|
|
3075
|
-
options: extension.options
|
|
3076
|
-
}));
|
|
3077
|
-
return extension;
|
|
3078
|
-
}
|
|
3079
|
-
};
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { detectDupes } from "@liveblocks/core";
|
|
3080
3
|
|
|
3081
|
-
// src/
|
|
4
|
+
// src/version.ts
|
|
5
|
+
var PKG_NAME = "@liveblocks/node-prosemirror";
|
|
6
|
+
var PKG_VERSION = "2.18.4-uns2";
|
|
7
|
+
var PKG_FORMAT = "esm";
|
|
3082
8
|
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
9
|
+
// src/document.ts
|
|
10
|
+
import { getSchema, getText } from "@tiptap/core";
|
|
11
|
+
import { EditorState } from "@tiptap/pm/state";
|
|
12
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
13
|
+
import { defaultMarkdownSerializer } from "prosemirror-markdown";
|
|
14
|
+
import { initProseMirrorDoc, updateYFragment } from "y-prosemirror";
|
|
15
|
+
import { applyUpdate, Doc, encodeStateAsUpdate, encodeStateVector } from "yjs";
|
|
3087
16
|
|
|
3088
17
|
// src/comment.ts
|
|
18
|
+
import { Mark, mergeAttributes } from "@tiptap/core";
|
|
3089
19
|
var LIVEBLOCKS_COMMENT_MARK_TYPE = "liveblocksCommentMark";
|
|
3090
20
|
var CommentExtension = Mark.create({
|
|
3091
21
|
name: LIVEBLOCKS_COMMENT_MARK_TYPE,
|
|
@@ -3125,6 +55,7 @@ var CommentExtension = Mark.create({
|
|
|
3125
55
|
});
|
|
3126
56
|
|
|
3127
57
|
// src/mention.ts
|
|
58
|
+
import { mergeAttributes as mergeAttributes2, Node } from "@tiptap/core";
|
|
3128
59
|
var LIVEBLOCKS_MENTION_TYPE = "liveblocksMention";
|
|
3129
60
|
var MentionExtension = Node.create({
|
|
3130
61
|
name: LIVEBLOCKS_MENTION_TYPE,
|
|
@@ -3141,7 +72,7 @@ var MentionExtension = Node.create({
|
|
|
3141
72
|
];
|
|
3142
73
|
},
|
|
3143
74
|
renderHTML({ HTMLAttributes }) {
|
|
3144
|
-
return ["liveblocks-mention",
|
|
75
|
+
return ["liveblocks-mention", mergeAttributes2(HTMLAttributes)];
|
|
3145
76
|
},
|
|
3146
77
|
addAttributes() {
|
|
3147
78
|
return {
|
|
@@ -3177,7 +108,7 @@ var MentionExtension = Node.create({
|
|
|
3177
108
|
|
|
3178
109
|
// src/document.ts
|
|
3179
110
|
var DEFAULT_SCHEMA = getSchema([
|
|
3180
|
-
|
|
111
|
+
StarterKit,
|
|
3181
112
|
CommentExtension,
|
|
3182
113
|
MentionExtension
|
|
3183
114
|
]);
|
|
@@ -3185,11 +116,11 @@ var getLiveblocksDocumentState = async (roomId, client, schema, field) => {
|
|
|
3185
116
|
const update = new Uint8Array(
|
|
3186
117
|
await client.getYjsDocumentAsBinaryUpdate(roomId)
|
|
3187
118
|
);
|
|
3188
|
-
const ydoc = new
|
|
3189
|
-
|
|
3190
|
-
const fragment = ydoc.getXmlFragment(
|
|
3191
|
-
const { mapping, doc } =
|
|
3192
|
-
const state =
|
|
119
|
+
const ydoc = new Doc();
|
|
120
|
+
applyUpdate(ydoc, update);
|
|
121
|
+
const fragment = ydoc.getXmlFragment(field ?? "default");
|
|
122
|
+
const { mapping, doc } = initProseMirrorDoc(fragment, schema);
|
|
123
|
+
const state = EditorState.create({
|
|
3193
124
|
schema,
|
|
3194
125
|
doc
|
|
3195
126
|
});
|
|
@@ -3215,12 +146,12 @@ var createDocumentFromContent = (content, schema) => {
|
|
|
3215
146
|
}
|
|
3216
147
|
};
|
|
3217
148
|
async function withProsemirrorDocument({ roomId, schema: maybeSchema, client, field }, callback) {
|
|
3218
|
-
const schema =
|
|
149
|
+
const schema = maybeSchema ?? DEFAULT_SCHEMA;
|
|
3219
150
|
let liveblocksState = await getLiveblocksDocumentState(
|
|
3220
151
|
roomId,
|
|
3221
152
|
client,
|
|
3222
153
|
schema,
|
|
3223
|
-
|
|
154
|
+
field ?? "default"
|
|
3224
155
|
);
|
|
3225
156
|
const val = await callback({
|
|
3226
157
|
/**
|
|
@@ -3231,7 +162,7 @@ async function withProsemirrorDocument({ roomId, schema: maybeSchema, client, fi
|
|
|
3231
162
|
roomId,
|
|
3232
163
|
client,
|
|
3233
164
|
schema,
|
|
3234
|
-
|
|
165
|
+
field ?? "default"
|
|
3235
166
|
);
|
|
3236
167
|
},
|
|
3237
168
|
/**
|
|
@@ -3239,12 +170,12 @@ async function withProsemirrorDocument({ roomId, schema: maybeSchema, client, fi
|
|
|
3239
170
|
*/
|
|
3240
171
|
async update(modifyFn) {
|
|
3241
172
|
const { ydoc, fragment, state, mapping } = liveblocksState;
|
|
3242
|
-
const beforeVector =
|
|
173
|
+
const beforeVector = encodeStateVector(ydoc);
|
|
3243
174
|
const afterState = state.apply(modifyFn(state.doc, state.tr));
|
|
3244
175
|
ydoc.transact(() => {
|
|
3245
|
-
|
|
176
|
+
updateYFragment(ydoc, fragment, afterState.doc, mapping);
|
|
3246
177
|
});
|
|
3247
|
-
const diffUpdate =
|
|
178
|
+
const diffUpdate = encodeStateAsUpdate(ydoc, beforeVector);
|
|
3248
179
|
await client.sendYjsBinaryUpdate(roomId, diffUpdate);
|
|
3249
180
|
await this.refresh();
|
|
3250
181
|
},
|
|
@@ -3296,7 +227,7 @@ async function withProsemirrorDocument({ roomId, schema: maybeSchema, client, fi
|
|
|
3296
227
|
* Helper function to return editor state as Markdown. By default it uses the defaultMarkdownSerializer from prosemirror-markdown, but you may pass your own
|
|
3297
228
|
*/
|
|
3298
229
|
toMarkdown(serializer) {
|
|
3299
|
-
return (
|
|
230
|
+
return (serializer ?? defaultMarkdownSerializer).serialize(
|
|
3300
231
|
liveblocksState.state.doc
|
|
3301
232
|
);
|
|
3302
233
|
},
|
|
@@ -3311,8 +242,8 @@ async function withProsemirrorDocument({ roomId, schema: maybeSchema, client, fi
|
|
|
3311
242
|
}
|
|
3312
243
|
|
|
3313
244
|
// src/index.ts
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
245
|
+
detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
246
|
+
export {
|
|
247
|
+
withProsemirrorDocument
|
|
248
|
+
};
|
|
3318
249
|
//# sourceMappingURL=index.js.map
|