Closed ansemjo closed 6 months ago
Haven't actually tested this yet but maybe something as simple as passing ParseOptions
straight down to toDoc
works?
diff --git a/projects/ngx-editor/src/lib/Editor.ts b/projects/ngx-editor/src/lib/Editor.ts
index adcd76b..36263b9 100644
--- a/projects/ngx-editor/src/lib/Editor.ts
+++ b/projects/ngx-editor/src/lib/Editor.ts
@@ -1,4 +1,4 @@
-import { Schema } from 'prosemirror-model';
+import { ParseOptions, Schema } from 'prosemirror-model';
import { EditorState, Plugin, Transaction } from 'prosemirror-state';
import { EditorProps, EditorView } from 'prosemirror-view';
import { Observable, Subject } from 'rxjs';
@@ -26,6 +26,7 @@ interface Options {
features?: EditorFeatures;
handleScrollToSelection?: EditorProps['handleScrollToSelection'];
linkValidationPattern?: string;
+ parseOptions?: ParseOptions;
}
interface EditorFeatures {
@@ -50,6 +51,7 @@ const DEFAULT_OPTIONS: Options = {
features: defaultFeatures,
handleScrollToSelection: null,
linkValidationPattern: '(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/??([^#\n\r]*)?#?([^\n\r]*)|(mailto:.*[@].*)',
+ parseOptions: undefined,
};
class Editor {
@@ -104,10 +106,10 @@ class Editor {
private createEditor(): void {
const { options, schema } = this;
- const { content = null, nodeViews } = options;
+ const { content = null, nodeViews, parseOptions } = options;
const { history = true, keyboardShortcuts = true, inputRules = true } = options;
- const doc = parseContent(content, schema);
+ const doc = parseContent(content, schema, parseOptions);
const plugins: Plugin[] = options.plugins ?? [];
const attributes: EditorProps['attributes'] = options.attributes ?? {};
diff --git a/projects/ngx-editor/src/lib/parsers.ts b/projects/ngx-editor/src/lib/parsers.ts
index 0498ec4..b2be9c7 100644
--- a/projects/ngx-editor/src/lib/parsers.ts
+++ b/projects/ngx-editor/src/lib/parsers.ts
@@ -1,4 +1,4 @@
-import { DOMSerializer, Schema, DOMParser, Node as ProseMirrorNode } from 'prosemirror-model';
+import { DOMSerializer, Schema, DOMParser, Node as ProseMirrorNode, ParseOptions } from 'prosemirror-model';
import defaultSchema from './schema';
import { HTML, isHtml } from './trustedTypesUtil';
@@ -24,16 +24,16 @@ export const toHTML = (json: Record<string, any>, inputSchema?: Schema): string
return div.innerHTML;
};
-export const toDoc = (html: HTML, inputSchema?: Schema): Record<string, any> => {
+export const toDoc = (html: HTML, inputSchema?: Schema, options?: ParseOptions): Record<string, any> => {
const schema = inputSchema ?? defaultSchema;
const el = document.createElement('div');
el.innerHTML = html as any;
- return DOMParser.fromSchema(schema).parse(el).toJSON();
+ return DOMParser.fromSchema(schema).parse(el, options).toJSON();
};
-export const parseContent = (value: HTML | Record<string, any> | null, schema: Schema): ProseMirrorNode => {
+export const parseContent = (value: HTML | Record<string, any> | null, schema: Schema, options?: ParseOptions): ProseMirrorNode => {
if (!value) {
return schema.nodeFromJSON(emptyDoc);
}
@@ -42,6 +42,6 @@ export const parseContent = (value: HTML | Record<string, any> | null, schema: S
return schema.nodeFromJSON(value);
}
- const docJson = toDoc(value as HTML, schema);
+ const docJson = toDoc(value as HTML, schema, options);
return schema.nodeFromJSON(docJson);
};
So, I figured out how to use a schema for my use-case (see the edit in the first comment above). I'm not sure how well that works for any nested nodes but so far it seems to work fine.
I'll leave the issue open for you to decide whether the API addition of ParseOptions
makes sense ..
Edit: sorry for the spam š¬ But I think this feature might still be necessary (or at least useful) because the above schema does not work when you pass plaintext content to the editor, which is not HTML yet. I can't figure out how to amend the doc
or text
schemas to correctly preserve whitespace either in that case. As a workaround you can just wrap the plaintext in <p>...</p>
and replace any newlines (\n
) with <br>
.
HI. Thanks for creating the issue. Will look into this tomorrow.
I've been running into the same issue. Since this issue is still open i assume it has yet to be implemented. Looking forward to this feature (or something similar that will allow the users to preserve white spaces when parsing from html to json with toDoc()
Added in v17.1.0
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in the thread.
Proposal
I think this is similar to #430. Even if you insert a
<code>
block, insert multiple spaces inside that block and then later re-parse the exported HTML with anngx-editor
(I'm using the "Reactive Forms" style, if that makes any difference), the spaces get trimmed down.The need for retaining spaces is also discussed on the ProseMirror forum, with the apparent solution being that you could pass
{ preserveWhiteSpace: true }
to PM. So yes, while the "editor itself does not [...] transform HTML", maybe it could help by passing this as an optional flag to ProseMirror?(Or is there a way to configure this via
attributes
or something and I just haven't figured it out yet? š¬)Willing to submit a PR?
None
I see that
preserveWhitespace
is used on the documentation page on Schema, but I'm not sure how to use / apply this to the entirety of the HTML that is passed to the editor?Edit: Overriding the default paragraph schema like this works for my use-case, too. I'm ignoring the
align
style here because I am manually aligning text with a monospace font anyway.