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/HtmlField.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/new_fields/HtmlField.ts (limited to 'src/new_fields/HtmlField.ts') diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts new file mode 100644 index 000000000..f8e54ade5 --- /dev/null +++ b/src/new_fields/HtmlField.ts @@ -0,0 +1,14 @@ +import { Deserializable } from "../client/util/SerializationHelper"; +import { serializable, primitive } from "serializr"; +import { ObjectField } from "./Doc"; + +@Deserializable("html") +export class URLField extends ObjectField { + @serializable(primitive()) + readonly html: string; + + constructor(html: string) { + super(); + this.html = html; + } +} -- cgit v1.2.3-70-g09d2 From 1eb965a5d9c8aaebf1970bc645edecfb7017b601 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 20 Apr 2019 03:29:35 -0400 Subject: Made the switch in a couple more classes --- src/Utils.ts | 3 -- src/client/views/nodes/DocumentContentsView.tsx | 26 ++------------ src/client/views/nodes/DocumentView.tsx | 16 +++++++-- src/client/views/nodes/FieldView.tsx | 45 ++++++++++--------------- src/client/views/nodes/ImageBox.tsx | 41 +++++++++++++--------- src/debug/Test.tsx | 4 +-- src/new_fields/Doc.ts | 5 +-- src/new_fields/HtmlField.ts | 2 +- src/new_fields/Schema.ts | 24 +++++++++++-- src/new_fields/Types.ts | 19 +++++++---- 10 files changed, 98 insertions(+), 87 deletions(-) (limited to 'src/new_fields/HtmlField.ts') diff --git a/src/Utils.ts b/src/Utils.ts index 98f75d3b9..066d653f5 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -2,7 +2,6 @@ import v4 = require('uuid/v4'); import v5 = require("uuid/v5"); import { Socket } from 'socket.io'; import { Message } from './server/Message'; -import { Document } from './fields/Document'; export class Utils { @@ -108,6 +107,4 @@ export function returnZero() { return 0; } export function emptyFunction() { } -export function emptyDocFunction(doc: Document) { } - export type Without = Pick>; \ No newline at end of file diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 07599c345..273401111 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -1,9 +1,5 @@ import { computed } from "mobx"; import { observer } from "mobx-react"; -import { FieldWaiting, Field } from "../../../fields/Field"; -import { Key } from "../../../fields/Key"; -import { KeyStore } from "../../../fields/KeyStore"; -import { ListField } from "../../../fields/ListField"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; @@ -22,46 +18,30 @@ import { VideoBox } from "./VideoBox"; import { WebBox } from "./WebBox"; import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox"; import React = require("react"); -import { Document } from "../../../fields/Document"; import { FieldViewProps } from "./FieldView"; import { Without, OmitKeys } from "../../../Utils"; +import { Cast } from "../../../new_fields/Types"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without; export interface JsxBindings { props: BindingProps; - [keyName: string]: BindingProps | Field; } @observer export class DocumentContentsView extends React.Component boolean, select: (ctrl: boolean) => void, - layoutKey: Key + layoutKey: string }> { - @computed get layout(): string { return this.props.Document.GetText(this.props.layoutKey, "

Error loading layout data

"); } - @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array()); } - @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array()); } - + @computed get layout(): string { return Cast(this.props.Document[this.props.layoutKey], "string", "

Error loading layout data

"); } CreateBindings(): JsxBindings { let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) }; - - for (const key of this.layoutKeys) { - bindings[key.Name + "Key"] = key; // this maps string values of the form Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data - } - for (const key of this.layoutFields) { - let field = this.props.Document.Get(key); - bindings[key.Name] = field && field !== FieldWaiting ? field.GetValue() : field; - } return bindings; } render() { - let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); - if (!lkeys || lkeys === FieldWaiting) { - return

Error loading layout keys

; - } return ; -const Document = makeInterface(schema); +export const positionSchema = createSchema({ + nativeWidth: "number", + nativeHeight: "number", + width: "number", + height: "number", + x: "number", + y: "number", +}); + +type Document = makeInterface<[typeof schema]>; +const Document = makeInterface([schema]); @observer export class DocumentView extends DocComponent(Document) { @@ -146,7 +155,7 @@ export class DocumentView extends DocComponent(Docu document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); e.stopPropagation(); - if (!SelectionManager.IsSelected(this) && e.button !== 2) + if (!SelectionManager.IsSelected(this) && e.button !== 2) { if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { if (this.props.Document.Get(KeyStore.MaximizedDoc) instanceof Document) { this.props.Document.GetAsync(KeyStore.MaximizedDoc, maxdoc => { @@ -159,6 +168,7 @@ export class DocumentView extends DocComponent(Docu SelectionManager.SelectDoc(this, e.ctrlKey); } } + } } stopPropagation = (e: React.SyntheticEvent) => { e.stopPropagation(); diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 93e385821..d8de5afec 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,30 +1,21 @@ import React = require("react"); import { observer } from "mobx-react"; import { computed } from "mobx"; -import { Field, FieldWaiting, FieldValue, Opt } from "../../../fields/Field"; -import { Document } from "../../../fields/Document"; -import { TextField } from "../../../fields/TextField"; -import { NumberField } from "../../../fields/NumberField"; -import { RichTextField } from "../../../fields/RichTextField"; -import { ImageField } from "../../../fields/ImageField"; -import { VideoField } from "../../../fields/VideoField"; -import { Key } from "../../../fields/Key"; import { FormattedTextBox } from "./FormattedTextBox"; import { ImageBox } from "./ImageBox"; import { WebBox } from "./WebBox"; import { VideoBox } from "./VideoBox"; import { AudioBox } from "./AudioBox"; -import { AudioField } from "../../../fields/AudioField"; -import { ListField } from "../../../fields/ListField"; import { DocumentContentsView } from "./DocumentContentsView"; import { Transform } from "../../util/Transform"; -import { KeyStore } from "../../../fields/KeyStore"; -import { returnFalse, emptyDocFunction, emptyFunction, returnOne } from "../../../Utils"; +import { returnFalse, emptyFunction, returnOne } from "../../../Utils"; import { CollectionView } from "../collections/CollectionView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; import { CollectionVideoView } from "../collections/CollectionVideoView"; import { IconField } from "../../../fields/IconFIeld"; import { IconBox } from "./IconBox"; +import { Opt, Doc, Field, FieldValue, FieldWaiting } from "../../../new_fields/Doc"; +import { List } from "../../../new_fields/List"; // @@ -33,9 +24,9 @@ import { IconBox } from "./IconBox"; // See the LayoutString method on each field view : ImageBox, FormattedTextBox, etc. // export interface FieldViewProps { - fieldKey: Key; + fieldKey: string; ContainingCollectionView: Opt; - Document: Document; + Document: Doc; isSelected: () => boolean; select: (isCtrlPressed: boolean) => void; isTopMost: boolean; @@ -56,17 +47,17 @@ export class FieldView extends React.Component { } @computed - get field(): FieldValue { - const { Document: doc, fieldKey } = this.props; - return doc.Get(fieldKey); + get field(): FieldValue { + const { Document, fieldKey } = this.props; + return Document[fieldKey]; } render() { const field = this.field; if (!field) { return

{''}

; } - if (field instanceof TextField) { - return

{field.Data}

; + if (typeof field === "string") { + return

{field}

; } else if (field instanceof RichTextField) { return ; @@ -83,7 +74,7 @@ export class FieldView extends React.Component { else if (field instanceof AudioField) { return ; } - else if (field instanceof Document) { + else if (field instanceof Doc) { return ( { PanelHeight={() => 100} isTopMost={true} //TODO Why is this top most? selectOnLoad={false} - focus={emptyDocFunction} + focus={emptyFunction} isSelected={returnFalse} select={returnFalse} - layoutKey={KeyStore.Layout} + layoutKey={"layout"} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} whenActiveChanged={this.props.whenActiveChanged} /> ); } - else if (field instanceof ListField) { + else if (field instanceof List) { return (
- {(field as ListField).Data.map(f => f instanceof Document ? f.Title : f.GetValue().toString()).join(", ")} + {field.map(f => f instanceof Doc ? f.title : f.toString()).join(", ")}
); } // bcz: this belongs here, but it doesn't render well so taking it out for now // else if (field instanceof HtmlField) { // return // } - else if (field instanceof NumberField) { - return

{field.Data}

; + else if (typeof field === "number") { + return

{field}

; } else if (field !== FieldWaiting) { - return

{JSON.stringify(field.GetValue())}

; + return

{JSON.stringify(field)}

; } else { return

{"Waiting for server..."}

; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index fd5381b77..3b72e9f39 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -3,11 +3,6 @@ import { action, observable } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app -import { Document } from '../../../fields/Document'; -import { FieldWaiting } from '../../../fields/Field'; -import { ImageField } from '../../../fields/ImageField'; -import { KeyStore } from '../../../fields/KeyStore'; -import { ListField } from '../../../fields/ListField'; import { Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; @@ -15,9 +10,23 @@ import { ContextMenu } from "../../views/ContextMenu"; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); +import { createSchema, makeInterface } from '../../../new_fields/Schema'; +import { DocComponent } from '../DocComponent'; +import { positionSchema } from './DocumentView'; +import { FieldValue, Cast } from '../../../new_fields/Types'; +import { URLField } from '../../../new_fields/URLField'; +import { Doc, FieldWaiting } from '../../../new_fields/Doc'; +import { List } from '../../../new_fields/List'; + +const schema = createSchema({ + curPage: "number" +}); + +type ImageDocument = makeInterface<[typeof schema, typeof positionSchema]>; +const ImageDocument = makeInterface([schema, positionSchema]); @observer -export class ImageBox extends React.Component { +export class ImageBox extends DocComponent(ImageDocument) { public static LayoutString() { return FieldView.LayoutString(ImageBox); } private _imgRef: React.RefObject; @@ -39,8 +48,8 @@ export class ImageBox extends React.Component { var h = this._imgRef.current!.naturalHeight; var w = this._imgRef.current!.naturalWidth; if (this._photoIndex === 0) { - this.props.Document.SetNumber(KeyStore.NativeHeight, this.props.Document.GetNumber(KeyStore.NativeWidth, 0) * h / w); - this.props.Document.SetNumber(KeyStore.Height, this.props.Document.Width() * h / w); + this.Document.nativeHeight = FieldValue(this.Document.nativeWidth, 0) * h / w; + this.Document.height = FieldValue(this.Document.width, 0) * h / w; } } @@ -126,9 +135,9 @@ export class ImageBox extends React.Component { } specificContextMenu = (e: React.MouseEvent): void => { - let field = this.props.Document.GetT(this.props.fieldKey, ImageField); + let field = Cast(this.Document[this.props.fieldKey], URLField); if (field && field !== FieldWaiting) { - let url = field.Data.href; + let url = field.url.href; ContextMenu.Instance.addItem({ description: "Copy path", event: () => { Utils.CopyText(url); @@ -140,11 +149,11 @@ export class ImageBox extends React.Component { @action onDotDown(index: number) { this._photoIndex = index; - this.props.Document.SetNumber(KeyStore.CurPage, index); + this.Document.curPage = index; } dots(paths: string[]) { - let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 1); + let nativeWidth = FieldValue(this.Document.nativeWidth, 1); let dist = Math.min(nativeWidth / paths.length, 40); let left = (nativeWidth - paths.length * dist) / 2; return paths.map((p, i) => @@ -155,12 +164,12 @@ export class ImageBox extends React.Component { } render() { - let field = this.props.Document.Get(this.props.fieldKey); + let field = this.Document[this.props.fieldKey]; let paths: string[] = ["http://www.cs.brown.edu/~bcz/face.gif"]; if (field === FieldWaiting) paths = ["https://image.flaticon.com/icons/svg/66/66163.svg"]; - else if (field instanceof ImageField) paths = [field.Data.href]; - else if (field instanceof ListField) paths = field.Data.filter(val => val as ImageField).map(p => (p as ImageField).Data.href); - let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 1); + else if (field instanceof URLField) paths = [field.url.href]; + else if (field instanceof List) paths = field.filter(val => val instanceof URLField).map(p => (p as URLField).url.href); + let nativeWidth = FieldValue(this.Document.nativeWidth, 1); return (
Image not found diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx index 8b9c9fa0b..81c69ca8e 100644 --- a/src/debug/Test.tsx +++ b/src/debug/Test.tsx @@ -16,8 +16,8 @@ const schema1 = createSchema({ testDoc: Doc }); -const TestDoc = makeInterface(schema1); -type TestDoc = makeInterface; +const TestDoc = makeInterface([schema1]); +type TestDoc = makeInterface<[typeof schema1]>; const schema2 = createSchema({ hello: URLField, diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 23a8c05cc..e0eb44ee9 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -33,6 +33,7 @@ export type Field = number | string | boolean | ObjectField | RefField; export type Opt = T | undefined; export type FieldWaiting = null; export const FieldWaiting: FieldWaiting = null; +export type FieldValue = Opt | FieldWaiting; export const Self = Symbol("Self"); @@ -81,8 +82,8 @@ export namespace Doc { const self = doc[Self]; return getField(self, key, ignoreProto); } - export function GetT(doc: Doc, key: string, ctor: FieldCtor, ignoreProto: boolean = false): Field | null | undefined { - return Cast(Get(doc, key, ignoreProto), ctor); + export function GetT(doc: Doc, key: string, ctor: FieldCtor, ignoreProto: boolean = false): T | null | undefined { + return Cast(Get(doc, key, ignoreProto), ctor) as T | null | undefined; } export function MakeDelegate(doc: Opt): Opt { if (!doc) { diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts index f8e54ade5..76fdb1f62 100644 --- a/src/new_fields/HtmlField.ts +++ b/src/new_fields/HtmlField.ts @@ -3,7 +3,7 @@ import { serializable, primitive } from "serializr"; import { ObjectField } from "./Doc"; @Deserializable("html") -export class URLField extends ObjectField { +export class HtmlField extends ObjectField { @serializable(primitive()) readonly html: string; diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts index 1607d4c15..1d1f56844 100644 --- a/src/new_fields/Schema.ts +++ b/src/new_fields/Schema.ts @@ -1,8 +1,26 @@ -import { Interface, ToInterface, Cast, FieldCtor, ToConstructor } from "./Types"; +import { Interface, ToInterface, Cast, FieldCtor, ToConstructor, HasTail, Head, Tail } from "./Types"; import { Doc } from "./Doc"; -export type makeInterface = Partial> & U; -export function makeInterface(schema: T): (doc: U) => makeInterface { +type All = { + 1: makeInterface, U> & All, U>, + 0: makeInterface, U> +}[HasTail extends true ? 1 : 0]; + +type AllToInterface = { + 1: ToInterface> & AllToInterface>, + 0: ToInterface> +}[HasTail extends true ? 1 : 0]; + +export type makeInterface = Partial> & U; +// export function makeInterface(schemas: T): (doc: U) => All; +// export function makeInterface(schema: T): (doc: U) => makeInterface; +export function makeInterface(schemas: T): (doc: U) => All { + let schema: Interface = {}; + for (const s of schemas) { + for (const key in s) { + schema[key] = s[key]; + } + } return function (doc: any) { return new Proxy(doc, { get(target, prop) { diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts index cafb208ce..6ffb3e02f 100644 --- a/src/new_fields/Types.ts +++ b/src/new_fields/Types.ts @@ -27,14 +27,17 @@ export type Tail = ((...t: T) => any) extends ((_: any, ...tail: infer TT) => any) ? TT : []; export type HasTail = T extends ([] | [any]) ? false : true; +//TODO Allow you to optionally specify default values for schemas, which should then make that field not be partial export interface Interface { [key: string]: ToConstructor | ListSpec; // [key: string]: ToConstructor | ListSpec; } -export type FieldCtor = ToConstructor | ListSpec; +export type FieldCtor = T extends List ? ListSpec : ToConstructor; -export function Cast>(field: Field | null | undefined, ctor: T): ToType | null | undefined { +export function Cast>(field: Field | null | undefined, ctor: T): ToType | null | undefined; +export function Cast>(field: Field | null | undefined, ctor: T, defaultVal: ToType): ToType; +export function Cast>(field: Field | null | undefined, ctor: T, defaultVal?: ToType): ToType | null | undefined { if (field !== undefined && field !== null) { if (typeof ctor === "string") { if (typeof field === ctor) { @@ -42,17 +45,19 @@ export function Cast>(field: Field | null | undefined } } else if (typeof ctor === "object") { if (field instanceof List) { - return field as ToType; + return field as any; } } else if (field instanceof (ctor as any)) { return field as ToType; } } else { - return field; + return defaultVal; } - return undefined; + return defaultVal; } -export function FieldValue(field: Opt | Promise>): Opt { - return field instanceof Promise ? undefined : field; +export function FieldValue(field: Opt | Promise>, defaultValue: U): T; +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 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/HtmlField.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 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/HtmlField.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