aboutsummaryrefslogtreecommitdiff
path: root/src/fields
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields')
-rw-r--r--src/fields/Doc.ts49
-rw-r--r--src/fields/SchemaHeaderField.ts2
-rw-r--r--src/fields/ScriptField.ts24
-rw-r--r--src/fields/util.ts11
4 files changed, 65 insertions, 21 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 612fc7fb8..0ceaff968 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -33,7 +33,10 @@ export namespace Field {
return !Field.IsField(field) ? '' : (onDelegate ? '=' : '') + (field instanceof ComputedField ? `:=${field.script.originalScript}` : Field.toScriptString(field));
}
export function toScriptString(field: Field): string {
- if (typeof field === 'string') return `"${field}"`;
+ if (typeof field === '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}"`;
+ }
if (typeof field === 'number' || typeof field === 'boolean') return String(field);
if (field === undefined || field === null) return 'null';
return field[ToScriptString]();
@@ -149,6 +152,28 @@ export class Doc extends RefField {
public static set MainDocId(id: string | undefined) {
this.mainDocId = id;
}
+
+ @observable public static CurrentlyLoading: Doc[];
+ // 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) {
+ Doc.CurrentlyLoading = [];
+ }
+ 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;
@@ -180,7 +205,7 @@ export class Doc extends RefField {
return DocCast(Doc.UserDoc().myRecentlyClosed);
}
public static get MyTrails() {
- return DocCast(Doc.UserDoc().myTrails);
+ return DocCast(Doc.ActiveDashboard?.myTrails);
}
public static get MyOverlayDocs() {
return DocCast(Doc.UserDoc().myOverlayDocs);
@@ -217,6 +242,8 @@ export class Doc extends RefField {
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) {
@@ -225,11 +252,13 @@ export class Doc extends RefField {
public static get ActiveTool(): InkTool {
return StrCast(Doc.UserDoc().activeTool, InkTool.None) as InkTool;
}
- public static get ActivePresentation() {
- return DocCast(Doc.UserDoc().activePresentation);
+ public static get ActivePresentation(): Opt<Doc> {
+ return DocCast(Doc.ActiveDashboard?.activePresentation);
}
public static set ActivePresentation(val) {
- Doc.UserDoc().activePresentation = new PrefetchProxy(val);
+ if (Doc.ActiveDashboard) {
+ Doc.ActiveDashboard.activePresentation = val;
+ }
}
constructor(id?: FieldId, forceSave?: boolean) {
super(id);
@@ -1176,7 +1205,7 @@ export namespace Doc {
}
// don't bother memoizing (caching) the result if called from a non-reactive context. (plus this avoids a warning message)
export function IsBrushedDegreeUnmemoized(doc: Doc) {
- if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return DocBrushStatus.unbrushed;
+ if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate || doc.opacity === 0) return DocBrushStatus.unbrushed;
const status = brushManager.BrushedDoc.has(doc) ? DocBrushStatus.selfBrushed : brushManager.BrushedDoc.has(Doc.GetProto(doc)) ? DocBrushStatus.protoBrushed : DocBrushStatus.unbrushed;
if (status === DocBrushStatus.unbrushed) {
const lastBrushed = Array.from(brushManager.BrushedDoc.keys()).lastElement();
@@ -1238,7 +1267,7 @@ export namespace Doc {
}
const highlightManager = new HighlightBrush();
export function IsHighlighted(doc: Doc) {
- if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return false;
+ if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate || doc.opacity === 0) return false;
return highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetProto(doc));
}
export function HighlightDoc(doc: Doc, dataAndDisplayDocs = true) {
@@ -1373,11 +1402,17 @@ export namespace Doc {
layoutDoc._viewScale = NumCast(layoutDoc._viewScale, 1) * contentScale;
layoutDoc._nativeWidth = undefined;
layoutDoc._nativeHeight = undefined;
+ layoutDoc._forceReflow = undefined;
+ layoutDoc._nativeHeightUnfrozen = undefined;
+ layoutDoc._nativeDimModifiable = undefined;
} else {
layoutDoc._autoHeight = false;
if (!Doc.NativeWidth(layoutDoc)) {
layoutDoc._nativeWidth = NumCast(layoutDoc._width, panelWidth);
layoutDoc._nativeHeight = NumCast(layoutDoc._height, panelHeight);
+ layoutDoc._forceReflow = true;
+ layoutDoc._nativeHeightUnfrozen = true;
+ layoutDoc._nativeDimModifiable = true;
}
}
});
diff --git a/src/fields/SchemaHeaderField.ts b/src/fields/SchemaHeaderField.ts
index 1321bc327..0b51db70b 100644
--- a/src/fields/SchemaHeaderField.ts
+++ b/src/fields/SchemaHeaderField.ts
@@ -115,7 +115,7 @@ export class SchemaHeaderField extends ObjectField {
}
[ToScriptString]() {
- return `header(${this.heading},${this.type}})`;
+ return `header(${this.heading},${this.type},${this.width}})`;
}
[ToString]() {
return `SchemaHeaderField`;
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 48d5c5563..4896c027d 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -9,7 +9,7 @@ import { Doc, Field, Opt } from './Doc';
import { Copy, Id, ToScriptString, ToString } from './FieldSymbols';
import { List } from './List';
import { ObjectField } from './ObjectField';
-import { Cast, NumCast, StrCast } from './Types';
+import { Cast, StrCast } from './Types';
import { Plugins } from './util';
function optional(propSchema: PropSchema) {
@@ -43,12 +43,11 @@ const scriptSchema = createSimpleSchema({
originalScript: true,
});
-function finalizeScript(script: ScriptField, captures: boolean) {
+function finalizeScript(script: ScriptField) {
const comp = CompileScript(script.script.originalScript, script.script.options);
if (!comp.compiled) {
throw new Error("Couldn't compile loaded script");
}
- !captures && ScriptField._scriptFieldCache.set(script.script.originalScript, comp);
if (script.setterscript) {
const compset = CompileScript(script.setterscript?.originalScript, script.setterscript.options);
if (!compset.compiled) {
@@ -72,9 +71,9 @@ async function deserializeScript(script: ScriptField) {
else if (!isNaN(Number(val))) captured[key] = Number(val);
else captured[key] = val;
})
- ).then(() => ((script as any).script = finalizeScript(script, true)));
+ ).then(() => ((script as any).script = finalizeScript(script)));
} else {
- (script as any).script = ScriptField.GetScriptFieldCache(script.script.originalScript) ?? finalizeScript(script, false);
+ (script as any).script = ScriptField.GetScriptFieldCache(script.script.originalScript) ?? finalizeScript(script);
}
}
@@ -105,7 +104,7 @@ export class ScriptField extends ObjectField {
}
this.rawscript = rawscript;
this.setterscript = setterscript;
- this.script = script ?? (CompileScript('false') as CompiledScript);
+ this.script = script ?? (CompileScript('false', { addReturn: true }) as CompiledScript);
}
// init(callback: (res: Field) => any) {
@@ -143,7 +142,7 @@ export class ScriptField extends ObjectField {
return this.script.originalScript;
}
public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
- const compiled = CompileScript(script, {
+ return CompileScript(script, {
params: {
this: Doc?.name || 'Doc', // this is the doc that executes the script
self: Doc?.name || 'Doc', // self is the root doc of the doc that executes the script
@@ -156,7 +155,6 @@ export class ScriptField extends ObjectField {
addReturn: addReturn,
capturedVariables,
});
- return compiled;
}
public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }) {
const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
@@ -189,13 +187,13 @@ export class ComputedField extends ScriptField {
const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
return compiled.compiled ? new ComputedField(compiled) : undefined;
}
- public static MakeInterpolatedNumber(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
+ public static MakeInterpolatedNumber(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number, defaultVal: Opt<number>) {
if (!doc[`${fieldKey}-indexed`]) {
const flist = new List<number>(numberRange(curTimecode + 1).map(i => undefined) as any as number[]);
- flist[curTimecode] = NumCast(doc[fieldKey]);
+ flist[curTimecode] = Cast(doc[fieldKey], 'number', null);
doc[`${fieldKey}-indexed`] = flist;
}
- const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey})`, {}, true, {});
+ const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey}, ${defaultVal})`, {}, true, {});
const setField = ScriptField.CompileScript(`setIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey}, value)`, { value: 'any' }, true, {});
return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
}
@@ -260,8 +258,8 @@ ScriptingGlobals.add(
);
ScriptingGlobals.add(
- function getIndexVal(list: any[], index: number) {
- return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), undefined as any);
+ function getIndexVal(list: any[], index: number, defaultVal: Opt<number> = undefined) {
+ return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), defaultVal);
},
'returns the value at a given index of a list',
'(list: any[], index: number)'
diff --git a/src/fields/util.ts b/src/fields/util.ts
index b3cbbe241..4a62a6a1f 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,8 +1,10 @@
import { action, observable, runInAction, trace } from 'mobx';
import { computedFn } from 'mobx-utils';
import { DocServer } from '../client/DocServer';
+import { CollectionViewType } from '../client/documents/DocumentTypes';
import { SerializationHelper } from '../client/util/SerializationHelper';
import { UndoManager } from '../client/util/UndoManager';
+import { CollectionDockingView } from '../client/views/collections/CollectionDockingView';
import { returnZero } from '../Utils';
import CursorField from './CursorField';
import {
@@ -278,6 +280,15 @@ function getEffectiveAcl(target: any, user?: string): symbol {
export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[], isDashboard?: boolean) {
if (!visited) visited = [] as Doc[];
if (visited.includes(target)) return;
+
+ if ((target._viewType === CollectionViewType.Docking && visited.length > 1) || Doc.GetProto(visited[0]) !== Doc.GetProto(target)) {
+ target[key] = acl;
+ if (target !== Doc.GetProto(target)) {
+ //apparently we can't call updateCachedAcls twice (once for the main dashboard, and again for the nested dashboard...???)
+ updateCachedAcls(target);
+ }
+ return;
+ }
visited.push(target);
const HierarchyMapping = new Map<string, number>([