aboutsummaryrefslogtreecommitdiff
path: root/src/fields
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields')
-rw-r--r--src/fields/Doc.ts57
-rw-r--r--src/fields/ScriptField.ts31
-rw-r--r--src/fields/util.ts22
3 files changed, 24 insertions, 86 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index ee164ab31..de94ed5db 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -33,20 +33,19 @@ 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') {
- 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}"`;
+ 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}"`;
+ case 'number':
+ case 'boolean':
+ return String(field);
}
- if (typeof field === 'number' || typeof field === 'boolean') return String(field);
- if (field === undefined || field === null) return 'null';
- return field[ToScriptString]();
+ return field?.[ToScriptString]?.() ?? 'null';
}
export function toString(field: Field): string {
- if (typeof field === 'string') return field;
- if (typeof field === 'number' || typeof field === 'boolean') return String(field);
- if (field instanceof ObjectField) return field[ToString]();
- if (field instanceof RefField) return field[ToString]();
- return '';
+ 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;
@@ -79,17 +78,14 @@ export async function DocCastAsync(field: FieldResult): Promise<Opt<Doc>> {
return Cast(field, Doc);
}
-export function NumListCast(field: FieldResult) {
- return Cast(field, listSpec('number'), []);
+export function NumListCast(field: FieldResult, defaultVal: number[] = []) {
+ return Cast(field, listSpec('number'), defaultVal);
}
-export function StrListCast(field: FieldResult) {
- return Cast(field, listSpec('string'), []);
+export function StrListCast(field: FieldResult, defaultVal: string[] = []) {
+ return Cast(field, listSpec('string'), defaultVal);
}
-export function DocListCast(field: FieldResult) {
- return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[];
-}
-export function DocListCastOrNull(field: FieldResult) {
- return Cast(field, listSpec(Doc), null)?.filter(d => d instanceof Doc) as Doc[] | undefined;
+export function DocListCast(field: FieldResult, defaultVal: Doc[] = []) {
+ return Cast(field, listSpec(Doc), defaultVal).filter(d => d instanceof Doc) as Doc[];
}
export const WidthSym = Symbol('Width');
@@ -153,17 +149,8 @@ export function updateCachedAcls(doc: Doc) {
}
@scriptingGlobal
-@Deserializable('Doc', updateCachedAcls).withFields(['id'])
+@Deserializable('Doc', updateCachedAcls, ['id'])
export class Doc extends RefField {
- //TODO tfs: these should be temporary...
- private static mainDocId: string | undefined;
- public static get MainDocId() {
- return this.mainDocId;
- }
- public static set MainDocId(id: string | undefined) {
- this.mainDocId = id;
- }
-
@observable public static CurrentlyLoading: Doc[];
// removes from currently loading display
@action
@@ -582,21 +569,13 @@ export namespace Doc {
// compare whether documents or their protos match
export function AreProtosEqual(doc?: Doc, other?: Doc) {
- if (!doc || !other) return false;
- const r = doc === other;
- const r2 = Doc.GetProto(doc) === other;
- const r3 = Doc.GetProto(other) === doc;
- const r4 = Doc.GetProto(doc) === Doc.GetProto(other) && Doc.GetProto(other) !== undefined;
- return r || r2 || r3 || r4;
+ return doc && other && Doc.GetProto(doc) === Doc.GetProto(other);
}
// Gets the data document for the document. Note: this is mis-named -- it does not specifically
// return the doc's proto, but rather recursively searches through the proto inheritance chain
// and returns the document who's proto is undefined or whose proto is marked as a base prototype ('isPrototype').
export function GetProto(doc: Doc): Doc {
- if (doc instanceof Promise) {
- // console.log("GetProto: warning: got Promise insead of Doc");
- }
const proto = doc && (Doc.GetT(doc, 'isPrototype', 'boolean', true) ? doc : doc.proto || doc);
return proto === doc ? proto : Doc.GetProto(proto);
}
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index b5eca78dd..feb419597 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -103,30 +103,9 @@ export class ScriptField extends ObjectField {
}
this.rawscript = rawscript;
this.setterscript = setterscript;
- this.script = script ?? (CompileScript('false', { addReturn: true }) as CompiledScript);
+ this.script = script ?? ScriptField.GetScriptFieldCache('false:') ?? (CompileScript('false', { addReturn: true }) as CompiledScript);
}
- // init(callback: (res: Field) => any) {
- // const options = this.options!;
- // const keys = Object.keys(options.options.capturedIds);
- // Server.GetFields(keys).then(fields => {
- // let captured: { [name: string]: Field } = {};
- // keys.forEach(key => captured[options.options.capturedIds[key]] = fields[key]);
- // const opts: ScriptOptions = {
- // addReturn: options.options.addReturn,
- // params: options.options.params,
- // requiredType: options.options.requiredType,
- // capturedVariables: captured
- // };
- // const script = CompileScript(options.script, opts);
- // if (!script.compiled) {
- // throw new Error("Can't compile script");
- // }
- // this._script = script;
- // callback(this);
- // });
- // }
-
[Copy](): ObjectField {
return new ScriptField(this.script, this.setterscript, this.rawscript);
}
@@ -172,7 +151,7 @@ export class ComputedField extends ScriptField {
_lastComputedResult: any;
//TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
value = computedFn((doc: Doc) => this._valueOutsideReaction(doc));
- _valueOutsideReaction = (doc: Doc) => (this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) || doc, _last_: this._lastComputedResult, _readOnly_: true }, console.log).result);
+ _valueOutsideReaction = (doc: Doc) => (this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) ?? doc, value: '', _last_: this._lastComputedResult, _readOnly_: true }, console.log).result);
[ToValue](doc: Doc) {
return ComputedField.toValue(doc, this);
@@ -181,12 +160,8 @@ export class ComputedField extends ScriptField {
return new ComputedField(this.script, this.setterscript, this.rawscript);
}
- public static MakeScript(script: string, params: object = {}) {
- const compiled = ScriptField.CompileScript(script, params, false);
- return compiled.compiled ? new ComputedField(compiled) : undefined;
- }
public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Doc | string | number | boolean }, setterscript?: string) {
- const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
+ const compiled = ScriptField.CompileScript(script, params, true, { value: '', ...capturedVariables });
const compiledsetter = setterscript ? ScriptField.CompileScript(setterscript, { ...params, value: 'any' }, false, capturedVariables) : undefined;
const compiledsetscript = compiledsetter?.compiled ? compiledsetter : undefined;
return compiled.compiled ? new ComputedField(compiled, compiledsetscript) : undefined;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 6ff13d5d3..70d9ed61f 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -48,15 +48,11 @@ export function TraceMobx() {
}
const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
- if (SerializationHelper.IsSerializing()) {
+ if (SerializationHelper.IsSerializing() || typeof prop === 'symbol') {
target[prop] = value;
return true;
}
- if (typeof prop === 'symbol') {
- target[prop] = value;
- return true;
- }
if (value !== undefined) {
value = value[SelfProxy] || value;
}
@@ -95,12 +91,8 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
delete target.__fields[prop];
} else {
target.__fieldKeys && (target.__fieldKeys[prop] = true);
- // if (target.__fields[prop] !== value) {
- // console.log("ASSIGN " + prop + " " + value);
- // }
target.__fields[prop] = value;
}
- //if (typeof value === "object" && !(value instanceof ObjectField)) debugger;
if (writeToServer) {
if (value === undefined) target[Update]({ $unset: { ['fields.' + prop]: '' } });
@@ -143,13 +135,6 @@ export function denormalizeEmail(email: string) {
return email.replace(/__/g, '.');
}
-// playground mode allows the user to add/delete documents or make layout changes without them saving to the server
-// let playgroundMode = false;
-
-// export function togglePlaygroundMode() {
-// playgroundMode = !playgroundMode;
-// }
-
/**
* Copies parent's acl fields to the child
*/
@@ -317,7 +302,6 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin && !(effectiveAcl === AclSelfEdit && value instanceof RichTextField)) return true;
// if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't
if (typeof prop === 'string' && prop.startsWith('acl') && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value))) return true;
- // if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Augment", "Can View", "Not Shared", undefined].includes(value)) return true;
if (typeof prop === 'string' && prop !== '__id' && prop !== '__fields' && prop.startsWith('_')) {
if (!prop.startsWith('__')) prop = prop.substring(1);
@@ -377,9 +361,9 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
export function deleteProperty(target: any, prop: string | number | symbol) {
if (typeof prop === 'symbol') {
delete target[prop];
- return true;
+ } else {
+ target[SelfProxy][prop] = undefined;
}
- target[SelfProxy][prop] = undefined;
return true;
}