diff options
Diffstat (limited to 'src/fields')
| -rw-r--r-- | src/fields/Doc.ts | 49 | ||||
| -rw-r--r-- | src/fields/SchemaHeaderField.ts | 2 | ||||
| -rw-r--r-- | src/fields/ScriptField.ts | 24 | ||||
| -rw-r--r-- | src/fields/util.ts | 11 |
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>([ |
