@kerebron/extension-menu 0.0.12 → 0.1.0

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.
@@ -1,9 +1,8 @@
1
1
  import { EditorView } from 'prosemirror-view';
2
- import { Fragment, Node as ProseMirrorNode, type Schema } from 'prosemirror-model';
2
+ import { Node as ProseMirrorNode, type Schema } from 'prosemirror-model';
3
3
  import type { EditorOptions, JSONContent } from './types.js';
4
- import { EditorState } from 'prosemirror-state';
4
+ import { EditorState, Transaction } from 'prosemirror-state';
5
5
  import { ChainedCommands } from './commands/CommandManager.js';
6
- export declare function getHTMLFromFragment(fragment: Fragment, schema: Schema): string;
7
6
  export declare class CoreEditor extends EventTarget {
8
7
  readonly options: Partial<EditorOptions>;
9
8
  private extensionManager;
@@ -15,14 +14,12 @@ export declare class CoreEditor extends EventTarget {
15
14
  chain(): ChainedCommands;
16
15
  can(): ChainedCommands;
17
16
  private createView;
18
- private dispatchTransaction;
17
+ dispatchTransaction(transaction: Transaction): void;
19
18
  private setupPlugins;
20
- getJSON(): JSONContent;
21
- /**
22
- * Get the document as HTML.
23
- */
24
- getHTML(): string;
25
19
  setDocument(content?: any, mediaType?: string): void;
26
- getDocument(mediaType?: string): void | ProseMirrorNode;
20
+ getDocument(mediaType?: string): void | ProseMirrorNode | JSONContent;
21
+ getJSON(): JSONContent;
22
+ clone(options?: Partial<EditorOptions>): CoreEditor;
23
+ debug(doc?: ProseMirrorNode): void;
27
24
  }
28
25
  //# sourceMappingURL=CoreEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CoreEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/src/CoreEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAEL,QAAQ,EACR,IAAI,IAAI,eAAe,EAEvB,KAAK,MAAM,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAW,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAkB,MAAM,8BAA8B,CAAC;AAE/E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,CAWR;AAeD,qBAAa,UAAW,SAAQ,WAAW;IACzC,SAAgB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,CAG7C;IACF,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAiB;IAChC,IAAI,EAAG,UAAU,CAAC;IAClB,KAAK,EAAG,WAAW,CAAC;gBAEf,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;IAyBhD,IAAW,MAAM,qBAEhB;IAEM,KAAK,IAAI,eAAe;IAIxB,GAAG,IAAI,eAAe;IAI7B,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,YAAY;IAcb,OAAO,IAAI,WAAW;IAI7B;;OAEG;IACI,OAAO,IAAI,MAAM;IAIjB,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM;IA4C7C,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM;CAUtC"}
1
+ {"version":3,"file":"CoreEditor.d.ts","sourceRoot":"","sources":["../../../src/editor/src/CoreEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,IAAI,IAAI,eAAe,EACvB,KAAK,MAAM,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAkB,MAAM,8BAA8B,CAAC;AAgC/E,qBAAa,UAAW,SAAQ,WAAW;IACzC,SAAgB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,CAG7C;IACF,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAiB;IAChC,IAAI,EAAG,UAAU,CAAC;IAClB,KAAK,EAAG,WAAW,CAAC;gBAEf,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;IAyBhD,IAAW,MAAM,qBAEhB;IAEM,KAAK,IAAI,eAAe;IAIxB,GAAG,IAAI,eAAe;IAI7B,OAAO,CAAC,UAAU;IAaX,mBAAmB,CAAC,WAAW,EAAE,WAAW;IAcnD,OAAO,CAAC,YAAY;IAcb,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM;IAwC7C,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM;IAkB9B,OAAO,IAAI,WAAW;IAItB,KAAK,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,UAAU;IAOvD,KAAK,CAAC,GAAG,CAAC,EAAE,eAAe;CAMnC"}
@@ -1,22 +1,36 @@
1
1
  import { EditorView } from 'prosemirror-view';
2
- import { DOMSerializer, } from 'prosemirror-model';
2
+ import { Node as ProseMirrorNode, } from 'prosemirror-model';
3
3
  import { ExtensionManager } from './ExtensionManager.js';
4
4
  import { EditorState } from 'prosemirror-state';
5
5
  import { createNodeFromContent } from './utilities/createNodeFromContent.js';
6
6
  import { CommandManager } from './commands/CommandManager.js';
7
- export function getHTMLFromFragment(fragment, schema) {
8
- const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
9
- const temporaryDocument = document.implementation.createHTMLDocument();
10
- const container = temporaryDocument.createElement('div');
11
- container.appendChild(documentFragment);
12
- return container.innerHTML;
13
- }
14
- function createDocument(content, schema, parseOptions = {}, options = {}) {
15
- return createNodeFromContent(content, schema, {
16
- slice: false,
17
- parseOptions,
18
- errorOnInvalidContent: options.errorOnInvalidContent,
19
- });
7
+ import { nodeToTreeString } from './nodeToTreeString.js';
8
+ function ensureDocSchema(doc, schema) {
9
+ if (doc.type.schema != schema) {
10
+ const findNode = (nodeName) => {
11
+ if (!schema.nodes[nodeName]) {
12
+ throw new Error(`Not able to rewrite schema for node '${nodeName}'`);
13
+ }
14
+ return schema.nodes[nodeName];
15
+ };
16
+ const findMark = (markName) => {
17
+ if (!schema.marks[markName]) {
18
+ throw new Error(`Not able to rewrite schema for mark '${markName}'`);
19
+ }
20
+ return schema.marks[markName];
21
+ };
22
+ // TODO fix readonly warnings
23
+ doc.type = findNode(doc.type.name);
24
+ doc.marks.forEach(mark => {
25
+ mark.type = findMark(mark.type.name);
26
+ });
27
+ doc.descendants(node => {
28
+ node.type = findNode(node.type.name);
29
+ node.marks.forEach(mark => {
30
+ mark.type = findMark(mark.type.name);
31
+ });
32
+ });
33
+ }
20
34
  }
21
35
  export class CoreEditor extends EventTarget {
22
36
  constructor(options = {}) {
@@ -80,7 +94,7 @@ export class CoreEditor extends EventTarget {
80
94
  return this.commandManager.can();
81
95
  }
82
96
  createView(content) {
83
- let doc = createDocument(content, this.schema, this.options.parseOptions, { errorOnInvalidContent: false });
97
+ const doc = createNodeFromContent(content, this.schema);
84
98
  this.state = EditorState.create({ doc });
85
99
  if (this.options.element) {
86
100
  this.view = new EditorView(this.options.element, {
@@ -113,21 +127,11 @@ export class CoreEditor extends EventTarget {
113
127
  });
114
128
  }
115
129
  }
116
- getJSON() {
117
- return this.state.doc.toJSON();
118
- }
119
- /**
120
- * Get the document as HTML.
121
- */
122
- getHTML() {
123
- return getHTMLFromFragment(this.state.doc.content, this.schema);
124
- }
125
130
  setDocument(content, mediaType) {
126
- if (!content) { // clear
131
+ if (!content) {
127
132
  content = {
128
133
  type: this.extensionManager.schema.topNodeType.name,
129
134
  content: this.extensionManager.schema.topNodeType.spec.EMPTY_DOC.content,
130
- // content: this.extensionManager.schema.topNodeType.createAndFill(),
131
135
  };
132
136
  mediaType = undefined;
133
137
  }
@@ -139,8 +143,9 @@ export class CoreEditor extends EventTarget {
139
143
  }
140
144
  }
141
145
  else {
142
- doc = createDocument(content, this.schema, this.options.parseOptions, { errorOnInvalidContent: false });
146
+ doc = createNodeFromContent(content, this.schema);
143
147
  }
148
+ ensureDocSchema(doc, this.schema);
144
149
  this.state = EditorState.create({
145
150
  doc,
146
151
  plugins: this.state.plugins,
@@ -161,9 +166,29 @@ export class CoreEditor extends EventTarget {
161
166
  if (mediaType) {
162
167
  const converter = this.extensionManager.converters[mediaType];
163
168
  if (converter) {
164
- return converter.fromDoc(this.state.doc);
169
+ const json = this.state.doc.toJSON();
170
+ const clonedDoc = ProseMirrorNode.fromJSON(this.state.schema, json);
171
+ return converter.fromDoc(clonedDoc);
172
+ }
173
+ if (mediaType === 'text/json') {
174
+ return this.getJSON();
165
175
  }
166
176
  }
167
177
  return this.state.doc;
168
178
  }
179
+ getJSON() {
180
+ return this.state.doc.toJSON();
181
+ }
182
+ clone(options = {}) {
183
+ return new CoreEditor({
184
+ ...options,
185
+ extensions: [...this.options.extensions]
186
+ });
187
+ }
188
+ debug(doc) {
189
+ if (!doc) {
190
+ doc = this.state.doc;
191
+ }
192
+ console.debug(nodeToTreeString(doc));
193
+ }
169
194
  }
@@ -20,7 +20,7 @@ export declare abstract class Extension {
20
20
  getProseMirrorPlugins(editor: CoreEditor, schema: Schema): Plugin[];
21
21
  getCommands(editor: CoreEditor): Partial<Commands>;
22
22
  getKeyboardShortcuts(): Partial<CommandShortcuts>;
23
- getConverters(): Record<string, Converter>;
23
+ getConverters(editor: CoreEditor, schema: Schema): Record<string, Converter>;
24
24
  setupSpec(spec: SchemaSpec): void;
25
25
  }
26
26
  //# sourceMappingURL=Extension.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Extension.d.ts","sourceRoot":"","sources":["../../../src/editor/src/Extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAE9B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAEnB,QAAQ,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC;CAC9B;AAED,8BAAsB,SAAS;IAIP,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC;IAHhE,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,SAAS,aAAuB,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM;IAGrE,aAAa,IAAI,SAAS,EAAE;IAI5B,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAInE,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIlD,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIjD,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IAI1C,SAAS,CAAC,IAAI,EAAE,UAAU;CAE3B"}
1
+ {"version":3,"file":"Extension.d.ts","sourceRoot":"","sources":["../../../src/editor/src/Extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,WAAW,eAAe;IAE9B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAEnB,QAAQ,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC;CAC9B;AAED,8BAAsB,SAAS;IAIP,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC;IAHhE,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,SAAS,aAAuB,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM;IAGrE,aAAa,IAAI,SAAS,EAAE;IAI5B,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAInE,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIlD,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIjD,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IAI5E,SAAS,CAAC,IAAI,EAAE,UAAU;CAE3B"}
@@ -25,7 +25,7 @@ export class Extension {
25
25
  getKeyboardShortcuts() {
26
26
  return {};
27
27
  }
28
- getConverters() {
28
+ getConverters(editor, schema) {
29
29
  return {};
30
30
  }
31
31
  setupSpec(spec) {
@@ -133,7 +133,7 @@ export class ExtensionManager {
133
133
  mergeShortcuts(extension.getKeyboardShortcuts(this.editor), extension.name);
134
134
  converters = {
135
135
  ...converters,
136
- ...extension.getConverters(this.schema),
136
+ ...extension.getConverters(this.editor, this.schema),
137
137
  };
138
138
  const nodeView = extension.getNodeView();
139
139
  if (nodeView) {
@@ -152,7 +152,7 @@ export class ExtensionManager {
152
152
  mergeShortcuts(extension.getKeyboardShortcuts(this.editor), extension.name);
153
153
  converters = {
154
154
  ...converters,
155
- ...extension.getConverters(this.schema),
155
+ ...extension.getConverters(this.editor, this.schema),
156
156
  };
157
157
  }
158
158
  }
@@ -2,4 +2,5 @@ export * from './CoreEditor.js';
2
2
  export * from './Extension.js';
3
3
  export * from './Mark.js';
4
4
  export * from './Node.js';
5
+ export * from './nodeToTreeString.js';
5
6
  //# sourceMappingURL=mod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/editor/src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/editor/src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,uBAAuB,CAAC"}
@@ -2,3 +2,4 @@ export * from './CoreEditor.js';
2
2
  export * from './Extension.js';
3
3
  export * from './Mark.js';
4
4
  export * from './Node.js';
5
+ export * from './nodeToTreeString.js';
@@ -0,0 +1,4 @@
1
+ import { Node } from 'prosemirror-model';
2
+ export declare function nodeToTreeString(node: Node | Node[] | readonly Node[], level?: number, currentPos?: number): string;
3
+ export declare function debugNode(node: Node | Node[]): void;
4
+ //# sourceMappingURL=nodeToTreeString.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeToTreeString.d.ts","sourceRoot":"","sources":["../../../src/editor/src/nodeToTreeString.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,mBAAmB,CAAC;AAYvC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,SAAS,IAAI,EAAE,EAAE,KAAK,SAAI,EAAE,UAAU,SAAI,UAmDhG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,QAE5C"}
@@ -0,0 +1,53 @@
1
+ function trimText(str, maxLen = 20) {
2
+ str = str.replaceAll('\n', '\\n');
3
+ if (str.length <= maxLen) {
4
+ return str;
5
+ }
6
+ return str.slice(0, maxLen) + '...';
7
+ }
8
+ export function nodeToTreeString(node, level = 0, currentPos = 0) {
9
+ let delim = '';
10
+ for (let i = 0; i < level; i++) {
11
+ delim += ' ';
12
+ }
13
+ let output = '';
14
+ if (Array.isArray(node)) {
15
+ for (const child of node) {
16
+ output += delim + nodeToTreeString(child, level + 1, currentPos).replace(/\s+$/gm, '') + '\n';
17
+ }
18
+ return output;
19
+ }
20
+ // https://prosemirror.net/docs/guide/#doc.indexing
21
+ let line = '';
22
+ // if (node.type) {
23
+ line += ` - [${node.type.name}] `;
24
+ // } else {
25
+ // line += ` - `;
26
+ // }
27
+ line += `pos: ${currentPos}, `;
28
+ line += `nodeSize: ${node.nodeSize}, `; // isLeaf ? 1 : 2 + this.content.size
29
+ line += `epos: ${currentPos + node.nodeSize}, `; // isLeaf ? 1 : 2 + this.content.size
30
+ if (node.content) {
31
+ line += `fragment.size: ${node.content.size}, `;
32
+ }
33
+ output += (delim + line) + '\n';
34
+ let marksLine = '';
35
+ if (node.marks) {
36
+ for (const mark of node.marks) {
37
+ marksLine += `(${mark.type.name}), `;
38
+ }
39
+ }
40
+ if (marksLine) {
41
+ output += (delim + ' ' + marksLine) + '\n';
42
+ }
43
+ if (node.text) {
44
+ output += (delim + ' "' + trimText(node.text) + '"') + '\n';
45
+ }
46
+ node.forEach((child, offset) => {
47
+ output += nodeToTreeString(child, level + 1, currentPos + offset + 1).replace(/\s+$/gm, '') + '\n'; // + (node.isLeaf ? 1 : 2)
48
+ });
49
+ return output;
50
+ }
51
+ export function debugNode(node) {
52
+ console.debug(nodeToTreeString(node));
53
+ }
@@ -1,12 +1,8 @@
1
- import { Fragment, Node as ProseMirrorNode, type ParseOptions, Schema } from 'prosemirror-model';
1
+ import { Fragment, Node as ProseMirrorNode, Schema } from 'prosemirror-model';
2
2
  import type { Content } from '../types.js';
3
3
  export type CreateNodeFromContentOptions = {
4
- slice?: boolean;
5
- parseOptions?: ParseOptions;
6
4
  errorOnInvalidContent?: boolean;
7
5
  };
8
- export declare function elementFromString(value: string): HTMLElement;
9
- export declare function createNodeFromHTML(content: string, schema: Schema, options?: CreateNodeFromContentOptions): ProseMirrorNode | Fragment;
10
6
  export declare function createNodeFromObject(content: Content | ProseMirrorNode | Fragment, schema: Schema, options?: CreateNodeFromContentOptions): ProseMirrorNode | Fragment;
11
- export declare function createNodeFromContent(content: string | Content | ProseMirrorNode | Fragment, schema: Schema, options?: CreateNodeFromContentOptions): ProseMirrorNode | Fragment;
7
+ export declare function createNodeFromContent(content: Content | ProseMirrorNode | Fragment, schema: Schema, options?: CreateNodeFromContentOptions): ProseMirrorNode | Fragment;
12
8
  //# sourceMappingURL=createNodeFromContent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createNodeFromContent.d.ts","sourceRoot":"","sources":["../../../../src/editor/src/utilities/createNodeFromContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,IAAI,IAAI,eAAe,EACvB,KAAK,YAAY,EACjB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAqBF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAQ5D;AAGD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,eAAe,GAAG,QAAQ,CAiE5B;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,EAC7C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,eAAe,GAAG,QAAQ,CAwC5B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,eAAe,GAAG,QAAQ,EACtD,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,eAAe,GAAG,QAAQ,CAiB5B"}
1
+ {"version":3,"file":"createNodeFromContent.d.ts","sourceRoot":"","sources":["../../../../src/editor/src/utilities/createNodeFromContent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,IAAI,IAAI,eAAe,EACvB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,4BAA4B,GAAG;IACzC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,EAC7C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,eAAe,GAAG,QAAQ,CAiC5B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,EAC7C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,4BAA4B,GACrC,eAAe,GAAG,QAAQ,CAY5B"}
@@ -1,105 +1,24 @@
1
- import { DOMParser, Fragment, Node as ProseMirrorNode, Schema, } from 'prosemirror-model';
2
- const removeWhitespaces = (node) => {
3
- const children = node.childNodes;
4
- for (let i = children.length - 1; i >= 0; i -= 1) {
5
- const child = children[i];
6
- if (child.nodeType === 3 && child.nodeValue &&
7
- /^(\n\s\s|\n)$/.test(child.nodeValue)) {
8
- node.removeChild(child);
9
- }
10
- else if (child.nodeType === 1) {
11
- removeWhitespaces(child);
12
- }
13
- }
14
- return node;
15
- };
16
- export function elementFromString(value) {
17
- // add a wrapper to preserve leading and trailing whitespace
18
- const wrappedValue = `<body>${value}</body>`;
19
- const html = new globalThis.DOMParser().parseFromString(wrappedValue, 'text/html').body;
20
- return removeWhitespaces(html);
21
- }
22
- // TODO: refactor to converters?
23
- export function createNodeFromHTML(content, schema, options) {
24
- options = {
25
- slice: true,
26
- parseOptions: {},
27
- ...options,
28
- };
29
- // Check for invalid content
30
- if (options.errorOnInvalidContent) {
31
- let hasInvalidContent = false;
32
- let invalidContent = '';
33
- // A copy of the current schema with a catch-all node at the end
34
- const contentCheckSchema = new Schema({
35
- topNode: schema.spec.topNode,
36
- marks: schema.spec.marks,
37
- // Prosemirror's schemas are executed such that: the last to execute, matches last
38
- // 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
39
- nodes: schema.spec.nodes.append({
40
- __unknown__catch__all__node: {
41
- content: 'inline*',
42
- group: 'block',
43
- parseDOM: [
44
- {
45
- tag: '*',
46
- getAttrs: (e) => {
47
- // If this is ever called, we know that the content has something that we don't know how to handle in the schema
48
- hasInvalidContent = true;
49
- // Try to stringify the element for a more helpful error message
50
- invalidContent = typeof e === 'string' ? e : e.outerHTML;
51
- return null;
52
- },
53
- },
54
- ],
55
- },
56
- }),
57
- });
58
- if (options.slice) {
59
- DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
60
- }
61
- else {
62
- DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
63
- }
64
- if (options.errorOnInvalidContent && hasInvalidContent) {
65
- throw new Error('Invalid HTML content', {
66
- cause: new Error(`Invalid element found: ${invalidContent}`),
67
- });
68
- }
69
- }
70
- const parser = DOMParser.fromSchema(schema);
71
- if (options.slice) {
72
- return parser.parseSlice(elementFromString(content), options.parseOptions)
73
- .content;
74
- }
75
- return parser.parse(elementFromString(content), options.parseOptions);
76
- }
1
+ import { Fragment, Node as ProseMirrorNode, } from 'prosemirror-model';
77
2
  export function createNodeFromObject(content, schema, options) {
78
- options = {
79
- slice: true,
80
- parseOptions: {},
81
- ...options,
82
- };
83
3
  try {
84
4
  // if the JSON Content is an array of nodes, create a fragment for each node
85
5
  if (Array.isArray(content) && content.length > 0) {
86
6
  return Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item)));
87
7
  }
88
8
  const node = schema.nodeFromJSON(content);
89
- if (options.errorOnInvalidContent) {
9
+ if (options?.errorOnInvalidContent) {
90
10
  node.check();
91
11
  }
92
12
  return node;
93
13
  }
94
14
  catch (error) {
95
- if (options.errorOnInvalidContent) {
15
+ if (options?.errorOnInvalidContent) {
96
16
  throw new Error('Invalid JSON content', {
97
17
  cause: error,
98
18
  });
99
19
  }
100
20
  console.warn('Invalid content.', 'Passed value:', content, 'Error:', error);
101
- // TODO: refactor using EMPTY_DOC prop?
102
- return createNodeFromHTML('', schema, options);
21
+ return schema.topNodeType.createAndFill(null, []);
103
22
  }
104
23
  }
105
24
  export function createNodeFromContent(content, schema, options) {
@@ -107,12 +26,8 @@ export function createNodeFromContent(content, schema, options) {
107
26
  return content;
108
27
  }
109
28
  const isJSONContent = typeof content === 'object' && content !== null;
110
- const isTextContent = typeof content === 'string';
111
29
  if (isJSONContent) {
112
30
  createNodeFromObject(content, schema, options);
113
31
  }
114
- if (isTextContent) {
115
- return createNodeFromHTML(content, schema, options);
116
- }
117
- return createNodeFromHTML('', schema, options);
32
+ return schema.topNodeType.createAndFill(null, []);
118
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerebron/extension-menu",
3
- "version": "0.0.12",
3
+ "version": "0.1.0",
4
4
  "license": "MIT",
5
5
  "module": "./esm/extension-menu/src/ExtensionMenu.js",
6
6
  "exports": {
@@ -11,10 +11,10 @@
11
11
  "scripts": {},
12
12
  "dependencies": {
13
13
  "prosemirror-keymap": "1.2.2",
14
- "prosemirror-model": "1.24.1",
14
+ "prosemirror-model": "1.25.1",
15
15
  "prosemirror-state": "1.4.3",
16
- "prosemirror-transform": "1.10.3",
17
- "prosemirror-view": "1.33.6"
16
+ "prosemirror-transform": "1.10.4",
17
+ "prosemirror-view": "1.40.0"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/node": "^20.9.0"