diff options
Diffstat (limited to 'src/fields')
| -rw-r--r-- | src/fields/Doc.ts | 46 | ||||
| -rw-r--r-- | src/fields/RichTextField.ts | 26 | ||||
| -rw-r--r-- | src/fields/RichTextUtils.ts | 10 |
3 files changed, 48 insertions, 34 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 40ef67f92..40da482d2 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -695,6 +695,9 @@ export namespace Doc { return bestAlias ?? Doc.MakeAlias(doc); } + // this lists out all the tag ids that can be in a RichTextField that might contain document ids. + // if a document is cloned, we need to make sure to clone all of these referenced documents as well; + export const DocsInTextFieldIds = ['audioId', 'textId', 'anchorId', 'docId']; export async function makeClone(doc: Doc, cloneMap: Map<string, Doc>, linkMap: Map<string, Doc>, rtfs: { copy: Doc; key: string; field: RichTextField }[], exclusions: string[], cloneLinks: boolean, asBranch: boolean): Promise<Doc> { if (Doc.IsBaseProto(doc)) return doc; if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!; @@ -713,12 +716,22 @@ export namespace Doc { if (docs !== undefined && docs.length) { const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch))); assignKey(new List<Doc>(clones)); - } else if (doc[key] instanceof Doc) { - assignKey(key.includes('layout[') ? undefined : key.startsWith('layout') ? (doc[key] as Doc) : await Doc.makeClone(doc[key] as Doc, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch)); // reference documents except copy documents that are expanded template fields } else { assignKey(ObjectField.MakeCopy(field)); if (field instanceof RichTextField) { - if (field.Data.includes('"audioId":') || field.Data.includes('"textId":') || field.Data.includes('"anchorId":')) { + if (DocsInTextFieldIds.some(id => field.Data.includes(`"${id}":`))) { + const docidsearch = new RegExp('(' + DocsInTextFieldIds.map(exp => '(' + exp + ')').join('|') + ')":"([a-z-A-Z0-9_]*)"', 'g'); + const rawdocids = field.Data.match(docidsearch); + const docids = rawdocids?.map((str: string) => + DocsInTextFieldIds.reduce((output, exp) => { + return output.replace(new RegExp(`${exp}":`, 'g'), ''); + }, str) + .replace(/"/g, '') + .trim() + ); + const results = docids && (await DocServer.GetRefFields(docids)); + const docs = results && Array.from(Object.keys(results)).map(key => DocCast(results[key])); + docs && docs.map(doc => Doc.makeClone(doc, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch)); rtfs.push({ copy, key, field }); } } @@ -726,24 +739,22 @@ export namespace Doc { }; const docAtKey = doc[key]; if (docAtKey instanceof Doc) { - if (!Doc.IsSystem(docAtKey) && (key === 'annotationOn' || key === 'proto' || ((key === 'anchor1' || key === 'anchor2') && doc.author === Doc.CurrentUserEmail))) { + if (!Doc.IsSystem(docAtKey) && (key.startsWith('layout') || key === 'annotationOn' || key === 'proto' || ((key === 'anchor1' || key === 'anchor2') && doc.author === Doc.CurrentUserEmail))) { assignKey(await Doc.makeClone(docAtKey, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch)); } else { assignKey(docAtKey); } + } else if (field instanceof RefField) { + assignKey(field); + } else if (cfield instanceof ComputedField) { + assignKey(cfield[Copy]()); + // ComputedField.MakeFunction(cfield.script.originalScript)); + } else if (field instanceof ObjectField) { + await copyObjectField(field); + } else if (field instanceof Promise) { + debugger; //This shouldn't happen... } else { - if (field instanceof RefField) { - assignKey(field); - } else if (cfield instanceof ComputedField) { - assignKey(cfield[Copy]()); - // ComputedField.MakeFunction(cfield.script.originalScript)); - } else if (field instanceof ObjectField) { - await copyObjectField(field); - } else if (field instanceof Promise) { - debugger; //This shouldn't happen... - } else { - assignKey(field); - } + assignKey(field); } }) ); @@ -807,7 +818,8 @@ export namespace Doc { }; const regex = `(${Doc.localServerPath()})([^"]*)`; const re = new RegExp(regex, 'g'); - copy[key] = new RichTextField(field.Data.replace(/("textId":|"audioId":|"anchorId":)"([^"]+)"/g, replacer).replace(re, replacer2), field.Text); + const docidsearch = new RegExp('(' + DocsInTextFieldIds.map(exp => `"${exp}":`).join('|') + ')"([^"]+)"', 'g'); + copy[key] = new RichTextField(field.Data.replace(docidsearch, replacer).replace(re, replacer2), field.Text); }); return { clone: copy, map: cloneMap, linkMap }; } diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts index d7edd4266..3e75a071f 100644 --- a/src/fields/RichTextField.ts +++ b/src/fields/RichTextField.ts @@ -1,11 +1,11 @@ -import { serializable } from "serializr"; -import { scriptingGlobal } from "../client/util/ScriptingGlobals"; -import { Deserializable } from "../client/util/SerializationHelper"; -import { Copy, ToScriptString, ToString } from "./FieldSymbols"; -import { ObjectField } from "./ObjectField"; +import { serializable } from 'serializr'; +import { scriptingGlobal } from '../client/util/ScriptingGlobals'; +import { Deserializable } from '../client/util/SerializationHelper'; +import { Copy, ToScriptString, ToString } from './FieldSymbols'; +import { ObjectField } from './ObjectField'; @scriptingGlobal -@Deserializable("RichTextField") +@Deserializable('RichTextField') export class RichTextField extends ObjectField { @serializable(true) readonly Data: string; @@ -13,14 +13,14 @@ export class RichTextField extends ObjectField { @serializable(true) readonly Text: string; - constructor(data: string, text: string = "") { + constructor(data: string, text: string = '') { super(); this.Data = data; this.Text = text; } 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('align')); } [Copy]() { @@ -28,14 +28,16 @@ export class RichTextField extends ObjectField { } [ToScriptString]() { - return `new RichTextField("${this.Data.replace(/"/g, "\\\"")}", "${this.Text}")`; + return `new RichTextField("${this.Data.replace(/"/g, '\\"')}", "${this.Text}")`; } [ToString]() { return this.Text; } public static DashField(fieldKey: string) { - 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":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`, ""); + 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":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docId":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`, + '' + ); } - -}
\ No newline at end of file +} diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts index bf055cd8b..239b59e83 100644 --- a/src/fields/RichTextUtils.ts +++ b/src/fields/RichTextUtils.ts @@ -264,18 +264,18 @@ export namespace RichTextUtils { const imageNode = (schema: any, image: ImageTemplate, textNote: Doc) => { const { url: src, width, agnostic } = image; - let docid: string; + let docId: string; const guid = Utils.GenerateDeterministicGuid(agnostic); const backingDocId = StrCast(textNote[guid]); if (!backingDocId) { const backingDoc = Docs.Create.ImageDocument(agnostic, { _width: 300, _height: 300 }); DocUtils.makeCustomViewClicked(backingDoc, Docs.Create.FreeformDocument); - docid = backingDoc[Id]; - textNote[guid] = docid; + docId = backingDoc[Id]; + textNote[guid] = docId; } else { - docid = backingDocId; + docId = backingDocId; } - return schema.node('image', { src, agnostic, width, docid, float: null, location: 'add:right' }); + return schema.node('image', { src, agnostic, width, docId, float: null, location: 'add:right' }); }; const textNode = (schema: any, run: docs_v1.Schema$TextRun) => { |
