@prosekit/core 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,863 @@
1
+ // src/error.ts
2
+ var ProseKitError = class extends Error {
3
+ }, EditorNotFoundError = class extends ProseKitError {
4
+ constructor() {
5
+ super(
6
+ "Unable to find editor. Pass it as an argument or call this function inside a ProseKit component."
7
+ );
8
+ }
9
+ }, DOMDocumentNotFoundError = class extends ProseKitError {
10
+ constructor() {
11
+ super(
12
+ "Unable to find browser Document. When not in the browser environment, you need to pass a DOM Document."
13
+ );
14
+ }
15
+ };
16
+
17
+ // src/utils/get-mark-type.ts
18
+ import "@prosekit/pm/model";
19
+ function getMarkType(schema, type) {
20
+ if (typeof type == "string") {
21
+ let markType = schema.marks[type];
22
+ if (!markType)
23
+ throw new ProseKitError(`Cannot find mark type "${type}"`);
24
+ return markType;
25
+ }
26
+ return type;
27
+ }
28
+
29
+ // src/utils/assert.ts
30
+ function assert(condition, message = "Assertion failed") {
31
+ if (!condition)
32
+ throw new ProseKitError(message);
33
+ }
34
+
35
+ // src/utils/get-node-type.ts
36
+ import "@prosekit/pm/model";
37
+ function getNodeType(schema, type) {
38
+ if (typeof type == "string") {
39
+ let nodeType = schema.nodes[type];
40
+ if (!nodeType)
41
+ throw new ProseKitError(`Cannot find ProseMirror node type "${type}"`);
42
+ return nodeType;
43
+ }
44
+ return type;
45
+ }
46
+
47
+ // src/types/priority.ts
48
+ var Priority = /* @__PURE__ */ ((Priority2) => (Priority2[Priority2.lowest = 0] = "lowest", Priority2[Priority2.low = 1] = "low", Priority2[Priority2.default = 2] = "default", Priority2[Priority2.high = 3] = "high", Priority2[Priority2.highest = 4] = "highest", Priority2))(Priority || {});
49
+
50
+ // src/facets/facet.ts
51
+ var facetCount = 0, Facet = class {
52
+ /**
53
+ * @internal
54
+ */
55
+ constructor(parent, singleton, _reducer, _reduce) {
56
+ this._reducer = _reducer;
57
+ this._reduce = _reduce;
58
+ /**
59
+ * @internal
60
+ */
61
+ this.index = facetCount++;
62
+ assert((_reduce || _reducer) && !(_reduce && _reducer)), this.parent = parent, this.singleton = singleton, this.path = parent ? [...parent.path, this.index] : [];
63
+ }
64
+ get reducer() {
65
+ var _a, _b;
66
+ return (_b = this._reducer) != null ? _b : (_a = this._reduce) == null ? void 0 : _a.call(this);
67
+ }
68
+ };
69
+ function defineFacet(options) {
70
+ var _a;
71
+ return new Facet(
72
+ options.parent,
73
+ (_a = options.singleton) != null ? _a : !1,
74
+ options.reducer,
75
+ options.reduce
76
+ );
77
+ }
78
+
79
+ // src/facets/base-extension.ts
80
+ import "@prosekit/pm/model";
81
+
82
+ // src/utils/array.ts
83
+ function uniqPush(prev, next) {
84
+ let result = [...prev];
85
+ for (let item of next)
86
+ result.includes(item) || result.push(item);
87
+ return result;
88
+ }
89
+ function arraySubstract(a, b) {
90
+ return a.filter((x) => !b.includes(x));
91
+ }
92
+ function toReversed(arr) {
93
+ var _a, _b;
94
+ return (_b = (_a = arr.toReversed) == null ? void 0 : _a.call(arr)) != null ? _b : [...arr].reverse();
95
+ }
96
+
97
+ // src/utils/is-not-null.ts
98
+ function isNotNull(value) {
99
+ return value != null;
100
+ }
101
+
102
+ // src/facets/facet-node.ts
103
+ function zip5(a, b, mapper) {
104
+ return [
105
+ mapper(a[0], b[0]),
106
+ mapper(a[1], b[1]),
107
+ mapper(a[2], b[2]),
108
+ mapper(a[3], b[3]),
109
+ mapper(a[4], b[4])
110
+ ];
111
+ }
112
+ function unionInput(a, b) {
113
+ return !a && !b ? null : uniqPush(a != null ? a : [], b != null ? b : []);
114
+ }
115
+ function subtractInput(a, b) {
116
+ return a ? b ? arraySubstract(a, b) : [...a] : null;
117
+ }
118
+ function unionChildren(a, b) {
119
+ let merged = new Map(a);
120
+ for (let [key, valueB] of b.entries()) {
121
+ let valueA = a.get(key);
122
+ merged.set(key, valueA ? unionFacetNode(valueA, valueB) : valueB);
123
+ }
124
+ return merged;
125
+ }
126
+ function subtractChildren(a, b) {
127
+ let merged = new Map(a);
128
+ for (let [key, valueB] of b.entries()) {
129
+ let valueA = a.get(key);
130
+ valueA && merged.set(key, subtractFacetNode(valueA, valueB));
131
+ }
132
+ return merged;
133
+ }
134
+ function unionFacetNode(a, b) {
135
+ return assert(a.facet === b.facet), new FacetNode(
136
+ a.facet,
137
+ zip5(a.inputs, b.inputs, unionInput),
138
+ unionChildren(a.children, b.children),
139
+ a.reducers
140
+ );
141
+ }
142
+ function subtractFacetNode(a, b) {
143
+ return assert(a.facet === b.facet), new FacetNode(
144
+ a.facet,
145
+ zip5(a.inputs, b.inputs, subtractInput),
146
+ subtractChildren(a.children, b.children),
147
+ a.reducers
148
+ );
149
+ }
150
+ var FacetNode = class {
151
+ constructor(facet, inputs = [null, null, null, null, null], children = /* @__PURE__ */ new Map(), reducers = [
152
+ null,
153
+ null,
154
+ null,
155
+ null,
156
+ null
157
+ ]) {
158
+ this.facet = facet;
159
+ this.inputs = inputs;
160
+ this.children = children;
161
+ this.reducers = reducers;
162
+ this.output = null;
163
+ }
164
+ calcOutput() {
165
+ var _a, _b, _c;
166
+ let inputs = [null, null, null, null, null], output = [null, null, null, null, null];
167
+ for (let pri = 0; pri < 5; pri++) {
168
+ let input = this.inputs[pri];
169
+ input && (inputs[pri] = [...input]);
170
+ }
171
+ for (let child of this.children.values()) {
172
+ let childOutput = child.getOutput();
173
+ for (let pri = 0; pri < 5; pri++)
174
+ childOutput[pri] && (inputs[pri] || (inputs[pri] = [])).push(childOutput[pri]);
175
+ }
176
+ if (this.facet.singleton) {
177
+ let reducer = (_a = this.reducers)[_b = 2 /* default */] || (_a[_b] = this.facet.reducer), input = inputs.filter(isNotNull).flat();
178
+ output[2 /* default */] = reducer(input);
179
+ } else
180
+ for (let pri = 0; pri < 5; pri++) {
181
+ let input = inputs[pri];
182
+ if (input) {
183
+ let reducer = (_c = this.reducers)[pri] || (_c[pri] = this.facet.reducer);
184
+ output[pri] = reducer(input);
185
+ }
186
+ }
187
+ return output;
188
+ }
189
+ getOutput() {
190
+ return this.output || (this.output = this.calcOutput()), this.output;
191
+ }
192
+ getSingletonOutput() {
193
+ return assert(this.facet.singleton), this.getOutput()[2 /* default */];
194
+ }
195
+ getRootOutput() {
196
+ assert(this.isRoot());
197
+ let output = this.getSingletonOutput();
198
+ return assert(output), output;
199
+ }
200
+ isRoot() {
201
+ return !this.facet.parent;
202
+ }
203
+ };
204
+
205
+ // src/facets/schema.ts
206
+ import { Schema as Schema3 } from "@prosekit/pm/model";
207
+
208
+ // src/facets/root.ts
209
+ function rootReducer(inputs) {
210
+ var _a;
211
+ let schema, commands, stateFunc, view;
212
+ for (let input of inputs)
213
+ schema = input.schema || schema, commands = input.commands || commands, stateFunc = input.state || stateFunc, view = input.view || view;
214
+ let state = schema && ((_a = stateFunc == null ? void 0 : stateFunc({ schema })) != null ? _a : { schema });
215
+ return { schema, state, commands, view };
216
+ }
217
+ var rootFacet = new Facet(
218
+ null,
219
+ !0,
220
+ rootReducer
221
+ );
222
+
223
+ // src/facets/schema.ts
224
+ var schemaFacet = defineFacet({
225
+ reducer: (specs) => {
226
+ assert(specs.length <= 1);
227
+ let spec = specs[0];
228
+ return { schema: spec ? new Schema3(spec) : null };
229
+ },
230
+ parent: rootFacet,
231
+ singleton: !0
232
+ });
233
+
234
+ // src/facets/base-extension.ts
235
+ var BaseExtension = class {
236
+ constructor() {
237
+ this.extension = [];
238
+ this.trees = [null, null, null, null, null];
239
+ }
240
+ /**
241
+ * @internal
242
+ */
243
+ getTree(priority) {
244
+ var _a, _b;
245
+ let pri = (_a = priority != null ? priority : this.priority) != null ? _a : 2 /* default */;
246
+ return (_b = this.trees)[pri] || (_b[pri] = this.createTree(pri));
247
+ }
248
+ /**
249
+ * @internal
250
+ */
251
+ findFacetOutput(facet) {
252
+ var _a;
253
+ let node = this.getTree();
254
+ for (let index of facet.path)
255
+ node = node == null ? void 0 : node.children.get(index);
256
+ return (_a = node == null ? void 0 : node.getOutput()) != null ? _a : null;
257
+ }
258
+ get schema() {
259
+ var _a, _b;
260
+ let output = this.findFacetOutput(schemaFacet);
261
+ return (_b = (_a = output == null ? void 0 : output.find(Boolean)) == null ? void 0 : _a.schema) != null ? _b : null;
262
+ }
263
+ };
264
+
265
+ // src/facets/facet-extension.ts
266
+ var FacetExtensionImpl = class extends BaseExtension {
267
+ /**
268
+ * @internal
269
+ */
270
+ constructor(facet, payloads) {
271
+ super();
272
+ this.facet = facet;
273
+ this.payloads = payloads;
274
+ }
275
+ /**
276
+ * @internal
277
+ */
278
+ createTree(priority) {
279
+ var _a;
280
+ let pri = (_a = this.priority) != null ? _a : priority, inputs = [null, null, null, null, null];
281
+ inputs[pri] = [...this.payloads];
282
+ let node = new FacetNode(this.facet, inputs);
283
+ for (; node.facet.parent; ) {
284
+ let children = /* @__PURE__ */ new Map([[node.facet.index, node]]);
285
+ node = new FacetNode(node.facet.parent, void 0, children);
286
+ }
287
+ return node;
288
+ }
289
+ };
290
+ function defineFacetPayload(facet, payloads) {
291
+ return new FacetExtensionImpl(facet, payloads);
292
+ }
293
+
294
+ // src/utils/parse.ts
295
+ import { DOMParser, DOMSerializer } from "@prosekit/pm/model";
296
+ import { EditorState } from "@prosekit/pm/state";
297
+
298
+ // src/utils/get-dom-api.ts
299
+ function findGlobalBrowserDocument() {
300
+ if (typeof document != "undefined")
301
+ return document;
302
+ if (typeof globalThis != "undefined" && globalThis.document)
303
+ return globalThis.document;
304
+ }
305
+ function findGlobalBrowserWindow() {
306
+ if (typeof window != "undefined")
307
+ return window;
308
+ if (typeof globalThis != "undefined" && globalThis.window)
309
+ return globalThis.window;
310
+ }
311
+ function findBrowserDocument(options) {
312
+ var _a, _b, _c;
313
+ return (_c = (_a = options == null ? void 0 : options.document) != null ? _a : findGlobalBrowserDocument()) != null ? _c : (_b = findGlobalBrowserWindow()) == null ? void 0 : _b.document;
314
+ }
315
+ function findBrowserWindow(options) {
316
+ var _a, _b, _c, _d;
317
+ return (_d = (_b = (_a = options == null ? void 0 : options.document) == null ? void 0 : _a.defaultView) != null ? _b : findGlobalBrowserWindow()) != null ? _d : (_c = findBrowserDocument(options)) == null ? void 0 : _c.defaultView;
318
+ }
319
+ function getBrowserDocument(options) {
320
+ let doc = findBrowserDocument(options);
321
+ if (doc) return doc;
322
+ throw new DOMDocumentNotFoundError();
323
+ }
324
+ function getBrowserWindow(options) {
325
+ let win = findBrowserWindow(options);
326
+ if (win) return win;
327
+ throw new DOMDocumentNotFoundError();
328
+ }
329
+
330
+ // src/utils/parse.ts
331
+ function jsonFromState(state) {
332
+ return state.toJSON();
333
+ }
334
+ function stateFromJSON(json, options) {
335
+ return EditorState.fromJSON({ schema: options.schema }, json);
336
+ }
337
+ function jsonFromNode(node) {
338
+ return node.toJSON();
339
+ }
340
+ function nodeFromJSON(json, options) {
341
+ return options.schema.nodeFromJSON(json);
342
+ }
343
+ function nodeFromElement(element, options) {
344
+ let { DOMParser: CustomDOMParser, schema, ...parseOptions } = options;
345
+ return (CustomDOMParser || DOMParser).fromSchema(schema).parse(element, parseOptions);
346
+ }
347
+ function elementFromNode(node, options) {
348
+ let Serializer = (options == null ? void 0 : options.DOMSerializer) || DOMSerializer, document2 = getBrowserDocument(options), schema = node.type.schema, serializer = Serializer.fromSchema(schema);
349
+ return schema.topNodeType !== node.type ? serializer.serializeNode(node, { document: document2 }) : serializer.serializeFragment(
350
+ node.content,
351
+ { document: document2 },
352
+ document2.createElement("div")
353
+ );
354
+ }
355
+ function elementFromHTML(html, options) {
356
+ let win = getBrowserWindow(options);
357
+ return new win.DOMParser().parseFromString(`<body><div>${html}</div></body>`, "text/html").body.firstElementChild;
358
+ }
359
+ function htmlFromElement(element) {
360
+ return element.outerHTML;
361
+ }
362
+ function nodeFromHTML(html, options) {
363
+ return nodeFromElement(elementFromHTML(html, options), options);
364
+ }
365
+ function htmlFromNode(node, options) {
366
+ return elementFromNode(node, options).outerHTML;
367
+ }
368
+ function jsonFromElement(element, options) {
369
+ return jsonFromNode(nodeFromElement(element, options));
370
+ }
371
+ function elementFromJSON(json, options) {
372
+ return elementFromNode(nodeFromJSON(json, options), options);
373
+ }
374
+ function jsonFromHTML(html, options) {
375
+ return jsonFromElement(elementFromHTML(html, options), options);
376
+ }
377
+ function htmlFromJSON(json, options) {
378
+ return htmlFromElement(elementFromJSON(json, options));
379
+ }
380
+
381
+ // src/extensions/default-state.ts
382
+ import { Selection } from "@prosekit/pm/state";
383
+
384
+ // src/facets/state.ts
385
+ var stateFacet = defineFacet({
386
+ reduce: () => {
387
+ let callbacks = [], state = (ctx) => {
388
+ var _a, _b, _c, _d, _e, _f;
389
+ let configs = callbacks.map((cb) => cb(ctx)), config = {
390
+ schema: ctx.schema,
391
+ storedMarks: [],
392
+ plugins: []
393
+ };
394
+ for (let c of configs)
395
+ config.schema = (_a = config.schema) != null ? _a : c.schema, config.doc = (_b = config.doc) != null ? _b : c.doc, config.selection = (_c = config.selection) != null ? _c : c.selection, config.storedMarks = [...config.storedMarks, ...(_d = c.storedMarks) != null ? _d : []], config.plugins = uniqPush((_e = config.plugins) != null ? _e : [], (_f = c.plugins) != null ? _f : []);
396
+ return assert(
397
+ config.doc || config.schema,
398
+ "Can't create state without a schema nor a document"
399
+ ), config.doc && (config.schema = void 0), config;
400
+ };
401
+ return function(inputs) {
402
+ return callbacks = inputs, { state };
403
+ };
404
+ },
405
+ singleton: !0,
406
+ parent: rootFacet
407
+ });
408
+
409
+ // src/extensions/default-state.ts
410
+ function defineDefaultState({
411
+ defaultDoc,
412
+ defaultHTML,
413
+ defaultSelection
414
+ }) {
415
+ if (defaultHTML && defaultDoc)
416
+ throw new ProseKitError(
417
+ "Only one of defaultHTML and defaultDoc can be provided"
418
+ );
419
+ return defineFacetPayload(stateFacet, [
420
+ ({ schema }) => {
421
+ let config = {};
422
+ return defaultHTML && (typeof defaultHTML == "string" ? defaultDoc = jsonFromHTML(defaultHTML, { schema }) : defaultDoc = jsonFromElement(defaultHTML, { schema })), defaultDoc && (config.doc = schema.nodeFromJSON(defaultDoc), defaultSelection && (config.selection = Selection.fromJSON(config.doc, defaultSelection))), config;
423
+ }
424
+ ]);
425
+ }
426
+
427
+ // src/utils/is-mark-absent.ts
428
+ function isMarkAbsent(node, from, to, markType, attrs) {
429
+ let mark = attrs ? markType.create(attrs) : markType, missing = !1;
430
+ return node.nodesBetween(from, to, (node2, pos, parent) => {
431
+ if (missing) return !1;
432
+ missing = !mark.isInSet(node2.marks) && !!parent && parent.type.allowsMarkType(markType);
433
+ }), missing;
434
+ }
435
+
436
+ // src/utils/is-mark-active.ts
437
+ function isMarkActive(state, type, attrs) {
438
+ let { from, $from, to, empty } = state.selection, markType = getMarkType(state.schema, type);
439
+ return empty ? !!(attrs ? markType.create(attrs) : markType).isInSet(state.storedMarks || $from.marks()) : !isMarkAbsent(state.doc, from, to, markType, attrs);
440
+ }
441
+
442
+ // src/utils/type-assertion.ts
443
+ import { Mark, ProseMirrorNode } from "@prosekit/pm/model";
444
+ import {
445
+ AllSelection,
446
+ NodeSelection,
447
+ TextSelection
448
+ } from "@prosekit/pm/state";
449
+ function isProseMirrorNode(node) {
450
+ return node instanceof ProseMirrorNode;
451
+ }
452
+ function isMark(mark) {
453
+ return mark instanceof Mark;
454
+ }
455
+ function isTextSelection(sel) {
456
+ return sel instanceof TextSelection;
457
+ }
458
+ function isNodeSelection(sel) {
459
+ return sel instanceof NodeSelection;
460
+ }
461
+ function isAllSelection(sel) {
462
+ return sel instanceof AllSelection;
463
+ }
464
+
465
+ // src/facets/union-extension.ts
466
+ var UnionExtensionImpl = class extends BaseExtension {
467
+ /**
468
+ * @internal
469
+ */
470
+ constructor(extension = []) {
471
+ super();
472
+ this.extension = extension;
473
+ }
474
+ /**
475
+ * @internal
476
+ */
477
+ createTree(priority) {
478
+ var _a;
479
+ let pri = (_a = this.priority) != null ? _a : priority, extensions = [...this.extension];
480
+ extensions.sort((a, b) => {
481
+ var _a2, _b;
482
+ return ((_a2 = a.priority) != null ? _a2 : pri) - ((_b = b.priority) != null ? _b : pri);
483
+ });
484
+ let children = extensions.map((ext) => ext.getTree(pri));
485
+ assert(children.length > 0);
486
+ let node = children[0];
487
+ for (let i = 1; i < children.length; i++)
488
+ node = unionFacetNode(node, children[i]);
489
+ return node;
490
+ }
491
+ };
492
+
493
+ // src/editor/union.ts
494
+ function union(extension) {
495
+ let array = Array.isArray(extension) ? extension : [extension];
496
+ return assert(array.length > 0, "At least one extension is required"), new UnionExtensionImpl(
497
+ array
498
+ );
499
+ }
500
+
501
+ // src/editor/editor.ts
502
+ import "@prosekit/pm/model";
503
+ import { EditorState as EditorState2 } from "@prosekit/pm/state";
504
+ import { EditorView } from "@prosekit/pm/view";
505
+
506
+ // src/utils/deep-equals.ts
507
+ import OrderedMap from "orderedmap";
508
+ function deepEquals(a, b) {
509
+ if (a === b)
510
+ return !0;
511
+ if (!a || !b)
512
+ return !1;
513
+ if (Array.isArray(a) && Array.isArray(b))
514
+ return a.length === b.length && a.every((x, i) => deepEquals(x, b[i]));
515
+ if (a instanceof OrderedMap && b instanceof OrderedMap)
516
+ return a.size === b.size && deepEquals(a.toObject(), b.toObject());
517
+ if (typeof a == "object" && typeof b == "object") {
518
+ let aKeys = Object.keys(a), bKeys = Object.keys(b);
519
+ return aKeys.length === bKeys.length && aKeys.every((key) => deepEquals(a[key], b[key]));
520
+ }
521
+ return !1;
522
+ }
523
+
524
+ // src/editor/builder.ts
525
+ import "@prosekit/pm/model";
526
+
527
+ // src/utils/attrs-match.ts
528
+ function attrsMatch(nodeOrMark, attrs) {
529
+ let currentAttrs = nodeOrMark.attrs;
530
+ for (let [key, value] of Object.entries(attrs))
531
+ if (currentAttrs[key] !== value)
532
+ return !1;
533
+ return !0;
534
+ }
535
+
536
+ // src/utils/is-node-active.ts
537
+ function isNodeActive(state, type, attrs) {
538
+ let $pos = state.selection.$from, nodeType = getNodeType(state.schema, type);
539
+ for (let depth = $pos.depth; depth >= 0; depth--) {
540
+ let node = $pos.node(depth);
541
+ if (node.type === nodeType && (!attrs || attrsMatch(node, attrs)))
542
+ return !0;
543
+ }
544
+ return !1;
545
+ }
546
+
547
+ // src/editor/builder.ts
548
+ function createNodeBuilders(schema, getState, createNode = defaultCreateNode) {
549
+ let builders = {};
550
+ for (let type of Object.values(schema.nodes)) {
551
+ let builder = (...args) => buildNode(type, args, createNode);
552
+ builder.isActive = (attrs) => {
553
+ let state = getState();
554
+ return state ? isNodeActive(state, type, attrs) : !1;
555
+ }, builders[type.name] = builder;
556
+ }
557
+ return builders;
558
+ }
559
+ function createMarkBuilders(schema, getState, applyMark = defaultApplyMark) {
560
+ let builders = {};
561
+ for (let type of Object.values(schema.marks)) {
562
+ let builder = (...args) => buildMark(type, args, applyMark);
563
+ builder.isActive = (attrs) => {
564
+ let state = getState();
565
+ return state ? isMarkActive(state, type, attrs) : !1;
566
+ }, builders[type.name] = builder;
567
+ }
568
+ return builders;
569
+ }
570
+ function buildMark(type, args, applyMark) {
571
+ let [attrs, children] = normalizeArgs(args), mark = type.create(attrs);
572
+ return applyMark(mark, flattenChildren(type.schema, children));
573
+ }
574
+ var defaultApplyMark = (mark, children) => children.map((child) => child.mark([mark]));
575
+ function buildNode(type, args, createNode) {
576
+ let [attrs, children] = normalizeArgs(args);
577
+ return createNode(type, attrs, flattenChildren(type.schema, children));
578
+ }
579
+ var defaultCreateNode = (type, attrs, children) => {
580
+ let node = type.createAndFill(attrs, children);
581
+ return assert(node, `Failed to create node ${type.name}`), node;
582
+ };
583
+ function flattenChildren(schema, children) {
584
+ let nodes = [];
585
+ for (let child of children)
586
+ if (typeof child == "string")
587
+ child && nodes.push(schema.text(child, null));
588
+ else if (Array.isArray(child))
589
+ nodes.push(...flattenChildren(schema, child));
590
+ else if (isProseMirrorNode(child))
591
+ nodes.push(child);
592
+ else
593
+ throw new ProseKitError(`Invalid node child: ${typeof child}`);
594
+ return nodes;
595
+ }
596
+ function normalizeArgs(args) {
597
+ let [attrs, ...children] = args;
598
+ return isNodeChild(attrs) ? (children.unshift(attrs), [null, children]) : typeof attrs == "object" ? [attrs, children] : [null, children];
599
+ }
600
+ function isNodeChild(value) {
601
+ return value ? typeof value == "string" || Array.isArray(value) || isProseMirrorNode(value) : !1;
602
+ }
603
+
604
+ // src/editor/editor.ts
605
+ function setupEditorExtension(options) {
606
+ let { defaultDoc, defaultHTML, defaultSelection } = options;
607
+ return defaultDoc || defaultHTML ? union([
608
+ options.extension,
609
+ defineDefaultState({
610
+ defaultDoc,
611
+ defaultHTML,
612
+ defaultSelection
613
+ })
614
+ ]) : options.extension;
615
+ }
616
+ function createEditor(options) {
617
+ let extension = setupEditorExtension(options);
618
+ return Editor.create(new EditorInstance(extension));
619
+ }
620
+ var EditorInstance = class {
621
+ constructor(extension) {
622
+ this.view = null;
623
+ this.commandAppliers = {};
624
+ this.getState = () => {
625
+ var _a;
626
+ return ((_a = this.view) == null ? void 0 : _a.state) || this.directEditorProps.state;
627
+ };
628
+ this.tree = extension.getTree();
629
+ let payload = this.tree.getRootOutput(), schema = payload.schema, stateConfig = payload.state;
630
+ assert(schema && stateConfig, "Schema must be defined");
631
+ let state = EditorState2.create(stateConfig);
632
+ if (payload.commands)
633
+ for (let [name, commandCreator] of Object.entries(payload.commands))
634
+ this.defineCommand(name, commandCreator);
635
+ this.nodeBuilders = createNodeBuilders(state.schema, this.getState), this.markBuilders = createMarkBuilders(state.schema, this.getState), this.schema = state.schema, this.directEditorProps = { state, ...payload.view };
636
+ }
637
+ updateState(state) {
638
+ this.view ? this.view.updateState(state) : this.directEditorProps.state = state;
639
+ }
640
+ updateExtension(extension, add) {
641
+ var _a, _b, _c, _d;
642
+ let view = this.view;
643
+ if (!view || view.isDestroyed)
644
+ return;
645
+ let tree = extension.getTree(), payload = tree.getRootOutput();
646
+ if (payload != null && payload.schema)
647
+ throw new ProseKitError("Schema cannot be changed");
648
+ if (payload != null && payload.view)
649
+ throw new ProseKitError("View cannot be changed");
650
+ let oldPayload = this.tree.getRootOutput(), oldPlugins = [...(_b = (_a = view.state) == null ? void 0 : _a.plugins) != null ? _b : []];
651
+ this.tree = add ? unionFacetNode(this.tree, tree) : subtractFacetNode(this.tree, tree);
652
+ let newPayload = this.tree.getRootOutput(), newPlugins = [...(_d = (_c = newPayload == null ? void 0 : newPayload.state) == null ? void 0 : _c.plugins) != null ? _d : []];
653
+ if (!deepEquals(oldPlugins, newPlugins)) {
654
+ let state = view.state.reconfigure({ plugins: newPlugins });
655
+ view.updateState(state);
656
+ }
657
+ if (newPayload != null && newPayload.commands && !deepEquals(oldPayload == null ? void 0 : oldPayload.commands, newPayload == null ? void 0 : newPayload.commands)) {
658
+ let commands = newPayload.commands, names = Object.keys(commands);
659
+ for (let name of names)
660
+ this.defineCommand(name, commands[name]);
661
+ }
662
+ }
663
+ mount(place) {
664
+ if (this.view)
665
+ throw new ProseKitError("Editor is already mounted");
666
+ if (!place)
667
+ throw new ProseKitError("Can't mount editor without a place");
668
+ this.view = new EditorView({ mount: place }, this.directEditorProps);
669
+ }
670
+ unmount() {
671
+ if (!this.view)
672
+ throw new ProseKitError("Editor is not mounted yet");
673
+ this.directEditorProps.state = this.view.state, this.view.destroy(), this.view = null;
674
+ }
675
+ get mounted() {
676
+ return !!this.view && !this.view.isDestroyed;
677
+ }
678
+ get assertView() {
679
+ if (!this.view)
680
+ throw new ProseKitError("Editor is not mounted");
681
+ return this.view;
682
+ }
683
+ definePlugins(plugins) {
684
+ let view = this.assertView, state = view.state, newPlugins = [...plugins, ...state.plugins], newState = state.reconfigure({ plugins: newPlugins });
685
+ view.setProps({ state: newState });
686
+ }
687
+ removePlugins(plugins) {
688
+ let view = this.view;
689
+ if (!view) return;
690
+ let state = view.state, newPlugins = state.plugins.filter((p) => !plugins.includes(p)), newState = state.reconfigure({ plugins: newPlugins });
691
+ view.setProps({ state: newState });
692
+ }
693
+ defineCommand(name, commandCreator) {
694
+ let applier = (...args) => {
695
+ let view = this.view;
696
+ return assert(view, `Cannot call command "${name}" before the editor is mounted`), commandCreator(...args)(view.state, view.dispatch.bind(view), view);
697
+ };
698
+ applier.canApply = (...args) => {
699
+ let view = this.view;
700
+ return view ? commandCreator(...args)(view.state, void 0, view) : !1;
701
+ }, this.commandAppliers[name] = applier;
702
+ }
703
+ removeCommand(name) {
704
+ delete this.commandAppliers[name];
705
+ }
706
+ }, Editor = class _Editor {
707
+ /**
708
+ * @internal
709
+ */
710
+ constructor(instance) {
711
+ this.afterMounted = [];
712
+ this.instance = instance, this.mount = this.mount.bind(this), this.unmount = this.unmount.bind(this), this.use = this.use.bind(this);
713
+ }
714
+ /**
715
+ * @internal
716
+ */
717
+ static create(instance) {
718
+ if (!(instance instanceof EditorInstance))
719
+ throw new TypeError("Invalid EditorInstance");
720
+ return new _Editor(instance);
721
+ }
722
+ /**
723
+ * Whether the editor is mounted.
724
+ */
725
+ get mounted() {
726
+ return this.instance.mounted;
727
+ }
728
+ /**
729
+ * The editor view.
730
+ */
731
+ get view() {
732
+ return this.instance.assertView;
733
+ }
734
+ /**
735
+ * The editor schema.
736
+ */
737
+ get schema() {
738
+ return this.instance.schema;
739
+ }
740
+ /**
741
+ * All commands defined by the editor.
742
+ */
743
+ get commands() {
744
+ return this.instance.commandAppliers;
745
+ }
746
+ /**
747
+ * Whether the editor is focused.
748
+ */
749
+ get focused() {
750
+ var _a, _b;
751
+ return (_b = (_a = this.instance.view) == null ? void 0 : _a.hasFocus()) != null ? _b : !1;
752
+ }
753
+ /**
754
+ * Mount the editor to the given HTML element.
755
+ * Pass `null` or `undefined` to unmount the editor.
756
+ */
757
+ mount(place) {
758
+ if (!place)
759
+ return this.unmount();
760
+ this.instance.mount(place), this.afterMounted.forEach((callback) => callback());
761
+ }
762
+ /**
763
+ * Unmount the editor. This is equivalent to `mount(null)`.
764
+ */
765
+ unmount() {
766
+ this.mounted && this.instance.unmount();
767
+ }
768
+ /**
769
+ * Focus the editor.
770
+ */
771
+ focus() {
772
+ var _a;
773
+ (_a = this.instance.view) == null || _a.focus();
774
+ }
775
+ /**
776
+ * Blur the editor.
777
+ */
778
+ blur() {
779
+ var _a;
780
+ (_a = this.instance.view) == null || _a.dom.blur();
781
+ }
782
+ /**
783
+ * Register an extension to the editor. Return a function to unregister the
784
+ * extension.
785
+ */
786
+ use(extension) {
787
+ if (!this.mounted) {
788
+ let canceled = !1, lazyRemove = null, lazyCreate = () => {
789
+ canceled || (lazyRemove = this.use(extension));
790
+ };
791
+ return this.afterMounted.push(lazyCreate), () => {
792
+ canceled = !0, lazyRemove == null || lazyRemove();
793
+ };
794
+ }
795
+ return this.instance.updateExtension(extension, !0), () => this.instance.updateExtension(extension, !1);
796
+ }
797
+ /**
798
+ * The editor's current state.
799
+ */
800
+ get state() {
801
+ return this.instance.getState();
802
+ }
803
+ /**
804
+ * Update the editor's state.
805
+ *
806
+ * @remarks
807
+ *
808
+ * This is an advanced method. Use it only if you have a specific reason to
809
+ * directly manipulate the editor's state.
810
+ */
811
+ updateState(state) {
812
+ this.instance.updateState(state);
813
+ }
814
+ get nodes() {
815
+ return this.instance.nodeBuilders;
816
+ }
817
+ get marks() {
818
+ return this.instance.markBuilders;
819
+ }
820
+ };
821
+
822
+ export {
823
+ ProseKitError,
824
+ EditorNotFoundError,
825
+ getMarkType,
826
+ assert,
827
+ getNodeType,
828
+ isNodeActive,
829
+ Priority,
830
+ toReversed,
831
+ isNotNull,
832
+ defineFacet,
833
+ rootFacet,
834
+ schemaFacet,
835
+ defineFacetPayload,
836
+ stateFacet,
837
+ jsonFromState,
838
+ stateFromJSON,
839
+ jsonFromNode,
840
+ nodeFromJSON,
841
+ nodeFromElement,
842
+ elementFromNode,
843
+ nodeFromHTML,
844
+ htmlFromNode,
845
+ elementFromJSON,
846
+ jsonFromHTML,
847
+ htmlFromJSON,
848
+ defineDefaultState,
849
+ isMarkAbsent,
850
+ isMarkActive,
851
+ isProseMirrorNode,
852
+ isMark,
853
+ isTextSelection,
854
+ isNodeSelection,
855
+ isAllSelection,
856
+ createNodeBuilders,
857
+ createMarkBuilders,
858
+ union,
859
+ setupEditorExtension,
860
+ createEditor,
861
+ EditorInstance,
862
+ Editor
863
+ };