aboutsummaryrefslogtreecommitdiff
path: root/src/fields
diff options
context:
space:
mode:
authorlaurawilsonri <laura_wilson@brown.edu>2019-03-18 18:14:27 -0400
committerlaurawilsonri <laura_wilson@brown.edu>2019-03-18 18:14:27 -0400
commit9d939c1190ef86e456cf26e9f5cb84743279f7a6 (patch)
tree24d72d918f2becf6762ea30b92da7339957eedbd /src/fields
parent67170e521366f8178645cc85aaf377e53b1a6f21 (diff)
parentf70ad315167b714f11f7d68f35a46abe9e525a4d (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into editableSchema
Diffstat (limited to 'src/fields')
-rw-r--r--src/fields/AudioField.ts8
-rw-r--r--src/fields/Document.ts62
-rw-r--r--src/fields/HtmlField.ts2
-rw-r--r--src/fields/ImageField.ts4
-rw-r--r--src/fields/KVPField0
-rw-r--r--src/fields/KVPField.ts30
-rw-r--r--src/fields/KeyStore.ts6
-rw-r--r--src/fields/ListField.ts50
-rw-r--r--src/fields/PDFField.ts4
-rw-r--r--src/fields/TupleField.ts59
-rw-r--r--src/fields/VideoField.ts4
-rw-r--r--src/fields/WebField.ts4
12 files changed, 150 insertions, 83 deletions
diff --git a/src/fields/AudioField.ts b/src/fields/AudioField.ts
index aefcc15c1..8864471ae 100644
--- a/src/fields/AudioField.ts
+++ b/src/fields/AudioField.ts
@@ -10,8 +10,8 @@ export class AudioField extends BasicField<URL> {
toString(): string {
return this.Data.href;
}
-
-
+
+
ToScriptString(): string {
return `new AudioField("${this.Data}")`;
}
@@ -20,10 +20,10 @@ export class AudioField extends BasicField<URL> {
return new AudioField(this.Data);
}
- ToJson(): { type: Types, data: URL, _id: string } {
+ ToJson(): { type: Types, data: string, _id: string } {
return {
type: Types.Audio,
- data: this.Data,
+ data: this.Data.href,
_id: this.Id
}
}
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index 25e239417..be0137128 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -2,7 +2,7 @@ import { Key } from "./Key"
import { KeyStore } from "./KeyStore";
import { Field, Cast, FieldWaiting, FieldValue, FieldId, Opt } from "./Field"
import { NumberField } from "./NumberField";
-import { ObservableMap, computed, action } from "mobx";
+import { ObservableMap, computed, action, runInAction } from "mobx";
import { TextField } from "./TextField";
import { ListField } from "./ListField";
import { Server } from "../client/Server";
@@ -11,6 +11,7 @@ import { UndoManager } from "../client/util/UndoManager";
import { HtmlField } from "./HtmlField";
export class Document extends Field {
+ //TODO tfs: We should probably store FieldWaiting in fields when we request it from the server so that we don't set up multiple server gets for the same document and field
public fields: ObservableMap<string, { key: Key, field: Field }> = new ObservableMap();
public _proxies: ObservableMap<string, FieldId> = new ObservableMap();
@@ -38,6 +39,11 @@ export class Document extends Field {
return this.GetText(KeyStore.Title, "<untitled>");
}
+ @computed
+ public get Fields() {
+ return this.fields;
+ }
+
/**
* Get the field in the document associated with the given key. If the
* associated field has not yet been filled in from the server, a request
@@ -119,9 +125,11 @@ export class Document extends Field {
* @returns `true` if the field exists on the document and `callback` will be called, and `false` otherwise
*/
GetAsync(key: Key, callback: (field: Field) => void): boolean {
- //TODO: This should probably check if this.fields contains the key before calling Server.GetDocumentField
- //This currently doesn't deal with prototypes
- if (this._proxies.has(key.Id)) {
+ //TODO: This currently doesn't deal with prototypes
+ let field = this.fields.get(key.Id);
+ if (field && field.field) {
+ callback(field.field);
+ } else if (this._proxies.has(key.Id)) {
Server.GetDocumentField(this, key, callback);
return true;
}
@@ -207,25 +215,37 @@ export class Document extends Field {
}
@action
- Set(key: Key, field: Field | undefined): void {
+ SetOnPrototype(key: Key, field: Field | undefined): void {
+ this.GetAsync(KeyStore.Prototype, (f: Field) => {
+ (f as Document).Set(key, field)
+ })
+ }
+
+ @action
+ Set(key: Key, field: Field | undefined, setOnPrototype = false): void {
let old = this.fields.get(key.Id);
let oldField = old ? old.field : undefined;
- if (field) {
- this.fields.set(key.Id, { key, field });
- this._proxies.set(key.Id, field.Id)
- // Server.AddDocumentField(this, key, field);
- } else {
- this.fields.delete(key.Id);
- this._proxies.delete(key.Id)
- // Server.DeleteDocumentField(this, key);
+ if (setOnPrototype) {
+ this.SetOnPrototype(key, field)
+ }
+ else {
+ if (field) {
+ this.fields.set(key.Id, { key, field });
+ this._proxies.set(key.Id, field.Id)
+ // Server.AddDocumentField(this, key, field);
+ } else {
+ this.fields.delete(key.Id);
+ this._proxies.delete(key.Id)
+ // Server.DeleteDocumentField(this, key);
+ }
+ Server.UpdateField(this);
}
if (oldField || field) {
UndoManager.AddEvent({
- undo: () => this.Set(key, oldField),
- redo: () => this.Set(key, field)
+ undo: () => this.Set(key, oldField, setOnPrototype),
+ redo: () => this.Set(key, field, setOnPrototype)
})
}
- Server.UpdateField(this);
}
@action
@@ -265,6 +285,15 @@ export class Document extends Field {
return protos;
}
+ CreateAlias(id?: string): Document {
+ let alias = new Document(id)
+ this.GetAsync(KeyStore.Prototype, (f: Field) => {
+ alias.Set(KeyStore.Prototype, f)
+ })
+
+ return alias
+ }
+
MakeDelegate(id?: string): Document {
let delegate = new Document(id);
@@ -281,6 +310,7 @@ export class Document extends Field {
throw new Error("Method not implemented.");
}
GetValue() {
+ return this.Title;
var title = (this._proxies.has(KeyStore.Title.Id) ? "???" : this.Title) + "(" + this.Id + ")";
return title;
//throw new Error("Method not implemented.");
diff --git a/src/fields/HtmlField.ts b/src/fields/HtmlField.ts
index a07326095..7cbdf7e58 100644
--- a/src/fields/HtmlField.ts
+++ b/src/fields/HtmlField.ts
@@ -15,7 +15,7 @@ export class HtmlField extends BasicField<string> {
return new HtmlField(this.Data);
}
- ToJson(): { _id: string; type: Types; data: any; } {
+ ToJson(): { _id: string; type: Types; data: string; } {
return {
type: Types.Html,
data: this.Data,
diff --git a/src/fields/ImageField.ts b/src/fields/ImageField.ts
index be8d73e68..a9ece7d7b 100644
--- a/src/fields/ImageField.ts
+++ b/src/fields/ImageField.ts
@@ -19,10 +19,10 @@ export class ImageField extends BasicField<URL> {
return new ImageField(this.Data);
}
- ToJson(): { type: Types, data: URL, _id: string } {
+ ToJson(): { type: Types, data: string, _id: string } {
return {
type: Types.Image,
- data: this.Data,
+ data: this.Data.href,
_id: this.Id
}
}
diff --git a/src/fields/KVPField b/src/fields/KVPField
deleted file mode 100644
index e69de29bb..000000000
--- a/src/fields/KVPField
+++ /dev/null
diff --git a/src/fields/KVPField.ts b/src/fields/KVPField.ts
deleted file mode 100644
index a7ecc0768..000000000
--- a/src/fields/KVPField.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { BasicField } from "./BasicField"
-import { FieldId } from "./Field";
-import { Types } from "../server/Message";
-import { Document } from "./Document"
-
-export class KVPField extends BasicField<Document> {
- constructor(data: Document | undefined = undefined, id?: FieldId, save: boolean = true) {
- super(data == undefined ? new Document() : data, save, id);
- }
-
- toString(): string {
- return this.Data.Title;
- }
-
- ToScriptString(): string {
- return `new KVPField("${this.Data}")`;
- }
-
- Copy() {
- return new KVPField(this.Data);
- }
-
- ToJson(): { type: Types, data: Document, _id: string } {
- return {
- type: Types.Text,
- data: this.Data,
- _id: this.Id
- }
- }
-} \ No newline at end of file
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index f93a68c85..68883d6f1 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -19,11 +19,13 @@ export namespace KeyStore {
export const Annotations = new Key("Annotations");
export const ViewType = new Key("ViewType");
export const Layout = new Key("Layout");
+ export const BackgroundColor = new Key("BackgroundColor");
export const BackgroundLayout = new Key("BackgroundLayout");
export const OverlayLayout = new Key("OverlayLayout");
export const LayoutKeys = new Key("LayoutKeys");
export const LayoutFields = new Key("LayoutFields");
export const ColumnsKey = new Key("SchemaColumns");
+ export const SchemaSplitPercentage = new Key("SchemaSplitPercentage");
export const Caption = new Key("Caption");
export const ActiveFrame = new Key("ActiveFrame");
export const DocumentText = new Key("DocumentText");
@@ -35,4 +37,8 @@ export namespace KeyStore {
export const CurPage = new Key("CurPage");
export const NumPages = new Key("NumPages");
export const Ink = new Key("Ink");
+ export const Cursors = new Key("Cursors");
+ export const OptionalRightCollection = new Key("OptionalRightCollection");
+ export const Archives = new Key("Archives");
+ export const Updated = new Key("Updated");
}
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
index ce32da0a6..4527ee548 100644
--- a/src/fields/ListField.ts
+++ b/src/fields/ListField.ts
@@ -16,8 +16,13 @@ export class ListField<T extends Field> extends BasicField<T[]> {
this.observeList();
}
+ private _processingServerUpdate: boolean = false;
+
private observeDisposer: Lambda | undefined;
private observeList(): void {
+ if (this.observeDisposer) {
+ this.observeDisposer()
+ }
this.observeDisposer = observe(this.Data as IObservableArray<T>, (change: IArrayChange<T> | IArraySplice<T>) => {
this.updateProxies()
if (change.type == "splice") {
@@ -31,14 +36,12 @@ export class ListField<T extends Field> extends BasicField<T[]> {
redo: () => this.Data[change.index] = change.newValue
})
}
- Server.UpdateField(this);
+ if (!this._processingServerUpdate)
+ Server.UpdateField(this);
});
}
protected setData(value: T[]) {
- if (this.observeDisposer) {
- this.observeDisposer()
- }
this.data = observable(value);
this.updateProxies();
this.observeList();
@@ -69,30 +72,29 @@ export class ListField<T extends Field> extends BasicField<T[]> {
init(callback: (field: Field) => any) {
Server.GetFields(this._proxies, action((fields: { [index: string]: Field }) => {
- if (!this.arraysEqual(this._proxies, this.Data.map(field => field.Id))) {
+ if (!this.arraysEqual(this._proxies, this.data.map(field => field.Id))) {
var dataids = this.data.map(d => d.Id);
- var added = this.data.length == this._proxies.length - 1;
+ var proxies = this._proxies.map(p => p);
+ var added = this.data.length < this._proxies.length;
var deleted = this.data.length > this._proxies.length;
for (let i = 0; i < dataids.length && added; i++)
- added = this._proxies.indexOf(dataids[i]) != -1;
+ added = proxies.indexOf(dataids[i]) != -1;
for (let i = 0; i < this._proxies.length && deleted; i++)
- deleted = dataids.indexOf(this._proxies[i]) != -1;
- if (added) { // if only 1 items was added
- for (let i = 0; i < this._proxies.length; i++)
- if (dataids.indexOf(this._proxies[i]) === -1)
- this.Data.splice(i, 0, fields[this._proxies[i]] as T);
- } else if (deleted) { // if only items were deleted
- for (let i = this.data.length - 1; i >= 0; i--) {
- if (this._proxies.indexOf(this.data[i].Id) === -1) {
- this.Data.splice(i, 1);
- }
- }
- } else // otherwise, just rebuild the whole list
- this.data = this._proxies.map(id => fields[id] as T)
- observe(this.Data, () => {
- this.updateProxies()
- Server.UpdateField(this);
- })
+ deleted = dataids.indexOf(proxies[i]) != -1;
+
+ this._processingServerUpdate = true;
+ for (let i = 0; i < proxies.length && added; i++) {
+ if (dataids.indexOf(proxies[i]) === -1)
+ this.Data.splice(i, 0, fields[proxies[i]] as T);
+ }
+ for (let i = dataids.length - 1; i >= 0 && deleted; i--) {
+ if (proxies.indexOf(dataids[i]) === -1)
+ this.Data.splice(i, 1);
+ }
+ if (!added && !deleted) {// otherwise, just rebuild the whole list
+ this.setData(proxies.map(id => fields[id] as T));
+ }
+ this._processingServerUpdate = false;
}
callback(this);
}))
diff --git a/src/fields/PDFField.ts b/src/fields/PDFField.ts
index f3a009001..b6625387e 100644
--- a/src/fields/PDFField.ts
+++ b/src/fields/PDFField.ts
@@ -22,10 +22,10 @@ export class PDFField extends BasicField<URL> {
return `new PDFField("${this.Data}")`;
}
- ToJson(): { type: Types, data: URL, _id: string } {
+ ToJson(): { type: Types, data: string, _id: string } {
return {
type: Types.PDF,
- data: this.Data,
+ data: this.Data.href,
_id: this.Id
}
}
diff --git a/src/fields/TupleField.ts b/src/fields/TupleField.ts
new file mode 100644
index 000000000..e2162c751
--- /dev/null
+++ b/src/fields/TupleField.ts
@@ -0,0 +1,59 @@
+import { action, IArrayChange, IArraySplice, IObservableArray, observe, observable, Lambda } from "mobx";
+import { Server } from "../client/Server";
+import { UndoManager } from "../client/util/UndoManager";
+import { Types } from "../server/Message";
+import { BasicField } from "./BasicField";
+import { Field, FieldId } from "./Field";
+
+export class TupleField<T, U> extends BasicField<[T, U]> {
+ constructor(data: [T, U], id?: FieldId, save: boolean = true) {
+ super(data, save, id);
+ if (save) {
+ Server.UpdateField(this);
+ }
+ this.observeTuple();
+ }
+
+ private observeDisposer: Lambda | undefined;
+ private observeTuple(): void {
+ this.observeDisposer = observe(this.Data as (T | U)[] as IObservableArray<T | U>, (change: IArrayChange<T | U> | IArraySplice<T | U>) => {
+ if (change.type === "update") {
+ UndoManager.AddEvent({
+ undo: () => this.Data[change.index] = change.oldValue,
+ redo: () => this.Data[change.index] = change.newValue
+ })
+ Server.UpdateField(this);
+ } else {
+ throw new Error("Why are you messing with the length of a tuple, huh?");
+ }
+ });
+ }
+
+ protected setData(value: [T, U]) {
+ if (this.observeDisposer) {
+ this.observeDisposer()
+ }
+ this.data = observable(value) as (T | U)[] as [T, U];
+ this.observeTuple();
+ }
+
+ UpdateFromServer(values: [T, U]) {
+ this.setData(values);
+ }
+
+ ToScriptString(): string {
+ return `new TupleField([${this.Data[0], this.Data[1]}])`;
+ }
+
+ Copy(): Field {
+ return new TupleField<T, U>(this.Data);
+ }
+
+ ToJson(): { type: Types, data: [T, U], _id: string } {
+ return {
+ type: Types.Tuple,
+ data: this.Data,
+ _id: this.Id
+ }
+ }
+} \ No newline at end of file
diff --git a/src/fields/VideoField.ts b/src/fields/VideoField.ts
index 5f4ae19bf..626e4ec83 100644
--- a/src/fields/VideoField.ts
+++ b/src/fields/VideoField.ts
@@ -19,10 +19,10 @@ export class VideoField extends BasicField<URL> {
return new VideoField(this.Data);
}
- ToJson(): { type: Types, data: URL, _id: string } {
+ ToJson(): { type: Types, data: string, _id: string } {
return {
type: Types.Video,
- data: this.Data,
+ data: this.Data.href,
_id: this.Id
}
}
diff --git a/src/fields/WebField.ts b/src/fields/WebField.ts
index 8f945d686..6c4de5000 100644
--- a/src/fields/WebField.ts
+++ b/src/fields/WebField.ts
@@ -19,10 +19,10 @@ export class WebField extends BasicField<URL> {
return new WebField(this.Data);
}
- ToJson(): { type: Types, data: URL, _id: string } {
+ ToJson(): { type: Types, data: string, _id: string } {
return {
type: Types.Web,
- data: this.Data,
+ data: this.Data.href,
_id: this.Id
}
}