aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json51
-rw-r--r--package.json5
-rw-r--r--src/Main.tsx40
-rw-r--r--src/Utils.ts14
-rw-r--r--src/controllers/FieldUpdatedArgs.ts27
-rw-r--r--src/controllers/KeyController.ts36
-rw-r--r--src/controllers/ListController.ts30
-rw-r--r--src/controllers/NumberController.ts14
-rw-r--r--src/controllers/TextController.ts14
-rw-r--r--src/fields/BasicField.ts (renamed from src/controllers/BasicFieldController.ts)4
-rw-r--r--src/fields/Document.ts (renamed from src/controllers/DocumentController.ts)43
-rw-r--r--src/fields/DocumentReference.ts (renamed from src/controllers/DocumentReferenceController.ts)24
-rw-r--r--src/fields/Field.ts (renamed from src/controllers/FieldController.ts)18
-rw-r--r--src/fields/FieldUpdatedArgs.ts27
-rw-r--r--src/fields/Key.ts37
-rw-r--r--src/fields/ListField.ts21
-rw-r--r--src/fields/NumberField.ts13
-rw-r--r--src/fields/TextField.ts13
-rw-r--r--src/stores/NodeCollectionStore.ts4
-rw-r--r--src/viewmodels/DocumentViewModel.ts11
-rw-r--r--src/views/freeformcanvas/FreeFormCanvas.tsx19
-rw-r--r--src/views/freeformcanvas/NodeContainer.tsx3
-rw-r--r--src/views/nodes/DocumentView.tsx50
-rw-r--r--test/test.ts98
24 files changed, 343 insertions, 273 deletions
diff --git a/package-lock.json b/package-lock.json
index 89aa74ba8..b75ff25f8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,11 @@
"integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==",
"dev": true
},
+ "@types/node": {
+ "version": "10.12.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
+ "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ=="
+ },
"@types/prop-types": {
"version": "15.5.8",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.8.tgz",
@@ -41,6 +46,14 @@
"@types/react": "*"
}
},
+ "@types/uuid": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz",
+ "integrity": "sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@webassemblyjs/ast": {
"version": "1.7.11",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz",
@@ -243,8 +256,7 @@
"acorn": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
- "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
- "dev": true
+ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw=="
},
"acorn-dynamic-import": {
"version": "3.0.0",
@@ -255,6 +267,14 @@
"acorn": "^5.0.0"
}
},
+ "acorn-jsx": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz",
+ "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==",
+ "requires": {
+ "acorn": "^5.0.3"
+ }
+ },
"ajv": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
@@ -453,7 +473,7 @@
},
"async": {
"version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
@@ -1147,7 +1167,7 @@
},
"content-disposition": {
"version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "resolved": "http://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
"dev": true
},
@@ -2013,7 +2033,7 @@
"dependencies": {
"array-flatten": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
"dev": true
}
@@ -2171,7 +2191,7 @@
},
"finalhandler": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"dev": true,
"requires": {
@@ -2979,7 +2999,7 @@
},
"globby": {
"version": "6.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
@@ -2992,7 +3012,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@@ -3172,7 +3192,7 @@
},
"http-errors": {
"version": "1.6.3",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
"requires": {
@@ -3201,7 +3221,7 @@
},
"http-proxy-middleware": {
"version": "0.18.0",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
+ "resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
"integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==",
"dev": true,
"requires": {
@@ -3853,7 +3873,7 @@
},
"media-typer": {
"version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
"dev": true
},
@@ -5051,6 +5071,15 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.7.0.tgz",
"integrity": "sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g=="
},
+ "react-jsx-parser": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/react-jsx-parser/-/react-jsx-parser-1.13.0.tgz",
+ "integrity": "sha512-oypIhM30ESZ8UkU0xDmzSV2Mtb2mVvtVnyNzjDxx2h2PCHpYFdDVLx1c15E3ot6nTIVlIh072tWwS3iJ7VVgmg==",
+ "requires": {
+ "acorn-jsx": "^4.1.1",
+ "react": "^16.4.0"
+ }
+ },
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
diff --git a/package.json b/package.json
index afd940acb..d4443eff0 100644
--- a/package.json
+++ b/package.json
@@ -27,11 +27,14 @@
"webpack-dev-server": "^3.1.14"
},
"dependencies": {
+ "@types/uuid": "^3.4.4",
"mobx": "^5.5.2",
"mobx-react": "^5.3.5",
"mobx-react-devtools": "^6.0.3",
"node-sass": "^4.11.0",
"react": "^16.5.2",
- "react-dom": "^16.5.2"
+ "react-dom": "^16.5.2",
+ "react-jsx-parser": "^1.13.0",
+ "uuid": "^3.3.2"
}
}
diff --git a/src/Main.tsx b/src/Main.tsx
index af7e2a8d4..21d8b4c1a 100644
--- a/src/Main.tsx
+++ b/src/Main.tsx
@@ -6,11 +6,17 @@ import { RootStore } from './stores/RootStore';
import { StaticTextNodeStore } from './stores/StaticTextNodeStore';
import { VideoNodeStore } from './stores/VideoNodeStore';
import { FreeFormCanvas } from './views/freeformcanvas/FreeFormCanvas';
-import { KeyController, KeyStore as KS } from './controllers/KeyController';
-import { NumberController } from './controllers/NumberController';
-import { DocumentController } from './controllers/DocumentController';
-import { TextController } from './controllers/TextController';
+import { Key, KeyStore as KS } from './fields/Key';
+import { NumberField } from './fields/NumberField';
+import { Document } from './fields/Document';
+import { TextField } from './fields/TextField';
+import { configure, runInAction } from 'mobx';
+import { NodeStore } from './stores/NodeStore';
+import { ListField } from './fields/ListField';
+configure({
+ enforceActions: "observed"
+});
const mainNodeCollection = new NodeCollectionStore();
ReactDOM.render((
@@ -25,7 +31,7 @@ ReactDOM.render((
let numNodes = 300;
let maxX = 10000;
let maxY = 10000;
-let nodes = []
+let nodes:NodeStore[] = []
for (let i = 0; i < numNodes; i++) {
nodes.push(new StaticTextNodeStore({ X: Math.random() * maxX, Y: Math.random() * maxY, Title: "Text Node Title", Text: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" }));
}
@@ -34,11 +40,19 @@ for (let i = 0; i < 20; i++) {
nodes.push(new VideoNodeStore({ X: Math.random() * maxX, Y: Math.random() * maxY, Title: "Video Node Title", Url: "http://cs.brown.edu/people/peichman/downloads/cted.mp4" }));
}
-mainNodeCollection.AddNodes(nodes);
-let doc1 = new DocumentController();
-doc1.SetField(KS.X, new NumberController(5));
-doc1.SetField(KS.Y, new NumberController(5));
-doc1.SetField(KS.Width, new NumberController(5));
-doc1.SetField(KS.Height, new NumberController(5));
-doc1.SetField(KS.Data, new TextController("Hello world"));
-mainNodeCollection.Docs.push(doc1); \ No newline at end of file
+runInAction(() => {
+ mainNodeCollection.AddNodes(nodes);
+ let doc1 = new Document();
+ doc1.SetField(KS.X, new NumberField(5));
+ doc1.SetField(KS.Y, new NumberField(5));
+ doc1.SetField(KS.Width, new NumberField(100));
+ doc1.SetField(KS.Height, new NumberField(50));
+ doc1.SetField(KS.Data, new TextField("Hello world"));
+ doc1.SetField(KS.View, new TextField('<p style="color:blue; font-size:40px">{Data + X}</p>'));
+ doc1.SetField(KS.ViewProps, new ListField([KS.Data, KS.X]));
+ let doc2 = doc1.MakeDelegate();
+ doc2.SetField(KS.X, new NumberField(150));
+ doc2.SetField(KS.Y, new NumberField(20));
+ mainNodeCollection.Docs.push(doc1);
+ mainNodeCollection.Docs.push(doc2);
+}); \ No newline at end of file
diff --git a/src/Utils.ts b/src/Utils.ts
index f404adf14..f352b87e3 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -1,15 +1,13 @@
-
+import v4 = require('uuid/v4');
+import v5 = require("uuid/v5");
export class Utils {
- public static GenerateGuid() {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
- }
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
+ public static GenerateGuid(): string {
+ return v4();
}
- public static GenerateDeterministicGuid(seed: string) {
- return seed;
+ public static GenerateDeterministicGuid(seed: string): string {
+ return v5(seed, v5.URL);
}
} \ No newline at end of file
diff --git a/src/controllers/FieldUpdatedArgs.ts b/src/controllers/FieldUpdatedArgs.ts
deleted file mode 100644
index f258c53e2..000000000
--- a/src/controllers/FieldUpdatedArgs.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { FieldController, Opt } from "./FieldController";
-import { DocumentController } from "./DocumentController";
-import { KeyController } from "./KeyController";
-
-export enum FieldUpdatedAction {
- Add,
- Remove,
- Replace,
- Update
-}
-
-export interface FieldUpdatedArgs {
- field: FieldController;
- action: FieldUpdatedAction;
-}
-
-export interface DocumentUpdatedArgs {
- field: DocumentController;
- key: KeyController;
-
- oldValue: Opt<FieldController>;
- newValue: Opt<FieldController>;
-
- fieldArgs?: FieldUpdatedArgs;
-
- action: FieldUpdatedAction;
-}
diff --git a/src/controllers/KeyController.ts b/src/controllers/KeyController.ts
deleted file mode 100644
index 68eed3961..000000000
--- a/src/controllers/KeyController.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { FieldController } from "./FieldController"
-import { Utils } from "../Utils";
-
-export class KeyController extends FieldController {
- get Name():string {
- return this.name;
- }
-
- constructor(private name:string){
- super(Utils.GenerateDeterministicGuid(name));
- }
-
- TrySetValue(value: any): boolean {
- throw new Error("Method not implemented.");
- }
-
- GetValue() {
- return this.Name;
- }
-
- Copy(): FieldController {
- return this;
- }
-
-
-}
-
-export namespace KeyStore {
- export let Prototype = new KeyController("Prototype");
- export let X = new KeyController("Y");
- export let Y = new KeyController("Y");
- export let Width = new KeyController("Width");
- export let Height = new KeyController("Height");
- export let Data = new KeyController("Data");
- export let View = new KeyController("View");
-} \ No newline at end of file
diff --git a/src/controllers/ListController.ts b/src/controllers/ListController.ts
deleted file mode 100644
index 94a4ae828..000000000
--- a/src/controllers/ListController.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { FieldController } from "./FieldController";
-import { BasicFieldController } from "./BasicFieldController";
-import { NumberController } from "./NumberController";
-import { TextController } from "./TextController";
-
-export class ListController<T extends FieldController> extends BasicFieldController<T[]> {
- constructor(data: T[] = []) {
- super(data.slice());
-
- let arr:TextController[] = [];
- this.Test(arr);
- }
-
- Test(test: FieldController[]){
- test.push(new NumberController());
- }
-
- Get(index:number) : T{
- return this.Data[index];
- }
-
- Set(index:number, value:T):void {
- this.Data[index] = value;
- }
-
- Copy(): FieldController {
- return new ListController<T>(this.Data);
- }
-
-} \ No newline at end of file
diff --git a/src/controllers/NumberController.ts b/src/controllers/NumberController.ts
deleted file mode 100644
index aeedf025b..000000000
--- a/src/controllers/NumberController.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { BasicFieldController } from "./BasicFieldController"
-import { FieldUpdatedAction } from "./FieldUpdatedArgs";
-
-export class NumberController extends BasicFieldController<number> {
- constructor(data: number = 0) {
- super(data);
- }
-
- Copy() {
- return new NumberController(this.Data);
- }
-
-
-} \ No newline at end of file
diff --git a/src/controllers/TextController.ts b/src/controllers/TextController.ts
deleted file mode 100644
index 5d4b43170..000000000
--- a/src/controllers/TextController.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { BasicFieldController } from "./BasicFieldController"
-import { FieldUpdatedAction } from "./FieldUpdatedArgs";
-
-export class TextController extends BasicFieldController<string> {
- constructor(data: string = "") {
- super(data);
- }
-
- Copy() {
- return new TextController(this.Data);
- }
-
-
-}
diff --git a/src/controllers/BasicFieldController.ts b/src/fields/BasicField.ts
index 923bc335c..437024d07 100644
--- a/src/controllers/BasicFieldController.ts
+++ b/src/fields/BasicField.ts
@@ -1,7 +1,7 @@
-import { FieldController } from "./FieldController"
+import { Field } from "./Field"
import { observable, computed, action } from "mobx";
-export abstract class BasicFieldController<T> extends FieldController {
+export abstract class BasicField<T> extends Field {
constructor(data: T) {
super();
diff --git a/src/controllers/DocumentController.ts b/src/fields/Document.ts
index 0627f9717..c315beaef 100644
--- a/src/controllers/DocumentController.ts
+++ b/src/fields/Document.ts
@@ -1,20 +1,18 @@
-import { FieldController, Cast, Opt } from "./FieldController"
-import { KeyController, KeyStore } from "./KeyController"
-import { TypedEvent, Listener, Disposable } from "../util/TypedEvent";
-import { DocumentUpdatedArgs, FieldUpdatedAction } from "./FieldUpdatedArgs";
+import { Field, Cast, Opt } from "./Field"
+import { Key, KeyStore } from "./Key"
import { ObservableMap } from "mobx";
-export class DocumentController extends FieldController {
- private fields: ObservableMap<KeyController, FieldController> = new ObservableMap();
+export class Document extends Field {
+ private fields: ObservableMap<Key, Field> = new ObservableMap();
- GetField(key: KeyController, ignoreProto?: boolean): Opt<FieldController> {
- let field: Opt<FieldController>;
+ GetField(key: Key, ignoreProto?: boolean): Opt<Field> {
+ let field: Opt<Field>;
if (ignoreProto) {
if (this.fields.has(key)) {
field = this.fields.get(key);
}
} else {
- let doc: Opt<DocumentController> = this;
+ let doc: Opt<Document> = this;
while (doc && !(doc.fields.has(key))) {
doc = doc.GetPrototype();
}
@@ -27,11 +25,16 @@ export class DocumentController extends FieldController {
return field;
}
- GetFieldT<T extends FieldController = FieldController>(key: KeyController, ctor: { new(): T }, ignoreProto?: boolean): Opt<T> {
+ GetFieldT<T extends Field = Field>(key: Key, ctor: { new(): T }, ignoreProto?: boolean): Opt<T> {
return Cast(this.GetField(key, ignoreProto), ctor);
}
- SetField(key: KeyController, field: Opt<FieldController>): void {
+ GetFieldValue<T, U extends { Data: T }>(key: Key, ctor: { new(): U }, defaultVal: T): T {
+ let val = this.GetField(key);
+ return (val && val instanceof ctor) ? val.Data : defaultVal;
+ }
+
+ SetField(key: Key, field: Opt<Field>): void {
if (field) {
this.fields.set(key, field);
} else {
@@ -39,7 +42,7 @@ export class DocumentController extends FieldController {
}
}
- SetFieldValue<T extends FieldController>(key: KeyController, value: any, ctor: { new(): T }): boolean {
+ SetFieldValue<T extends Field>(key: Key, value: any, ctor: { new(): T }): boolean {
let field = this.GetField(key);
if (field != null) {
return field.TrySetValue(value);
@@ -54,13 +57,13 @@ export class DocumentController extends FieldController {
}
}
- GetPrototype(): Opt<DocumentController> {
- return this.GetFieldT(KeyStore.Prototype, DocumentController, true);
+ GetPrototype(): Opt<Document> {
+ return this.GetFieldT(KeyStore.Prototype, Document, true);
}
- GetAllPrototypes(): DocumentController[] {
- let protos: DocumentController[] = [];
- let doc: Opt<DocumentController> = this;
+ GetAllPrototypes(): Document[] {
+ let protos: Document[] = [];
+ let doc: Opt<Document> = this;
while (doc != null) {
protos.push(doc);
doc = doc.GetPrototype();
@@ -68,8 +71,8 @@ export class DocumentController extends FieldController {
return protos;
}
- MakeDelegate(): DocumentController {
- let delegate = new DocumentController();
+ MakeDelegate(): Document {
+ let delegate = new Document();
delegate.SetField(KeyStore.Prototype, this);
@@ -82,7 +85,7 @@ export class DocumentController extends FieldController {
GetValue() {
throw new Error("Method not implemented.");
}
- Copy(): FieldController {
+ Copy(): Field {
throw new Error("Method not implemented.");
}
diff --git a/src/controllers/DocumentReferenceController.ts b/src/fields/DocumentReference.ts
index 8e0aaf0e9..936067bd2 100644
--- a/src/controllers/DocumentReferenceController.ts
+++ b/src/fields/DocumentReference.ts
@@ -1,18 +1,18 @@
-import { FieldController, Opt } from "./FieldController";
-import { DocumentController } from "./DocumentController";
-import { KeyController } from "./KeyController";
+import { Field, Opt } from "./Field";
+import { Document } from "./Document";
+import { Key } from "./Key";
import { DocumentUpdatedArgs } from "./FieldUpdatedArgs";
-export class DocumentReferenceController extends FieldController {
- get Key(): KeyController{
+export class DocumentReference extends Field {
+ get Key(): Key{
return this.key;
}
- get Document(): DocumentController {
+ get Document(): Document {
return this.document;
}
- constructor(private document: DocumentController, private key: KeyController) {
+ constructor(private document: Document, private key: Key) {
super();
}
@@ -20,13 +20,13 @@ export class DocumentReferenceController extends FieldController {
// this.FieldUpdated.emit(args.fieldArgs);
}
- Dereference() : Opt<FieldController> {
+ Dereference() : Opt<Field> {
return this.document.GetField(this.key);
}
- DereferenceToRoot(): Opt<FieldController> {
- let field: Opt<FieldController> = this;
- while (field instanceof DocumentReferenceController) {
+ DereferenceToRoot(): Opt<Field> {
+ let field: Opt<Field> = this;
+ while (field instanceof DocumentReference) {
field = field.Dereference();
}
return field;
@@ -38,7 +38,7 @@ export class DocumentReferenceController extends FieldController {
GetValue() {
throw new Error("Method not implemented.");
}
- Copy(): FieldController {
+ Copy(): Field {
throw new Error("Method not implemented.");
}
diff --git a/src/controllers/FieldController.ts b/src/fields/Field.ts
index ec59f53e8..46f92f203 100644
--- a/src/controllers/FieldController.ts
+++ b/src/fields/Field.ts
@@ -1,9 +1,9 @@
import { TypedEvent } from "../util/TypedEvent";
import { FieldUpdatedArgs } from "./FieldUpdatedArgs";
-import { DocumentReferenceController } from "./DocumentReferenceController";
+import { DocumentReference } from "./DocumentReference";
import { Utils } from "../Utils";
-export function Cast<T extends FieldController>(field: Opt<FieldController>, ctor: { new(): T }): Opt<T> {
+export function Cast<T extends Field>(field: Opt<Field>, ctor: { new(): T }): Opt<T> {
if (field) {
if (ctor && field instanceof ctor) {
return field;
@@ -14,7 +14,7 @@ export function Cast<T extends FieldController>(field: Opt<FieldController>, cto
export type Opt<T> = T | undefined;
-export abstract class FieldController {
+export abstract class Field {
//FieldUpdated: TypedEvent<Opt<FieldUpdatedArgs>> = new TypedEvent<Opt<FieldUpdatedArgs>>();
private id: string;
@@ -26,22 +26,22 @@ export abstract class FieldController {
this.id = id || Utils.GenerateGuid();
}
- Dereference(): Opt<FieldController> {
+ Dereference(): Opt<Field> {
return this;
}
- DereferenceToRoot(): Opt<FieldController> {
+ DereferenceToRoot(): Opt<Field> {
return this;
}
- DereferenceT<T extends FieldController = FieldController>(ctor: { new(): T }): Opt<T> {
+ DereferenceT<T extends Field = Field>(ctor: { new(): T }): Opt<T> {
return Cast(this.Dereference(), ctor);
}
- DereferenceToRootT<T extends FieldController = FieldController>(ctor: { new(): T }): Opt<T> {
+ DereferenceToRootT<T extends Field = Field>(ctor: { new(): T }): Opt<T> {
return Cast(this.DereferenceToRoot(), ctor);
}
- Equals(other: FieldController): boolean {
+ Equals(other: Field): boolean {
return this.id === other.id;
}
@@ -49,6 +49,6 @@ export abstract class FieldController {
abstract GetValue(): any;
- abstract Copy(): FieldController;
+ abstract Copy(): Field;
} \ No newline at end of file
diff --git a/src/fields/FieldUpdatedArgs.ts b/src/fields/FieldUpdatedArgs.ts
new file mode 100644
index 000000000..23ccf2a5a
--- /dev/null
+++ b/src/fields/FieldUpdatedArgs.ts
@@ -0,0 +1,27 @@
+import { Field, Opt } from "./Field";
+import { Document } from "./Document";
+import { Key } from "./Key";
+
+export enum FieldUpdatedAction {
+ Add,
+ Remove,
+ Replace,
+ Update
+}
+
+export interface FieldUpdatedArgs {
+ field: Field;
+ action: FieldUpdatedAction;
+}
+
+export interface DocumentUpdatedArgs {
+ field: Document;
+ key: Key;
+
+ oldValue: Opt<Field>;
+ newValue: Opt<Field>;
+
+ fieldArgs?: FieldUpdatedArgs;
+
+ action: FieldUpdatedAction;
+}
diff --git a/src/fields/Key.ts b/src/fields/Key.ts
new file mode 100644
index 000000000..42881c8a6
--- /dev/null
+++ b/src/fields/Key.ts
@@ -0,0 +1,37 @@
+import { Field } from "./Field"
+import { Utils } from "../Utils";
+
+export class Key extends Field {
+ get Name():string {
+ return this.name;
+ }
+
+ constructor(private name:string){
+ super(Utils.GenerateDeterministicGuid(name));
+ }
+
+ TrySetValue(value: any): boolean {
+ throw new Error("Method not implemented.");
+ }
+
+ GetValue() {
+ return this.Name;
+ }
+
+ Copy(): Field {
+ return this;
+ }
+
+
+}
+
+export namespace KeyStore {
+ export let Prototype = new Key("Prototype");
+ export let X = new Key("X");
+ export let Y = new Key("Y");
+ export let Width = new Key("Width");
+ export let Height = new Key("Height");
+ export let Data = new Key("Data");
+ export let View = new Key("View");
+ export let ViewProps = new Key("ViewProps");
+} \ No newline at end of file
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
new file mode 100644
index 000000000..dd96ea8c8
--- /dev/null
+++ b/src/fields/ListField.ts
@@ -0,0 +1,21 @@
+import { Field } from "./Field";
+import { BasicField } from "./BasicField";
+
+export class ListField<T extends Field> extends BasicField<T[]> {
+ constructor(data: T[] = []) {
+ super(data.slice());
+ }
+
+ Get(index:number) : T{
+ return this.Data[index];
+ }
+
+ Set(index:number, value:T):void {
+ this.Data[index] = value;
+ }
+
+ Copy(): Field {
+ return new ListField<T>(this.Data);
+ }
+
+} \ No newline at end of file
diff --git a/src/fields/NumberField.ts b/src/fields/NumberField.ts
new file mode 100644
index 000000000..cbe15f987
--- /dev/null
+++ b/src/fields/NumberField.ts
@@ -0,0 +1,13 @@
+import { BasicField } from "./BasicField"
+
+export class NumberField extends BasicField<number> {
+ constructor(data: number = 0) {
+ super(data);
+ }
+
+ Copy() {
+ return new NumberField(this.Data);
+ }
+
+
+} \ No newline at end of file
diff --git a/src/fields/TextField.ts b/src/fields/TextField.ts
new file mode 100644
index 000000000..a7c221788
--- /dev/null
+++ b/src/fields/TextField.ts
@@ -0,0 +1,13 @@
+import { BasicField } from "./BasicField"
+
+export class TextField extends BasicField<string> {
+ constructor(data: string = "") {
+ super(data);
+ }
+
+ Copy() {
+ return new TextField(this.Data);
+ }
+
+
+}
diff --git a/src/stores/NodeCollectionStore.ts b/src/stores/NodeCollectionStore.ts
index b6f2ef8e0..ac4f515f1 100644
--- a/src/stores/NodeCollectionStore.ts
+++ b/src/stores/NodeCollectionStore.ts
@@ -1,6 +1,6 @@
import { computed, observable, action } from "mobx";
import { NodeStore } from "./NodeStore";
-import { DocumentController } from "../controllers/DocumentController";
+import { Document } from "../fields/Document";
export class NodeCollectionStore extends NodeStore {
@@ -11,7 +11,7 @@ export class NodeCollectionStore extends NodeStore {
public Nodes: NodeStore[] = new Array<NodeStore>();
@observable
- public Docs: DocumentController[] = [];
+ public Docs: Document[] = [];
@computed
public get Transform(): string {
diff --git a/src/viewmodels/DocumentViewModel.ts b/src/viewmodels/DocumentViewModel.ts
new file mode 100644
index 000000000..008275f3c
--- /dev/null
+++ b/src/viewmodels/DocumentViewModel.ts
@@ -0,0 +1,11 @@
+import { Document } from "../fields/Document";
+
+export class DocumentViewModel {
+ constructor(private doc: Document) {
+
+ }
+
+ get Doc(): Document {
+ return this.doc;
+ }
+} \ No newline at end of file
diff --git a/src/views/freeformcanvas/FreeFormCanvas.tsx b/src/views/freeformcanvas/FreeFormCanvas.tsx
index a80e11ef5..3552ffa54 100644
--- a/src/views/freeformcanvas/FreeFormCanvas.tsx
+++ b/src/views/freeformcanvas/FreeFormCanvas.tsx
@@ -3,8 +3,10 @@ import { NodeCollectionStore } from "../../stores/NodeCollectionStore";
import "./FreeFormCanvas.scss";
import { NodeContainer } from "./NodeContainer";
import React = require("react");
-import { KeyStore } from "../../controllers/KeyController";
-import { NumberController } from "../../controllers/NumberController";
+import { KeyStore } from "../../fields/Key";
+import { NumberField } from "../../fields/NumberField";
+import { TextField } from "../../fields/TextField";
+import { action } from "mobx";
interface IProps {
store: NodeCollectionStore
@@ -15,6 +17,7 @@ export class FreeFormCanvas extends React.Component<IProps> {
private _isPointerDown: boolean = false;
+ @action
onPointerDown = (e: React.PointerEvent): void => {
e.stopPropagation();
e.preventDefault();
@@ -25,6 +28,7 @@ export class FreeFormCanvas extends React.Component<IProps> {
document.addEventListener("pointerup", this.onPointerUp);
}
+ @action
onPointerUp = (e: PointerEvent): void => {
e.stopPropagation();
e.preventDefault();
@@ -33,14 +37,12 @@ export class FreeFormCanvas extends React.Component<IProps> {
document.removeEventListener("pointerup", this.onPointerUp);
let doc = this.props.store.Docs[0];
- let xField = doc.GetFieldT(KeyStore.X, NumberController);
- let x = xField ? xField.Data : 0;
- let yField = doc.GetFieldT(KeyStore.Y, NumberController);
- let y = yField ? yField.Data : 0;
- this.props.store.Docs[0].SetFieldValue(KeyStore.X, x + 10, NumberController);
- this.props.store.Docs[0].SetFieldValue(KeyStore.Y, y + 10, NumberController);
+ let dataField = doc.GetFieldT(KeyStore.Data, TextField);
+ let data = dataField ? dataField.Data : "";
+ this.props.store.Docs[0].SetFieldValue(KeyStore.Data, data + " hello", TextField);
}
+ @action
onPointerMove = (e: PointerEvent): void => {
e.stopPropagation();
e.preventDefault();
@@ -51,6 +53,7 @@ export class FreeFormCanvas extends React.Component<IProps> {
this.props.store.Y += e.movementY;
}
+ @action
onPointerWheel = (e: React.WheelEvent): void => {
e.stopPropagation();
e.preventDefault();
diff --git a/src/views/freeformcanvas/NodeContainer.tsx b/src/views/freeformcanvas/NodeContainer.tsx
index c59ab194e..6c3cb2af2 100644
--- a/src/views/freeformcanvas/NodeContainer.tsx
+++ b/src/views/freeformcanvas/NodeContainer.tsx
@@ -7,6 +7,7 @@ import { VideoNodeView } from "../nodes/VideoNodeView";
import "./FreeFormCanvas.scss";
import React = require("react");
import { DocumentView } from "../nodes/DocumentView";
+import { DocumentViewModel } from "../../viewmodels/DocumentViewModel";
interface IProps {
store: NodeCollectionStore
@@ -19,7 +20,7 @@ export class NodeContainer extends React.Component<IProps> {
return (
<div className="node-container">
{this.props.store.Docs.map(doc => {
- return (<DocumentView key={doc.Id} doc={doc} />);
+ return (<DocumentView key={doc.Id} dvm={new DocumentViewModel(doc)} />);
})}
</div>
);
diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx
index d3f025388..059d6c69e 100644
--- a/src/views/nodes/DocumentView.tsx
+++ b/src/views/nodes/DocumentView.tsx
@@ -1,27 +1,27 @@
import { observer } from "mobx-react";
-import { DocumentController } from "../../controllers/DocumentController";
import React = require("react");
import { computed } from "mobx";
-import { KeyStore } from "../../controllers/KeyController";
-import { NumberController } from "../../controllers/NumberController";
-import { TextController } from "../../controllers/TextController";
+import { KeyStore, Key } from "../../fields/Key";
+import { NumberField } from "../../fields/NumberField";
+import { TextField } from "../../fields/TextField";
+import { DocumentViewModel } from "../../viewmodels/DocumentViewModel";
+import { ListField } from "../../fields/ListField";
+const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
interface IProps {
- doc:DocumentController;
+ dvm:DocumentViewModel;
}
@observer
export class DocumentView extends React.Component<IProps> {
@computed
get x(): number {
- let field = this.props.doc.GetFieldT(KeyStore.X, NumberController);
- return field ? field.Data : 0;
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.X, NumberField, Number(0));
}
@computed
get y(): number {
- let field = this.props.doc.GetFieldT(KeyStore.Y, NumberController);
- return field ? field.Data : 0;
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.Y, NumberField, Number(0));
}
@computed
@@ -31,31 +31,49 @@ export class DocumentView extends React.Component<IProps> {
@computed
get width(): number {
- let field = this.props.doc.GetFieldT(KeyStore.Width, NumberController);
- return field ? field.Data : 0;
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.Width, NumberField, Number(0));
}
@computed
get height(): number {
- let field = this.props.doc.GetFieldT(KeyStore.Height, NumberController);
- return field ? field.Data : 0;
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.Height, NumberField, Number(0));
}
//Temp
@computed
get data(): string {
- let field = this.props.doc.GetFieldT(KeyStore.Data, TextController);
- return field ? field.Data : "";
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.Data, TextField, String(""));
+ }
+
+ @computed
+ get layout(): string {
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.View, TextField, String("<p>Error loading layout data</p>"));
+ }
+
+ @computed
+ get layoutFields(): Key[] {
+ return this.props.dvm.Doc.GetFieldValue(KeyStore.ViewProps, ListField, new Array<Key>());
}
render() {
+ let doc = this.props.dvm.Doc;
+ let bindings:any = {};
+ for (const key of this.layoutFields) {
+ let field = doc.GetField(key);
+ if(field) {
+ bindings[key.Name] = field.GetValue();
+ }
+ }
return (
<div className="node" style={{
transform: this.transform,
width: this.width,
height: this.height
}}>
- <p>{this.data}</p>
+ <JsxParser
+ bindings={bindings}
+ jsx={this.layout}
+ />
</div>
);
}
diff --git a/test/test.ts b/test/test.ts
index ad6c96781..8c1740ba6 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -1,21 +1,21 @@
-import { NumberController } from "../src/controllers/NumberController";
+import { NumberField } from "../src/fields/NumberField";
import { expect } from 'chai';
import 'mocha'
-import { KeyController } from "../src/controllers/KeyController";
-import { DocumentController } from "../src/controllers/DocumentController";
+import { Key } from "../src/fields/Key";
+import { Document } from "../src/fields/Document";
import { autorun, reaction } from "mobx";
-import { DocumentReferenceController } from "../src/controllers/DocumentReferenceController";
-import { TextController } from "../src/controllers/TextController";
-import { FieldController } from "../src/controllers/FieldController";
+import { DocumentReference } from "../src/fields/DocumentReference";
+import { TextField } from "../src/fields/TextField";
+import { Field } from "../src/fields/Field";
describe('Number Controller', () => {
it('Should be constructable', () => {
- const numController = new NumberController(15);
+ const numController = new NumberField(15);
expect(numController.Data).to.equal(15);
});
it('Should update', () => {
- const numController = new NumberController(15);
+ const numController = new NumberField(15);
let ran = false;
reaction(() => numController.Data, (data) => {ran = true;})
expect(ran).to.equal(false);
@@ -26,25 +26,25 @@ describe('Number Controller', () => {
describe("Document", () =>{
it('should hold fields', () => {
- let key = new KeyController("Test");
- let key2 = new KeyController("Test2");
- let field = new NumberController(15);
- let doc = new DocumentController();
+ let key = new Key("Test");
+ let key2 = new Key("Test2");
+ let field = new NumberField(15);
+ let doc = new Document();
doc.SetField(key, field);
- let getField = doc.GetFieldT(key, NumberController);
- let getField2 = doc.GetFieldT(key2, NumberController);
+ let getField = doc.GetFieldT(key, NumberField);
+ let getField2 = doc.GetFieldT(key2, NumberField);
expect(getField).to.equal(field);
expect(getField2).to.equal(undefined);
});
it('should update', () => {
- let doc = new DocumentController();
- let key = new KeyController("Test");
+ let doc = new Document();
+ let key = new Key("Test");
let ran = false;
reaction(() => doc.GetField(key), (field) => {ran = true});
expect(ran).to.equal(false);
- doc.SetField(key, new NumberController(5));
+ doc.SetField(key, new NumberField(5));
expect(ran).to.equal(true);
});
@@ -52,19 +52,19 @@ describe("Document", () =>{
describe("Reference", () => {
it('should dereference', () => {
- let doc = new DocumentController();
- let doc2 = new DocumentController();
- const key = new KeyController("test");
- const key2 = new KeyController("test2");
+ let doc = new Document();
+ let doc2 = new Document();
+ const key = new Key("test");
+ const key2 = new Key("test2");
- const numCont = new NumberController(55);
+ const numCont = new NumberField(55);
doc.SetField(key, numCont);
- let ref = new DocumentReferenceController(doc, key);
- let ref2 = new DocumentReferenceController(doc, key2);
+ let ref = new DocumentReference(doc, key);
+ let ref2 = new DocumentReference(doc, key2);
doc2.SetField(key2, ref);
- let ref3 = new DocumentReferenceController(doc2, key2);
- let ref4 = new DocumentReferenceController(doc2, key);
+ let ref3 = new DocumentReference(doc2, key2);
+ let ref4 = new DocumentReference(doc2, key);
expect(ref.Dereference()).to.equal(numCont);
expect(ref.DereferenceToRoot()).to.equal(numCont);
@@ -77,13 +77,13 @@ describe("Reference", () => {
});
it('should work with prototypes', () => {
- let doc = new DocumentController;
+ let doc = new Document;
let doc2 = doc.MakeDelegate();
- let key = new KeyController("test");
+ let key = new Key("test");
expect(doc.GetField(key)).to.equal(undefined);
expect(doc2.GetField(key)).to.equal(undefined);
- let num = new NumberController(55);
- let num2 = new NumberController(56);
+ let num = new NumberField(55);
+ let num2 = new NumberField(56);
doc.SetField(key, num);
expect(doc.GetField(key)).to.equal(num);
@@ -95,23 +95,23 @@ describe("Reference", () => {
});
it('should update through layers', () => {
- let doc = new DocumentController();
- let doc2 = new DocumentController();
- let doc3 = new DocumentController();
- const key = new KeyController("test");
- const key2 = new KeyController("test2");
- const key3 = new KeyController("test3");
-
- const numCont = new NumberController(55);
+ let doc = new Document();
+ let doc2 = new Document();
+ let doc3 = new Document();
+ const key = new Key("test");
+ const key2 = new Key("test2");
+ const key3 = new Key("test3");
+
+ const numCont = new NumberField(55);
doc.SetField(key, numCont);
- const ref = new DocumentReferenceController(doc, key);
+ const ref = new DocumentReference(doc, key);
doc2.SetField(key2, ref);
- const ref3 = new DocumentReferenceController(doc2, key2);
+ const ref3 = new DocumentReference(doc2, key2);
doc3.SetField(key3, ref3);
let ran = false;
reaction(() => {
- let field = (<FieldController>(<FieldController>doc3.GetField(key3)).DereferenceToRoot()).GetValue();
+ let field = (<Field>(<Field>doc3.GetField(key3)).DereferenceToRoot()).GetValue();
return field;
}, (field) => {
ran = true;
@@ -122,32 +122,32 @@ describe("Reference", () => {
expect(ran).to.equal(true);
ran = false;
- doc.SetField(key, new NumberController(33));
+ doc.SetField(key, new NumberField(33));
expect(ran).to.equal(true);
ran = false;
- doc.SetField(key2, new NumberController(4));
+ doc.SetField(key2, new NumberField(4));
expect(ran).to.equal(false);
- doc2.SetField(key2, new TextController("hello"));
+ doc2.SetField(key2, new TextField("hello"));
expect(ran).to.equal(true);
ran = false;
- doc3.SetField(key3, new TextController("world"));
+ doc3.SetField(key3, new TextField("world"));
expect(ran).to.equal(true);
ran = false;
});
it('should update with prototypes', () => {
- let doc = new DocumentController();
+ let doc = new Document();
let doc2 = doc.MakeDelegate();
- const key = new KeyController("test");
+ const key = new Key("test");
- const numCont = new NumberController(55);
+ const numCont = new NumberField(55);
let ran = false;
reaction(() => {
- let field = doc2.GetFieldT(key, NumberController);
+ let field = doc2.GetFieldT(key, NumberField);
if(field) {
return field.Data;
}