aboutsummaryrefslogtreecommitdiff
path: root/src/fields/Doc.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields/Doc.ts')
-rw-r--r--src/fields/Doc.ts464
1 files changed, 107 insertions, 357 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 2f9eea492..6dece87b5 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1,46 +1,23 @@
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { saveAs } from 'file-saver';
import { action, computed, observable, ObservableMap, ObservableSet, runInAction } from 'mobx';
import { computedFn } from 'mobx-utils';
import { alias, map, serializable } from 'serializr';
import { DocServer } from '../client/DocServer';
-import { DocumentType } from '../client/documents/DocumentTypes';
+import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes';
import { LinkManager } from '../client/util/LinkManager';
import { scriptingGlobal, ScriptingGlobals } from '../client/util/ScriptingGlobals';
import { afterDocDeserialize, autoObject, Deserializable, SerializationHelper } from '../client/util/SerializationHelper';
import { undoable } from '../client/util/UndoManager';
+import { DocumentView } from '../client/views/nodes/DocumentView';
import { decycle } from '../decycler/decycler';
import * as JSZipUtils from '../JSZipUtils';
-import { incrementTitleCopy, intersectRect, Utils } from '../Utils';
+import { incrementTitleCopy, Utils } from '../Utils';
import { DateField } from './DateField';
import {
- AclAdmin,
- AclAugment,
- AclEdit,
- AclPrivate,
- AclReadonly,
- Animation,
- AudioPlay,
- Brushed,
- CachedUpdates,
- DirectLinks,
- DocAcl,
- DocCss,
- DocData,
- DocFields,
- DocLayout,
- DocViews,
- FieldKeys,
- FieldTuples,
- ForceServerWrite,
- Height,
- Highlight,
- Initializing,
- Self,
- SelfProxy,
- UpdatingFromServer,
- Width,
-} from './DocSymbols';
+ AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, Animation, AudioPlay, Brushed, CachedUpdates, DirectLinks,
+ DocAcl, DocCss, DocData, DocFields, DocLayout, DocViews, FieldKeys, FieldTuples, ForceServerWrite, Height, Highlight,
+ Initializing, Self, SelfProxy, UpdatingFromServer, Width
+} from './DocSymbols'; // prettier-ignore
import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToScriptString, ToString } from './FieldSymbols';
import { InkField, InkTool } from './InkField';
import { List, ListFieldName } from './List';
@@ -52,9 +29,8 @@ import { listSpec } from './Schema';
import { ComputedField, ScriptField } from './ScriptField';
import { BoolCast, Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor } from './Types';
import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField } from './URLField';
-import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, TraceMobx } from './util';
+import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, setter, SharingPermissions } from './util';
import JSZip = require('jszip');
-import { DocumentView } from '../client/views/nodes/DocumentView';
export const LinkedTo = '-linkedTo';
export namespace Field {
export function toKeyValueString(doc: Doc, key: string): string {
@@ -66,25 +42,23 @@ export namespace Field {
: ''
: (onDelegate ? '=' : '') + (field instanceof ComputedField ? `:=${field.script.originalScript}` : field instanceof ScriptField ? `$=${field.script.originalScript}` : Field.toScriptString(field));
}
- export function toScriptString(field: Field): string {
+ export function toScriptString(field: Field) {
switch (typeof field) {
- case 'string':
- if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s
- return !field.includes('`') ? `\`${field}\`` : `"${field}"`;
+ case 'string': if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s
+ return !field.includes('`') ? `\`${field}\`` : `"${field}"`;
case 'number':
- case 'boolean':
- return String(field);
- }
- return field?.[ToScriptString]?.() ?? 'null';
+ case 'boolean':return String(field);
+ default: return field?.[ToScriptString]?.() ?? 'null';
+ } // prettier-ignore
}
- export function toString(field: Field): string {
+ export function toString(field: Field) {
if (typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean') return String(field);
return field?.[ToString]?.() || '';
}
export function IsField(field: any): field is Field;
export function IsField(field: any, includeUndefined: true): field is Field | undefined;
export function IsField(field: any, includeUndefined: boolean = false): field is Field | undefined {
- return typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean' || field instanceof ObjectField || field instanceof RefField || (includeUndefined && field === undefined);
+ return ['string', 'number', 'boolean'].includes(typeof field) || field instanceof ObjectField || field instanceof RefField || (includeUndefined && field === undefined);
}
export function Copy(field: any) {
return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field;
@@ -107,11 +81,6 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
const list = Cast(field, listSpec(Doc));
return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue);
}
-
-export async function DocCastAsync(field: FieldResult): Promise<Opt<Doc>> {
- return Cast(field, Doc);
-}
-
export function NumListCast(field: FieldResult, defaultVal: number[] = []) {
return Cast(field, listSpec('number'), defaultVal);
}
@@ -162,140 +131,51 @@ export function updateCachedAcls(doc: Doc) {
@Deserializable('Doc', updateCachedAcls, ['id'])
export class Doc extends RefField {
@observable public static RecordingEvent = 0;
-
- // this isn't really used at the moment, but is intended to indicate whether ink stroke are passed through a gesture recognizer
- static GetRecognizeGestures() {
- return BoolCast(Doc.UserDoc()._recognizeGestures);
- }
- static SetRecognizeGestures(show: boolean) {
- Doc.UserDoc()._recognizeGestures = show;
- }
-
- //
- // This controls whether fontIconButtons will display labels under their icons or not
- //
- static GetShowIconLabels() {
- return BoolCast(Doc.UserDoc()._showLabel);
- }
- static SetShowIconLabels(show: boolean) {
- Doc.UserDoc()._showLabel = show;
- }
- @observable public static CurrentlyLoading: Doc[] = []; // this assignment doesn't work. the actual assignment happens in DocumentManager's constructor
- // removes from currently loading display
- @action
- public static removeCurrentlyLoading(doc: Doc) {
- if (Doc.CurrentlyLoading) {
- const index = Doc.CurrentlyLoading.indexOf(doc);
- index !== -1 && Doc.CurrentlyLoading.splice(index, 1);
- }
- }
-
- // adds doc to currently loading display
- @action
- public static addCurrentlyLoading(doc: Doc) {
- if (Doc.CurrentlyLoading.indexOf(doc) === -1) {
- Doc.CurrentlyLoading.push(doc);
- }
- }
-
@observable public static GuestDashboard: Doc | undefined;
@observable public static GuestTarget: Doc | undefined;
@observable public static GuestMobile: Doc | undefined;
- public static get MySharedDocs() {
- return DocCast(Doc.UserDoc().mySharedDocs);
- }
- public static get MyUserDocView() {
- return DocCast(Doc.UserDoc().myUserDocView);
- }
- public static get MyDockedBtns() {
- return DocCast(Doc.UserDoc().myDockedBtns);
- }
- public static get MySearcher() {
- return DocCast(Doc.UserDoc().mySearcher);
- }
- public static get MyHeaderBar() {
- return DocCast(Doc.UserDoc().myHeaderBar);
- }
- public static get MyLeftSidebarMenu() {
- return DocCast(Doc.UserDoc().myLeftSidebarMenu);
- }
- public static get MyLeftSidebarPanel() {
- return DocCast(Doc.UserDoc().myLeftSidebarPanel);
- }
- public static get MyContextMenuBtns() {
- return DocCast(Doc.UserDoc().myContextMenuBtns);
- }
- public static get MyTopBarBtns() {
- return DocCast(Doc.UserDoc().myTopBarBtns);
- }
- public static get MyRecentlyClosed() {
- return DocCast(Doc.UserDoc().myRecentlyClosed);
- }
- public static get MyTrails() {
- return DocCast(Doc.ActiveDashboard?.myTrails);
- }
- public static IsInMyOverlay(doc: Doc) {
- return DocListCast(Doc.MyOverlayDocs?.data).includes(doc);
- }
- public static AddToMyOverlay(doc: Doc) {
- Doc.AddDocToList(Doc.MyOverlayDocs, undefined, doc);
- }
- public static RemFromMyOverlay(doc: Doc) {
- Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, doc);
- }
- public static get MyOverlayDocs() {
- return DocCast(Doc.UserDoc().myOverlayDocs);
- }
- public static get MyPublishedDocs() {
- return DocCast(Doc.UserDoc().myPublishedDocs);
- }
- public static get MyDashboards() {
- return DocCast(Doc.UserDoc().myDashboards);
- }
- public static get MyTemplates() {
- return DocCast(Doc.UserDoc().myTemplates);
- }
- public static get MyImports() {
- return DocCast(Doc.UserDoc().myImports);
- }
- public static get MyFilesystem() {
- return DocCast(Doc.UserDoc().myFilesystem);
- }
- public static get MyTools() {
- return DocCast(Doc.UserDoc().myTools);
- }
- public static get ActivePage() {
- return StrCast(Doc.UserDoc().activePage);
- }
- public static set ActivePage(val) {
- Doc.UserDoc().activePage = val;
- DocServer.UPDATE_SERVER_CACHE();
- }
- public static IsComicStyle(doc?: Doc) {
- return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic';
- }
- public static get ActiveDashboard() {
- return DocCast(Doc.UserDoc().activeDashboard);
- }
- public static set ActiveDashboard(val: Doc | undefined) {
- const overlays = Cast(Doc.MyOverlayDocs.data, listSpec(Doc), null);
- overlays && (overlays.length = 0);
- Doc.UserDoc().activeDashboard = val;
- }
- public static set ActiveTool(tool: InkTool) {
- Doc.UserDoc().activeTool = tool;
- }
- public static get ActiveTool(): InkTool {
- return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool;
- }
- public static get ActivePresentation(): Opt<Doc> {
- return DocCast(Doc.ActiveDashboard?.activePresentation);
- }
- public static set ActivePresentation(val) {
- if (Doc.ActiveDashboard) {
- Doc.ActiveDashboard.activePresentation = val;
- }
- }
+ public static CurrentUserEmail: string = '';
+
+ public static get MySharedDocs() { return DocCast(Doc.UserDoc().mySharedDocs); } // prettier-ignore
+ public static get MyUserDocView() { return DocCast(Doc.UserDoc().myUserDocView); } // prettier-ignore
+ public static get MyDockedBtns() { return DocCast(Doc.UserDoc().myDockedBtns); } // prettier-ignore
+ public static get MySearcher() { return DocCast(Doc.UserDoc().mySearcher); } // prettier-ignore
+ public static get MyHeaderBar() { return DocCast(Doc.UserDoc().myHeaderBar); } // prettier-ignore
+ public static get MyLeftSidebarMenu() { return DocCast(Doc.UserDoc().myLeftSidebarMenu); } // prettier-ignore
+ public static get MyLeftSidebarPanel() { return DocCast(Doc.UserDoc().myLeftSidebarPanel); } // prettier-ignore
+ public static get MyContextMenuBtns() { return DocCast(Doc.UserDoc().myContextMenuBtns); } // prettier-ignore
+ public static get MyTopBarBtns() { return DocCast(Doc.UserDoc().myTopBarBtns); } // prettier-ignore
+ public static get MyRecentlyClosed() { return DocCast(Doc.UserDoc().myRecentlyClosed); } // prettier-ignore
+ public static get MyTrails() { return DocCast(Doc.ActiveDashboard?.myTrails); } // prettier-ignore
+ public static get MyOverlayDocs() { return DocListCast(Doc.ActiveDashboard?.myOverlayDocs ?? DocCast(Doc.UserDoc().myOverlayDocs).data); } // prettier-ignore
+ public static get MyPublishedDocs() { return DocListCast(Doc.ActiveDashboard?.myPublishedDocs ?? DocCast(Doc.UserDoc().myPublishedDocs).data); } // prettier-ignore
+ public static get MyDashboards() { return DocCast(Doc.UserDoc().myDashboards); } // prettier-ignore
+ public static get MyTemplates() { return DocCast(Doc.UserDoc().myTemplates); } // prettier-ignore
+ public static get MyImports() { return DocCast(Doc.UserDoc().myImports); } // prettier-ignore
+ public static get MyFilesystem() { return DocCast(Doc.UserDoc().myFilesystem); } // prettier-ignore
+ public static get MyTools() { return DocCast(Doc.UserDoc().myTools); } // prettier-ignore
+ public static get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode); } // prettier-ignore
+ public static set noviceMode(val) { Doc.UserDoc().noviceMode = val; } // prettier-ignore
+ public static get IsSharingEnabled() { return BoolCast(Doc.UserDoc().isSharingEnabled); } // prettier-ignore
+ public static set IsSharingEnabled(val) { Doc.UserDoc().isSharingEnabled = val; } // prettier-ignore
+ public static get defaultAclPrivate() { return Doc.UserDoc().defaultAclPrivate; } // prettier-ignore
+ public static set defaultAclPrivate(val) { Doc.UserDoc().defaultAclPrivate = val; } // prettier-ignore
+ public static get ActivePage() { return StrCast(Doc.UserDoc().activePage); } // prettier-ignore
+ public static set ActivePage(val) { Doc.UserDoc().activePage = val; } // prettier-ignore
+ public static get ActiveTool(): InkTool { return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool; } // prettier-ignore
+ public static set ActiveTool(tool:InkTool){ Doc.UserDoc().activeTool = tool; } // prettier-ignore
+ public static get ActivePresentation() { return DocCast(Doc.ActiveDashboard?.activePresentation) as Opt<Doc>; } // prettier-ignore
+ public static set ActivePresentation(val) { Doc.ActiveDashboard && (Doc.ActiveDashboard.activePresentation = val) } // prettier-ignore
+ public static get ActiveDashboard() { return DocCast(Doc.UserDoc().activeDashboard); } // prettier-ignore
+ public static set ActiveDashboard(val: Opt<Doc>) { Doc.UserDoc().activeDashboard = val; } // prettier-ignore
+
+ public static IsInMyOverlay(doc: Doc) { return Doc.MyOverlayDocs.includes(doc); } // prettier-ignore
+ public static AddToMyOverlay(doc: Doc) { Doc.ActiveDashboard?.myOverlayDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myOverlayDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
+ public static RemFromMyOverlay(doc: Doc) { Doc.ActiveDashboard?.myOverlayDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myOverlayDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myOverlayDocs), undefined, doc); } // prettier-ignore
+ public static AddToMyPublished(doc: Doc) { Doc.ActiveDashboard?.myPublishedDocs ? Doc.AddDocToList(Doc.ActiveDashboard, 'myPublishedDocs', doc) : Doc.AddDocToList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
+ public static RemFromMyPublished(doc: Doc){ Doc.ActiveDashboard?.myPublishedDocs ? Doc.RemoveDocFromList(Doc.ActiveDashboard,'myPublishedDocs', doc) : Doc.RemoveDocFromList(DocCast(Doc.UserDoc().myPublishedDocs), undefined, doc); } // prettier-ignore
+ public static IsComicStyle(doc?: Doc) { return doc && Doc.ActiveDashboard && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === 'comic' ; } // prettier-ignore
+
constructor(id?: FieldId, forceSave?: boolean) {
super(id);
const docProxy = new Proxy<this>(this, {
@@ -359,17 +239,14 @@ export class Doc extends RefField {
@observable public [Highlight]: boolean = false;
@observable public [Brushed]: boolean = false;
@observable public [DocViews] = new ObservableSet<DocumentView>();
- static __Anim(Doc: Doc) {
- // for debugging to print AnimationSym field easily.
- return Doc[Animation];
- }
+ private [Self] = this;
+ private [SelfProxy]: any;
private [UpdatingFromServer]: boolean = false;
private [ForceServerWrite]: boolean = false;
- public [Initializing]: boolean = false;
+ private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
- private [Self] = this;
- private [SelfProxy]: any;
+ public [Initializing]: boolean = false;
public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: Field[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => {
if (!this[UpdatingFromServer] || this[ForceServerWrite]) {
DocServer.UpdateField(this[Id], serverOp);
@@ -380,9 +257,7 @@ export class Doc extends RefField {
public [Height] = () => NumCast(this[SelfProxy]._height);
public [ToScriptString] = () => `idToDoc("${this[Self][Id]}")`;
public [ToString] = () => `Doc(${GetEffectiveAcl(this[SelfProxy]) === AclPrivate ? '-inaccessible-' : this[SelfProxy].title})`;
- public get [DocLayout]() {
- return this[SelfProxy].__LAYOUT__;
- }
+ public get [DocLayout]() { return this[SelfProxy].__LAYOUT__; } // prettier-ignore
public get [DocData](): Doc {
const self = this[SelfProxy];
return self.resolvedDataDoc && !self.isTemplateForField ? self : Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self);
@@ -403,29 +278,6 @@ export class Doc extends RefField {
return undefined;
}
- private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
- public static get noviceMode() {
- return Doc.UserDoc().noviceMode as boolean;
- }
- public static set noviceMode(val) {
- Doc.UserDoc().noviceMode = val;
- }
- public static get IsSharingEnabled() {
- return Doc.UserDoc().isSharingEnabled as boolean;
- }
- public static set IsSharingEnabled(val) {
- Doc.UserDoc().isSharingEnabled = val;
- }
- public static get defaultAclPrivate() {
- return Doc.UserDoc().defaultAclPrivate;
- }
- public static set defaultAclPrivate(val) {
- Doc.UserDoc().defaultAclPrivate = val;
- }
- public static CurrentUserEmail: string = '';
- public static get CurrentUserEmailNormalized() {
- return normalizeEmail(Doc.CurrentUserEmail);
- }
public async [HandleUpdate](diff: any) {
const set = diff.$set;
const sameAuthor = this.author === Doc.CurrentUserEmail;
@@ -482,17 +334,6 @@ export class Doc extends RefField {
}
export namespace Doc {
- // export function GetAsync(doc: Doc, key: string, ignoreProto: boolean = false): Promise<Field | undefined> {
- // const self = doc[Self];
- // return new Promise(res => getField(self, key, ignoreProto, res));
- // }
- // export function GetTAsync<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): Promise<T | undefined> {
- // return new Promise(async res => {
- // const field = await GetAsync(doc, key, ignoreProto);
- // return Cast(field, ctor);
- // });
- // }
-
export function SetContainer(doc: Doc, container: Doc) {
doc.embedContainer = container;
}
@@ -626,10 +467,9 @@ export namespace Doc {
/**
* @returns the index of doc toFind in list of docs, -1 otherwise
*/
- export function IndexOf(toFind: Doc, list: Doc[], allowProtos: boolean = true) {
- let index = list.reduce((p, v, i) => (v instanceof Doc && v === toFind ? i : p), -1);
- index = allowProtos && index !== -1 ? index : list.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, toFind) ? i : p), -1);
- return index; // list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind));
+ export function IndexOf(toFind: Doc, list: Doc[]) {
+ const index = list.indexOf(toFind);
+ return index !== -1 ? index : list.findIndex(doc => Doc.AreProtosEqual(doc, toFind));
}
/**
@@ -663,11 +503,10 @@ export namespace Doc {
}
const list = Cast(listDoc[key], listSpec(Doc));
if (list) {
- if (allowDuplicates !== true) {
- const pind = list.reduce((l, d, i) => (d instanceof Doc && d[Id] === doc[Id] ? i : l), -1);
+ if (!allowDuplicates) {
+ const pind = list.findIndex(d => d instanceof Doc && d[Id] === doc[Id]);
if (pind !== -1) {
return true;
- //list.splice(pind, 1); // bcz: this causes schemaView docs in the Catalog to move to the bottom of the schema view when they are dragged even though they haven't left the collection
}
}
if (first) {
@@ -687,22 +526,6 @@ export namespace Doc {
return false;
}
- /**
- * Computes the bounds of the contents of a set of documents.
- */
- export function ComputeContentBounds(docList: Doc[]) {
- const bounds = docList.reduce(
- (bounds, doc) => ({
- x: Math.min(NumCast(doc.x), bounds.x),
- y: Math.min(NumCast(doc.y), bounds.y),
- r: Math.max(NumCast(doc.x) + doc[Width](), bounds.r),
- b: Math.max(NumCast(doc.y) + doc[Height](), bounds.b),
- }),
- { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE }
- );
- return bounds;
- }
-
export function MakeEmbedding(doc: Doc, id?: string) {
const embedding = !GetT(doc, 'isDataDoc', 'boolean', true) && doc.proto ? Doc.MakeCopy(doc, undefined, id) : Doc.MakeDelegate(doc, id);
const layout = Doc.LayoutField(embedding);
@@ -779,7 +602,7 @@ export namespace Doc {
} else if (field instanceof RefField) {
assignKey(field);
} else if (cfield instanceof ComputedField) {
- assignKey(cfield[Copy]()); // ComputedField.MakeFunction(cfield.script.originalScript));
+ assignKey(cfield[Copy]());
} else if (field instanceof ObjectField) {
await copyObjectField(field);
} else if (field instanceof Promise) {
@@ -990,29 +813,6 @@ export namespace Doc {
return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc), data: resolvedDataDoc };
}
- export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
- Object.keys(doc).forEach(key => {
- const field = ProxyField.WithoutProxy(() => doc[key]);
- if (key === 'proto' && copyProto) {
- if (doc.proto instanceof Doc && overwrite.proto instanceof Doc) {
- overwrite[key] = Doc.Overwrite(doc.proto, overwrite.proto);
- }
- } else {
- if (field instanceof RefField) {
- overwrite[key] = field;
- } else if (field instanceof ObjectField) {
- overwrite[key] = ObjectField.MakeCopy(field);
- } else if (field instanceof Promise) {
- debugger; //This shouldn't happend...
- } else {
- overwrite[key] = field;
- }
- }
- });
-
- return overwrite;
- }
-
export function FindReferences(infield: Doc | List<any>, references: Set<Doc>, system: boolean | undefined) {
if (infield instanceof List<any>) {
infield.forEach(val => (val instanceof Doc || val instanceof List) && FindReferences(val, references, system));
@@ -1217,22 +1017,8 @@ export namespace Doc {
return '/doc/' + (doc ? doc[Id] : '');
}
- export function overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
- const doc2Layout = Doc.Layout(doc2);
- const doc1Layout = Doc.Layout(doc1);
- const x2 = NumCast(doc2.x) - clusterDistance;
- const y2 = NumCast(doc2.y) - clusterDistance;
- const w2 = NumCast(doc2Layout._width) + clusterDistance;
- const h2 = NumCast(doc2Layout._height) + clusterDistance;
- const x = NumCast(doc1.x) - clusterDistance;
- const y = NumCast(doc1.y) - clusterDistance;
- const w = NumCast(doc1Layout._width) + clusterDistance;
- const h = NumCast(doc1Layout._height) + clusterDistance;
- return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
- }
-
- export function isBrushedHighlightedDegree(doc: Doc) {
- return Doc.IsHighlighted(doc) ? DocBrushStatus.highlighted : Doc.IsBrushedDegree(doc);
+ export function GetBrushHighlightStatus(doc: Doc) {
+ return Doc.IsHighlighted(doc) ? DocBrushStatus.highlighted : Doc.GetBrushStatus(doc);
}
export class DocBrush {
BrushedDoc = new Set<Doc>();
@@ -1269,12 +1055,12 @@ export namespace Doc {
return Doc.NativeWidth(doc, dataDoc, useDim) / (Doc.NativeHeight(doc, dataDoc, useDim) || 1);
}
export function NativeWidth(doc?: Doc, dataDoc?: Doc, useWidth?: boolean) {
- return !doc ? 0 : NumCast(doc._nativeWidth, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeWidth'], useWidth ? doc[Width]() : 0));
+ return !doc ? 0 : NumCast(doc._nativeWidth, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeWidth'], useWidth ? NumCast(doc._width) : 0));
}
export function NativeHeight(doc?: Doc, dataDoc?: Doc, useHeight?: boolean) {
if (!doc) return 0;
- const nheight = (Doc.NativeWidth(doc, dataDoc, useHeight) * doc[Height]()) / doc[Width]();
- const dheight = NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeHeight'], useHeight ? doc[Height]() : 0);
+ const nheight = (Doc.NativeWidth(doc, dataDoc, useHeight) * NumCast(doc._height)) / NumCast(doc._width);
+ const dheight = NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + '_nativeHeight'], useHeight ? NumCast(doc._height) : 0);
return NumCast(doc._nativeHeight, nheight || dheight);
}
export function SetNativeWidth(doc: Doc, width: number | undefined, fieldKey?: string) {
@@ -1337,36 +1123,22 @@ export namespace Doc {
highlighted = 3,
}
// returns 'how' a Doc has been brushed over - whether the document itself was brushed, it's prototype, or neither
- export function IsBrushedDegree(doc: Doc) {
+ export function GetBrushStatus(doc: Doc) {
if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate || doc.opacity === 0) return DocBrushStatus.unbrushed;
return doc[Brushed] ? DocBrushStatus.selfBrushed : Doc.GetProto(doc)[Brushed] ? DocBrushStatus.protoBrushed : DocBrushStatus.unbrushed;
}
export function BrushDoc(doc: Doc, unbrush = false) {
- if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return doc;
- brushManager.brushDoc(doc, unbrush);
- brushManager.brushDoc(Doc.GetProto(doc), unbrush);
+ if (doc && GetEffectiveAcl(doc) !== AclPrivate && GetEffectiveAcl(Doc.GetProto(doc)) !== AclPrivate) {
+ brushManager.brushDoc(doc, unbrush);
+ brushManager.brushDoc(Doc.GetProto(doc), unbrush);
+ }
return doc;
}
export function UnBrushDoc(doc: Doc) {
return BrushDoc(doc, true);
}
-
- export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) {
- const linkAnchor2 = DocCast(linkDoc.link_anchor_2);
- const linkAnchor1 = DocCast(linkDoc.link_anchor_1);
- if (linkDoc.link_matchEmbeddings) {
- return [linkAnchor2, linkAnchor2.annotationOn].includes(anchorDoc) ? '2' : '1';
- }
- if (Doc.AreProtosEqual(linkAnchor2, anchorDoc) || Doc.AreProtosEqual(linkAnchor2.annotationOn as Doc, anchorDoc)) return '2';
- return Doc.AreProtosEqual(linkAnchor1, anchorDoc) || Doc.AreProtosEqual(linkAnchor1.annotationOn as Doc, anchorDoc) ? '1' : '2';
- }
-
- export function linkFollowUnhighlight() {
- clearTimeout(UnhighlightTimer);
- UnhighlightWatchers.forEach(watcher => watcher());
- UnhighlightWatchers.length = 0;
- highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc));
- document.removeEventListener('pointerdown', linkFollowUnhighlight);
+ export function UnBrushAllDocs() {
+ Array.from(brushManager.BrushedDoc).forEach(action(doc => (doc[Brushed] = false)));
}
let UnhighlightWatchers: (() => void)[] = [];
@@ -1376,6 +1148,13 @@ export namespace Doc {
UnhighlightWatchers.push(watcher);
} else watcher();
}
+ export function linkFollowUnhighlight() {
+ clearTimeout(UnhighlightTimer);
+ UnhighlightWatchers.forEach(watcher => watcher());
+ UnhighlightWatchers.length = 0;
+ highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc));
+ document.removeEventListener('pointerdown', linkFollowUnhighlight);
+ }
export function linkFollowHighlight(destDoc: Doc | Doc[], dataAndDisplayDocs = true, presentation_effect?: Doc) {
linkFollowUnhighlight();
(destDoc instanceof Doc ? [destDoc] : destDoc).forEach(doc => Doc.HighlightDoc(doc, dataAndDisplayDocs, presentation_effect));
@@ -1415,9 +1194,6 @@ export namespace Doc {
});
});
}
- export function UnBrushAllDocs() {
- Array.from(brushManager.BrushedDoc).forEach(action(doc => (doc[Brushed] = false)));
- }
export function getDocTemplate(doc?: Doc) {
return !doc
@@ -1433,41 +1209,6 @@ export namespace Doc {
: undefined;
}
- export function matchFieldValue(doc: Doc, key: string, value: any): boolean {
- const hasFunctionFilter = Utils.HasFunctionFilter(value);
- if (hasFunctionFilter) {
- return hasFunctionFilter(StrCast(doc[key]));
- }
- if (key === LinkedTo) {
- // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
- const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
- const matchLink = (value: string, anchor: Doc) => {
- const linkedToExp = value?.split('=');
- if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value;
- return 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,DocCast(link.link_anchor_1)) ||
- matchLink(value,DocCast(link.link_anchor_2)) ));
- }
- if (typeof value === 'string') {
- value = value.replace(`,${Utils.noRecursionHack}`, '');
- }
- const fieldVal = doc[key];
- // prettier-ignore
- if ((value === Doc.FilterAny && fieldVal !== undefined) ||
- (value === Doc.FilterNone && fieldVal === undefined)) {
- return true;
- }
- const vals = StrListCast(fieldVal); // list typing is very imperfect. casting to a string list doesn't mean that the entries will actually be strings
- if (vals.length) {
- return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
- }
- return Field.toString(fieldVal as Field).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
- }
-
export function deiconifyView(doc: Doc) {
StrCast(doc.layout_fieldKey).split('_')[1] === 'icon' && setNativeView(doc);
}
@@ -1603,15 +1344,25 @@ export namespace Doc {
}
// prettier-ignore
- export function toIcon(doc?: Doc, isOpen?: boolean) {
- switch (isOpen !== undefined ? DocumentType.COL: StrCast(doc?.type)) {
+ export function toIcon(doc?: Doc, isOpen?: Opt<boolean>) {
+ if (isOpen) return doc?.isFolder ? 'chevron-down' : 'folder-open';
+ switch (StrCast(doc?.type)) {
case DocumentType.IMG: return 'image';
case DocumentType.COMPARISON: return 'columns';
case DocumentType.RTF: return 'sticky-note';
case DocumentType.COL:
- const folder: IconProp = isOpen === true ? 'folder-open' : isOpen === false ? 'folder' : doc?.title==='Untitled Collection'? 'object-group': 'chalkboard';
- const chevron: IconProp = isOpen === true ? 'chevron-down' : isOpen === false ? 'chevron-right' : 'question';
- return !doc?.isFolder ? folder : chevron;
+ if (doc?.isFolder) {
+ switch (doc.type_collection) {
+ default: return isOpen === false ? 'chevron-right' : 'question';
+ } // prettier-ignore
+ }
+ switch (doc?.type_collection) {
+ case CollectionViewType.Freeform : return 'object-group';
+ case CollectionViewType.NoteTaking : return 'chalkboard';
+ case CollectionViewType.Schema : return 'table-cells';
+ case CollectionViewType.Docking: return 'solar-panel';
+ default: return 'folder';
+ } // prettier-ignore
case DocumentType.WEB: return 'globe-asia';
case DocumentType.SCREENSHOT: return 'photo-video';
case DocumentType.WEBCAM: return 'video';
@@ -1628,9 +1379,9 @@ export namespace Doc {
case DocumentType.DATAVIZ: return 'chart-bar';
case DocumentType.EQUATION: return 'calculator';
case DocumentType.SIMULATION: return 'rocket';
- case DocumentType.CONFIG: return 'question-circle';
- default: return 'question';
+ case DocumentType.CONFIG: return 'folder-closed';
}
+ return 'question';
}
///
@@ -1839,14 +1590,13 @@ ScriptingGlobals.add(function sameDocs(doc1: any, doc2: any) {
ScriptingGlobals.add(function assignDoc(doc: Doc, field: string, id: string) {
return Doc.assignDocToField(doc, field, id);
});
-ScriptingGlobals.add(function docCast(doc: FieldResult): any {
- return DocCastAsync(doc);
+ScriptingGlobals.add(function docCastAsync(doc: FieldResult): any {
+ return Cast(doc, Doc);
});
ScriptingGlobals.add(function activePresentationItem() {
const curPres = Doc.ActivePresentation;
return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)];
});
-
ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: any, modifiers: 'match' | 'check' | 'x' | 'remove') {
Doc.setDocFilter(container, key, value, modifiers);
});