@prosekit/core 0.0.17 → 0.0.18

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.
@@ -12,6 +12,7 @@ import type { IsEqual } from 'type-fest';
12
12
  import { Mark } from '@prosekit/pm/model';
13
13
  import type { MarkSpec } from '@prosekit/pm/model';
14
14
  import { MarkType } from '@prosekit/pm/model';
15
+ import { MarkType as MarkType_2 } from 'prosemirror-model';
15
16
  import { Node as Node_2 } from 'prosemirror-model';
16
17
  import type { NodeSpec } from '@prosekit/pm/model';
17
18
  import { NodeType } from '@prosekit/pm/model';
@@ -34,15 +35,24 @@ declare type Action = (options: {
34
35
  view?: EditorView;
35
36
  }) => boolean;
36
37
 
38
+ /**
39
+ * Add the given mark to the inline content.
40
+ */
37
41
  declare function addMark(options: {
42
+ /**
43
+ * The type of the mark to add.
44
+ */
38
45
  type: string | MarkType;
46
+ /**
47
+ * The attributes of the mark to add.
48
+ */
39
49
  attrs?: Attrs | null;
40
50
  /**
41
- * The start position of the mark. By default it will be the start position of current selection.
51
+ * The start position of the document. By default it will be the start position of current selection.
42
52
  */
43
53
  from?: number;
44
54
  /**
45
- * The end position of the mark. By default it will be the end position of current selection.
55
+ * The end position of the document. By default it will be the end position of current selection.
46
56
  */
47
57
  to?: number;
48
58
  }): Command;
@@ -58,6 +68,28 @@ export declare function assertTypeEqual<T, U>(_val: IsEqual<T, U>): void;
58
68
 
59
69
  export declare function attrsMatch(nodeOrMark: ProseMirrorNode | Mark, attrs: Attrs): boolean;
60
70
 
71
+ export declare abstract class BaseExtension<T extends ExtensionTyping = ExtensionTyping> implements Extension<T> {
72
+ extension: Extension | Extension[];
73
+ priority?: Priority;
74
+ _type?: T;
75
+ /**
76
+ * @internal
77
+ *
78
+ * Whether this extension has payload that can be converted to a schema.
79
+ *
80
+ * Notice that this does not mean that the extension has a schema. For
81
+ * example, a `FacetExtension` with a `schemaFacet` will return `true` for
82
+ * this property, but will return `null` for `schema`.
83
+ */
84
+ abstract hasSchema: boolean;
85
+ /**
86
+ * @internal
87
+ *
88
+ * The schema that this extension represents.
89
+ */
90
+ abstract schema: Schema | null;
91
+ }
92
+
61
93
  export declare function collectNodes(content: NodeContent): ProseMirrorNode[];
62
94
 
63
95
  export declare interface CommandApplier<Args extends any[] = any[]> {
@@ -91,7 +123,7 @@ declare type ConverterTuple = Tuple5<FacetConverter | undefined>;
91
123
  /**
92
124
  * @public
93
125
  */
94
- declare function createEditor<E extends Extension>({ extension, defaultDoc, defaultSelection, }: EditorOptions<E>): Editor<E>;
126
+ declare function createEditor<E extends Extension>({ extension, defaultDoc, defaultHTML, defaultSelection, }: EditorOptions<E>): Editor<E>;
95
127
  export { createEditor }
96
128
  export { createEditor as createEditor_alias_1 }
97
129
 
@@ -105,13 +137,20 @@ export declare const default_alias_1: UserProjectConfigExport;
105
137
 
106
138
  declare interface DefaultStateOptions {
107
139
  /**
108
- * A JSON representation of a ProseMirror document.
140
+ * A JSON object representing the starting document to use when creating the
141
+ * editor.
109
142
  */
110
- doc?: NodeJson;
143
+ defaultDoc?: NodeJson;
111
144
  /**
112
- * A JSON representation of a ProseMirror selection.
145
+ * A HTML string representing the starting document to use when creating the
146
+ * editor.
147
+ */
148
+ defaultHTML?: string;
149
+ /**
150
+ * A JSON object representing the starting selection to use when creating the
151
+ * editor. It's only used when `defaultDoc` or `defaultHTML` is also provided.
113
152
  */
114
- selection?: SelectionJson;
153
+ defaultSelection?: SelectionJson;
115
154
  }
116
155
  export { DefaultStateOptions }
117
156
  export { DefaultStateOptions as DefaultStateOptions_alias_1 }
@@ -143,6 +182,18 @@ declare function defineBaseCommands(): Extension<{
143
182
  to?: number | undefined;
144
183
  }];
145
184
  selectAll: [];
185
+ addMark: [options: {
186
+ type: string | MarkType_2;
187
+ attrs?: Attrs_2 | null | undefined;
188
+ from?: number | undefined;
189
+ to?: number | undefined;
190
+ }];
191
+ removeMark: [options: {
192
+ type: string | MarkType_2;
193
+ attrs?: Attrs_2 | null | undefined;
194
+ from?: number | undefined;
195
+ to?: number | undefined;
196
+ }];
146
197
  };
147
198
  }>;
148
199
  export { defineBaseCommands }
@@ -163,7 +214,7 @@ declare function defineCommands<T extends Record<string, CommandCreator> = Recor
163
214
  export { defineCommands }
164
215
  export { defineCommands as defineCommands_alias_1 }
165
216
 
166
- declare function defineDefaultState(options: DefaultStateOptions): Extension;
217
+ declare function defineDefaultState({ defaultDoc, defaultHTML, defaultSelection, }: DefaultStateOptions): Extension;
167
218
  export { defineDefaultState }
168
219
  export { defineDefaultState as defineDefaultState_alias_1 }
169
220
 
@@ -181,7 +232,7 @@ export { defineDoc as defineDoc_alias_1 }
181
232
  */
182
233
  declare function defineEventHandler(options: {
183
234
  update?: VoidFunction;
184
- }): FacetExtension<VoidFunction, PluginPayload>;
235
+ }): Extension<ExtensionTyping<string, string, CommandArgs>>;
185
236
  export { defineEventHandler }
186
237
  export { defineEventHandler as defineEventHandler_alias_1 }
187
238
 
@@ -327,15 +378,34 @@ declare interface EditorOptions<E extends Extension> {
327
378
  * editor.
328
379
  */
329
380
  defaultDoc?: NodeJson;
381
+ /**
382
+ * A HTML string representing the starting document to use when creating the
383
+ * editor.
384
+ */
385
+ defaultHTML?: string;
330
386
  /**
331
387
  * A JSON object representing the starting selection to use when creating the
332
- * editor. It's only used when `defaultDoc` is also provided.
388
+ * editor. It's only used when `defaultDoc` or `defaultHTML` is also provided.
333
389
  */
334
390
  defaultSelection?: SelectionJson;
335
391
  }
336
392
  export { EditorOptions }
337
393
  export { EditorOptions as EditorOptions_alias_1 }
338
394
 
395
+ /**
396
+ * Parse a HTML element to a ProseMirror document JSON.
397
+ */
398
+ declare function elementToJSON(element: HTMLElement, schema: Schema): NodeJson;
399
+ export { elementToJSON }
400
+ export { elementToJSON as elementToJSON_alias_1 }
401
+
402
+ /**
403
+ * Parse a HTML element to a ProseMirror node.
404
+ */
405
+ declare function elementToNode(element: HTMLElement, schema: Schema): ProseMirrorNode;
406
+ export { elementToNode }
407
+ export { elementToNode as elementToNode_alias_1 }
408
+
339
409
  declare type EmptyValue = undefined | null | EmptyObject;
340
410
 
341
411
  export declare type ExceptEmptyValue<T> = ConditionalExcept<T, EmptyValue>;
@@ -347,6 +417,12 @@ declare interface Extension<T extends ExtensionTyping = ExtensionTyping> {
347
417
  extension: Extension | Extension[];
348
418
  priority?: Priority;
349
419
  _type?: T;
420
+ /**
421
+ * @public
422
+ *
423
+ * The schema that this extension represents.
424
+ */
425
+ schema: Schema | null;
350
426
  }
351
427
  export { Extension }
352
428
  export { Extension as Extension_alias_1 }
@@ -431,13 +507,17 @@ declare class Facet<Input, Output> {
431
507
  * @internal
432
508
  */
433
509
  readonly singleton: boolean;
510
+ /**
511
+ * @internal
512
+ */
513
+ isSchema: boolean;
434
514
  private constructor();
435
- static define<Input, Output>({ converter: converter, convert: convert, next, singleton, }: FacetOptions<Input, Output>): Facet<Input, Output>;
515
+ static define<Input, Output>({ converter, convert, next, singleton, }: FacetOptions<Input, Output>): Facet<Input, Output>;
436
516
  /**
437
517
  * @internal
438
518
  */
439
519
  static defineRootFacet<Input>(options: Omit<FacetOptions<Input, Input>, 'next'>): Facet<Input, Input>;
440
- extension(payloads: Input[]): FacetExtension<Input, Output>;
520
+ extension(payloads: Input[]): Extension;
441
521
  }
442
522
  export { Facet }
443
523
  export { Facet as Facet_alias_1 }
@@ -453,14 +533,14 @@ export declare interface FacetConverter<Input = any, Output = any> {
453
533
  /**
454
534
  * @public
455
535
  */
456
- declare class FacetExtension<Input, Output> {
536
+ export declare class FacetExtensionImpl<Input, Output> extends BaseExtension {
457
537
  readonly facet: Facet<Input, Output>;
458
538
  readonly payloads: Input[];
459
539
  extension: Extension;
540
+ hasSchema: boolean;
541
+ schema: null;
460
542
  constructor(facet: Facet<Input, Output>, payloads: Input[]);
461
543
  }
462
- export { FacetExtension }
463
- export { FacetExtension as FacetExtension_alias_1 }
464
544
 
465
545
  /**
466
546
  * @public
@@ -474,6 +554,10 @@ declare interface FacetOptions<Input, Output> {
474
554
  export { FacetOptions }
475
555
  export { FacetOptions as FacetOptions_alias_1 }
476
556
 
557
+ export declare function getBrowserDocument(): Document | undefined;
558
+
559
+ export declare function getBrowserWindow(): (Window & typeof globalThis) | null | undefined;
560
+
477
561
  export declare function getCustomSelection(state: EditorState, from?: number | null, to?: number | null): Selection_2;
478
562
 
479
563
  export declare function getFacetCount(): number;
@@ -492,6 +576,20 @@ declare function getNodeType(schema: Schema, type: string | NodeType): NodeType;
492
576
  export { getNodeType }
493
577
  export { getNodeType as getNodeType_alias_1 }
494
578
 
579
+ /**
580
+ * Parse a HTML element to a ProseMirror document JSON.
581
+ */
582
+ declare function htmlToJSON(html: string, schema: Schema): NodeJson;
583
+ export { htmlToJSON }
584
+ export { htmlToJSON as htmlToJSON_alias_1 }
585
+
586
+ /**
587
+ * Parse a HTML string to a ProseMirror node.
588
+ */
589
+ declare function htmlToNode(html: string, schema: Schema): ProseMirrorNode;
590
+ export { htmlToNode }
591
+ export { htmlToNode as htmlToNode_alias_1 }
592
+
495
593
  declare function insertNode(options: {
496
594
  node: ProseMirrorNode;
497
595
  pos?: number;
@@ -604,6 +702,8 @@ declare interface NodeViewOptions {
604
702
  export { NodeViewOptions }
605
703
  export { NodeViewOptions as NodeViewOptions_alias_1 }
606
704
 
705
+ export declare function notNull<T>(value: T | null | undefined): value is T;
706
+
607
707
  export declare function objectEqual<T>(a: T, b: T): boolean;
608
708
 
609
709
  declare type Payload = unknown;
@@ -649,6 +749,30 @@ declare class ProseKitError extends Error {
649
749
  export { ProseKitError }
650
750
  export { ProseKitError as ProseKitError_alias_1 }
651
751
 
752
+ /**
753
+ * Remove the given mark from the inline content.
754
+ */
755
+ declare function removeMark(options: {
756
+ /**
757
+ * The type of the mark to remove.
758
+ */
759
+ type: string | MarkType;
760
+ /**
761
+ * If attrs is given, remove precisely the mark with the given attrs. Otherwise, remove all marks of the given type.
762
+ */
763
+ attrs?: Attrs | null;
764
+ /**
765
+ * The start position of the document. By default it will be the start position of current selection.
766
+ */
767
+ from?: number;
768
+ /**
769
+ * The end position of the document. By default it will be the end position of current selection.
770
+ */
771
+ to?: number;
772
+ }): Command;
773
+ export { removeMark }
774
+ export { removeMark as removeMark_alias_1 }
775
+
652
776
  export declare const schemaFacet: Facet<SchemaPayload, SchemaPayload>;
653
777
 
654
778
  export declare type SchemaPayload = SchemaSpec;
@@ -755,6 +879,15 @@ declare function union<E extends Extension | Extension[]>(extension: E): Simplif
755
879
  export { union }
756
880
  export { union as union_alias_1 }
757
881
 
882
+ export declare class UnionExtensionImpl<T extends ExtensionTyping = ExtensionTyping> extends BaseExtension<T> implements Extension<T> {
883
+ extension: BaseExtension[];
884
+ private _schema;
885
+ private hasSchemaCount;
886
+ constructor(extension?: BaseExtension[]);
887
+ get hasSchema(): boolean;
888
+ get schema(): Schema | null;
889
+ }
890
+
758
891
  export declare function uniqPush<T>(prev: readonly T[], next: readonly T[]): T[];
759
892
 
760
893
  export declare function uniqRemove<T>(prev: T[], next: T[]): T[];
@@ -1,5 +1,6 @@
1
1
  export { addMark } from './_tsup-dts-rollup';
2
2
  export { insertNode } from './_tsup-dts-rollup';
3
+ export { removeMark } from './_tsup-dts-rollup';
3
4
  export { setBlockType } from './_tsup-dts-rollup';
4
5
  export { toggleMark } from './_tsup-dts-rollup';
5
6
  export { toggleNode } from './_tsup-dts-rollup';
@@ -34,7 +35,6 @@ export { pluginFacet } from './_tsup-dts-rollup';
34
35
  export { PluginPayload } from './_tsup-dts-rollup';
35
36
  export { defineText } from './_tsup-dts-rollup';
36
37
  export { Facet } from './_tsup-dts-rollup';
37
- export { FacetExtension } from './_tsup-dts-rollup';
38
38
  export { FacetOptions } from './_tsup-dts-rollup';
39
39
  export { CommandArgs } from './_tsup-dts-rollup';
40
40
  export { Extension } from './_tsup-dts-rollup';
@@ -51,3 +51,7 @@ export { Priority } from './_tsup-dts-rollup';
51
51
  export { SimplifyUnion } from './_tsup-dts-rollup';
52
52
  export { getMarkType } from './_tsup-dts-rollup';
53
53
  export { getNodeType } from './_tsup-dts-rollup';
54
+ export { elementToJSON } from './_tsup-dts-rollup';
55
+ export { elementToNode } from './_tsup-dts-rollup';
56
+ export { htmlToJSON } from './_tsup-dts-rollup';
57
+ export { htmlToNode } from './_tsup-dts-rollup';
@@ -75,6 +75,24 @@ function insertNode(options) {
75
75
  };
76
76
  }
77
77
 
78
+ // src/commands/remove-mark.ts
79
+ import "@prosekit/pm/model";
80
+ import "@prosekit/pm/state";
81
+ function removeMark(options) {
82
+ return (state, dispatch) => {
83
+ var _a, _b;
84
+ const markType = getMarkType(state.schema, options.type);
85
+ const mark = options.attrs ? markType.create(options.attrs) : markType;
86
+ const from = (_a = options.from) != null ? _a : state.selection.from;
87
+ const to = (_b = options.to) != null ? _b : state.selection.to;
88
+ if (from > to) {
89
+ return false;
90
+ }
91
+ dispatch == null ? void 0 : dispatch(state.tr.removeMark(from, to, mark));
92
+ return true;
93
+ };
94
+ }
95
+
78
96
  // src/commands/set-block-type.ts
79
97
  import "@prosekit/pm/state";
80
98
 
@@ -198,7 +216,7 @@ function toggleNode({
198
216
  }
199
217
 
200
218
  // src/editor/editor.ts
201
- import { Schema as Schema4 } from "@prosekit/pm/model";
219
+ import { Schema as Schema6 } from "@prosekit/pm/model";
202
220
  import { EditorState } from "@prosekit/pm/state";
203
221
  import { EditorView } from "@prosekit/pm/view";
204
222
 
@@ -226,6 +244,14 @@ function uniqRemove(prev, next) {
226
244
  return result;
227
245
  }
228
246
 
247
+ // src/facets/base-extension.ts
248
+ import "@prosekit/pm/model";
249
+ var BaseExtension = class {
250
+ constructor() {
251
+ this.extension = [];
252
+ }
253
+ };
254
+
229
255
  // src/facets/facet.ts
230
256
  var facetCount = 0;
231
257
  function getFacetCount() {
@@ -237,6 +263,10 @@ var Facet = class _Facet {
237
263
  * @internal
238
264
  */
239
265
  this.index = facetCount++;
266
+ /**
267
+ * @internal
268
+ */
269
+ this.isSchema = false;
240
270
  this.converter = converter;
241
271
  this.next = next;
242
272
  this.singleton = singleton;
@@ -263,13 +293,17 @@ var Facet = class _Facet {
263
293
  return _Facet.define(options);
264
294
  }
265
295
  extension(payloads) {
266
- return new FacetExtension(this, payloads);
296
+ return new FacetExtensionImpl(this, payloads);
267
297
  }
268
298
  };
269
- var FacetExtension = class {
299
+ var FacetExtensionImpl = class extends BaseExtension {
270
300
  constructor(facet, payloads) {
301
+ var _a;
302
+ super();
271
303
  this.facet = facet;
272
304
  this.payloads = payloads;
305
+ this.schema = null;
306
+ this.hasSchema = !!(facet.isSchema || ((_a = facet.next) == null ? void 0 : _a.isSchema));
273
307
  }
274
308
  };
275
309
 
@@ -304,118 +338,97 @@ var stateFacet = Facet.defineRootFacet({
304
338
  }
305
339
  });
306
340
 
307
- // src/extensions/default-state.ts
308
- function defineDefaultState(options) {
309
- return stateFacet.extension([
310
- ({ schema }) => {
311
- const config = {};
312
- if (options.doc) {
313
- config.doc = schema.nodeFromJSON(options.doc);
314
- if (options.selection) {
315
- config.selection = Selection.fromJSON(config.doc, options.selection);
316
- }
317
- }
318
- return config;
319
- }
320
- ]);
321
- }
341
+ // src/utils/parse.ts
342
+ import { DOMParser } from "@prosekit/pm/model";
322
343
 
323
- // src/utils/type-assertion.ts
324
- import { Mark, ProseMirrorNode } from "@prosekit/pm/model";
325
- function isProseMirrorNode(node) {
326
- return node instanceof ProseMirrorNode;
344
+ // src/utils/get-dom-api.ts
345
+ function getGlobalBrowserDocument() {
346
+ if (typeof document !== "undefined") {
347
+ return document;
348
+ }
349
+ if (typeof globalThis !== "undefined" && globalThis.document) {
350
+ return globalThis.document;
351
+ }
327
352
  }
328
- function isMark(mark) {
329
- return mark instanceof Mark;
353
+ function getGlobalBrowserWindow() {
354
+ if (typeof window !== "undefined") {
355
+ return window;
356
+ }
357
+ if (typeof globalThis !== "undefined" && globalThis.window) {
358
+ return globalThis.window;
359
+ }
330
360
  }
331
-
332
- // src/utils/is-mark-active.ts
333
- function isMarkActive(state, type, attrs) {
361
+ function getBrowserWindow() {
334
362
  var _a;
335
- const markType = getMarkType(state.schema, type);
336
- const mark = attrs ? markType.create(attrs) : markType;
337
- const { from, to, $from, $to } = state.selection;
338
- return state.doc.rangeHasMark(from, to, mark) || hasMark(
339
- [...$from.marks(), ...$to.marks(), ...(_a = state.storedMarks) != null ? _a : []],
340
- mark
341
- );
342
- }
343
- function hasMark(marks, mark) {
344
- if (marks.length === 0) {
345
- return false;
346
- }
347
- if (isMark(mark)) {
348
- return marks.some((m) => m.eq(mark));
349
- } else {
350
- return marks.some((m) => m.type === mark);
363
+ const win = getGlobalBrowserWindow();
364
+ if (win) {
365
+ return win;
351
366
  }
367
+ return (_a = getGlobalBrowserDocument()) == null ? void 0 : _a.defaultView;
352
368
  }
353
369
 
354
- // src/editor/builder.ts
355
- import "@prosekit/pm/model";
356
- function createNodeBuilder(getState, type) {
357
- const builder = (...args) => buildNode(type, args);
358
- builder.isActive = (attrs) => {
359
- const state = getState();
360
- return state ? isNodeActive(state, type, attrs) : false;
361
- };
362
- return builder;
370
+ // src/utils/parse.ts
371
+ function elementToNode(element, schema) {
372
+ return DOMParser.fromSchema(schema).parse(element);
363
373
  }
364
- function createMarkBuilder(getState, type) {
365
- const builder = (...args) => buildMark(type, args);
366
- builder.isActive = (attrs) => {
367
- const state = getState();
368
- return state ? isMarkActive(state, type, attrs) : false;
369
- };
370
- return builder;
371
- }
372
- function buildMark(type, args) {
373
- const [attrs, children] = normalizeArgs(args);
374
- return flattenChildren(type.schema, children, type.create(attrs));
374
+ function elementToJSON(element, schema) {
375
+ return elementToNode(element, schema).toJSON();
375
376
  }
376
- function buildNode(type, args) {
377
- const [attrs, children] = normalizeArgs(args);
378
- const node = type.createAndFill(attrs, flattenChildren(type.schema, children));
379
- if (!node) {
380
- throw new ProseKitError(`Couldn't create node ${type.name}`);
381
- }
382
- return node;
377
+ function htmlToNode(html, schema) {
378
+ return elementToNode(htmlToElement(html), schema);
383
379
  }
384
- function flattenChildren(schema, children, mark) {
385
- const nodes = [];
386
- for (const child of children) {
387
- if (typeof child === "string") {
388
- if (child) {
389
- nodes.push(schema.text(child, mark ? [mark] : null));
390
- }
391
- } else if (Array.isArray(child)) {
392
- nodes.push(...flattenChildren(schema, child, mark));
393
- } else if (isProseMirrorNode(child)) {
394
- nodes.push(mark ? child.mark(mark.addToSet(child.marks)) : child);
395
- } else {
396
- throw new ProseKitError(`Invalid node child: ${typeof child}`);
397
- }
398
- }
399
- return nodes;
380
+ function htmlToJSON(html, schema) {
381
+ return elementToJSON(htmlToElement(html), schema);
400
382
  }
401
- function normalizeArgs(args) {
402
- const [attrs, ...children] = args;
403
- if (isNodeChild(args)) {
404
- children.unshift(args);
405
- return [null, children];
406
- } else if (typeof attrs === "object") {
407
- return [attrs, children];
408
- } else {
409
- return [null, children];
383
+ function htmlToElement(html) {
384
+ const win = getBrowserWindow();
385
+ if (!win) {
386
+ throw new ProseKitError(
387
+ "No Browser Document Found. You can only parse a HTML string in the browser environment."
388
+ );
410
389
  }
390
+ const parser = new win.DOMParser();
391
+ return parser.parseFromString(`<body>${html}</body>`, "text/html").body;
411
392
  }
412
- function isNodeChild(value) {
413
- if (!value) {
414
- return false;
393
+
394
+ // src/extensions/default-state.ts
395
+ function defineDefaultState({
396
+ defaultDoc,
397
+ defaultHTML,
398
+ defaultSelection
399
+ }) {
400
+ if (defaultHTML && defaultDoc) {
401
+ throw new ProseKitError(
402
+ "Only one of defaultHTML and defaultDoc can be provided"
403
+ );
415
404
  }
416
- return typeof value === "string" || Array.isArray(value) || isProseMirrorNode(value);
405
+ return stateFacet.extension([
406
+ ({ schema }) => {
407
+ const config = {};
408
+ if (defaultHTML) {
409
+ defaultDoc = htmlToJSON(defaultHTML, schema);
410
+ }
411
+ if (defaultDoc) {
412
+ config.doc = schema.nodeFromJSON(defaultDoc);
413
+ if (defaultSelection) {
414
+ config.selection = Selection.fromJSON(config.doc, defaultSelection);
415
+ }
416
+ }
417
+ return config;
418
+ }
419
+ ]);
417
420
  }
418
421
 
422
+ // src/types/priority.ts
423
+ var Priority = /* @__PURE__ */ ((Priority2) => {
424
+ Priority2[Priority2["lowest"] = 4] = "lowest";
425
+ Priority2[Priority2["low"] = 3] = "low";
426
+ Priority2[Priority2["default"] = 2] = "default";
427
+ Priority2[Priority2["high"] = 1] = "high";
428
+ Priority2[Priority2["highest"] = 0] = "highest";
429
+ return Priority2;
430
+ })(Priority || {});
431
+
419
432
  // src/facets/command.ts
420
433
  var commandFacet = Facet.defineRootFacet({
421
434
  convert: (inputs) => {
@@ -439,6 +452,7 @@ var schemaFacet = Facet.defineRootFacet({
439
452
  return { nodes, marks, topNode };
440
453
  }
441
454
  });
455
+ schemaFacet.isSchema = true;
442
456
 
443
457
  // src/facets/view.ts
444
458
  var viewFacet = Facet.defineRootFacet({
@@ -447,17 +461,7 @@ var viewFacet = Facet.defineRootFacet({
447
461
  }
448
462
  });
449
463
 
450
- // src/types/priority.ts
451
- var Priority = /* @__PURE__ */ ((Priority2) => {
452
- Priority2[Priority2["lowest"] = 4] = "lowest";
453
- Priority2[Priority2["low"] = 3] = "low";
454
- Priority2[Priority2["default"] = 2] = "default";
455
- Priority2[Priority2["high"] = 1] = "high";
456
- Priority2[Priority2["highest"] = 0] = "highest";
457
- return Priority2;
458
- })(Priority || {});
459
-
460
- // src/editor/flatten.ts
464
+ // src/facets/flatten.ts
461
465
  function flattenInputTuple(inputTuple) {
462
466
  return [
463
467
  ...inputTuple[0],
@@ -506,7 +510,7 @@ function extractFacets(root) {
506
510
  while (extensions.length > 0) {
507
511
  const ext = extensions.pop();
508
512
  const pri = priorities.pop();
509
- if (ext instanceof FacetExtension) {
513
+ if (ext instanceof FacetExtensionImpl) {
510
514
  const facet = ext.facet;
511
515
  if (!facets[facet.index]) {
512
516
  facets[facet.index] = facet;
@@ -631,26 +635,165 @@ function updateExtension(prevInputs, prevConverters, extension, mode) {
631
635
  return { schemaInput, stateInput, viewInput, commandInput };
632
636
  }
633
637
 
634
- // src/editor/type-utils.ts
635
- function union(extension) {
636
- if (extension && Array.isArray(extension)) {
637
- return { extension };
638
+ // src/utils/type-assertion.ts
639
+ import { Mark, ProseMirrorNode } from "@prosekit/pm/model";
640
+ function isProseMirrorNode(node) {
641
+ return node instanceof ProseMirrorNode;
642
+ }
643
+ function isMark(mark) {
644
+ return mark instanceof Mark;
645
+ }
646
+
647
+ // src/utils/is-mark-active.ts
648
+ function isMarkActive(state, type, attrs) {
649
+ const markType = getMarkType(state.schema, type);
650
+ const mark = attrs ? markType.create(attrs) : markType;
651
+ const { from, $from, to, empty } = state.selection;
652
+ if (empty) {
653
+ return hasMark(state.storedMarks || $from.marks(), mark);
654
+ } else {
655
+ return state.doc.rangeHasMark(from, to, mark);
656
+ }
657
+ }
658
+ function hasMark(marks, mark) {
659
+ if (marks.length === 0) {
660
+ return false;
661
+ }
662
+ if (isMark(mark)) {
663
+ return marks.some((m) => m.eq(mark));
664
+ } else {
665
+ return marks.some((m) => m.type === mark);
666
+ }
667
+ }
668
+
669
+ // src/editor/builder.ts
670
+ import "@prosekit/pm/model";
671
+ function createNodeBuilder(getState, type) {
672
+ const builder = (...args) => buildNode(type, args);
673
+ builder.isActive = (attrs) => {
674
+ const state = getState();
675
+ return state ? isNodeActive(state, type, attrs) : false;
676
+ };
677
+ return builder;
678
+ }
679
+ function createMarkBuilder(getState, type) {
680
+ const builder = (...args) => buildMark(type, args);
681
+ builder.isActive = (attrs) => {
682
+ const state = getState();
683
+ return state ? isMarkActive(state, type, attrs) : false;
684
+ };
685
+ return builder;
686
+ }
687
+ function buildMark(type, args) {
688
+ const [attrs, children] = normalizeArgs(args);
689
+ return flattenChildren(type.schema, children, type.create(attrs));
690
+ }
691
+ function buildNode(type, args) {
692
+ const [attrs, children] = normalizeArgs(args);
693
+ const node = type.createAndFill(attrs, flattenChildren(type.schema, children));
694
+ if (!node) {
695
+ throw new ProseKitError(`Couldn't create node ${type.name}`);
696
+ }
697
+ return node;
698
+ }
699
+ function flattenChildren(schema, children, mark) {
700
+ const nodes = [];
701
+ for (const child of children) {
702
+ if (typeof child === "string") {
703
+ if (child) {
704
+ nodes.push(schema.text(child, mark ? [mark] : null));
705
+ }
706
+ } else if (Array.isArray(child)) {
707
+ nodes.push(...flattenChildren(schema, child, mark));
708
+ } else if (isProseMirrorNode(child)) {
709
+ nodes.push(mark ? child.mark(mark.addToSet(child.marks)) : child);
710
+ } else {
711
+ throw new ProseKitError(`Invalid node child: ${typeof child}`);
712
+ }
713
+ }
714
+ return nodes;
715
+ }
716
+ function normalizeArgs(args) {
717
+ const [attrs, ...children] = args;
718
+ if (isNodeChild(args)) {
719
+ children.unshift(args);
720
+ return [null, children];
721
+ } else if (typeof attrs === "object") {
722
+ return [attrs, children];
723
+ } else {
724
+ return [null, children];
725
+ }
726
+ }
727
+ function isNodeChild(value) {
728
+ if (!value) {
729
+ return false;
730
+ }
731
+ return typeof value === "string" || Array.isArray(value) || isProseMirrorNode(value);
732
+ }
733
+
734
+ // src/facets/union-extension.ts
735
+ import { Schema as Schema5 } from "@prosekit/pm/model";
736
+ var UnionExtensionImpl = class extends BaseExtension {
737
+ constructor(extension = []) {
738
+ super();
739
+ this.extension = extension;
740
+ this._schema = void 0;
741
+ this.hasSchemaCount = 0;
742
+ for (const e of extension) {
743
+ if (e instanceof BaseExtension) {
744
+ this.hasSchemaCount += e.hasSchema ? 1 : 0;
745
+ } else {
746
+ throw new ProseKitError("Invalid extension");
747
+ }
748
+ }
749
+ }
750
+ get hasSchema() {
751
+ return this.hasSchemaCount > 0;
752
+ }
753
+ get schema() {
754
+ var _a;
755
+ if (this._schema !== void 0) {
756
+ return this._schema;
757
+ }
758
+ if (this.hasSchemaCount === 0) {
759
+ this._schema = null;
760
+ return this._schema;
761
+ }
762
+ if (this.hasSchemaCount === 1) {
763
+ const schema = (_a = this.extension.find((e) => e.hasSchema)) == null ? void 0 : _a.schema;
764
+ if (schema) {
765
+ this._schema = schema;
766
+ return this._schema;
767
+ }
768
+ }
769
+ const { schemaInput } = updateExtension([], [], this, "add");
770
+ this._schema = schemaInput ? new Schema5(schemaInput) : null;
771
+ return this._schema;
638
772
  }
639
- return extension;
773
+ };
774
+
775
+ // src/editor/union.ts
776
+ function union(extension) {
777
+ const array = Array.isArray(extension) ? extension : [extension];
778
+ return new UnionExtensionImpl(
779
+ array
780
+ );
640
781
  }
641
782
 
642
783
  // src/editor/editor.ts
643
784
  function createEditor({
644
785
  extension,
645
786
  defaultDoc,
787
+ defaultHTML,
646
788
  defaultSelection
647
789
  }) {
648
- if (defaultDoc) {
790
+ if (defaultDoc || defaultHTML) {
649
791
  extension = union([
650
792
  extension,
651
793
  defineDefaultState({
652
- doc: defaultDoc,
653
- selection: defaultSelection
794
+ defaultDoc,
795
+ defaultHTML,
796
+ defaultSelection
654
797
  })
655
798
  ]);
656
799
  }
@@ -668,7 +811,7 @@ var EditorInstance = class {
668
811
  if (!schemaInput) {
669
812
  throw new ProseKitError("Schema must be defined");
670
813
  }
671
- const schema = new Schema4(schemaInput);
814
+ const schema = new Schema6(schemaInput);
672
815
  const stateConfig = stateInput ? stateInput({ schema }) : { schema };
673
816
  const state = EditorState.create(stateConfig);
674
817
  if (commandInput) {
@@ -859,7 +1002,9 @@ var Editor = class _Editor {
859
1002
 
860
1003
  // src/editor/with-priority.ts
861
1004
  function withPriority(extension, priority) {
862
- return { extension, priority };
1005
+ const result = union(extension);
1006
+ result.priority = priority;
1007
+ return result;
863
1008
  }
864
1009
 
865
1010
  // src/commands/insert-text.ts
@@ -936,7 +1081,9 @@ function defineBaseCommands() {
936
1081
  insertNode: insertNode2,
937
1082
  wrap,
938
1083
  setBlockType,
939
- selectAll
1084
+ selectAll,
1085
+ addMark,
1086
+ removeMark
940
1087
  });
941
1088
  }
942
1089
 
@@ -1233,7 +1380,6 @@ function defineText() {
1233
1380
  export {
1234
1381
  Editor,
1235
1382
  Facet,
1236
- FacetExtension,
1237
1383
  Priority,
1238
1384
  ProseKitError,
1239
1385
  addMark,
@@ -1254,10 +1400,15 @@ export {
1254
1400
  defineParagraph,
1255
1401
  definePlugin,
1256
1402
  defineText,
1403
+ elementToJSON,
1404
+ elementToNode,
1257
1405
  getMarkType,
1258
1406
  getNodeType,
1407
+ htmlToJSON,
1408
+ htmlToNode,
1259
1409
  insertNode,
1260
1410
  pluginFacet,
1411
+ removeMark,
1261
1412
  setBlockType,
1262
1413
  toggleMark,
1263
1414
  toggleNode,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.0.17",
4
+ "version": "0.0.18",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",