aboutsummaryrefslogtreecommitdiff
path: root/src/fields/ListField.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields/ListField.ts')
-rw-r--r--src/fields/ListField.ts96
1 files changed, 81 insertions, 15 deletions
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
index b6eab5f86..8311e737b 100644
--- a/src/fields/ListField.ts
+++ b/src/fields/ListField.ts
@@ -5,12 +5,18 @@ import { Types } from "../server/Message";
import { BasicField } from "./BasicField";
import { Field, FieldId } from "./Field";
import { FieldMap } from "../client/SocketStub";
+import { ScriptField } from "./ScriptField";
export class ListField<T extends Field> extends BasicField<T[]> {
private _proxies: string[] = [];
- constructor(data: T[] = [], id?: FieldId, save: boolean = true) {
+ private _scriptIds: string[] = [];
+ private scripts: ScriptField[] = [];
+
+ constructor(data: T[] = [], scripts: ScriptField[] = [], id?: FieldId, save: boolean = true) {
super(data, save, id);
+ this.scripts = scripts;
this.updateProxies();
+ this._scriptIds = this.scripts.map(script => script.Id);
if (save) {
Server.UpdateField(this);
}
@@ -25,17 +31,22 @@ export class ListField<T extends Field> extends BasicField<T[]> {
this.observeDisposer();
}
this.observeDisposer = observe(this.Data as IObservableArray<T>, (change: IArrayChange<T> | IArraySplice<T>) => {
+ const target = change.object;
this.updateProxies();
if (change.type === "splice") {
+ this.runScripts(change.removed, false);
UndoManager.AddEvent({
- undo: () => this.Data.splice(change.index, change.addedCount, ...change.removed),
- redo: () => this.Data.splice(change.index, change.removedCount, ...change.added)
+ undo: () => target.splice(change.index, change.addedCount, ...change.removed),
+ redo: () => target.splice(change.index, change.removedCount, ...change.added)
});
+ this.runScripts(change.added, true);
} else {
+ this.runScripts([change.oldValue], false);
UndoManager.AddEvent({
- undo: () => this.Data[change.index] = change.oldValue,
- redo: () => this.Data[change.index] = change.newValue
+ undo: () => target[change.index] = change.oldValue,
+ redo: () => target[change.index] = change.newValue
});
+ this.runScripts([change.newValue], true);
}
if (!this._processingServerUpdate) {
Server.UpdateField(this);
@@ -43,19 +54,60 @@ export class ListField<T extends Field> extends BasicField<T[]> {
});
}
+ private runScripts(fields: T[], added: boolean) {
+ for (const script of this.scripts) {
+ this.runScript(fields, script, added);
+ }
+ }
+
+ private runScript(fields: T[], script: ScriptField, added: boolean) {
+ if (!this._processingServerUpdate) {
+ for (const field of fields) {
+ script.script.run({ field, added });
+ }
+ }
+ }
+
+ addScript(script: ScriptField) {
+ this.scripts.push(script);
+ this._scriptIds.push(script.Id);
+
+ this.runScript(this.Data, script, true);
+ UndoManager.AddEvent({
+ undo: () => this.removeScript(script),
+ redo: () => this.addScript(script),
+ });
+ Server.UpdateField(this);
+ }
+
+ removeScript(script: ScriptField) {
+ const index = this.scripts.indexOf(script);
+ if (index === -1) {
+ return;
+ }
+ this.scripts.splice(index, 1);
+ this._scriptIds.splice(index, 1);
+ UndoManager.AddEvent({
+ undo: () => this.addScript(script),
+ redo: () => this.removeScript(script),
+ });
+ this.runScript(this.Data, script, false);
+ Server.UpdateField(this);
+ }
+
protected setData(value: T[]) {
+ this.runScripts(this.data, false);
+
this.data = observable(value);
this.updateProxies();
this.observeList();
+ this.runScripts(this.data, true);
}
private updateProxies() {
this._proxies = this.Data.map(field => field.Id);
}
- UpdateFromServer(fields: string[]) {
- this._proxies = fields;
- }
private arraysEqual(a: any[], b: any[]) {
if (a === b) return true;
if (a === null || b === null) return false;
@@ -73,7 +125,7 @@ export class ListField<T extends Field> extends BasicField<T[]> {
}
init(callback: (field: Field) => any) {
- Server.GetFields(this._proxies, action((fields: FieldMap) => {
+ const fieldsPromise = Server.GetFields(this._proxies).then(action((fields: FieldMap) => {
if (!this.arraysEqual(this._proxies, this.data.map(field => field.Id))) {
var dataids = this.data.map(d => d.Id);
var proxies = this._proxies.map(p => p);
@@ -102,8 +154,13 @@ export class ListField<T extends Field> extends BasicField<T[]> {
}
this._processingServerUpdate = false;
}
- callback(this);
}));
+
+ const scriptsPromise = Server.GetFields(this._scriptIds).then((fields: FieldMap) => {
+ this.scripts = this._scriptIds.map(id => fields[id] as ScriptField);
+ });
+
+ Promise.all([fieldsPromise, scriptsPromise]).then(() => callback(this));
}
ToScriptString(): string {
@@ -114,17 +171,26 @@ export class ListField<T extends Field> extends BasicField<T[]> {
return new ListField<T>(this.Data);
}
- ToJson(): { type: Types, data: string[], _id: string } {
+
+ UpdateFromServer(data: { fields: string[], scripts: string[] }) {
+ this._proxies = data.fields;
+ this._scriptIds = data.scripts;
+ }
+ ToJson(): { type: Types, data: { fields: string[], scripts: string[] }, _id: string } {
return {
type: Types.List,
- data: this._proxies || [],
+ data: {
+ fields: this._proxies,
+ scripts: this._scriptIds,
+ },
_id: this.Id
};
}
- static FromJson(id: string, ids: string[]): ListField<Field> {
- let list = new ListField([], id, false);
- list._proxies = ids;
+ static FromJson(id: string, data: { fields: string[], scripts: string[] }): ListField<Field> {
+ let list = new ListField([], [], id, false);
+ list._proxies = data.fields;
+ list._scriptIds = data.scripts;
return list;
}
} \ No newline at end of file