aboutsummaryrefslogtreecommitdiff
path: root/src/fields/RichTextField.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields/RichTextField.ts')
-rw-r--r--src/fields/RichTextField.ts60
1 files changed, 53 insertions, 7 deletions
diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts
index 3f13f7e6d..bcef1fefc 100644
--- a/src/fields/RichTextField.ts
+++ b/src/fields/RichTextField.ts
@@ -13,14 +13,19 @@ export class RichTextField extends ObjectField {
@serializable(true)
readonly Text: string;
- constructor(data: string, text: string = '') {
+ /**
+ * NOTE: if 'text' doesn't match the plain text of 'data', this can cause infinite loop problems or other artifacts when rendered.
+ * @param data this is the formatted text representation of the RTF
+ * @param text this is the plain text of whatever text is in the 'data'
+ */
+ constructor(data: string, text: string) {
super();
this.Data = data;
- this.Text = text;
+ this.Text = text; // ideally, we'd compute 'text' from 'data' by doing what Prosemirror does at run-time ... just need to figure out how to write that function accurately
}
Empty() {
- return !(this.Text || this.Data.toString().includes('dashField') || this.Data.toString().includes('align'));
+ return !(this.Text || this.Data.toString().includes('dashField') || this.Data.toString().includes('dashDoc') || this.Data.toString().includes('align'));
}
[Copy]() {
@@ -37,10 +42,51 @@ export class RichTextField extends ObjectField {
return this.Text;
}
- public static RTFfield() {
- return new RichTextField(
- `{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`,
- ''
+ // AARAV ADD=
+ static ToProsemirrorDoc = (content: Record<string, unknown>[], selection: Record<string, unknown>) => ({
+ doc: {
+ type: 'doc',
+ content,
+ },
+ selection,
+ });
+
+ private static ToProsemirrorTextContent = (text: string, styles?: { bold?: boolean; italic?: boolean; fontSize?: number; color?: string }) => [
+ {
+ type: 'text',
+ marks: [
+ ...(styles?.bold ? [{ type: 'strong' }] : []),
+ ...(styles?.italic ? [{ type: 'em' }] : []),
+ ...(styles?.fontSize ? [{ type: 'pFontSize', attrs: { fontSize: `${styles.fontSize}px` } }] : []),
+ ...(styles?.color ? [{ type: 'pFontColor', attrs: { fontColor: styles.color } }] : []),
+ ],
+ text,
+ },
+ ];
+
+ private static ToProsemirrorDashDocContent = (docId: string) => [
+ {
+ type: 'dashDoc',
+ attrs: { width: '200px', height: '200px', title: 'dashDoc', float: 'unset', hidden: false, docId },
+ },
+ ];
+
+ private static ToProsemirror = (plaintext: string, imgDocId?: string, styles?: { bold?: boolean; italic?: boolean; fontSize?: number; color?: string }, selectBack?: number) =>
+ RichTextField.ToProsemirrorDoc(
+ plaintext
+ .split('\n')
+ .filter(text => (imgDocId ? text : true)) // if there's an image doc, we don't want it repeat for each paragraph -- assume there's only one paragraph with text in it
+ .map(text => ({
+ type: 'paragraph',
+ content: [
+ ...(text.length ? RichTextField.ToProsemirrorTextContent(text, styles) : []), // An empty paragraph gets treated as a line break
+ ...(imgDocId ? RichTextField.ToProsemirrorDashDocContent(imgDocId) : []),
+ ],
+ })),
+ { type: 'text', anchor: 2 + plaintext.length - (selectBack ?? 0), head: 2 + plaintext.length }
);
+
+ public static textToRtf(text: string, imgDocId?: string, styles?: { bold?: boolean; italic?: boolean; fontSize?: number; color?: string }, selectBack?: number) {
+ return new RichTextField(JSON.stringify(RichTextField.ToProsemirror(text, imgDocId, styles, selectBack)), text);
}
}