From e678ac7f21e0c44eaa8ad88577093cdb313e21bb Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Fri, 19 Apr 2019 23:13:17 -0400
Subject: Deleted more old fields and split new stuff into multiple files
---
src/new_fields/List.ts | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 src/new_fields/List.ts
(limited to 'src/new_fields/List.ts')
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
new file mode 100644
index 000000000..a1a623f83
--- /dev/null
+++ b/src/new_fields/List.ts
@@ -0,0 +1,35 @@
+import { Deserializable, autoObject } from "../client/util/SerializationHelper";
+import { Field, ObjectField, Update, OnUpdate, Self } from "./Doc";
+import { setter, getter } from "./util";
+import { serializable, alias, list } from "serializr";
+import { observable } from "mobx";
+
+@Deserializable("list")
+class ListImpl extends ObjectField {
+ constructor() {
+ super();
+ const list = new Proxy(this, {
+ set: function (a, b, c, d) { return setter(a, b, c, d); },
+ get: getter,
+ deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
+ defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
+ });
+ return list;
+ }
+
+ [key: number]: T | null | undefined;
+
+ @serializable(alias("fields", list(autoObject())))
+ @observable
+ private __fields: (T | null | undefined)[] = [];
+
+ private [Update] = (diff: any) => {
+ console.log(diff);
+ const update = this[OnUpdate];
+ update && update(diff);
+ }
+
+ private [Self] = this;
+}
+export type List = ListImpl & T[];
+export const List: { new (): List } = ListImpl as any;
\ No newline at end of file
--
cgit v1.2.3-70-g09d2
From 8ddec1c70c01b3d7d919908299e1168b75698dc7 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Sat, 20 Apr 2019 19:06:28 -0400
Subject: More refactoring
---
.../views/collections/CollectionDockingView.tsx | 65 +++++++++++-----------
src/new_fields/Doc.ts | 13 +++--
src/new_fields/List.ts | 2 +-
src/new_fields/Proxy.ts | 20 +++----
src/new_fields/Types.ts | 2 -
src/new_fields/URLField.ts | 12 ++--
src/new_fields/util.ts | 4 +-
7 files changed, 59 insertions(+), 59 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index e4c647635..b6c87231f 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -4,11 +4,8 @@ import 'golden-layout/src/css/goldenlayout-dark-theme.css';
import { action, observable, reaction, trace } from "mobx";
import { observer } from "mobx-react";
import * as ReactDOM from 'react-dom';
-import { Document } from "../../../fields/Document";
-import { KeyStore } from "../../../fields/KeyStore";
import Measure from "react-measure";
-import { FieldId, Opt, Field, FieldWaiting } from "../../../fields/Field";
-import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne } from "../../../Utils";
+import { Utils, returnTrue, emptyFunction, returnOne } from "../../../Utils";
import { Server } from "../../Server";
import { undoBatch } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
@@ -17,20 +14,22 @@ import React = require("react");
import { SubCollectionViewProps } from "./CollectionSubView";
import { ServerUtils } from "../../../server/ServerUtil";
import { DragManager, DragLinksAsDocuments } from "../../util/DragManager";
-import { TextField } from "../../../fields/TextField";
-import { ListField } from "../../../fields/ListField";
-import { Transform } from '../../util/Transform'
+import { Transform } from '../../util/Transform';
+import { Doc, Id, Opt, Field, FieldId } from "../../../new_fields/Doc";
+import { Cast, FieldValue } from "../../../new_fields/Types";
+import { List } from "../../../new_fields/List";
+import { DocServer } from "../../DocServer";
@observer
export class CollectionDockingView extends React.Component {
public static Instance: CollectionDockingView;
- public static makeDocumentConfig(document: Document) {
+ public static makeDocumentConfig(document: Doc) {
return {
type: 'react-component',
component: 'DocumentFrameRenderer',
- title: document.Title,
+ title: document.title,
props: {
- documentId: document.Id,
+ documentId: document[Id],
//collectionDockingView: CollectionDockingView.Instance
}
};
@@ -48,14 +47,14 @@ export class CollectionDockingView extends React.Component
this.AddRightSplit(dragDoc, true).contentItems[0].tab._dragListener.
onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 }));
}
@action
- public OpenFullScreen(document: Document) {
+ public OpenFullScreen(document: Doc) {
let newItemStackConfig = {
type: 'stack',
content: [CollectionDockingView.makeDocumentConfig(document)]
@@ -83,7 +82,7 @@ export class CollectionDockingView extends React.Component void = () => {
if (this._containerRef.current) {
reaction(
- () => this.props.Document.GetText(KeyStore.Data, ""),
+ () => Cast(this.props.Document.data, "string", ""),
() => {
if (!this._goldenLayout || this._ignoreStateChange !== JSON.stringify(this._goldenLayout.toConfig())) {
setTimeout(() => this.setupGoldenLayout(), 1);
@@ -203,7 +202,7 @@ export class CollectionDockingView extends React.Component) =>
- (sourceDoc instanceof Document) && DragLinksAsDocuments(tab, x, y, sourceDoc)));
+ (sourceDoc instanceof Doc) && DragLinksAsDocuments(tab, x, y, sourceDoc)));
} else
if ((className === "lm_title" || className === "lm_tab lm_active") && !e.shiftKey) {
e.stopPropagation();
@@ -213,11 +212,11 @@ export class CollectionDockingView extends React.Component) => {
- if (f instanceof Document) {
+ if (f instanceof Doc) {
DragManager.StartDocumentDrag([tab], new DragManager.DocumentDragData([f]), x, y,
{
handlers: {
- dragComplete: action(emptyFunction),
+ dragComplete: emptyFunction,
},
hideSource: false
});
@@ -235,7 +234,7 @@ export class CollectionDockingView extends React.Component {
var json = JSON.stringify(this._goldenLayout.toConfig());
- this.props.Document.SetText(KeyStore.Data, json);
+ this.props.Document.data = json;
}
itemDropped = () => {
@@ -264,10 +263,9 @@ export class CollectionDockingView extends React.Component${count}`);
tab.element.append(counter);
counter.DashDocId = tab.contentItem.config.props.documentId;
- tab.reactionDisposer = reaction(() => [f.GetT(KeyStore.LinkedFromDocs, ListField), f.GetT(KeyStore.LinkedToDocs, ListField)],
- (lists) => {
- let count = (lists.length > 0 && lists[0] && lists[0]!.Data ? lists[0]!.Data.length : 0) +
- (lists.length > 1 && lists[1] && lists[1]!.Data ? lists[1]!.Data.length : 0);
+ tab.reactionDisposer = reaction((): [List | null | undefined, List | null | undefined] => [Cast(f.linkedFromDocs, List), Cast(f.linkedToDocs, List)],
+ ([linkedFrom, linkedTo]) => {
+ let count = (linkedFrom ? linkedFrom.length : 0) + (linkedTo ? linkedTo.length : 0);
counter.innerHTML = count;
});
}));
@@ -319,19 +317,22 @@ export class DockedFrameRenderer extends React.Component {
_mainCont = React.createRef();
@observable private _panelWidth = 0;
@observable private _panelHeight = 0;
- @observable private _document: Opt;
+ @observable private _document: Opt;
constructor(props: any) {
super(props);
- Server.GetField(this.props.documentId, action((f: Opt) => this._document = f as Document));
+ DocServer.GetRefField(this.props.documentId).then(action((f: Opt) => this._document = f as Doc));
}
- nativeWidth = () => this._document!.GetNumber(KeyStore.NativeWidth, this._panelWidth);
- nativeHeight = () => this._document!.GetNumber(KeyStore.NativeHeight, this._panelHeight);
+ nativeWidth = () => Cast(this._document!.nativeWidth, "number", this._panelWidth);
+ nativeHeight = () => Cast(this._document!.nativeHeight, "number", this._panelHeight);
contentScaling = () => {
- let wscale = this._panelWidth / (this.nativeWidth() ? this.nativeWidth() : this._panelWidth);
- if (wscale * this.nativeHeight() > this._panelHeight)
- return this._panelHeight / (this.nativeHeight() ? this.nativeHeight() : this._panelHeight);
+ const nativeH = this.nativeHeight();
+ const nativeW = this.nativeWidth();
+ let wscale = this._panelWidth / nativeW;
+ if (wscale * nativeH > this._panelHeight) {
+ return this._panelHeight / nativeH;
+ }
return wscale;
}
@@ -349,7 +350,7 @@ export class DockedFrameRenderer extends React.Component {
return (
- {
selectOnLoad={false}
parentActive={returnTrue}
whenActiveChanged={emptyFunction}
- focus={emptyDocFunction}
+ focus={emptyFunction}
ContainingCollectionView={undefined} />
);
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index e0eb44ee9..8cbd8cf38 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -6,14 +6,15 @@ import { DocServer } from "../client/DocServer";
import { setter, getter, getField } from "./util";
import { Cast, FieldCtor } from "./Types";
+export type FieldId = string;
export const HandleUpdate = Symbol("HandleUpdate");
export const Id = Symbol("Id");
export abstract class RefField {
@serializable(alias("id", primitive()))
- private __id: string;
- readonly [Id]: string;
+ private __id: FieldId;
+ readonly [Id]: FieldId;
- constructor(id?: string) {
+ constructor(id?: FieldId) {
this.__id = id || Utils.GenerateGuid();
this[Id] = this.__id;
}
@@ -39,7 +40,7 @@ export const Self = Symbol("Self");
@Deserializable("doc").withFields(["id"])
export class Doc extends RefField {
- constructor(id?: string, forceSave?: boolean) {
+ constructor(id?: FieldId, forceSave?: boolean) {
super(id);
const doc = new Proxy(this, {
set: setter,
@@ -53,7 +54,7 @@ export class Doc extends RefField {
return doc;
}
- [key: string]: Field | null | undefined;
+ [key: string]: Field | FieldWaiting | undefined;
@serializable(alias("fields", map(autoObject())))
@observable
@@ -72,7 +73,6 @@ export namespace Doc {
return new Promise(res => getField(self, key, ignoreProto, res));
}
export function GetTAsync(doc: Doc, key: string, ctor: FieldCtor, ignoreProto: boolean = false): Promise {
- const self = doc[Self];
return new Promise(async res => {
const field = await GetAsync(doc, key, ignoreProto);
return Cast(field, ctor);
@@ -90,6 +90,7 @@ export namespace Doc {
return undefined;
}
const delegate = new Doc();
+ //TODO Does this need to be doc[Self]?
delegate.prototype = doc;
return delegate;
}
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index a1a623f83..58b252f7b 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -9,7 +9,7 @@ class ListImpl extends ObjectField {
constructor() {
super();
const list = new Proxy(this, {
- set: function (a, b, c, d) { return setter(a, b, c, d); },
+ set: setter,
get: getter,
deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
index 3b4b2e452..6a78388c1 100644
--- a/src/new_fields/Proxy.ts
+++ b/src/new_fields/Proxy.ts
@@ -1,7 +1,8 @@
import { Deserializable } from "../client/util/SerializationHelper";
-import { RefField, Id, ObjectField } from "./Doc";
+import { RefField, Id, ObjectField, FieldWaiting } from "./Doc";
import { primitive, serializable } from "serializr";
-import { observable } from "mobx";
+import { observable, action } from "mobx";
+import { DocServer } from "../client/DocServer";
@Deserializable("proxy")
export class ProxyField extends ObjectField {
@@ -32,7 +33,7 @@ export class ProxyField extends ObjectField {
private failed = false;
private promise?: Promise;
- value(callback?: ((field: T | undefined) => void)): T | undefined | null {
+ value(callback?: ((field: T | undefined) => void)): T | undefined | FieldWaiting {
if (this.cache) {
callback && callback(this.cache);
return this.cache;
@@ -41,13 +42,12 @@ export class ProxyField extends ObjectField {
return undefined;
}
if (!this.promise) {
- // this.promise = Server.GetField(this.fieldId).then(action((field: any) => {
- // this.promise = undefined;
- // this.cache = field;
- // if (field === undefined) this.failed = true;
- // return field;
- // }));
- this.promise = new Promise(r => r());
+ this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => {
+ this.promise = undefined;
+ this.cache = field;
+ if (field === undefined) this.failed = true;
+ return field;
+ }));
}
callback && this.promise.then(callback);
return null;
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 6ffb3e02f..0fbd8984c 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -50,8 +50,6 @@ export function Cast>(field: Field | null | undefined
} else if (field instanceof (ctor as any)) {
return field as ToType;
}
- } else {
- return defaultVal;
}
return defaultVal;
}
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index d27a2b692..e456a7d16 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -1,16 +1,16 @@
import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable } from "serializr";
+import { serializable, custom } from "serializr";
import { ObjectField } from "./Doc";
function url() {
- return {
- serializer: function (value: URL) {
+ return custom(
+ function (value: URL) {
return value.href;
},
- deserializer: function (jsonValue: string, done: (err: any, val: any) => void) {
- done(undefined, new URL(jsonValue));
+ function (jsonValue: string) {
+ return new URL(jsonValue);
}
- };
+ );
}
@Deserializable("url")
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 0f08ecf03..3806044bd 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -22,6 +22,7 @@ export function setter(target: any, prop: string | symbol | number, value: any,
value = new ProxyField(value);
}
if (value instanceof ObjectField) {
+ //TODO Instead of target, maybe use target[Self]
if (value[Parent] && value[Parent] !== target) {
throw new Error("Can't put the same object in multiple documents at the same time");
}
@@ -51,7 +52,7 @@ export function getter(target: any, prop: string | symbol | number, receiver: an
if (SerializationHelper.IsSerializing()) {
return target[prop];
}
- return getField(target, prop, receiver);
+ return getField(target, prop);
}
export function getField(target: any, prop: string | number, ignoreProto: boolean = false, callback?: (field: Field | undefined) => void): any {
@@ -69,5 +70,4 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
}
callback && callback(field);
return field;
-
}
--
cgit v1.2.3-70-g09d2
From 5a9e437bbd175b36a161e1d96c8ae873dfe6d105 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Mon, 22 Apr 2019 03:39:39 -0400
Subject: More
---
src/client/views/collections/CollectionSubView.tsx | 6 +++
.../collectionFreeForm/CollectionFreeFormView.tsx | 43 +++++++++++-----------
src/client/views/nodes/ImageBox.tsx | 2 +-
src/debug/Test.tsx | 13 +------
src/new_fields/Doc.ts | 13 +++++--
src/new_fields/List.ts | 5 ++-
src/new_fields/Schema.ts | 20 ++++++++--
src/new_fields/Types.ts | 27 ++++++++------
8 files changed, 74 insertions(+), 55 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 3add288fd..1a839fdcb 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -20,6 +20,8 @@ import { CollectionPDFView } from "./CollectionPDFView";
import { CollectionVideoView } from "./CollectionVideoView";
import { Doc } from "../../../new_fields/Doc";
import { DocComponent } from "../DocComponent";
+import { listSpec } from "../../../new_fields/Schema";
+import { Cast } from "../../../new_fields/Types";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -50,6 +52,10 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) {
this.createDropTarget(ele);
}
+ get children() {
+ return Cast(this.props.Document[this.props.fieldKey], listSpec(Doc));
+ }
+
@action
protected setCursorPosition(position: [number, number]) {
let ind;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 32104b49d..ee7d65d23 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -20,17 +20,19 @@ import { MarqueeView } from "./MarqueeView";
import React = require("react");
import v5 = require("uuid/v5");
import { createSchema, makeInterface } from "../../../../new_fields/Schema";
-import { Doc } from "../../../../new_fields/Doc";
-import { FieldValue } from "../../../../new_fields/Types";
+import { Doc, Id } from "../../../../new_fields/Doc";
+import { FieldValue, Cast } from "../../../../new_fields/Types";
+import { pageSchema } from "../../nodes/ImageBox";
+import { List } from "../../../../new_fields/List";
export const panZoomSchema = createSchema({
panX: "number",
panY: "number",
- zoom: "number"
+ scale: "number"
});
-type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof positionSchema]>;
-const PanZoomDocument: (doc: Doc) => PanZoomDocument = makeInterface(panZoomSchema, positionSchema);
+type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof positionSchema, typeof pageSchema]>;
+const PanZoomDocument = makeInterface(panZoomSchema, positionSchema, pageSchema);
@observer
export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@@ -41,24 +43,24 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
private get _pheight() { return this.props.PanelHeight(); }
@computed get nativeWidth() { return FieldValue(this.Document.nativeWidth, 0); }
- @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
+ @computed get nativeHeight() { return FieldValue(this.Document.nativeHeight, 0); }
private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
- private get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's?
+ private get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; }
private childViews = () => this.views;
- private panX = () => this.props.Document.GetNumber(KeyStore.PanX, 0);
- private panY = () => this.props.Document.GetNumber(KeyStore.PanY, 0);
- private zoomScaling = () => this.props.Document.GetNumber(KeyStore.Scale, 1);
+ private panX = () => FieldValue(this.Document.panX, 0);
+ private panY = () => FieldValue(this.Document.panY, 0);
+ private zoomScaling = () => FieldValue(this.Document.scale, 1);
private centeringShiftX = () => !this.nativeWidth ? this._pwidth / 2 : 0; // shift so pan position is at center of window for non-overlay collections
private centeringShiftY = () => !this.nativeHeight ? this._pheight / 2 : 0;// shift so pan position is at center of window for non-overlay collections
private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
private getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
- private addLiveTextBox = (newBox: Document) => {
- this._selectOnLoaded = newBox.Id;// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+ private addLiveTextBox = (newBox: Doc) => {
+ this._selectOnLoaded = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newBox, false);
}
- private addDocument = (newBox: Document, allowDuplicates: boolean) => {
- newBox.SetNumber(KeyStore.Zoom, this.props.Document.GetNumber(KeyStore.Scale, 1));
+ private addDocument = (newBox: Doc, allowDuplicates: boolean) => {
+ newBox.zoom = FieldValue(this.Document.scale, 1);
return this.props.addDocument(this.bringToFront(newBox), false);
}
private selectDocuments = (docs: Document[]) => {
@@ -67,14 +69,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
SelectionManager.SelectDoc(dv!, true));
}
public getActiveDocuments = () => {
- var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
- return this.props.Document.GetList(this.props.fieldKey, [] as Document[]).reduce((active, doc) => {
- var page = doc.GetNumber(KeyStore.Page, -1);
- if (page === curPage || page === -1) {
- active.push(doc);
- }
- return active;
- }, [] as Document[]);
+ const curPage = FieldValue(this.Document.curPage, -1);
+ return FieldValue(this.children, [] as Doc[]).filter(doc => {
+ var page = Cast(doc.page, "number", -1);
+ return page === curPage || page === -1;
+ });
}
@undoBatch
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c11aee56e..cd003ba71 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -71,7 +71,7 @@ export class ImageBox extends DocComponent(ImageD
@undoBatch
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.data instanceof DragManager.DocumentDragData) {
- de.data.droppedDocuments.map(action((drop: Document) => {
+ de.data.droppedDocuments.forEach(action((drop: Document) => {
let layout = drop.GetText(KeyStore.BackgroundLayout, "");
if (layout.indexOf(ImageBox.name) !== -1) {
let imgData = this.props.Document.Get(KeyStore.Data);
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index 22a39f31e..179f987e0 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -1,12 +1,10 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { SerializationHelper } from '../client/util/SerializationHelper';
-import { createSchema, makeInterface, makeStrictInterface } from '../new_fields/Schema';
+import { createSchema, makeInterface, makeStrictInterface, listSpec } from '../new_fields/Schema';
import { ImageField } from '../new_fields/URLField';
import { Doc } from '../new_fields/Doc';
-import { ListSpec } from '../new_fields/Types';
import { List } from '../new_fields/List';
-const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
const schema1 = createSchema({
hello: "number",
@@ -22,7 +20,7 @@ type TestDoc = makeInterface<[typeof schema1]>;
const schema2 = createSchema({
hello: ImageField,
test: "boolean",
- fields: { List: "number" } as ListSpec,
+ fields: listSpec("number"),
url: "number",
testDoc: ImageField
});
@@ -30,13 +28,6 @@ const schema2 = createSchema({
const Test2Doc = makeStrictInterface(schema2);
type Test2Doc = makeStrictInterface;
-const schema3 = createSchema({
- test: "boolean",
-});
-
-const Test3Doc = makeStrictInterface(schema3);
-type Test3Doc = makeStrictInterface;
-
const assert = (bool: boolean) => {
if (!bool) throw new Error();
};
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 5d18cbb2e..60abccce6 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -4,7 +4,7 @@ import { autoObject, SerializationHelper, Deserializable } from "../client/util/
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
import { setter, getter, getField } from "./util";
-import { Cast, FieldCtor } from "./Types";
+import { Cast, ToConstructor } from "./Types";
export type FieldId = string;
export const HandleUpdate = Symbol("HandleUpdate");
@@ -28,6 +28,7 @@ export const Parent = Symbol("Parent");
export class ObjectField {
protected [OnUpdate]?: (diff?: any) => void;
private [Parent]?: Doc;
+ readonly [Id] = "";
}
export type Field = number | string | boolean | ObjectField | RefField;
@@ -71,7 +72,7 @@ export namespace Doc {
const self = doc[Self];
return new Promise(res => getField(self, key, ignoreProto, res));
}
- export function GetTAsync(doc: Doc, key: string, ctor: FieldCtor, ignoreProto: boolean = false): Promise {
+ export function GetTAsync(doc: Doc, key: string, ctor: ToConstructor, ignoreProto: boolean = false): Promise {
return new Promise(async res => {
const field = await GetAsync(doc, key, ignoreProto);
return Cast(field, ctor);
@@ -81,9 +82,15 @@ export namespace Doc {
const self = doc[Self];
return getField(self, key, ignoreProto);
}
- export function GetT(doc: Doc, key: string, ctor: FieldCtor, ignoreProto: boolean = false): T | null | undefined {
+ export function GetT(doc: Doc, key: string, ctor: ToConstructor, ignoreProto: boolean = false): T | null | undefined {
return Cast(Get(doc, key, ignoreProto), ctor) as T | null | undefined;
}
+ export async function SetOnPrototype(doc: Doc, key: string, value: Field) {
+ const proto = await Cast(doc.prototype, Doc);
+ if (proto) {
+ proto[key] = value;
+ }
+ }
export function MakeDelegate(doc: Opt): Opt {
if (!doc) {
return undefined;
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 58b252f7b..f3ec9e2c5 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -6,8 +6,9 @@ import { observable } from "mobx";
@Deserializable("list")
class ListImpl extends ObjectField {
- constructor() {
+ constructor(fields: T[] = []) {
super();
+ this.__fields = fields;
const list = new Proxy(this, {
set: setter,
get: getter,
@@ -21,7 +22,7 @@ class ListImpl extends ObjectField {
@serializable(alias("fields", list(autoObject())))
@observable
- private __fields: (T | null | undefined)[] = [];
+ private __fields: (T | null | undefined)[];
private [Update] = (diff: any) => {
console.log(diff);
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
index 3b7078cb0..59c6db0bd 100644
--- a/src/new_fields/Schema.ts
+++ b/src/new_fields/Schema.ts
@@ -1,5 +1,7 @@
-import { Interface, ToInterface, Cast, FieldCtor, ToConstructor, HasTail, Head, Tail } from "./Types";
+import { Interface, ToInterface, Cast, ToConstructor, HasTail, Head, Tail, ListSpec, ToType } from "./Types";
import { Doc, Field, ObjectField } from "./Doc";
+import { URLField } from "./URLField";
+import { List } from "./List";
type AllToInterface = {
1: ToInterface> & AllToInterface>,
@@ -10,10 +12,10 @@ export const emptySchema = createSchema({});
export const Document = makeInterface(emptySchema);
export type Document = makeInterface<[typeof emptySchema]>;
-export type makeInterface = Partial> & U;
+export type makeInterface = Partial> & Doc;
// export function makeInterface(schemas: T): (doc: U) => All;
// export function makeInterface(schema: T): (doc: U) => makeInterface;
-export function makeInterface(...schemas: T): (doc: U) => makeInterface {
+export function makeInterface(...schemas: T): (doc: Doc) => makeInterface {
let schema: Interface = {};
for (const s of schemas) {
for (const key in s) {
@@ -33,7 +35,10 @@ export function makeInterface(...schemas:
return true;
}
});
- return function (doc: any) {
+ return function (doc: Doc) {
+ if (!(doc instanceof Doc)) {
+ throw new Error("Currently wrapping a schema in another schema isn't supported");
+ }
const obj = Object.create(proto, { doc: { value: doc, writable: false } });
return obj;
};
@@ -59,6 +64,9 @@ export function makeStrictInterface(schema: T): (doc: Doc)
});
}
return function (doc: any) {
+ if (!(doc instanceof Doc)) {
+ throw new Error("Currently wrapping a schema in another schema isn't supported");
+ }
const obj = Object.create(proto);
obj.__doc = doc;
return obj;
@@ -69,3 +77,7 @@ export function createSchema(schema: T): T & { prototype: T
schema.prototype = Doc;
return schema as any;
}
+
+export function listSpec>(type: U): ListSpec> {
+ return { List: type as any };//TODO Types
+}
\ No newline at end of file
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index f4f66fe5c..fbf002c84 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -1,25 +1,28 @@
import { Field, Opt, FieldWaiting, FieldResult } from "./Doc";
import { List } from "./List";
-export type ToType =
+export type ToType | ListSpec> =
T extends "string" ? string :
T extends "number" ? number :
T extends "boolean" ? boolean :
T extends ListSpec ? List :
// T extends { new(...args: any[]): infer R } ? (R | Promise) : never;
+ T extends { new(...args: any[]): List } ? never :
T extends { new(...args: any[]): infer R } ? R : never;
-export type ToConstructor =
+export type ToConstructor =
T extends string ? "string" :
T extends number ? "number" :
- T extends boolean ? "boolean" : new (...args: any[]) => T;
+ T extends boolean ? "boolean" :
+ T extends List ? ListSpec :
+ new (...args: any[]) => T;
-export type ToInterface = {
+export type ToInterface = {
[P in keyof T]: ToType;
};
-// type ListSpec = { List: FieldCtor> | ListSpec> };
-export type ListSpec = { List: FieldCtor };
+// type ListSpec = { List: ToContructor> | ListSpec> };
+export type ListSpec = { List: ToConstructor };
// type ListType = { 0: List>>, 1: ToType> }[HasTail extends true ? 0 : 1];
@@ -34,11 +37,9 @@ export interface Interface {
// [key: string]: ToConstructor | ListSpec;
}
-export type FieldCtor = T extends List ? ListSpec : ToConstructor;
-
-export function Cast>(field: Field | FieldWaiting | undefined, ctor: T): FieldResult>;
-export function Cast>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal: ToType): ToType;
-export function Cast>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType): FieldResult> | undefined {
+export function Cast | ListSpec>(field: Field | FieldWaiting | undefined, ctor: T): FieldResult>;
+export function Cast | ListSpec>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal: ToType): ToType;
+export function Cast | ListSpec>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType): FieldResult> | undefined {
if (field instanceof Promise) {
return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) : defaultVal;
}
@@ -58,7 +59,9 @@ export function Cast>(field: Field | FieldWaiting | u
return defaultVal;
}
-export function FieldValue(field: Opt | Promise>, defaultValue: U): T;
+type WithoutList = T extends List ? R[] : T;
+
+export function FieldValue>(field: Opt | Promise>, defaultValue: U): WithoutList;
export function FieldValue(field: Opt | Promise>): Opt;
export function FieldValue(field: Opt | Promise>, defaultValue?: T): Opt {
return field instanceof Promise ? defaultValue : field;
--
cgit v1.2.3-70-g09d2
From 5ffb2f404a6a3da851c0fe7318b73f5c7723c3d7 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Tue, 23 Apr 2019 01:05:12 -0400
Subject: Did most of Documents and some other stuff
---
src/Utils.ts | 19 +-
src/client/documents/Documents.ts | 202 +++++++++------------
src/client/northstar/dash-fields/HistogramField.ts | 2 +-
.../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +-
src/client/views/nodes/DocumentContentsView.tsx | 2 +-
src/new_fields/Doc.ts | 31 +++-
src/new_fields/List.ts | 2 +-
src/new_fields/Types.ts | 2 +-
src/new_fields/util.ts | 12 +-
9 files changed, 139 insertions(+), 135 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/Utils.ts b/src/Utils.ts
index 066d653f5..59ff45dc9 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -86,13 +86,20 @@ export class Utils {
}
}
-export function OmitKeys(obj: any, keys: any, addKeyFunc?: (dup: any) => void) {
+export function OmitKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void): { omit: any, extract: any } {
+ const omit: any = { ...obj };
+ const extract: any = {};
+ keys.forEach(key => {
+ extract[key] = omit[key];
+ delete omit[key];
+ });
+ addKeyFunc && addKeyFunc(omit);
+ return { omit, extract };
+}
+
+export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
var dup: any = {};
- for (var key in obj) {
- if (keys.indexOf(key) === -1) {
- dup[key] = obj[key];
- }
- }
+ keys.forEach(key => dup[key] = obj[key]);
addKeyFunc && addKeyFunc(dup);
return dup;
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b0bb74d89..a145a76c9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,20 +1,6 @@
-import { AudioField } from "../../fields/AudioField";
-import { Document } from "../../fields/Document";
-import { Field, Opt } from "../../fields/Field";
-import { HtmlField } from "../../fields/HtmlField";
-import { ImageField } from "../../fields/ImageField";
-import { InkField, StrokeData } from "../../fields/InkField";
-import { Key } from "../../fields/Key";
-import { KeyStore } from "../../fields/KeyStore";
-import { ListField } from "../../fields/ListField";
-import { PDFField } from "../../fields/PDFField";
-import { TextField } from "../../fields/TextField";
-import { VideoField } from "../../fields/VideoField";
-import { WebField } from "../../fields/WebField";
import { HistogramField } from "../northstar/dash-fields/HistogramField";
import { HistogramBox } from "../northstar/dash-nodes/HistogramBox";
import { HistogramOperation } from "../northstar/operations/HistogramOperation";
-import { Server } from "../Server";
import { CollectionPDFView } from "../views/collections/CollectionPDFView";
import { CollectionVideoView } from "../views/collections/CollectionVideoView";
import { CollectionView } from "../views/collections/CollectionView";
@@ -34,39 +20,47 @@ import { AttributeTransformationModel } from "../northstar/core/attribute/Attrib
import { AggregateFunction } from "../northstar/model/idea/idea";
import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss";
import { IconBox } from "../views/nodes/IconBox";
-import { IconField } from "../../fields/IconFIeld";
+import { Field, Doc, Opt } from "../../new_fields/Doc";
+import { OmitKeys } from "../../Utils";
+import { ImageField, VideoField, AudioField, PdfField, WebField } from "../../new_fields/URLField";
+import { HtmlField } from "../../new_fields/HtmlField";
+import { List } from "../../new_fields/List";
+import { Cast } from "../../new_fields/Types";
export interface DocumentOptions {
x?: number;
y?: number;
- ink?: Map;
+ // ink?: Map;
width?: number;
height?: number;
nativeWidth?: number;
nativeHeight?: number;
title?: string;
- panx?: number;
- pany?: number;
+ panX?: number;
+ panY?: number;
page?: number;
scale?: number;
layout?: string;
- layoutKeys?: Key[];
viewType?: number;
backgroundColor?: string;
copyDraggedItems?: boolean;
+ backgroundLayout?: string;
+ curPage?: number;
+ // [key: string]: Opt;
}
+const delegateKeys = ["x", "y", "width", "height", "panX", "panY"];
-export namespace Documents {
- let textProto: Document;
- let histoProto: Document;
- let imageProto: Document;
- let webProto: Document;
- let collProto: Document;
- let kvpProto: Document;
- let videoProto: Document;
- let audioProto: Document;
- let pdfProto: Document;
- let iconProto: Document;
+export namespace Docs {
+ let textProto: Doc;
+ let histoProto: Doc;
+ let imageProto: Doc;
+ let webProto: Doc;
+ let collProto: Doc;
+ let kvpProto: Doc;
+ let videoProto: Doc;
+ let audioProto: Doc;
+ let pdfProto: Doc;
+ let iconProto: Doc;
const textProtoId = "textProto";
const histoProtoId = "histoProto";
const pdfProtoId = "pdfProto";
@@ -92,110 +86,80 @@ export namespace Documents {
iconProto = fields[iconProtoId] as Document || CreateIconPrototype();
});
}
- function assignOptions(doc: Document, options: DocumentOptions): Document {
- if (options.nativeWidth !== undefined) { doc.SetNumber(KeyStore.NativeWidth, options.nativeWidth); }
- if (options.nativeHeight !== undefined) { doc.SetNumber(KeyStore.NativeHeight, options.nativeHeight); }
- if (options.title !== undefined) { doc.SetText(KeyStore.Title, options.title); }
- if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); }
- if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); }
- if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); }
- if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); }
- if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); }
- if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
- if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
- if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
- if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
- if (options.copyDraggedItems !== undefined) { doc.SetBoolean(KeyStore.CopyDraggedItems, options.copyDraggedItems); }
- return doc;
- }
- function assignToDelegate(doc: Document, options: DocumentOptions): Document {
- if (options.x !== undefined) { doc.SetNumber(KeyStore.X, options.x); }
- if (options.y !== undefined) { doc.SetNumber(KeyStore.Y, options.y); }
- if (options.width !== undefined) { doc.SetNumber(KeyStore.Width, options.width); }
- if (options.height !== undefined) { doc.SetNumber(KeyStore.Height, options.height); }
- if (options.panx !== undefined) { doc.SetNumber(KeyStore.PanX, options.panx); }
- if (options.pany !== undefined) { doc.SetNumber(KeyStore.PanY, options.pany); }
- return doc;
+ function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Doc {
+ return Doc.assign(new Doc(protoId, true), { ...options, title: title, layout: layout });
}
-
- function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document {
- return assignOptions(new Document(protoId), { ...options, title: title, layout: layout });
+ function SetInstanceOptions(doc: Doc, options: DocumentOptions, value: U) {
+ const deleg = Doc.MakeDelegate(doc);
+ deleg.data = value;
+ return Doc.assign(deleg, options);
}
- function SetInstanceOptions(doc: Document, options: DocumentOptions, value: [T, { new(): U }] | Document, id?: string) {
- var deleg = doc.MakeDelegate(id);
- if (value instanceof Document) {
- deleg.Set(KeyStore.Data, value);
- }
- else {
- deleg.SetData(KeyStore.Data, value[0], value[1]);
- }
- return assignOptions(deleg, options);
+ function SetDelegateOptions(doc: Doc, options: DocumentOptions) {
+ const deleg = Doc.MakeDelegate(doc);
+ return Doc.assign(deleg, options);
}
- function CreateImagePrototype(): Document {
+ function CreateImagePrototype(): Doc {
let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
- imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString());
- imageProto.SetNumber(KeyStore.CurPage, 0);
+ { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0 });
return imageProto;
}
- function CreateHistogramPrototype(): Document {
+ function CreateHistogramPrototype(): Doc {
let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
- histoProto.SetText(KeyStore.BackgroundLayout, HistogramBox.LayoutString());
+ { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString() });
return histoProto;
}
- function CreateIconPrototype(): Document {
+ function CreateIconPrototype(): Doc {
let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(),
- { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE) });
return iconProto;
}
- function CreateTextPrototype(): Document {
+ function CreateTextPrototype(): Doc {
let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 150 });
return textProto;
}
- function CreatePdfPrototype(): Document {
+ function CreatePdfPrototype(): Doc {
let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 1200, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
- pdfProto.SetNumber(KeyStore.CurPage, 1);
- pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString());
+ { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1 });
return pdfProto;
}
- function CreateWebPrototype(): Document {
+ function CreateWebPrototype(): Doc {
let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 300 });
return webProto;
}
- function CreateCollectionPrototype(): Document {
+ function CreateCollectionPrototype(): Doc {
let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
- { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] });
+ { panX: 0, panY: 0, scale: 1, width: 500, height: 500 });
return collProto;
}
- function CreateKVPPrototype(): Document {
+ function CreateKVPPrototype(): Doc {
let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 150 });
return kvpProto;
}
- function CreateVideoPrototype(): Document {
+ function CreateVideoPrototype(): Doc {
let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
- videoProto.SetNumber(KeyStore.CurPage, 0);
- videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
+ { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0 });
return videoProto;
}
- function CreateAudioPrototype(): Document {
+ function CreateAudioPrototype(): Doc {
let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] });
+ { x: 0, y: 0, width: 300, height: 150 });
return audioProto;
}
+ function CreateInstance(proto: Doc, data: Field, options: DocumentOptions) {
+ const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys);
+ return SetDelegateOptions(SetInstanceOptions(proto, protoProps, data), delegateProps);
+ }
export function ImageDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(imageProto, options, [new URL(url), ImageField]).MakeDelegate(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
+ return CreateInstance(imageProto, new ImageField(new URL(url)), options);
// let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
// [new URL(url), ImageField]);
// doc.SetText(KeyStore.Caption, "my caption...");
@@ -204,23 +168,23 @@ export namespace Documents {
// return doc;
}
export function VideoDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(videoProto, options, [new URL(url), VideoField]), options);
+ return CreateInstance(videoProto, new VideoField(new URL(url)), options);
}
export function AudioDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(audioProto, options, [new URL(url), AudioField]), options);
+ return CreateInstance(audioProto, new AudioField(new URL(url)), options);
}
- export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}, id?: string, delegId?: string) {
- return assignToDelegate(SetInstanceOptions(histoProto, options, [histoOp, HistogramField], id).MakeDelegate(delegId), options);
+ export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}) {
+ return CreateInstance(histoProto, new HistogramField(histoOp), options);
}
export function TextDocument(options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(textProto, options, ["", TextField]).MakeDelegate(), options);
+ return CreateInstance(textProto, "", options);
}
export function IconDocument(icon: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(iconProto, { width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), layoutKeys: [KeyStore.Data], layout: IconBox.LayoutString(), ...options }, [icon, IconField]), options);
+ return CreateInstance(iconProto, new IconField(icon), options);
}
export function PdfDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(pdfProto, options, [new URL(url), PDFField]).MakeDelegate(), options);
+ return CreateInstance(pdfProto, new PdfField(new URL(url)), options);
}
export async function DBDocument(url: string, options: DocumentOptions = {}) {
let schemaName = options.title ? options.title : "-no schema-";
@@ -248,35 +212,35 @@ export namespace Documents {
return Documents.TreeDocument([], { width: 50, height: 100, title: schemaName });
}
export function WebDocument(url: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(webProto, options, [new URL(url), WebField]).MakeDelegate(), options);
+ return CreateInstance(webProto, new WebField(new URL(url)), options);
}
export function HtmlDocument(html: string, options: DocumentOptions = {}) {
- return assignToDelegate(SetInstanceOptions(webProto, options, [html, HtmlField]).MakeDelegate(), options);
+ return CreateInstance(webProto, new HtmlField(html), options);
}
- export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) {
- return assignToDelegate(SetInstanceOptions(kvpProto, options, document, id), options);
+ export function KVPDocument(document: Doc, options: DocumentOptions = {}) {
+ return CreateInstance(kvpProto, document, options);
}
- export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string, makePrototype: boolean = true) {
+ export function FreeformDocument(documents: Array, options: DocumentOptions, makePrototype: boolean = true) {
if (!makePrototype) {
- return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id);
+ return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, new List(documents));
}
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate(), options);
+ return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Freeform });
}
- export function SchemaDocument(documents: Array, options: DocumentOptions, id?: string) {
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options);
+ export function SchemaDocument(documents: Array, options: DocumentOptions) {
+ return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Schema });
}
- export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) {
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Tree }, [documents, ListField], id), options);
+ export function TreeDocument(documents: Array, options: DocumentOptions) {
+ return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Tree });
}
- export function DockDocument(config: string, options: DocumentOptions, id?: string) {
- return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options);
+ export function DockDocument(config: string, options: DocumentOptions) {
+ return CreateInstance(collProto, config, { ...options, viewType: CollectionViewType.Docking });
}
- export function CaptionDocument(doc: Document) {
- const captionDoc = doc.CreateAlias();
- captionDoc.SetText(KeyStore.OverlayLayout, FixedCaption());
- captionDoc.SetNumber(KeyStore.Width, doc.GetNumber(KeyStore.Width, 0));
- captionDoc.SetNumber(KeyStore.Height, doc.GetNumber(KeyStore.Height, 0));
+ export function CaptionDocument(doc: Doc) {
+ const captionDoc = Doc.MakeAlias(doc);
+ captionDoc.overlayLayout = FixedCaption();
+ captionDoc.width = Cast(doc.width, "number", 0);
+ captionDoc.height = Cast(doc.height, "number", 0);
return captionDoc;
}
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index c699691a4..932166b21 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -15,7 +15,7 @@ export class HistogramField extends BasicField {
}
toString(): string {
- return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']));
+ return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit);
}
Copy(): Field {
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index c6eea5623..7b7b7e65e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -71,7 +71,7 @@ export class CollectionFreeFormDocumentView extends DocComponentError loading layout data
"); }
CreateBindings(): JsxBindings {
- let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) };
+ let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit };
return bindings;
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 5ae095e68..987cb2cc4 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -4,7 +4,7 @@ import { autoObject, SerializationHelper, Deserializable } from "../client/util/
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
import { setter, getter, getField } from "./util";
-import { Cast, ToConstructor } from "./Types";
+import { Cast, ToConstructor, PromiseValue } from "./Types";
export type FieldId = string;
export const HandleUpdate = Symbol("HandleUpdate");
@@ -54,7 +54,8 @@ export class Doc extends RefField {
return doc;
}
- [key: string]: Field | FieldWaiting | undefined;
+ proto: FieldResult;
+ [key: string]: FieldResult;
@serializable(alias("fields", map(autoObject())))
@observable
@@ -92,6 +93,32 @@ export namespace Doc {
proto[key] = value;
}
}
+ export function assign(doc: Doc, fields: Partial>>) {
+ for (const key in fields) {
+ if (fields.hasOwnProperty(key)) {
+ const value = fields[key];
+ if (value !== undefined) {
+ doc[key] = value;
+ }
+ }
+ }
+ return doc;
+ }
+
+ export function MakeAlias(doc: Doc) {
+ const alias = new Doc;
+
+ PromiseValue(Cast(doc.proto, Doc)).then(proto => {
+ if (proto) {
+ alias.proto = proto;
+ }
+ });
+
+ return alias;
+ }
+
+ export function MakeDelegate(doc: Doc): Doc;
+ export function MakeDelegate(doc: Opt): Opt;
export function MakeDelegate(doc: Opt): Opt {
if (!doc) {
return undefined;
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index f3ec9e2c5..f01ac210a 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -33,4 +33,4 @@ class ListImpl extends ObjectField {
private [Self] = this;
}
export type List = ListImpl & T[];
-export const List: { new (): List } = ListImpl as any;
\ No newline at end of file
+export const List: { new (fields?: T[]): List } = ListImpl as any;
\ No newline at end of file
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 246b0624e..55083765a 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -68,7 +68,7 @@ export function FieldValue(field: Opt | Promise>, def
}
export interface PromiseLike {
- then(callback: (field: Opt | PromiseLike) => void): void;
+ then(callback: (field: Opt) => void): void;
}
export function PromiseValue(field: FieldResult): PromiseLike> {
return field instanceof Promise ? field : { then(cb: ((field: Opt) => void)) { return cb(field); } };
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 3806044bd..2d9721b2e 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -2,6 +2,7 @@ import { UndoManager } from "../client/util/UndoManager";
import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField } from "./Proxy";
+import { FieldValue } from "./Types";
export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
if (SerializationHelper.IsSerializing()) {
@@ -61,11 +62,16 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
return field.value(callback);
}
if (field === undefined && !ignoreProto) {
- const proto = getField(target, "prototype", true);
+ const proto = getField(target, "proto", true);
if (proto instanceof Doc) {
let field = proto[prop];
- callback && callback(field === null ? undefined : field);
- return field;
+ if (field instanceof Promise) {
+ callback && field.then(callback);
+ return undefined;
+ } else {
+ callback && callback(field);
+ return field;
+ }
}
}
callback && callback(field);
--
cgit v1.2.3-70-g09d2
From d4a77dd055685dd81a762ef40e0c3b7606586e9c Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Sat, 27 Apr 2019 21:40:17 -0400
Subject: Split more files up
---
src/client/DocServer.ts | 3 +-
src/client/northstar/dash-fields/HistogramField.ts | 2 +-
src/client/northstar/dash-nodes/HistogramBox.tsx | 3 +-
src/client/util/Scripting.ts | 1 +
src/client/views/Main.tsx | 3 +-
.../views/collections/CollectionBaseView.tsx | 3 +-
.../views/collections/CollectionDockingView.tsx | 3 +-
.../views/collections/CollectionSchemaView.tsx | 3 +-
src/client/views/collections/CollectionSubView.tsx | 3 +-
.../views/collections/CollectionTreeView.tsx | 3 +-
.../CollectionFreeFormLinksView.tsx | 3 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 3 +-
src/client/views/nodes/DocumentView.tsx | 3 +-
src/client/views/nodes/FieldView.tsx | 1 +
src/client/views/nodes/LinkMenu.tsx | 3 +-
src/new_fields/Doc.ts | 37 +++-------------------
src/new_fields/HtmlField.ts | 2 +-
src/new_fields/IconField.ts | 2 +-
src/new_fields/InkField.ts | 2 +-
src/new_fields/List.ts | 3 +-
src/new_fields/ObjectField.ts | 17 ++++++++++
src/new_fields/Proxy.ts | 4 ++-
src/new_fields/RefField.ts | 18 +++++++++++
src/new_fields/RichTextField.ts | 2 +-
src/new_fields/Schema.ts | 8 ++---
src/new_fields/Types.ts | 2 +-
src/new_fields/URLField.ts | 2 +-
src/new_fields/util.ts | 4 ++-
.../authentication/controllers/WorkspacesMenu.tsx | 3 +-
src/server/database.ts | 2 ++
30 files changed, 88 insertions(+), 60 deletions(-)
create mode 100644 src/new_fields/ObjectField.ts
create mode 100644 src/new_fields/RefField.ts
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 3f17baec6..c7cbfce37 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,8 +1,9 @@
import * as OpenSocket from 'socket.io-client';
import { MessageStore, Types, Message } from "./../server/Message";
-import { Opt, FieldWaiting, RefField, HandleUpdate } from '../new_fields/Doc';
+import { Opt, FieldWaiting } from '../new_fields/Doc';
import { Utils } from '../Utils';
import { SerializationHelper } from './util/SerializationHelper';
+import { RefField, HandleUpdate } from '../new_fields/RefField';
export namespace DocServer {
const _cache: { [id: string]: RefField | Promise> } = {};
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index 118f4cf7f..730289536 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -3,7 +3,7 @@ import { custom, serializable } from "serializr";
import { ColumnAttributeModel } from "../../../client/northstar/core/attribute/AttributeModel";
import { AttributeTransformationModel } from "../../../client/northstar/core/attribute/AttributeTransformationModel";
import { HistogramOperation } from "../../../client/northstar/operations/HistogramOperation";
-import { ObjectField } from "../../../new_fields/Doc";
+import { ObjectField } from "../../../new_fields/ObjectField";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { OmitKeys } from "../../../Utils";
import { Deserializable } from "../../util/SerializationHelper";
diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx
index 4a65b14cf..a9c68ccba 100644
--- a/src/client/northstar/dash-nodes/HistogramBox.tsx
+++ b/src/client/northstar/dash-nodes/HistogramBox.tsx
@@ -20,7 +20,8 @@ import { HistogramLabelPrimitives } from "./HistogramLabelPrimitives";
import { StyleConstants } from "../utils/StyleContants";
import { NumCast, Cast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
-import { Doc, Id } from "../../../new_fields/Doc";
+import { Doc } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/RefField";
@observer
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index dbec82340..e45f61c11 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -11,6 +11,7 @@ import { Docs } from "../documents/Documents";
import { Doc, Field } from '../../new_fields/Doc';
import { ImageField, PdfField, VideoField, AudioField } from '../../new_fields/URLField';
import { List } from '../../new_fields/List';
+import { RichTextField } from '../../new_fields/RichTextField';
export interface ScriptSucccess {
success: true;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 1e3d4e259..4a68d1c68 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -33,10 +33,11 @@ import { MainOverlayTextBox } from './MainOverlayTextBox';
import { DocumentView } from './nodes/DocumentView';
import { PreviewCursor } from './PreviewCursor';
import { SelectionManager } from '../util/SelectionManager';
-import { FieldResult, Field, Doc, Id, Opt } from '../../new_fields/Doc';
+import { FieldResult, Field, Doc, Opt } from '../../new_fields/Doc';
import { Cast, FieldValue, StrCast } from '../../new_fields/Types';
import { DocServer } from '../DocServer';
import { listSpec } from '../../new_fields/Schema';
+import { Id } from '../../new_fields/RefField';
@observer
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 4807dc40a..b2fba1415 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -4,9 +4,10 @@ import * as React from 'react';
import { ContextMenu } from '../ContextMenu';
import { FieldViewProps } from '../nodes/FieldView';
import { Cast, FieldValue, PromiseValue, NumCast } from '../../../new_fields/Types';
-import { Doc, FieldResult, Opt, Id } from '../../../new_fields/Doc';
+import { Doc, FieldResult, Opt } from '../../../new_fields/Doc';
import { listSpec } from '../../../new_fields/Schema';
import { List } from '../../../new_fields/List';
+import { Id } from '../../../new_fields/RefField';
export enum CollectionViewType {
Invalid,
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 2ff409b9b..1574562c6 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -13,11 +13,12 @@ import React = require("react");
import { SubCollectionViewProps } from "./CollectionSubView";
import { DragManager, DragLinksAsDocuments } from "../../util/DragManager";
import { Transform } from '../../util/Transform';
-import { Doc, Id, Opt, Field, FieldId } from "../../../new_fields/Doc";
+import { Doc, Opt, Field } from "../../../new_fields/Doc";
import { Cast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
import { listSpec } from "../../../new_fields/Schema";
+import { Id, FieldId } from "../../../new_fields/RefField";
@observer
export class CollectionDockingView extends React.Component {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 874170f3d..58d20819b 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -19,10 +19,11 @@ import { DocumentView } from "../nodes/DocumentView";
import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
-import { Opt, Field, Doc, Id } from "../../../new_fields/Doc";
+import { Opt, Field, Doc } from "../../../new_fields/Doc";
import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
import { List } from "../../../new_fields/List";
+import { Id } from "../../../new_fields/RefField";
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 558a8728f..4d090b680 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -10,12 +10,13 @@ import * as rp from 'request-promise';
import { CollectionView } from "./CollectionView";
import { CollectionPDFView } from "./CollectionPDFView";
import { CollectionVideoView } from "./CollectionVideoView";
-import { Doc, ObjectField, Opt } from "../../../new_fields/Doc";
+import { Doc, Opt } from "../../../new_fields/Doc";
import { DocComponent } from "../DocComponent";
import { listSpec } from "../../../new_fields/Schema";
import { Cast, PromiseValue } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
+import { ObjectField } from "../../../new_fields/ObjectField";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index c9d8d83c8..7ec9a8549 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -10,7 +10,8 @@ import "./CollectionTreeView.scss";
import React = require("react");
import { Document, listSpec } from '../../../new_fields/Schema';
import { Cast, StrCast, BoolCast } from '../../../new_fields/Types';
-import { Doc, Id } from '../../../new_fields/Doc';
+import { Doc } from '../../../new_fields/Doc';
+import { Id } from '../../../new_fields/RefField';
export interface TreeViewProps {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index ce9995630..f693d55e8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -7,10 +7,11 @@ import { CollectionViewProps } from "../CollectionSubView";
import "./CollectionFreeFormLinksView.scss";
import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView";
import React = require("react");
-import { Doc, Id } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../new_fields/Doc";
import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types";
import { listSpec } from "../../../../new_fields/Schema";
import { List } from "../../../../new_fields/List";
+import { Id } from "../../../../new_fields/RefField";
@observer
export class CollectionFreeFormLinksView extends React.Component {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 047fbad18..18107e98a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -19,10 +19,11 @@ import { MarqueeView } from "./MarqueeView";
import React = require("react");
import v5 = require("uuid/v5");
import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Schema";
-import { Doc, Id } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../new_fields/Doc";
import { FieldValue, Cast, NumCast } from "../../../../new_fields/Types";
import { pageSchema } from "../../nodes/ImageBox";
import { List } from "../../../../new_fields/List";
+import { Id } from "../../../../new_fields/RefField";
export const panZoomSchema = createSchema({
panX: "number",
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index aabc1633e..c304b6a35 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -15,7 +15,7 @@ import { ContextMenu } from "../ContextMenu";
import { DocumentContentsView } from "./DocumentContentsView";
import "./DocumentView.scss";
import React = require("react");
-import { Field, Opt, Doc, Id } from "../../../new_fields/Doc";
+import { Opt, Doc } from "../../../new_fields/Doc";
import { DocComponent } from "../DocComponent";
import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema";
import { FieldValue, Cast, PromiseValue } from "../../../new_fields/Types";
@@ -24,6 +24,7 @@ import { CollectionFreeFormView } from "../collections/collectionFreeForm/Collec
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView";
import { DocServer } from "../../DocServer";
+import { Id } from "../../../new_fields/RefField";
const linkSchema = createSchema({
title: "string",
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c00c47fc4..dc36c5914 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -16,6 +16,7 @@ import { Opt, Doc, FieldResult } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
import { ImageField, VideoField, AudioField } from "../../../new_fields/URLField";
import { IconField } from "../../../new_fields/IconField";
+import { RichTextField } from "../../../new_fields/RichTextField";
//
diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx
index 3ecc8555d..e21adebbc 100644
--- a/src/client/views/nodes/LinkMenu.tsx
+++ b/src/client/views/nodes/LinkMenu.tsx
@@ -5,9 +5,10 @@ import { LinkBox } from "./LinkBox";
import { LinkEditor } from "./LinkEditor";
import './LinkMenu.scss';
import React = require("react");
-import { Doc, Id } from "../../../new_fields/Doc";
+import { Doc } from "../../../new_fields/Doc";
import { Cast, FieldValue } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
+import { Id } from "../../../new_fields/RefField";
interface Props {
docView: DocumentView;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index fb7b6e360..4ef2a465f 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -8,38 +8,8 @@ import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types";
import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
import { List } from "./List";
-
-export type FieldId = string;
-export const HandleUpdate = Symbol("HandleUpdate");
-export const Id = Symbol("Id");
-export abstract class RefField {
- @serializable(alias("id", primitive()))
- private __id: FieldId;
- readonly [Id]: FieldId;
-
- constructor(id?: FieldId) {
- this.__id = id || Utils.GenerateGuid();
- this[Id] = this.__id;
- }
-
- protected [HandleUpdate]?(diff: any): void;
-}
-
-export const Update = Symbol("Update");
-export const OnUpdate = Symbol("OnUpdate");
-export const Parent = Symbol("Parent");
-export class ObjectField {
- protected [OnUpdate]?: (diff?: any) => void;
- private [Parent]?: Doc;
- readonly [Id] = "";
-}
-
-export namespace ObjectField {
- export function MakeCopy(field: ObjectField) {
- //TODO Types
- return field;
- }
-}
+import { ObjectField } from "./ObjectField";
+import { RefField, FieldId, Id } from "./RefField";
export function IsField(field: any): field is Field {
return (typeof field === "string")
@@ -53,6 +23,7 @@ export type Opt = T | undefined;
export type FieldWaiting = T extends undefined ? never : Promise;
export type FieldResult = Opt | FieldWaiting>;
+export const Update = Symbol("Update");
export const Self = Symbol("Self");
@Deserializable("doc").withFields(["id"])
@@ -161,7 +132,7 @@ export namespace Doc {
copy[key] = field;
}
}
- })
+ });
return copy;
}
diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts
index 76fdb1f62..808a3499b 100644
--- a/src/new_fields/HtmlField.ts
+++ b/src/new_fields/HtmlField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, primitive } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
@Deserializable("html")
export class HtmlField extends ObjectField {
diff --git a/src/new_fields/IconField.ts b/src/new_fields/IconField.ts
index 32f3aa4d5..46f111f8e 100644
--- a/src/new_fields/IconField.ts
+++ b/src/new_fields/IconField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, primitive } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
@Deserializable("icon")
export class IconField extends ObjectField {
diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts
index 49e6bf61e..42223c494 100644
--- a/src/new_fields/InkField.ts
+++ b/src/new_fields/InkField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
export enum InkTool {
None,
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index f01ac210a..428f661c9 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -1,8 +1,9 @@
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
-import { Field, ObjectField, Update, OnUpdate, Self } from "./Doc";
+import { Field, Update, Self } from "./Doc";
import { setter, getter } from "./util";
import { serializable, alias, list } from "serializr";
import { observable } from "mobx";
+import { ObjectField, OnUpdate } from "./ObjectField";
@Deserializable("list")
class ListImpl extends ObjectField {
diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts
new file mode 100644
index 000000000..9cac2c528
--- /dev/null
+++ b/src/new_fields/ObjectField.ts
@@ -0,0 +1,17 @@
+import { Doc } from "./Doc";
+
+export const OnUpdate = Symbol("OnUpdate");
+export const Parent = Symbol("Parent");
+const Id = Symbol("Object Id");
+export class ObjectField {
+ protected [OnUpdate]?: (diff?: any) => void;
+ private [Parent]?: Doc;
+ readonly [Id] = "";
+}
+
+export namespace ObjectField {
+ export function MakeCopy(field: ObjectField) {
+ //TODO Types
+ return field;
+ }
+}
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
index 2aa78731e..56e41cc0f 100644
--- a/src/new_fields/Proxy.ts
+++ b/src/new_fields/Proxy.ts
@@ -1,8 +1,10 @@
import { Deserializable } from "../client/util/SerializationHelper";
-import { RefField, Id, ObjectField, FieldWaiting } from "./Doc";
+import { FieldWaiting } from "./Doc";
import { primitive, serializable } from "serializr";
import { observable, action } from "mobx";
import { DocServer } from "../client/DocServer";
+import { RefField, Id } from "./RefField";
+import { ObjectField } from "./ObjectField";
@Deserializable("proxy")
export class ProxyField extends ObjectField {
diff --git a/src/new_fields/RefField.ts b/src/new_fields/RefField.ts
new file mode 100644
index 000000000..202c65f21
--- /dev/null
+++ b/src/new_fields/RefField.ts
@@ -0,0 +1,18 @@
+import { serializable, primitive, alias } from "serializr";
+import { Utils } from "../Utils";
+
+export type FieldId = string;
+export const HandleUpdate = Symbol("HandleUpdate");
+export const Id = Symbol("Id");
+export abstract class RefField {
+ @serializable(alias("id", primitive()))
+ private __id: FieldId;
+ readonly [Id]: FieldId;
+
+ constructor(id?: FieldId) {
+ this.__id = id || Utils.GenerateGuid();
+ this[Id] = this.__id;
+ }
+
+ protected [HandleUpdate]?(diff: any): void;
+}
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts
index 156e4efd9..0fa3cf73c 100644
--- a/src/new_fields/RichTextField.ts
+++ b/src/new_fields/RichTextField.ts
@@ -1,4 +1,4 @@
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
import { serializable } from "serializr";
export class RichTextField extends ObjectField {
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
index 5081521c7..7444878fe 100644
--- a/src/new_fields/Schema.ts
+++ b/src/new_fields/Schema.ts
@@ -21,15 +21,15 @@ export function makeInterface(...schemas: T): (doc?: Doc)
}
}
const proto = new Proxy({}, {
- get(target: any, prop) {
- const field = target.doc[prop];
+ get(target: any, prop, receiver) {
+ const field = receiver.doc[prop];
if (prop in schema) {
return Cast(field, (schema as any)[prop]);
}
return field;
},
- set(target: any, prop, value) {
- target.doc[prop] = value;
+ set(target: any, prop, value, receiver) {
+ receiver.doc[prop] = value;
return true;
}
});
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 7fa18673f..3f8eabd45 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -1,4 +1,4 @@
-import { Field, Opt, FieldWaiting, FieldResult, RefField } from "./Doc";
+import { Field, Opt, FieldResult } from "./Doc";
import { List } from "./List";
export type ToType | ListSpec> =
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index 1da245e73..95c679df7 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom } from "serializr";
-import { ObjectField } from "./Doc";
+import { ObjectField } from "./ObjectField";
function url() {
return custom(
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 2d9721b2e..011e8c8d9 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -1,8 +1,10 @@
import { UndoManager } from "../client/util/UndoManager";
-import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc";
+import { Update, Doc, Field } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField } from "./Proxy";
import { FieldValue } from "./Types";
+import { RefField, Id } from "./RefField";
+import { ObjectField, Parent, OnUpdate } from "./ObjectField";
export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
if (SerializationHelper.IsSerializing()) {
diff --git a/src/server/authentication/controllers/WorkspacesMenu.tsx b/src/server/authentication/controllers/WorkspacesMenu.tsx
index 29327e5ad..91756315d 100644
--- a/src/server/authentication/controllers/WorkspacesMenu.tsx
+++ b/src/server/authentication/controllers/WorkspacesMenu.tsx
@@ -3,8 +3,9 @@ import { observable, action, configure, reaction, computed, ObservableMap, runIn
import { observer } from "mobx-react";
import './WorkspacesMenu.css';
import { EditableView } from '../../../client/views/EditableView';
-import { Doc, Id } from '../../../new_fields/Doc';
+import { Doc } from '../../../new_fields/Doc';
import { StrCast } from '../../../new_fields/Types';
+import { Id } from '../../../new_fields/RefField';
export interface WorkspaceMenuProps {
active: Doc | undefined;
diff --git a/src/server/database.ts b/src/server/database.ts
index a61b4d823..6b3b6797f 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -60,11 +60,13 @@ export class Database {
}
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) {
+ console.log("getDocument");
this.db && this.db.collection(collectionName).findOne({ id: id }, (err, result) =>
fn(result ? ({ id: result._id, type: result.type, data: result.data }) : undefined));
}
public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = Database.DocumentsCollection) {
+ console.log("getDocuments");
this.db && this.db.collection(collectionName).find({ id: { "$in": ids } }).toArray((err, docs) => {
if (err) {
console.log(err.message);
--
cgit v1.2.3-70-g09d2
From a60abe83ce1e780968e6fd0601cfabce6979a110 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Sun, 28 Apr 2019 05:08:16 -0400
Subject: Started implementing list updates
---
src/new_fields/List.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 428f661c9..ecde4edc7 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -2,14 +2,68 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self } from "./Doc";
import { setter, getter } from "./util";
import { serializable, alias, list } from "serializr";
-import { observable } from "mobx";
+import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda } from "mobx";
import { ObjectField, OnUpdate } from "./ObjectField";
+const listHandlers: any = {
+ push(...items: any[]) {
+ console.log("push");
+ console.log(...items);
+ return this[Self].__fields.push(...items);
+ },
+ pop(): any {
+ return this[Self].__fields.pop();
+ }
+};
+
+function listGetter(target: any, prop: string | number | symbol, receiver: any): any {
+ if (listHandlers.hasOwnProperty(prop)) {
+ return listHandlers[prop];
+ }
+ return getter(target, prop, receiver);
+}
+
+interface ListSpliceUpdate {
+ type: "splice";
+ index: number;
+ added: T[];
+ removedCount: number;
+}
+
+interface ListIndexUpdate {
+ type: "update";
+ index: number;
+ newValue: T;
+}
+
+type ListUpdate = ListSpliceUpdate | ListIndexUpdate;
+
+const ObserveDisposer = Symbol("Observe Disposer");
+
+function listObserver(this: ListImpl, change: IArrayChange | IArraySplice) {
+ if (change.type === "splice") {
+ this[Update]({
+ index: change.index,
+ removedCount: change.removedCount,
+ added: change.added,
+ type: change.type
+ });
+ } else {
+ //This should already be handled by the getter for the Proxy
+ // this[Update]({
+ // index: change.index,
+ // newValue: change.newValue,
+ // type: change.type
+ // });
+ }
+}
+
@Deserializable("list")
class ListImpl extends ObjectField {
constructor(fields: T[] = []) {
super();
this.__fields = fields;
+ this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
const list = new Proxy(this, {
set: setter,
get: getter,
@@ -31,6 +85,7 @@ class ListImpl extends ObjectField {
update && update(diff);
}
+ private [ObserveDisposer]: Lambda;
private [Self] = this;
}
export type List = ListImpl & T[];
--
cgit v1.2.3-70-g09d2
From 307564d9b02ed9d4de8ffa4229b0494bf8d671bd Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Mon, 29 Apr 2019 01:36:00 -0400
Subject: Fixes
---
src/client/util/SerializationHelper.ts | 5 +++++
src/new_fields/Doc.ts | 20 +++++++++++++++++---
src/new_fields/List.ts | 26 +++++++++++++++++++-------
src/new_fields/util.ts | 14 +++++++++-----
src/server/database.ts | 2 +-
5 files changed, 51 insertions(+), 16 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index ac70aba9d..1a8cc3a44 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -63,6 +63,11 @@ export function Deserializable(name: string): DeserializableOpts;
export function Deserializable(constructor: Function): void;
export function Deserializable(constructor: Function | string): DeserializableOpts | void {
function addToMap(name: string, ctor: Function) {
+ const schema = getDefaultModelSchema(ctor as any) as any;
+ if (schema.targetClass !== ctor) {
+ const newSchema = { ...schema, factory: () => new (ctor as any)() };
+ setDefaultModelSchema(ctor as any, newSchema);
+ }
if (!(name in serializationTypes)) {
serializationTypes[name] = ctor;
reverseMap[ctor.name] = name;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 4ef2a465f..d15b6309d 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -3,12 +3,12 @@ import { serializable, primitive, map, alias, list } from "serializr";
import { autoObject, SerializationHelper, Deserializable } from "../client/util/SerializationHelper";
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
-import { setter, getter, getField } from "./util";
+import { setter, getter, getField, updateFunction } from "./util";
import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types";
import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
import { List } from "./List";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Parent, OnUpdate } from "./ObjectField";
import { RefField, FieldId, Id } from "./RefField";
export function IsField(field: any): field is Field {
@@ -47,9 +47,23 @@ export class Doc extends RefField {
[key: string]: FieldResult;
@serializable(alias("fields", map(autoObject())))
+ private get __fields() {
+ return this.___fields;
+ }
+
+ private set __fields(value) {
+ this.___fields = value;
+ for (const key in value) {
+ const field = value[key];
+ if (!(field instanceof ObjectField)) continue;
+ field[Parent] = this[Self];
+ field[OnUpdate] = updateFunction(this[Self], key, field);
+ }
+ }
+
@observable
//{ [key: string]: Field | FieldWaiting | undefined }
- private __fields: any = {};
+ private ___fields: any = {};
private [Update] = (diff: any) => {
DocServer.UpdateField(this[Id], diff);
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index ecde4edc7..e4a80f7a1 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -2,13 +2,13 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self } from "./Doc";
import { setter, getter } from "./util";
import { serializable, alias, list } from "serializr";
-import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda } from "mobx";
+import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
import { ObjectField, OnUpdate } from "./ObjectField";
const listHandlers: any = {
push(...items: any[]) {
- console.log("push");
- console.log(...items);
+ // console.log("push");
+ // console.log(...items);
return this[Self].__fields.push(...items);
},
pop(): any {
@@ -62,7 +62,7 @@ function listObserver(this: ListImpl, change: IArrayChange extends ObjectField {
constructor(fields: T[] = []) {
super();
- this.__fields = fields;
+ this.___fields = fields;
this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
const list = new Proxy(this, {
set: setter,
@@ -76,13 +76,25 @@ class ListImpl extends ObjectField {
[key: number]: T | null | undefined;
@serializable(alias("fields", list(autoObject())))
+ private get __fields() {
+ return this.___fields;
+ }
+
+ private set __fields(value) {
+ this.___fields = value;
+ this[ObserveDisposer]();
+ this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
+ }
+
+ // @serializable(alias("fields", list(autoObject())))
@observable
- private __fields: (T | null | undefined)[];
+ private ___fields: (T | null | undefined)[];
private [Update] = (diff: any) => {
- console.log(diff);
+ // console.log(diff);
const update = this[OnUpdate];
- update && update(diff);
+ // update && update(diff);
+ update && update();
}
private [ObserveDisposer]: Lambda;
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index b2299f34a..511820115 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -31,17 +31,14 @@ export const setter = action(function (target: any, prop: string | symbol | numb
throw new Error("Can't put the same object in multiple documents at the same time");
}
value[Parent] = target;
- value[OnUpdate] = (diff?: any) => {
- if (!diff) diff = SerializationHelper.Serialize(value);
- target[Update]({ [prop]: diff });
- };
+ value[OnUpdate] = updateFunction(target, prop, value);
}
if (curValue instanceof ObjectField) {
delete curValue[Parent];
delete curValue[OnUpdate];
}
target.__fields[prop] = value;
- target[Update]({ ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) });
+ target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
UndoManager.AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue
@@ -80,3 +77,10 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
callback && callback(field);
return field;
}
+
+export function updateFunction(target: any, prop: any, value: any) {
+ return (diff?: any) => {
+ if (!diff) diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ target[Update](diff);
+ };
+}
\ No newline at end of file
diff --git a/src/server/database.ts b/src/server/database.ts
index 4775c0eeb..37cfcf3a3 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -20,7 +20,7 @@ export class Database {
let newProm: Promise;
const run = (): Promise => {
return new Promise(resolve => {
- collection.updateOne({ _id: id }, { $set: value }, { upsert }
+ collection.updateOne({ _id: id }, value, { upsert }
, (err, res) => {
if (err) {
console.log(err.message);
--
cgit v1.2.3-70-g09d2
From 877b104a61d2ab072e3b6a006168ec03e2c46365 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Tue, 30 Apr 2019 00:11:27 -0400
Subject: Mostly fixed lists
---
src/client/util/UndoManager.ts | 4 +-
.../collectionFreeForm/CollectionFreeFormView.tsx | 1 +
src/debug/Test.tsx | 8 +-
src/new_fields/Doc.ts | 10 +-
src/new_fields/List.ts | 192 +++++++++++++++++----
src/new_fields/util.ts | 8 +
6 files changed, 179 insertions(+), 44 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index f7c3e5a7b..0b5280c4a 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -141,10 +141,10 @@ export namespace UndoManager {
});
//TODO Make this return the return value
- export function RunInBatch(fn: () => void, batchName: string) {
+ export function RunInBatch(fn: () => T, batchName: string) {
let batch = StartBatch(batchName);
try {
- runInAction(fn);
+ return runInAction(fn);
} finally {
batch.end();
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dcded7648..d796bd8d5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -272,6 +272,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
get views() {
let curPage = FieldValue(this.Document.curPage, -1);
let docviews = (this.children || []).filter(doc => doc).reduce((prev, doc) => {
+ if (!FieldValue(doc)) return prev;
var page = Cast(doc.page, "number", -1);
if (page === curPage || page === -1) {
let minim = Cast(doc.isMinimized, "boolean");
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index 7415d4b28..04ef00722 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -61,14 +61,12 @@ class Test extends React.Component {
assert(test2.testDoc === undefined);
test2.url = 35;
assert(test2.url === 35);
- const l = new List();
+ const l = new List();
//TODO push, and other array functions don't go through the proxy
- l.push(1);
+ l.push(doc2);
//TODO currently length, and any other string fields will get serialized
- l.length = 3;
- l[2] = 5;
+ doc.list = l;
console.log(l.slice());
- console.log(SerializationHelper.Serialize(l));
}
render() {
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index d15b6309d..6ddb0df89 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -3,7 +3,7 @@ import { serializable, primitive, map, alias, list } from "serializr";
import { autoObject, SerializationHelper, Deserializable } from "../client/util/SerializationHelper";
import { Utils } from "../Utils";
import { DocServer } from "../client/DocServer";
-import { setter, getter, getField, updateFunction } from "./util";
+import { setter, getter, getField, updateFunction, deleteProperty } from "./util";
import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types";
import { UndoManager, undoBatch } from "../client/util/UndoManager";
import { listSpec } from "./Schema";
@@ -34,7 +34,7 @@ export class Doc extends RefField {
set: setter,
get: getter,
ownKeys: target => Object.keys(target.__fields),
- deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
+ deleteProperty: deleteProperty,
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
if (!id || forceSave) {
@@ -151,8 +151,8 @@ export namespace Doc {
}
export function MakeLink(source: Doc, target: Doc): Doc {
- let linkDoc = new Doc;
- UndoManager.RunInBatch(() => {
+ return UndoManager.RunInBatch(() => {
+ let linkDoc = new Doc;
linkDoc.title = "New Link";
linkDoc.linkDescription = "";
linkDoc.linkTags = "Default";
@@ -171,8 +171,8 @@ export namespace Doc {
source.linkedToDocs = linkedTo = new List();
}
linkedTo.push(linkDoc);
+ return linkDoc;
}, "make link");
- return linkDoc;
}
export function MakeDelegate(doc: Doc): Doc;
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index e4a80f7a1..ec1bf44a9 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -1,21 +1,173 @@
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self } from "./Doc";
-import { setter, getter } from "./util";
+import { setter, getter, deleteProperty } from "./util";
import { serializable, alias, list } from "serializr";
import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
import { ObjectField, OnUpdate } from "./ObjectField";
+import { RefField } from "./RefField";
+import { ProxyField } from "./Proxy";
const listHandlers: any = {
- push(...items: any[]) {
- // console.log("push");
- // console.log(...items);
- return this[Self].__fields.push(...items);
+ /// Mutator methods
+ copyWithin() {
+ throw new Error("copyWithin not supported yet");
+ },
+ fill(value: any, start?: number, end?: number) {
+ if (value instanceof RefField) {
+ throw new Error("fill with RefFields not supported yet");
+ }
+ const res = this[Self].__fields.fill(value, start, end);
+ this[Update]();
+ return res;
},
pop(): any {
- return this[Self].__fields.pop();
+ const field = toRealField(this[Self].__fields.pop());
+ this[Update]();
+ return field;
+ },
+ push(...items: any[]) {
+ items = items.map(toObjectField);
+ const res = this[Self].__fields.push(...items);
+ this[Update]();
+ return res;
+ },
+ reverse() {
+ const res = this[Self].__fields.reverse();
+ this[Update]();
+ return res;
+ },
+ shift() {
+ const res = toRealField(this[Self].__fields.shift());
+ this[Update]();
+ return res;
+ },
+ sort(cmpFunc: any) {
+ const res = this[Self].__fields.sort(cmpFunc ? (first: any, second: any) => cmpFunc(toRealField(first), toRealField(second)) : undefined);
+ this[Update]();
+ return res;
+ },
+ splice(start: number, deleteCount: number, ...items: any[]) {
+ items = items.map(toObjectField);
+ const res = this[Self].__fields.splice(start, deleteCount, ...items);
+ this[Update]();
+ return res.map(toRealField);
+ },
+ unshift(...items: any[]) {
+ items = items.map(toObjectField);
+ const res = this[Self].__fields.unshift(...items);
+ this[Update]();
+ return res;
+
+ },
+ /// Accessor methods
+ concat(...items: any[]) {
+ return this[Self].__fields.map(toRealField).concat(...items);
+ },
+ includes(valueToFind: any, fromIndex: number) {
+ const fields = this[Self].__fields;
+ if (valueToFind instanceof RefField) {
+ return fields.map(toRealField).includes(valueToFind, fromIndex);
+ } else {
+ return fields.includes(valueToFind, fromIndex);
+ }
+ },
+ indexOf(valueToFind: any, fromIndex: number) {
+ const fields = this[Self].__fields;
+ if (valueToFind instanceof RefField) {
+ return fields.map(toRealField).indexOf(valueToFind, fromIndex);
+ } else {
+ return fields.indexOf(valueToFind, fromIndex);
+ }
+ },
+ join(separator: any) {
+ return this[Self].__fields.map(toRealField).join(separator);
+ },
+ lastIndexOf(valueToFind: any, fromIndex: number) {
+ const fields = this[Self].__fields;
+ if (valueToFind instanceof RefField) {
+ return fields.map(toRealField).lastIndexOf(valueToFind, fromIndex);
+ } else {
+ return fields.lastIndexOf(valueToFind, fromIndex);
+ }
+ },
+ slice(begin: number, end: number) {
+ return this[Self].__fields.slice(begin, end).map(toRealField);
+ },
+
+ /// Iteration methods
+ entries() {
+ return this[Self].__fields.map(toRealField).entries();
+ },
+ every(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).every(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.every((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ filter(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).filter(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.filter((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ find(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).find(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.find((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ findIndex(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).findIndex(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.findIndex((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ forEach(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).forEach(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.forEach((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ map(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).map(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.map((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ reduce(callback: any, initialValue: any) {
+ return this[Self].__fields.map(toRealField).reduce(callback, initialValue);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.reduce((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
+ },
+ reduceRight(callback: any, initialValue: any) {
+ return this[Self].__fields.map(toRealField).reduceRight(callback, initialValue);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.reduceRight((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
+ },
+ some(callback: any, thisArg: any) {
+ return this[Self].__fields.map(toRealField).some(callback, thisArg);
+ // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+ // If we don't want to support the array parameter, we should use this version instead
+ // return this[Self].__fields.some((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+ },
+ values() {
+ return this[Self].__fields.map(toRealField).values();
+ },
+ [Symbol.iterator]() {
+ return this[Self].__fields.map(toRealField).values();
}
};
+function toObjectField(field: Field) {
+ return field instanceof RefField ? new ProxyField(field) : field;
+}
+
+function toRealField(field: Field) {
+ return field instanceof ProxyField ? field.value() : field;
+}
+
function listGetter(target: any, prop: string | number | symbol, receiver: any): any {
if (listHandlers.hasOwnProperty(prop)) {
return listHandlers[prop];
@@ -38,36 +190,15 @@ interface ListIndexUpdate {
type ListUpdate = ListSpliceUpdate | ListIndexUpdate;
-const ObserveDisposer = Symbol("Observe Disposer");
-
-function listObserver(this: ListImpl, change: IArrayChange | IArraySplice) {
- if (change.type === "splice") {
- this[Update]({
- index: change.index,
- removedCount: change.removedCount,
- added: change.added,
- type: change.type
- });
- } else {
- //This should already be handled by the getter for the Proxy
- // this[Update]({
- // index: change.index,
- // newValue: change.newValue,
- // type: change.type
- // });
- }
-}
-
@Deserializable("list")
class ListImpl extends ObjectField {
constructor(fields: T[] = []) {
super();
this.___fields = fields;
- this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
const list = new Proxy(this, {
set: setter,
- get: getter,
- deleteProperty: () => { throw new Error("Currently properties can't be deleted from documents, assign to undefined instead"); },
+ get: listGetter,
+ deleteProperty: deleteProperty,
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
return list;
@@ -82,8 +213,6 @@ class ListImpl extends ObjectField {
private set __fields(value) {
this.___fields = value;
- this[ObserveDisposer]();
- this[ObserveDisposer] = observe(this.__fields as IObservableArray, listObserver.bind(this));
}
// @serializable(alias("fields", list(autoObject())))
@@ -97,7 +226,6 @@ class ListImpl extends ObjectField {
update && update();
}
- private [ObserveDisposer]: Lambda;
private [Self] = this;
}
export type List = ListImpl & T[];
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 511820115..128817ab8 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -78,6 +78,14 @@ export function getField(target: any, prop: string | number, ignoreProto: boolea
return field;
}
+export function deleteProperty(target: any, prop: string | number | symbol) {
+ if (typeof prop === "symbol") {
+ delete target[prop];
+ return true;
+ }
+ throw new Error("Currently properties can't be deleted from documents, assign to undefined instead");
+}
+
export function updateFunction(target: any, prop: any, value: any) {
return (diff?: any) => {
if (!diff) diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
--
cgit v1.2.3-70-g09d2
From d2fb3085fe17a9c66eab893b2a3d000a5bdec054 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Tue, 30 Apr 2019 20:17:21 -0400
Subject: Fixed list typings
---
src/client/views/DocumentDecorations.tsx | 3 ++-
src/new_fields/List.ts | 8 ++++----
2 files changed, 6 insertions(+), 5 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 084220f76..8ee6a5b64 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -252,8 +252,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
}
}
}
- if (SelectionManager.SelectedDocuments()[0].props.addDocument !== undefined)
+ if (SelectionManager.SelectedDocuments()[0].props.addDocument !== undefined) {
SelectionManager.SelectedDocuments()[0].props.addDocument!(iconDoc!);
+ }
return iconDoc;
}
@action
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index ec1bf44a9..817ae943b 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -1,5 +1,5 @@
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
-import { Field, Update, Self } from "./Doc";
+import { Field, Update, Self, FieldResult } from "./Doc";
import { setter, getter, deleteProperty } from "./util";
import { serializable, alias, list } from "serializr";
import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
@@ -194,17 +194,17 @@ type ListUpdate = ListSpliceUpdate | ListIndexUpdate;
class ListImpl extends ObjectField {
constructor(fields: T[] = []) {
super();
- this.___fields = fields;
const list = new Proxy(this, {
set: setter,
get: listGetter,
deleteProperty: deleteProperty,
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
+ (list as any).push(...fields);
return list;
}
- [key: number]: T | null | undefined;
+ [key: number]: FieldResult;
@serializable(alias("fields", list(autoObject())))
private get __fields() {
@@ -217,7 +217,7 @@ class ListImpl extends ObjectField {
// @serializable(alias("fields", list(autoObject())))
@observable
- private ___fields: (T | null | undefined)[];
+ private ___fields: (T extends RefField ? ProxyField : T)[] = [];
private [Update] = (diff: any) => {
// console.log(diff);
--
cgit v1.2.3-70-g09d2
From ee31019f719b46db57de486e66158e9600515edd Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Tue, 30 Apr 2019 20:41:51 -0400
Subject: all non-list object field [Copy] implemented
---
src/Utils.ts | 16 +++++++++++++++-
src/client/northstar/dash-fields/HistogramField.ts | 4 ++--
src/new_fields/HtmlField.ts | 6 +++++-
src/new_fields/IconField.ts | 6 +++++-
src/new_fields/InkField.ts | 9 ++++++++-
src/new_fields/List.ts | 6 +++++-
src/new_fields/ObjectField.ts | 12 ++++++------
src/new_fields/Proxy.ts | 14 +++++++++++---
src/new_fields/RichTextField.ts | 6 +++++-
src/new_fields/URLField.ts | 6 +++++-
10 files changed, 67 insertions(+), 18 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/Utils.ts b/src/Utils.ts
index c1ad88e2f..d4b6f5377 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -116,4 +116,18 @@ export function returnZero() { return 0; }
export function emptyFunction() { }
-export type Without = Pick>;
\ No newline at end of file
+export type Without = Pick>;
+
+export type Predicate = (entry: [K, V]) => boolean;
+
+export function deepCopy(source: Map, predicate?: Predicate) {
+ let deepCopy = new Map();
+ let entries = source.entries(), next = entries.next();
+ while (!next.done) {
+ let entry = next.value;
+ if (!predicate || predicate(entry)) {
+ deepCopy.set(entry[0], entry[1]);
+ }
+ }
+ return deepCopy;
+}
\ No newline at end of file
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index 730289536..f01f08487 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -3,7 +3,7 @@ import { custom, serializable } from "serializr";
import { ColumnAttributeModel } from "../../../client/northstar/core/attribute/AttributeModel";
import { AttributeTransformationModel } from "../../../client/northstar/core/attribute/AttributeTransformationModel";
import { HistogramOperation } from "../../../client/northstar/operations/HistogramOperation";
-import { ObjectField } from "../../../new_fields/ObjectField";
+import { ObjectField, Copy } from "../../../new_fields/ObjectField";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { OmitKeys } from "../../../Utils";
import { Deserializable } from "../../util/SerializationHelper";
@@ -49,7 +49,7 @@ export class HistogramField extends ObjectField {
return JSON.stringify(OmitKeys(this.HistoOp, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit);
}
- Copy(): HistogramField {
+ [Copy]() {
return new HistogramField(this.HistoOp.Copy());
}
}
\ No newline at end of file
diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts
index 808a3499b..d998746bb 100644
--- a/src/new_fields/HtmlField.ts
+++ b/src/new_fields/HtmlField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, primitive } from "serializr";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Copy } from "./ObjectField";
@Deserializable("html")
export class HtmlField extends ObjectField {
@@ -11,4 +11,8 @@ export class HtmlField extends ObjectField {
super();
this.html = html;
}
+
+ [Copy]() {
+ return new HtmlField(this.html);
+ }
}
diff --git a/src/new_fields/IconField.ts b/src/new_fields/IconField.ts
index c79a2f79a..1a928389d 100644
--- a/src/new_fields/IconField.ts
+++ b/src/new_fields/IconField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, primitive } from "serializr";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Copy } from "./ObjectField";
@Deserializable("icon")
export class IconField extends ObjectField {
@@ -11,4 +11,8 @@ export class IconField extends ObjectField {
super();
this.icon = icon;
}
+
+ [Copy]() {
+ return new IconField(this.icon);
+ }
}
diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts
index f95952c2e..86a8bd18a 100644
--- a/src/new_fields/InkField.ts
+++ b/src/new_fields/InkField.ts
@@ -1,6 +1,9 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Copy } from "./ObjectField";
+import { number } from "prop-types";
+import { any } from "bluebird";
+import { deepCopy } from "../Utils";
export enum InkTool {
None,
@@ -34,4 +37,8 @@ export class InkField extends ObjectField {
super();
this.inkData = data || new Map;
}
+
+ [Copy]() {
+ return new InkField(deepCopy(this.inkData))
+ }
}
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index ec1bf44a9..c1bd15cd1 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -3,7 +3,7 @@ import { Field, Update, Self } from "./Doc";
import { setter, getter, deleteProperty } from "./util";
import { serializable, alias, list } from "serializr";
import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
-import { ObjectField, OnUpdate } from "./ObjectField";
+import { ObjectField, OnUpdate, Copy } from "./ObjectField";
import { RefField } from "./RefField";
import { ProxyField } from "./Proxy";
@@ -215,6 +215,10 @@ class ListImpl extends ObjectField {
this.___fields = value;
}
+ [Copy]() {
+ return new ListImpl();
+ }
+
// @serializable(alias("fields", list(autoObject())))
@observable
private ___fields: (T | null | undefined)[];
diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts
index 9cac2c528..0f3777af6 100644
--- a/src/new_fields/ObjectField.ts
+++ b/src/new_fields/ObjectField.ts
@@ -2,16 +2,16 @@ import { Doc } from "./Doc";
export const OnUpdate = Symbol("OnUpdate");
export const Parent = Symbol("Parent");
-const Id = Symbol("Object Id");
-export class ObjectField {
+export const Copy = Symbol("Copy");
+
+export abstract class ObjectField {
protected [OnUpdate]?: (diff?: any) => void;
private [Parent]?: Doc;
- readonly [Id] = "";
+ abstract [Copy](): ObjectField;
}
export namespace ObjectField {
- export function MakeCopy(field: ObjectField) {
- //TODO Types
- return field;
+ export function MakeCopy(field: T) {
+ return field[Copy]();
}
}
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
index 56e41cc0f..fd99ae1c0 100644
--- a/src/new_fields/Proxy.ts
+++ b/src/new_fields/Proxy.ts
@@ -4,20 +4,28 @@ import { primitive, serializable } from "serializr";
import { observable, action } from "mobx";
import { DocServer } from "../client/DocServer";
import { RefField, Id } from "./RefField";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Copy } from "./ObjectField";
@Deserializable("proxy")
export class ProxyField extends ObjectField {
constructor();
constructor(value: T);
- constructor(value?: T) {
+ constructor(fieldId: string);
+ constructor(value?: T | string) {
super();
- if (value) {
+ if (typeof value === "string") {
+ this.fieldId = value;
+ } else if (value) {
this.cache = value;
this.fieldId = value[Id];
}
}
+ [Copy]() {
+ if (this.cache) return new ProxyField(this.cache);
+ return new ProxyField(this.fieldId);
+ }
+
@serializable(primitive())
readonly fieldId: string = "";
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts
index f2033d5a7..eb30e76de 100644
--- a/src/new_fields/RichTextField.ts
+++ b/src/new_fields/RichTextField.ts
@@ -1,4 +1,4 @@
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Copy } from "./ObjectField";
import { serializable } from "serializr";
import { Deserializable } from "../client/util/SerializationHelper";
@@ -11,4 +11,8 @@ export class RichTextField extends ObjectField {
super();
this.Data = data;
}
+
+ [Copy]() {
+ return new RichTextField(this.Data);
+ }
}
\ No newline at end of file
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index 95c679df7..d7120a5d2 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -1,6 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom } from "serializr";
-import { ObjectField } from "./ObjectField";
+import { ObjectField, Copy } from "./ObjectField";
function url() {
return custom(
@@ -21,6 +21,10 @@ export class URLField extends ObjectField {
super();
this.url = url;
}
+
+ [Copy]() {
+ return new URLField(this.url);
+ }
}
@Deserializable("audio") export class AudioField extends URLField { }
--
cgit v1.2.3-70-g09d2
From 1c1254431f2b76f9fa5f9b552e2e6ccdd1f45b8b Mon Sep 17 00:00:00 2001
From: Sam Wilkins
Date: Tue, 30 Apr 2019 22:46:37 -0400
Subject: copying in theory fully implemented
---
src/new_fields/List.ts | 8 ++++++--
src/new_fields/URLField.ts | 4 ++--
2 files changed, 8 insertions(+), 4 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 3325302aa..5852e2c30 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -190,6 +190,8 @@ interface ListIndexUpdate {
type ListUpdate = ListSpliceUpdate | ListIndexUpdate;
+type StoredType = T extends RefField ? ProxyField : T;
+
@Deserializable("list")
class ListImpl extends ObjectField {
constructor(fields: T[] = []) {
@@ -216,12 +218,14 @@ class ListImpl extends ObjectField {
}
[Copy]() {
- return new ListImpl();
+ let copiedData = this.__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
+ let deepCopy = new ListImpl(copiedData as any);
+ return deepCopy;
}
// @serializable(alias("fields", list(autoObject())))
@observable
- private ___fields: (T extends RefField ? ProxyField : T)[] = [];
+ private ___fields: StoredType[] = [];
private [Update] = (diff: any) => {
// console.log(diff);
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index d7120a5d2..d00a95a16 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -22,8 +22,8 @@ export class URLField extends ObjectField {
this.url = url;
}
- [Copy]() {
- return new URLField(this.url);
+ [Copy](): this {
+ return new (this.constructor as any)(this.url);
}
}
--
cgit v1.2.3-70-g09d2
From ca4a0a6454e69f0eeabdfb6ec78f8ecd60e18b76 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Wed, 1 May 2019 02:03:40 -0400
Subject: Undo with lists is working better
---
src/client/views/DocumentDecorations.tsx | 8 ++++----
.../collectionFreeForm/CollectionFreeFormLinksView.tsx | 4 ++--
src/new_fields/Doc.ts | 9 ++++++---
src/new_fields/List.ts | 2 +-
src/new_fields/util.ts | 16 +++++++++++++---
5 files changed, 26 insertions(+), 13 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3ed8ba3b2..2a6d72dbc 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -57,8 +57,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
reaction(() => SelectionManager.SelectedDocuments().slice(), (docs) => docs.length === 0 && (this._edtingTitle = false));
}
- @action titleChanged = (event: any) => { this._title = event.target.value; }
- @action titleBlur = () => { this._edtingTitle = false; }
+ @action titleChanged = (event: any) => { this._title = event.target.value; };
+ @action titleBlur = () => { this._edtingTitle = false; };
@action titleEntered = (e: any) => {
var key = e.keyCode || e.which;
// enter pressed
@@ -238,7 +238,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
iconDoc.y = NumCast(doc.y) - 24;
iconDoc.maximizedDoc = doc;
doc.minimizedDoc = iconDoc;
- console.log("Layout " + iconDoc.layout)
+ console.log("Layout " + iconDoc.layout);
docView.props.addDocument && docView.props.addDocument(iconDoc, false);
return iconDoc;
}
@@ -274,7 +274,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
minDocs.map(minDoc => {
minDoc.x = NumCast(minDocs[0].x);
minDoc.y = NumCast(minDocs[0].y);
- minDoc.linkTags = new List(minDocs.filter(d => d != minDoc));
+ minDoc.linkTags = new List(minDocs.filter(d => d !== minDoc));
if (this._iconifying && selectedDocs[0].props.removeDocument) {
selectedDocs[0].props.removeDocument(minDoc);
(minDoc.maximizedDoc as Doc).minimizedDoc = undefined;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 4a75fccff..b34e0856e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -60,11 +60,11 @@ export class CollectionFreeFormLinksView extends React.Component();
}
let srcBrushDocs = Cast(srcTarg.brushingDocs, listSpec(Doc));
if (srcBrushDocs === undefined) {
- srcTarg.brushingDocs = srcBrushDocs = new List();
+ srcTarg.brushingDocs = srcBrushDocs = new List();
}
brushAction(dstBrushDocs);
brushAction(srcBrushDocs);
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 113380ce8..b2979af11 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -25,6 +25,7 @@ export type FieldResult = Opt | FieldWaiting { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
+ this[SelfProxy] = doc;
if (!id || forceSave) {
DocServer.CreateField(SerializationHelper.Serialize(doc));
}
@@ -68,7 +70,7 @@ export class Doc extends RefField {
const field = value[key];
if (!(field instanceof ObjectField)) continue;
field[Parent] = this[Self];
- field[OnUpdate] = updateFunction(this[Self], key, field);
+ field[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
}
}
@@ -81,8 +83,9 @@ export class Doc extends RefField {
}
private [Self] = this;
- public [WidthSym] = () => { return NumCast(this.__fields.width); } // bcz: is this the right way to access width/height? it didn't work with : this.width
- public [HeightSym] = () => { return NumCast(this.__fields.height); }
+ private [SelfProxy]: any;
+ public [WidthSym] = () => NumCast(this.__fields.width); // bcz: is this the right way to access width/height? it didn't work with : this.width
+ public [HeightSym] = () => NumCast(this.__fields.height);
}
export namespace Doc {
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 5852e2c30..ff10a3f73 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -218,7 +218,7 @@ class ListImpl extends ObjectField {
}
[Copy]() {
- let copiedData = this.__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
+ let copiedData = this[Self].__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
let deepCopy = new ListImpl(copiedData as any);
return deepCopy;
}
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 128817ab8..bbd8157f6 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -31,7 +31,7 @@ export const setter = action(function (target: any, prop: string | symbol | numb
throw new Error("Can't put the same object in multiple documents at the same time");
}
value[Parent] = target;
- value[OnUpdate] = updateFunction(target, prop, value);
+ value[OnUpdate] = updateFunction(target, prop, value, receiver);
}
if (curValue instanceof ObjectField) {
delete curValue[Parent];
@@ -86,9 +86,19 @@ export function deleteProperty(target: any, prop: string | number | symbol) {
throw new Error("Currently properties can't be deleted from documents, assign to undefined instead");
}
-export function updateFunction(target: any, prop: any, value: any) {
+export function updateFunction(target: any, prop: any, value: any, receiver: any) {
+ let current = ObjectField.MakeCopy(value);
return (diff?: any) => {
- if (!diff) diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ if (true || !diff) {
+ diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ const oldValue = current;
+ const newValue = ObjectField.MakeCopy(value);
+ current = newValue;
+ UndoManager.AddEvent({
+ redo() { receiver[prop] = newValue; },
+ undo() { receiver[prop] = oldValue; }
+ });
+ }
target[Update](diff);
};
}
\ No newline at end of file
--
cgit v1.2.3-70-g09d2
From eebe58b47acfe3b13c22407b98763cdbd6e1eb58 Mon Sep 17 00:00:00 2001
From: Tyler Schicke
Date: Thu, 2 May 2019 01:31:03 -0400
Subject: "Fixed" proto access issue This is actually cause by import order,
which I didn't really fix yet but which needs to be fixed
---
src/client/views/nodes/DocumentView.tsx | 4 +---
src/new_fields/Doc.ts | 5 +++--
src/new_fields/List.ts | 2 +-
src/new_fields/Schema.ts | 2 +-
src/new_fields/Types.ts | 2 +-
5 files changed, 7 insertions(+), 8 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b35d68c4b..f58dc4a02 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -198,9 +198,7 @@ export class DocumentView extends DocComponent(Docu
CollectionDockingView.Instance.AddRightSplit(kvp);
}
fullScreenClicked = (e: React.MouseEvent): void => {
- const doc = Doc.MakeDelegate(FieldValue(this.props.Document.proto));
- // bcz .. should this work?
- // const doc = Doc.MakeDelegate(FieldValue(this.Document.proto));
+ const doc = Doc.MakeDelegate(FieldValue(this.Document.proto));
if (doc) {
CollectionDockingView.Instance.OpenFullScreen(doc);
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 6162b3c76..8dd293f2d 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -9,7 +9,7 @@ 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";
+// import { Docs } from "../client/documents/Documents";
export function IsField(field: any): field is Field {
return (typeof field === "string")
@@ -183,7 +183,8 @@ export namespace Doc {
export function MakeLink(source: Doc, target: Doc) {
UndoManager.RunInBatch(() => {
- let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 });
+ // let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 });
+ let linkDoc = new Doc;
linkDoc.title = "-link name-";
linkDoc.linkDescription = "";
linkDoc.linkTags = "Default";
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index ff10a3f73..1c4b96c81 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -2,7 +2,7 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self, FieldResult } from "./Doc";
import { setter, getter, deleteProperty } from "./util";
import { serializable, alias, list } from "serializr";
-import { observable, observe, IArrayChange, IArraySplice, IObservableArray, Lambda, reaction } from "mobx";
+import { observable } from "mobx";
import { ObjectField, OnUpdate, Copy } from "./ObjectField";
import { RefField } from "./RefField";
import { ProxyField } from "./Proxy";
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
index 7444878fe..b821baec9 100644
--- a/src/new_fields/Schema.ts
+++ b/src/new_fields/Schema.ts
@@ -10,7 +10,7 @@ export const emptySchema = createSchema({});
export const Document = makeInterface(emptySchema);
export type Document = makeInterface<[typeof emptySchema]>;
-export type makeInterface = Partial> & Doc;
+export type makeInterface = Partial> & Doc & { proto: Doc | undefined };
// export function makeInterface(schemas: T): (doc: U) => All;
// export function makeInterface(schema: T): (doc: U) => makeInterface;
export function makeInterface(...schemas: T): (doc?: Doc) => makeInterface {
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index e179c2602..60f08dc90 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -18,7 +18,7 @@ export type ToConstructor =
new (...args: any[]) => T;
export type ToInterface = {
- [P in keyof T]: FieldResult>;
+ [P in Exclude]: FieldResult>;
};
// type ListSpec = { List: ToContructor> | ListSpec> };
--
cgit v1.2.3-70-g09d2
From a78282cdf7fbb99386484640e1fb89d4b9b0cbee Mon Sep 17 00:00:00 2001
From: bob
Date: Thu, 2 May 2019 16:19:07 -0400
Subject: fixed some things with trees and summaries.
---
src/client/views/Main.tsx | 3 +--
src/client/views/Templates.tsx | 12 +++++++++++-
src/client/views/collections/CollectionTreeView.tsx | 10 +++++++---
.../views/collections/collectionFreeForm/MarqueeView.tsx | 4 +++-
src/client/views/nodes/DocumentContentsView.tsx | 3 ++-
src/client/views/nodes/FieldView.tsx | 11 ++++-------
src/client/views/nodes/ImageBox.scss | 2 ++
src/new_fields/List.ts | 6 +++---
src/server/authentication/models/current_user_utils.ts | 2 ++
9 files changed, 35 insertions(+), 18 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index a07a2d5b1..97eb73d7f 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -144,8 +144,7 @@ export class Main extends React.Component {
createNewWorkspace = async (id?: string) => {
const list = Cast(CurrentUserUtils.UserDocument.data, listSpec(Doc));
if (list) {
- let libraryDoc = Docs.TreeDocument([CurrentUserUtils.UserDocument], { x: 0, y: 400, title: `Library: ${CurrentUserUtils.email} ${list.length + 1}` });
- libraryDoc.excludeFromLibrary = true;
+ let libraryDoc = await (CurrentUserUtils.UserDocument.library as Doc);
let freeformDoc = Docs.FreeformDocument([], { x: 0, y: 400, title: `WS collection ${list.length + 1}` });
var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(libraryDoc, 150), CollectionDockingView.makeDocumentConfig(freeformDoc, 600)] }] };
let mainDoc = Docs.DockDocument([libraryDoc, freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${list.length + 1}` });
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index e17dd2354..668ae5312 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -54,7 +54,17 @@ export namespace Templates {
`{layout}
{props.Document.title}
`
);
export const Summary = new Template("Title", TemplatePosition.InnerTop,
- `{layout}
{props.Document.doc1.title}
`
+ `
+
+ {layout}
+
+
+
+
+
+
+
+
`
);
export const TemplateList: Template[] = [Title, OuterCaption, InnerCaption, SideCaption];
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 48b226615..2cef1462b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
import { faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from "mobx";
+import { action, observable, trace } from "mobx";
import { observer } from "mobx-react";
import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager";
import { EditableView } from "../EditableView";
@@ -145,8 +145,11 @@ class TreeView extends React.Component {
;
}
public static GetChildElements(docs: Doc[], remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType) {
- return docs.filter(child => !child.excludeFromLibrary).map(child =>
- );
+ return docs.filter(child => !child.excludeFromLibrary).filter(doc => FieldValue(doc)).map(child => {
+ console.log("child = " + child[Id]);
+ return
+ }
+ );
}
}
@@ -168,6 +171,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
}
}
render() {
+ trace();
const children = this.children;
let dropAction = StrCast(this.props.Document.dropAction, "alias") as dropActionType;
if (!children) {
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index c58e7780c..82027a6f2 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -180,7 +180,9 @@ export class MarqueeView extends React.Component
// SelectionManager.DeselectAll();
if (e.key === "r") {
let summary = Docs.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" });
- summary.doc1 = newCollection.proto!;
+ summary.doc1 = selected[0];
+ if (selected.length > 1)
+ summary.doc2 = selected[1];
summary.templates = new List([Templates.Summary.Layout]);
this.props.addLiveTextDocument(summary);
e.preventDefault();
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 24e8a36ae..ddfe79a5c 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -15,6 +15,7 @@ import { IconBox } from "./IconBox";
import { KeyValueBox } from "./KeyValueBox";
import { PDFBox } from "./PDFBox";
import { VideoBox } from "./VideoBox";
+import { FieldView } from "./FieldView";
import { WebBox } from "./WebBox";
import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
import React = require("react");
@@ -63,7 +64,7 @@ export class DocumentContentsView extends React.Component {
}
render() {
const field = this.field;
- if (!field) {
+ if (field === undefined) {
return {''}
;
}
- if (typeof field === "string") {
- return {field}
;
- }
+ // if (typeof field === "string") {
+ // return {field}
;
+ // }
else if (field instanceof RichTextField) {
return ;
}
@@ -108,9 +108,6 @@ export class FieldView extends React.Component {
// else if (field instanceof HtmlField) {
// return
// }
- else if (typeof field === "number") {
- return {field}
;
- }
else if (!(field instanceof Promise)) {
return {JSON.stringify(field)}
;
}
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index 9fe211df0..2316a050e 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -10,6 +10,8 @@
}
.imageBox-cont-interactive {
pointer-events: all;
+ width:100%;
+ height:auto;
}
.imageBox-dot {
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 1c4b96c81..db7932cec 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -2,7 +2,7 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper";
import { Field, Update, Self, FieldResult } from "./Doc";
import { setter, getter, deleteProperty } from "./util";
import { serializable, alias, list } from "serializr";
-import { observable } from "mobx";
+import { observable, action } from "mobx";
import { ObjectField, OnUpdate, Copy } from "./ObjectField";
import { RefField } from "./RefField";
import { ProxyField } from "./Proxy";
@@ -25,12 +25,12 @@ const listHandlers: any = {
this[Update]();
return field;
},
- push(...items: any[]) {
+ push: action(function (this: any, ...items: any[]) {
items = items.map(toObjectField);
const res = this[Self].__fields.push(...items);
this[Update]();
return res;
- },
+ }),
reverse() {
const res = this[Self].__fields.reverse();
this[Update]();
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 9db470ca0..93c2afb1d 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -26,6 +26,8 @@ export class CurrentUserUtils {
doc.title = this.email;
doc.data = new List();
doc.optionalRightCollection = Docs.SchemaDocument([], { title: "Pending documents" });
+ doc.library = Docs.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` });
+ (doc.library as Doc).excludeFromLibrary = true;
return doc;
}
--
cgit v1.2.3-70-g09d2
From 94971b6104432b740c22d6ff0cf9a410ec60bc90 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik
Date: Thu, 2 May 2019 21:26:17 -0400
Subject: added actions to more list funcs
---
src/new_fields/List.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'src/new_fields/List.ts')
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index db7932cec..96018dafa 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -46,12 +46,12 @@ const listHandlers: any = {
this[Update]();
return res;
},
- splice(start: number, deleteCount: number, ...items: any[]) {
+ splice: action(function (this: any, start: number, deleteCount: number, ...items: any[]) {
items = items.map(toObjectField);
const res = this[Self].__fields.splice(start, deleteCount, ...items);
this[Update]();
return res.map(toRealField);
- },
+ }),
unshift(...items: any[]) {
items = items.map(toObjectField);
const res = this[Self].__fields.unshift(...items);
@@ -60,9 +60,9 @@ const listHandlers: any = {
},
/// Accessor methods
- concat(...items: any[]) {
+ concat: action(function (this: any, ...items: any[]) {
return this[Self].__fields.map(toRealField).concat(...items);
- },
+ }),
includes(valueToFind: any, fromIndex: number) {
const fields = this[Self].__fields;
if (valueToFind instanceof RefField) {
--
cgit v1.2.3-70-g09d2