aboutsummaryrefslogtreecommitdiff
path: root/src/client/documents/DocUtils.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-04-21 13:48:58 -0400
committerbobzel <zzzman@gmail.com>2025-04-21 13:48:58 -0400
commit17e24e780b54f2f7015c0ca955c3aa5091bba19c (patch)
treeb13002c92d58cb52a02b46e4e1d578f1d57125f2 /src/client/documents/DocUtils.ts
parent22a40443193320487c27ce02bd3f134d13cb7d65 (diff)
parent1f294ef4a171eec72a069a9503629eaf7975d983 (diff)
merged with master and cleaned up outpainting a bit.
Diffstat (limited to 'src/client/documents/DocUtils.ts')
-rw-r--r--src/client/documents/DocUtils.ts113
1 files changed, 55 insertions, 58 deletions
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts
index 1c7ccadd1..7b36c3a66 100644
--- a/src/client/documents/DocUtils.ts
+++ b/src/client/documents/DocUtils.ts
@@ -8,7 +8,6 @@ import * as JSZipUtils from '../../JSZipUtils';
import { decycle } from '../../decycler/decycler';
import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Field, FieldResult, FieldType, LinkedTo, Opt, StrListCast } from '../../fields/Doc';
-import { DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { InkData, InkDataFieldName, InkField } from '../../fields/InkField';
import { List, ListFieldName } from '../../fields/List';
@@ -56,13 +55,13 @@ export namespace DocUtils {
const matchLink = (val: string, anchor: Doc) => {
const linkedToExp = (val ?? '').split('=');
if (linkedToExp.length === 1) return Field.toScriptString(anchor) === val;
- return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
+ return DocCast(anchor[linkedToExp[0]]) && Field.toScriptString(DocCast(anchor[linkedToExp[0]])!) === linkedToExp[1];
};
// prettier-ignore
return (value === Doc.FilterNone && !allLinks.length) ||
(value === Doc.FilterAny && !!allLinks.length) ||
- (allLinks.some(link => matchLink(value as string, DocCast(link.link_anchor_1)) ||
- matchLink(value as string, DocCast(link.link_anchor_2)) ));
+ (allLinks.some(link => (DocCast(link.link_anchor_1) && matchLink(value as string, DocCast(link.link_anchor_1)!)) ||
+ (DocCast(link.link_anchor_2) && matchLink(value as string, DocCast(link.link_anchor_2)!)) ));
}
if (typeof value === 'string') {
value = value.replace(`,${ClientUtils.noRecursionHack}`, '');
@@ -267,7 +266,7 @@ export namespace DocUtils {
Object.keys(funcs)
.filter(key => !key.endsWith('-setter'))
.forEach(key => {
- const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+ const cfield = ComputedField.DisableCompute(() => FieldValue(doc[key]));
const func = funcs[key];
if (ScriptCast(cfield)?.script.originalScript !== func) {
const setFunc = Cast(funcs[key + '-setter'], 'string', null);
@@ -284,10 +283,10 @@ export namespace DocUtils {
}
return val1 === val2;
};
- Object.entries(reqdOpts).forEach(pair => {
- const targetDoc = pair[0].startsWith('_') ? doc : Doc.GetProto(doc as Doc);
- if (!Object.getOwnPropertyNames(targetDoc).includes(pair[0].replace(/^_/, '')) || !compareValues(pair[1], targetDoc[pair[0]])) {
- targetDoc[pair[0]] = pair[1];
+ Object.entries(reqdOpts).forEach(([key, val]) => {
+ const targetDoc = key.startsWith('_') ? doc : Doc.GetProto(doc as Doc);
+ if (!Object.getOwnPropertyNames(targetDoc).includes(key.replace(/^_/, '')) || !compareValues(val, targetDoc[key])) {
+ targetDoc[key] = val as FieldType;
}
});
items?.forEach(item => !DocListCast(doc.data).includes(item) && Doc.AddDocToList(Doc.GetProto(doc), 'data', item));
@@ -376,17 +375,18 @@ export namespace DocUtils {
const documentList: ContextMenuProps[] = foo
.filter(btnDoc => !btnDoc.hidden)
- .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
+ .map(btnDoc => DocCast(btnDoc?.dragFactory))
.filter(doc => doc && doc !== Doc.UserDoc().emptyTrail && doc.title)
+ .map(doc => doc!)
.map(dragDoc => ({
description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
event: undoable(() => {
- const newDoc = DocUtils.copyDragFactory(dragDoc);
+ const newDoc = (dragDoc.isTemplateDoc ? DocUtils.delegateDragFactory : DocUtils.copyDragFactory)(dragDoc);
if (newDoc) {
- newDoc.author = ClientUtils.CurrentUserEmail();
+ newDoc._author = ClientUtils.CurrentUserEmail();
newDoc.x = x;
newDoc.y = y;
- newDoc[DocData].backgroundColor = Doc.UserDoc().textBackgroundColor;
+ newDoc.$backgroundColor = Doc.UserDoc().textBackgroundColor;
DocumentView.SetSelectOnLoad(newDoc);
if (pivotField) {
newDoc[pivotField] = pivotValue;
@@ -438,6 +438,7 @@ export namespace DocUtils {
.filter(btnDoc => !btnDoc.hidden)
.map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
.filter(doc => doc && doc !== Doc.UserDoc().emptyTrail && doc !== Doc.UserDoc().emptyNote && doc.title)
+ .map(doc => doc!)
.map(dragDoc => ({
description: ':' + StrCast(dragDoc.title).replace('Untitled ', ''),
event: undoable(() => {
@@ -495,11 +496,11 @@ export namespace DocUtils {
.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc)
.filter(d => d.isTemplateDoc);
// bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized
- // first try to find a template that matches the specific document type (<typeName>_<templateName>). otherwise, fallback to a general match on <templateName>
+ // first try to find a template that matches the specific document type (<typeName><TemplateName>). otherwise, fallback to a general match on <templateName>
!docLayoutTemplate &&
allTemplates.forEach(tempDoc => {
const templateType = StrCast(doc[templateName + '_fieldKey'] || doc.type);
- StrCast(tempDoc.title) === templateName + '_' + templateType && (docLayoutTemplate = tempDoc);
+ StrCast(tempDoc.title) === templateName + (templateType[0].toUpperCase() + templateType.slice(1)) && (docLayoutTemplate = tempDoc);
});
!docLayoutTemplate &&
allTemplates.forEach(tempDoc => {
@@ -523,18 +524,13 @@ export namespace DocUtils {
Doc.ApplyTemplateTo(docLayoutTemplate, doc, customName, undefined);
}
} else {
- let fieldTemplate: Opt<Doc>;
- if (doc.data instanceof RichTextField || typeof doc.data === 'string') {
- fieldTemplate = Docs.Create.TextDocument('', options);
- } else if (doc.data instanceof PdfField) {
- fieldTemplate = Docs.Create.PdfDocument('http://www.msn.com', options);
- } else if (doc.data instanceof VideoField) {
- fieldTemplate = Docs.Create.VideoDocument('http://www.cs.brown.edu', options);
- } else if (doc.data instanceof AudioField) {
- fieldTemplate = Docs.Create.AudioDocument('http://www.cs.brown.edu', options);
- } else if (doc.data instanceof ImageField) {
- fieldTemplate = Docs.Create.ImageDocument('http://www.cs.brown.edu', options);
- }
+ const fieldTemplate = (() => {
+ if (doc.data instanceof RichTextField || typeof doc.data === 'string') return Docs.Create.TextDocument('', options);
+ if (doc.data instanceof PdfField) return Docs.Create.PdfDocument('http://www.msn.com', options);
+ if (doc.data instanceof VideoField) return Docs.Create.VideoDocument('http://www.cs.brown.edu', options);
+ if (doc.data instanceof AudioField) return Docs.Create.AudioDocument('http://www.cs.brown.edu', options);
+ if (doc.data instanceof ImageField) return Docs.Create.ImageDocument('http://www.cs.brown.edu', options);
+ })();
const docTemplate = creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + '(' + doc.title + ')', isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, docTemplate ? Doc.GetProto(docTemplate) : docTemplate);
docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
@@ -579,7 +575,7 @@ export namespace DocUtils {
Docs.Create.FreeformDocument([], {
_width: NumCast(layoutDoc._width) + 10,
_height: Math.max(NumCast(layoutDoc._height), NumCast(layoutDoc._width) + 10),
- _isLightbox: true,
+ isLightbox: true,
_layout_fitWidth: true,
title: StrCast(doc.title) + ' [Portal]',
}),
@@ -715,37 +711,38 @@ export namespace DocUtils {
nativeWidth: 40,
nativeHeight: 40,
})
- : Docs.Create.TextDocument('', {
- annotationOn,
- backgroundColor,
- x,
- y,
- title,
- ...(defaultTextTemplate
- ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance
- : {
- _width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200,
- _height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35,
- _layout_centered: BoolCast(Doc.UserDoc()._layout_centered),
- _layout_fitWidth: true,
- _layout_autoHeight: true,
- backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor),
- borderColor: Doc.UserDoc().borderColor as string,
- borderWidth: Doc.UserDoc().borderWidth as number,
- text_fitBox: BoolCast(Doc.UserDoc().fitBox),
- text_align: StrCast(Doc.UserDoc().textAlign),
- text_fontColor: StrCast(Doc.UserDoc().fontColor),
- text_fontFamily: StrCast(Doc.UserDoc().fontFamily),
- text_fontWeight: StrCast(Doc.UserDoc().fontWeight),
- text_fontStyle: StrCast(Doc.UserDoc().fontStyle),
- text_fontDecoration: StrCast(Doc.UserDoc().fontDecoration),
- }),
- });
+ : (defaultTextTemplate?.type === DocumentType.JOURNAL ? Docs.Create.DailyJournalDocument:Docs.Create.TextDocument)(
+ '',
+ {
+ annotationOn,
+ backgroundColor,
+ x,
+ y,
+ title,
+ ...(defaultTextTemplate
+ ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance
+ : {
+ _width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200,
+ _height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35,
+ _layout_autoHeight: true,
+ backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor),
+ borderColor: Doc.UserDoc().borderColor as string,
+ borderWidth: Doc.UserDoc().borderWidth as number,
+ text_centered: BoolCast(Doc.UserDoc().textCentered),
+ text_fitBox: BoolCast(Doc.UserDoc().fitBox),
+ text_align: StrCast(Doc.UserDoc().textAlign),
+ text_fontColor: StrCast(Doc.UserDoc().fontColor),
+ text_fontFamily: StrCast(Doc.UserDoc().fontFamily),
+ text_fontWeight: StrCast(Doc.UserDoc().fontWeight),
+ text_fontStyle: StrCast(Doc.UserDoc().fontStyle),
+ text_fontDecoration: StrCast(Doc.UserDoc().fontDecoration),
+ }),
+ });
if (defaultTextTemplate) {
tbox.layout_fieldKey = 'layout_' + StrCast(defaultTextTemplate.title);
Doc.GetProto(tbox)[StrCast(tbox.layout_fieldKey)] = defaultTextTemplate; // set the text doc's layout to render with the text template
- tbox[DocData].proto = defaultTextTemplate; // and also set the text doc to inherit from the template (this allows the template to specify default field values)
+ tbox.$proto = defaultTextTemplate; // and also set the text doc to inherit from the template (this allows the template to specify default field values)
}
return tbox;
}
@@ -873,13 +870,13 @@ export namespace DocUtils {
const ndoc = Doc.MakeDelegateWithProto(dragFactory);
if (ndoc && dragFactory.dragFactory_count !== undefined) {
dragFactory.dragFactory_count = NumCast(dragFactory.dragFactory_count) + 1;
- Doc.GetProto(ndoc).title = ndoc.title + ' ' + NumCast(dragFactory.dragFactory_count).toString();
+ Doc.GetProto(ndoc).title = ndoc.title;
}
return ndoc;
}
- export async function Zip(doc: Doc, zipFilename = 'dashExport.zip') {
- const { clone, map, linkMap } = await Doc.MakeClone(doc);
+ export function Zip(doc: Doc, zipFilename = 'dashExport.zip') {
+ const { clone, map, linkMap } = Doc.MakeClone(doc);
const proms = new Set<string>();
function replacer(key: string, value: { url: string; [key: string]: unknown }) {
if (key && ['branchOf', 'cloneOf', 'cursors'].includes(key)) return undefined;