aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields/Doc.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/new_fields/Doc.ts')
-rw-r--r--src/new_fields/Doc.ts93
1 files changed, 46 insertions, 47 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 46ccb3e90..02dd34cb4 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -4,12 +4,9 @@ import { autoObject, SerializationHelper, Deserializable } from "../client/util/
import { DocServer } from "../client/DocServer";
import { setter, getter, getField, updateFunction, deleteProperty } from "./util";
import { Cast, ToConstructor, PromiseValue, FieldValue, NumCast } from "./Types";
-import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
-import { List } from "./List";
import { ObjectField, Parent, OnUpdate } from "./ObjectField";
import { RefField, FieldId, Id, HandleUpdate } from "./RefField";
-import { Docs } from "../client/documents/Documents";
export function IsField(field: any): field is Field {
return (typeof field === "string")
@@ -29,15 +26,21 @@ export const SelfProxy = Symbol("SelfProxy");
export const WidthSym = Symbol("Width");
export const HeightSym = Symbol("Height");
+/**
+ * Cast any field to either a List of Docs or undefined if the given field isn't a List of Docs.
+ * If a default value is given, that will be returned instead of undefined.
+ * If a default value is given, the returned value should not be modified as it might be a temporary value.
+ * If no default value is given, and the returned value is not undefined, it can be safely modified.
+ */
export function DocListCastAsync(field: FieldResult): Promise<Doc[] | undefined>;
export function DocListCastAsync(field: FieldResult, defaultValue: Doc[]): Promise<Doc[]>;
export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
const list = Cast(field, listSpec(Doc));
- return list ? Promise.all(list) : Promise.resolve(defaultValue);
+ return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue);
}
-export function DocListCast(field: FieldResult) {
- return Cast(field, listSpec(Doc), []).filter(d => d && d instanceof Doc).map(d => d as Doc)
+export function DocListCast(field: FieldResult): Doc[] {
+ return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[];
}
@Deserializable("doc").withFields(["id"])
@@ -130,11 +133,12 @@ export namespace Doc {
const self = doc[Self];
return getField(self, key, ignoreProto);
}
- export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): T | null | undefined {
- return Cast(Get(doc, key, ignoreProto), ctor) as T | null | undefined;
+ export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> {
+ return Cast(Get(doc, key, ignoreProto), ctor) as FieldResult<T>;
}
export async function SetOnPrototype(doc: Doc, key: string, value: Field) {
- const proto = doc.proto;
+ const proto = Object.getOwnPropertyNames(doc).indexOf("isPrototype") === -1 ? doc.proto : doc;
+
if (proto) {
proto[key] = value;
}
@@ -152,22 +156,43 @@ export namespace Doc {
for (const key in fields) {
if (fields.hasOwnProperty(key)) {
const value = fields[key];
- if (value !== undefined) {
- doc[key] = value;
- }
+ // Do we want to filter out undefineds?
+ // if (value !== undefined) {
+ doc[key] = value;
+ // }
}
}
return doc;
}
+ // compare whether documents or their protos match
+ export function AreProtosEqual(doc: Doc, other: Doc) {
+ let r = (doc[Id] === other[Id]);
+ let r2 = (doc.proto && doc.proto.Id === other[Id]);
+ let r3 = (other.proto && other.proto.Id === doc[Id]);
+ let r4 = (doc.proto && other.proto && doc.proto[Id] === other.proto[Id]);
+ return r || r2 || r3 || r4 ? true : false;
+ }
+
+ // gets the document's prototype or returns the document if it is a prototype
+ export function GetProto(doc: Doc) {
+ return Object.getOwnPropertyNames(doc).indexOf("isPrototype") === -1 ? doc.proto! : doc;
+ }
+
+
export function MakeAlias(doc: Doc) {
+ const proto = Object.getOwnPropertyNames(doc).indexOf("isPrototype") === -1 ? doc.proto : undefined;
const alias = new Doc;
- PromiseValue(Cast(doc.proto, Doc)).then(proto => {
- if (proto) {
- alias.proto = proto;
- }
- });
+ if (!proto) {
+ alias.proto = doc;
+ } else {
+ PromiseValue(Cast(doc.proto, Doc)).then(proto => {
+ if (proto) {
+ alias.proto = proto;
+ }
+ });
+ }
return alias;
}
@@ -193,39 +218,13 @@ export namespace Doc {
return copy;
}
- export function MakeLink(source: Doc, target: Doc) {
- UndoManager.RunInBatch(() => {
- let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 });
- //let linkDoc = new Doc;
- linkDoc.proto!.title = "-link name-";
- linkDoc.linkDescription = "";
- linkDoc.linkTags = "Default";
-
- linkDoc.linkedTo = target;
- linkDoc.linkedFrom = source;
-
- let linkedFrom = Cast(target.linkedFromDocs, listSpec(Doc));
- if (!linkedFrom) {
- target.linkedFromDocs = linkedFrom = new List<Doc>();
- }
- linkedFrom.push(linkDoc);
-
- let linkedTo = Cast(source.linkedToDocs, listSpec(Doc));
- if (!linkedTo) {
- source.linkedToDocs = linkedTo = new List<Doc>();
- }
- linkedTo.push(linkDoc);
- return linkDoc;
- }, "make link");
- }
-
- export function MakeDelegate(doc: Doc): Doc;
- export function MakeDelegate(doc: Opt<Doc>): Opt<Doc>;
- export function MakeDelegate(doc: Opt<Doc>): Opt<Doc> {
+ export function MakeDelegate(doc: Doc, id?: string): Doc;
+ export function MakeDelegate(doc: Opt<Doc>, id?: string): Opt<Doc>;
+ export function MakeDelegate(doc: Opt<Doc>, id?: string): Opt<Doc> {
if (!doc) {
return undefined;
}
- const delegate = new Doc();
+ const delegate = new Doc(id, true);
delegate.proto = doc;
return delegate;
}