aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts1
-rw-r--r--src/client/northstar/operations/HistogramOperation.ts5
-rw-r--r--src/client/util/DragManager.ts8
-rw-r--r--src/client/views/PreviewCursor.tsx4
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx6
-rw-r--r--src/client/views/collections/CollectionSubView.tsx20
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx4
-rw-r--r--src/client/views/collections/CollectionVideoView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx64
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx4
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx8
-rw-r--r--src/client/views/nodes/PDFBox.tsx5
-rw-r--r--src/fields/TemplateField.ts43
-rw-r--r--src/new_fields/CursorField.ts55
-rw-r--r--src/new_fields/Doc.ts2
-rw-r--r--src/new_fields/InkField.ts5
-rw-r--r--src/new_fields/List.ts49
-rw-r--r--src/new_fields/ObjectField.ts5
20 files changed, 177 insertions, 117 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 00233a989..11929455c 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -19,7 +19,6 @@ import { ColumnAttributeModel } from "../northstar/core/attribute/AttributeModel
import { AttributeTransformationModel } from "../northstar/core/attribute/AttributeTransformationModel";
import { AggregateFunction } from "../northstar/model/idea/idea";
import { Template } from "../views/Templates";
-import { TemplateField } from "../../fields/TemplateField";
import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss";
import { IconBox } from "../views/nodes/IconBox";
import { Field, Doc, Opt } from "../../new_fields/Doc";
diff --git a/src/client/northstar/operations/HistogramOperation.ts b/src/client/northstar/operations/HistogramOperation.ts
index 5c9c832c0..78b206bdc 100644
--- a/src/client/northstar/operations/HistogramOperation.ts
+++ b/src/client/northstar/operations/HistogramOperation.ts
@@ -65,7 +65,7 @@ export class HistogramOperation extends BaseOperation implements IBaseFilterCons
@computed
public get FilterString(): string {
if (this.OverridingFilters.length > 0) {
- return "(" + this.OverridingFilters.filter(fm => fm != null).map(fm => fm.ToPythonString()).join(" || ") + ")";
+ return "(" + this.OverridingFilters.filter(fm => fm !== null).map(fm => fm.ToPythonString()).join(" || ") + ")";
}
let filterModels: FilterModel[] = [];
return FilterModel.GetFilterModelsRecursive(this, new Set<IBaseFilterProvider>(), filterModels, true);
@@ -89,8 +89,9 @@ export class HistogramOperation extends BaseOperation implements IBaseFilterCons
@action
public DrillDown(up: boolean) {
if (!up) {
- if (!this.BarFilterModels.length)
+ if (!this.BarFilterModels.length) {
return;
+ }
this._stackedFilters.push(this.BarFilterModels.map(f => f));
this.OverridingFilters.length = 0;
this.OverridingFilters.push(...this._stackedFilters[this._stackedFilters.length - 1]);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index eaf851a75..266679c16 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -158,9 +158,9 @@ export namespace DragManager {
runInAction(() => StartDragFunctions.map(func => func()));
StartDrag(eles, dragData, downX, downY, options,
(dropData: { [id: string]: any }) =>
- (dropData.droppedDocuments = dragData.userDropAction == "alias" || (!dragData.userDropAction && dragData.dropAction == "alias") ?
+ (dropData.droppedDocuments = dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ?
dragData.draggedDocuments.map(d => Doc.MakeAlias(d)) :
- dragData.userDropAction == "copy" || (!dragData.userDropAction && dragData.dropAction == "copy") ?
+ dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ?
dragData.draggedDocuments.map(d => Doc.MakeCopy(d, true)) :
dragData.draggedDocuments));
}
@@ -284,7 +284,7 @@ export namespace DragManager {
};
let hideDragElements = () => {
- dragElements.map(dragElement => dragElement.parentNode == dragDiv && dragDiv.removeChild(dragElement));
+ dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
eles.map(ele => (ele.hidden = false));
};
let endDrag = () => {
@@ -293,7 +293,7 @@ export namespace DragManager {
if (options) {
options.handlers.dragComplete({});
}
- }
+ };
AbortDrag = () => {
hideDragElements();
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 4ac4b9c95..78024a58c 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -17,7 +17,7 @@ export class PreviewCursor extends React.Component<{}> {
constructor(props: any) {
super(props);
- document.addEventListener("keydown", this.onKeyPress)
+ document.addEventListener("keydown", this.onKeyPress);
}
@action
@@ -27,7 +27,7 @@ export class PreviewCursor extends React.Component<{}> {
// the keyPress here.
//if not these keys, make a textbox if preview cursor is active!
if (e.key.startsWith("F") && !e.key.endsWith("F")) {
- } else if (e.key != "Escape" && e.key != "Alt" && e.key != "Shift" && e.key != "Meta" && e.key != "Control" && !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) {
+ } else if (e.key !== "Escape" && e.key !== "Alt" && e.key !== "Shift" && e.key !== "Meta" && e.key !== "Control" && !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) {
if ((!e.ctrlKey && !e.metaKey) || e.key === "v" || e.key === "q") {
PreviewCursor.Visible && PreviewCursor._onKeyPress && PreviewCursor._onKeyPress(e);
PreviewCursor.Visible = false;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index d894909d0..159815ea5 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -392,13 +392,15 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
get previewPanelCenteringOffset() { return (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2; }
get content() {
- if (!this._document)
+ if (!this._document) {
return (null);
+ }
return (
<div className="collectionDockingView-content" ref={this._mainCont}
style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px)` }}>
- <DocumentView key={this._document![Id]} Document={this._document!}
+ <DocumentView key={this._document[Id]} Document={this._document}
toggleMinimized={emptyFunction}
+ bringToFront={emptyFunction}
addDocument={undefined}
removeDocument={undefined}
ContentScaling={this.contentScaling}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 082692d8d..0b08e150a 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -10,13 +10,14 @@ import * as rp from 'request-promise';
import { CollectionView } from "./CollectionView";
import { CollectionPDFView } from "./CollectionPDFView";
import { CollectionVideoView } from "./CollectionVideoView";
-import { Doc, Opt } from "../../../new_fields/Doc";
+import { Doc, Opt, FieldResult } from "../../../new_fields/Doc";
import { DocComponent } from "../DocComponent";
import { listSpec } from "../../../new_fields/Schema";
-import { Cast, PromiseValue, FieldValue } from "../../../new_fields/Types";
+import { Cast, PromiseValue, FieldValue, ListSpec } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
import { ObjectField } from "../../../new_fields/ObjectField";
+import CursorField, { CursorPosition, CursorMetadata } from "../../../new_fields/CursorField";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -30,8 +31,6 @@ export interface SubCollectionViewProps extends CollectionViewProps {
CollectionView: CollectionView | CollectionPDFView | CollectionVideoView;
}
-export type CursorEntry = TupleField<[string, string], [number, number]>;
-
export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
class CollectionSubView extends DocComponent<SubCollectionViewProps, T>(schemaCtor) {
private dropDisposer?: DragManager.DragDropDisposer;
@@ -55,25 +54,24 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
@action
protected async setCursorPosition(position: [number, number]) {
- return;
let ind;
let doc = this.props.Document;
let id = CurrentUserUtils.id;
let email = CurrentUserUtils.email;
+ let pos = { x: position[0], y: position[1] };
if (id && email) {
- let textInfo: [string, string] = [id, email];
const proto = await doc.proto;
if (!proto) {
return;
}
- let cursors = await Cast(proto.cursors, listSpec(ObjectField));
+ let cursors = Cast(proto.cursors, listSpec(CursorField));
if (!cursors) {
- proto.cursors = cursors = new List<ObjectField>();
+ proto.cursors = cursors = new List<CursorField>();
}
- if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.Data[0][0] === id)) > -1) {
- cursors[ind].Data[1] = position;
+ if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.data.metadata.id === id)) > -1) {
+ cursors[ind].setPosition(pos);
} else {
- let entry = new TupleField<[string, string], [number, number]>([textInfo, position]);
+ let entry = new CursorField({ metadata: { id: id, identifier: email }, position: pos });
cursors.push(entry);
}
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6e690236f..33787f06b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -146,8 +146,8 @@ class TreeView extends React.Component<TreeViewProps> {
}
}
- onPointerEnter = (e: React.PointerEvent): void => { this.props.document.libraryBrush = true; }
- onPointerLeave = (e: React.PointerEvent): void => { this.props.document.libraryBrush = false; }
+ onPointerEnter = (e: React.PointerEvent): void => { this.props.document.libraryBrush = true; };
+ onPointerLeave = (e: React.PointerEvent): void => { this.props.document.libraryBrush = false; };
render() {
let bulletType = BulletType.List;
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 9dee217cb..cb3fd1ba4 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -90,7 +90,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
}
}
- setVideoBox = (player: VideoBox) => { this._videoBox = player; }
+ setVideoBox = (player: VideoBox) => { this._videoBox = player; };
private subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => {
let props = { ...this.props, ...renderProps };
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 036745eca..642118d75 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -1,26 +1,35 @@
import { computed } from "mobx";
import { observer } from "mobx-react";
-import { CollectionViewProps, CursorEntry } from "../CollectionSubView";
+import { CollectionViewProps } from "../CollectionSubView";
import "./CollectionFreeFormView.scss";
import React = require("react");
import v5 = require("uuid/v5");
import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
+import CursorField from "../../../../new_fields/CursorField";
+import { List } from "../../../../new_fields/List";
+import { Cast } from "../../../../new_fields/Types";
+import { listSpec } from "../../../../new_fields/Schema";
@observer
export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
- protected getCursors(): CursorEntry[] {
+
+ protected getCursors(): CursorField[] {
let doc = this.props.Document;
+
let id = CurrentUserUtils.id;
- let cursors = doc.GetList(KeyStore.Cursors, [] as CursorEntry[]);
- let notMe = cursors.filter(entry => entry.Data[0][0] !== id);
- return id ? notMe : [];
+ if (!id) {
+ return [];
+ }
+
+ let cursors = Cast(doc.cursors, listSpec(CursorField));
+
+ return (cursors || []).filter(cursor => cursor.data.metadata.id !== id);
}
private crosshairs?: HTMLCanvasElement;
drawCrosshairs = (backgroundColor: string) => {
if (this.crosshairs) {
- let c = this.crosshairs;
- let ctx = c.getContext('2d');
+ let ctx = this.crosshairs.getContext('2d');
if (ctx) {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, 20, 20);
@@ -49,29 +58,26 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
}
}
}
- @computed
+
get sharedCursors() {
- return this.getCursors().map(entry => {
- if (entry.Data.length > 0) {
- let id = entry.Data[0][0];
- let email = entry.Data[0][1];
- let point = entry.Data[1];
- this.drawCrosshairs("#" + v5(id, v5.URL).substring(0, 6).toUpperCase() + "22");
- return (
- <div key={id} className="collectionFreeFormRemoteCursors-cont"
- style={{ transform: `translate(${point[0] - 10}px, ${point[1] - 10}px)` }}
- >
- <canvas className="collectionFreeFormRemoteCursors-canvas"
- ref={(el) => { if (el) this.crosshairs = el; }}
- width={20}
- height={20}
- />
- <p className="collectionFreeFormRemoteCursors-symbol">
- {email[0].toUpperCase()}
- </p>
- </div>
- );
- }
+ return this.getCursors().map(c => {
+ let m = c.data.metadata;
+ let l = c.data.position;
+ this.drawCrosshairs("#" + v5(m.id, v5.URL).substring(0, 6).toUpperCase() + "22");
+ return (
+ <div key={m.id} className="collectionFreeFormRemoteCursors-cont"
+ style={{ transform: `translate(${l.x - 10}px, ${l.y - 10}px)` }}
+ >
+ <canvas className="collectionFreeFormRemoteCursors-canvas"
+ ref={(el) => { if (el) this.crosshairs = el; }}
+ width={20}
+ height={20}
+ />
+ <p className="collectionFreeFormRemoteCursors-symbol">
+ {m.identifier[0].toUpperCase()}
+ </p>
+ </div>
+ );
});
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c1d149098..6861ce58b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -309,7 +309,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
{this.childViews}
</InkingCanvas>
</CollectionFreeFormLinksView>
- {/* <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" /> */}
+ <CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />
</CollectionFreeFormViewPannableContents>
</MarqueeView>
<CollectionFreeFormOverlayView {...this.getDocumentViewProps(this.props.Document)} {...this.props} />
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index d8855fe66..1bf39e335 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -170,7 +170,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
if (this._commandExecuted) {
return;
}
- if (e.key === "Backspace" || e.key === "Delete" || e.key == "d") {
+ if (e.key === "Backspace" || e.key === "Delete" || e.key === "d") {
this._commandExecuted = true;
this.marqueeSelect().map(d => this.props.removeDocument(d));
let ink = Cast(this.props.container.props.Document.ink, InkField);
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 92033ea44..b05f2eea2 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -203,8 +203,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
}
- onPointerEnter = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = true; }
- onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; }
+ onPointerEnter = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = true; };
+ onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; };
borderRounding = () => {
let br = NumCast(this.props.Document.borderRounding);
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index e7fb94777..37dc05ca5 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -100,7 +100,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let titlestr = str.substr(0, Math.min(40, str.length));
let target = this.props.Document.proto ? this.props.Document.proto : this.props.Document;
target.title = "-" + titlestr + (str.length > 40 ? "..." : "");
- };
+ }
}
}
@@ -221,8 +221,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
onPointerDown = (e: React.PointerEvent): void => {
if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) {
e.stopPropagation();
- if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip)
+ if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) {
this._toolTipTextMenu.tooltip.style.opacity = "0";
+ }
}
if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey) {
if (e.target && (e.target as any).href) {
@@ -248,8 +249,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
}
onPointerUp = (e: React.PointerEvent): void => {
- if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip)
+ if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) {
this._toolTipTextMenu.tooltip.style.opacity = "1";
+ }
if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
e.stopPropagation();
}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index eb45ea273..caa66cbeb 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -215,8 +215,9 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
if (e.altKey) {
this._alt = true;
} else {
- if (e.metaKey)
+ if (e.metaKey) {
e.stopPropagation();
+ }
}
document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointerup", this.onPointerUp);
@@ -286,7 +287,7 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
renderHeight = 2400;
@computed
get pdfPage() {
- return <Page height={this.renderHeight} pageNumber={this.curPage} onLoadSuccess={this.onLoaded} />
+ return <Page height={this.renderHeight} pageNumber={this.curPage} onLoadSuccess={this.onLoaded} />;
}
@computed
get pdfContent() {
diff --git a/src/fields/TemplateField.ts b/src/fields/TemplateField.ts
deleted file mode 100644
index 72ae13c2e..000000000
--- a/src/fields/TemplateField.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { BasicField } from "./BasicField";
-import { Types } from "../server/Message";
-import { FieldId } from "./Field";
-import { Template, TemplatePosition } from "../client/views/Templates";
-
-
-export class TemplateField extends BasicField<Array<Template>> {
- constructor(data: Array<Template> = [], id?: FieldId, save: boolean = true) {
- super(data, save, id);
- }
-
- ToScriptString(): string {
- return `new TemplateField("${this.Data}")`;
- }
-
- Copy() {
- return new TemplateField(this.Data);
- }
-
- ToJson() {
- let templates: Array<{ name: string, position: TemplatePosition, layout: string }> = [];
- this.Data.forEach(template => {
- templates.push({ name: template.Name, layout: template.Layout, position: template.Position });
- });
- return {
- type: Types.Templates,
- data: templates,
- id: this.Id,
- };
- }
-
- UpdateFromServer(data: any) {
- this.data = new Array(data);
- }
-
- static FromJson(id: string, data: any): TemplateField {
- let templates: Array<Template> = [];
- data.forEach((template: { name: string, position: number, layout: string }) => {
- templates.push(new Template(template.name, template.position, template.layout));
- });
- return new TemplateField(templates, id, false);
- }
-} \ No newline at end of file
diff --git a/src/new_fields/CursorField.ts b/src/new_fields/CursorField.ts
new file mode 100644
index 000000000..7fd326a5f
--- /dev/null
+++ b/src/new_fields/CursorField.ts
@@ -0,0 +1,55 @@
+import { ObjectField, Copy, OnUpdate } from "./ObjectField";
+import { observable } from "mobx";
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, createSimpleSchema, object } from "serializr";
+
+export type CursorPosition = {
+ x: number,
+ y: number
+}
+
+export type CursorMetadata = {
+ id: string,
+ identifier: string
+}
+
+export type CursorData = {
+ metadata: CursorMetadata,
+ position: CursorPosition
+}
+
+const PositionSchema = createSimpleSchema({
+ x: true,
+ y: true
+});
+
+const MetadataSchema = createSimpleSchema({
+ id: true,
+ identifier: true
+});
+
+const CursorSchema = createSimpleSchema({
+ metadata: object(MetadataSchema),
+ position: object(PositionSchema)
+});
+
+@Deserializable("cursor")
+export default class CursorField extends ObjectField {
+
+ @serializable(object(CursorSchema))
+ readonly data: CursorData;
+
+ constructor(data: CursorData) {
+ super();
+ this.data = data;
+ }
+
+ setPosition(position: CursorPosition) {
+ this.data.position = position;
+ this[OnUpdate]();
+ }
+
+ [Copy]() {
+ return new CursorField(this.data);
+ }
+} \ No newline at end of file
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index afcf71fc9..f844dad6e 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -25,7 +25,7 @@ export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<Extract
export const Update = Symbol("Update");
export const Self = Symbol("Self");
-const SelfProxy = Symbol("SelfProxy");
+export const SelfProxy = Symbol("SelfProxy");
export const WidthSym = Symbol("Width");
export const HeightSym = Symbol("Height");
diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts
index 86a8bd18a..2d75f8a19 100644
--- a/src/new_fields/InkField.ts
+++ b/src/new_fields/InkField.ts
@@ -1,8 +1,6 @@
import { Deserializable } from "../client/util/SerializationHelper";
import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
import { ObjectField, Copy } from "./ObjectField";
-import { number } from "prop-types";
-import { any } from "bluebird";
import { deepCopy } from "../Utils";
export enum InkTool {
@@ -11,6 +9,7 @@ export enum InkTool {
Highlighter,
Eraser
}
+
export interface StrokeData {
pathData: Array<{ x: number, y: number }>;
color: string;
@@ -39,6 +38,6 @@ export class InkField extends ObjectField {
}
[Copy]() {
- return new InkField(deepCopy(this.inkData))
+ return new InkField(deepCopy(this.inkData));
}
}
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 5aba64406..88a65eba4 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -1,9 +1,9 @@
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
-import { Field, Update, Self, FieldResult } from "./Doc";
-import { setter, getter, deleteProperty } from "./util";
+import { Field, Update, Self, FieldResult, SelfProxy } from "./Doc";
+import { setter, getter, deleteProperty, updateFunction } from "./util";
import { serializable, alias, list } from "serializr";
import { observable, action } from "mobx";
-import { ObjectField, OnUpdate, Copy } from "./ObjectField";
+import { ObjectField, OnUpdate, Copy, Parent } from "./ObjectField";
import { RefField } from "./RefField";
import { ProxyField } from "./Proxy";
@@ -27,7 +27,17 @@ const listHandlers: any = {
},
push: action(function (this: any, ...items: any[]) {
items = items.map(toObjectField);
- const res = this[Self].__fields.push(...items);
+ const list = this[Self];
+ const length = list.__fields.length;
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ //TODO Error checking to make sure parent doesn't already exist
+ if (item instanceof ObjectField) {
+ item[Parent] = list;
+ item[OnUpdate] = updateFunction(list, i + length, item, this);
+ }
+ }
+ const res = list.__fields.push(...items);
this[Update]();
return res;
}),
@@ -48,12 +58,33 @@ const listHandlers: 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);
+ const list = this[Self];
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ //TODO Error checking to make sure parent doesn't already exist
+ //TODO Need to change indices of other fields in array
+ if (item instanceof ObjectField) {
+ item[Parent] = list;
+ item[OnUpdate] = updateFunction(list, i + start, item, this);
+ }
+ }
+ const res = list.__fields.splice(start, deleteCount, ...items);
this[Update]();
return res.map(toRealField);
}),
unshift(...items: any[]) {
items = items.map(toObjectField);
+ const list = this[Self];
+ const length = list.__fields.length;
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ //TODO Error checking to make sure parent doesn't already exist
+ //TODO Need to change indices of other fields in array
+ if (item instanceof ObjectField) {
+ item[Parent] = list;
+ item[OnUpdate] = updateFunction(list, i, item, this);
+ }
+ }
const res = this[Self].__fields.unshift(...items);
this[Update]();
return res;
@@ -202,6 +233,7 @@ class ListImpl<T extends Field> extends ObjectField {
deleteProperty: deleteProperty,
defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
});
+ this[SelfProxy] = list;
(list as any).push(...fields);
return list;
}
@@ -215,6 +247,12 @@ class ListImpl<T extends Field> extends ObjectField {
private set __fields(value) {
this.___fields = value;
+ for (const key in value) {
+ const field = value[key];
+ if (!(field instanceof ObjectField)) continue;
+ (field as ObjectField)[Parent] = this[Self];
+ (field as ObjectField)[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
+ }
}
[Copy]() {
@@ -235,6 +273,7 @@ class ListImpl<T extends Field> extends ObjectField {
}
private [Self] = this;
+ private [SelfProxy]: any;
}
export type List<T extends Field> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[];
export const List: { new <T extends Field>(fields?: T[]): List<T> } = ListImpl as any; \ No newline at end of file
diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts
index 0f3777af6..f276bfa67 100644
--- a/src/new_fields/ObjectField.ts
+++ b/src/new_fields/ObjectField.ts
@@ -1,12 +1,13 @@
import { Doc } from "./Doc";
+import { RefField } from "./RefField";
export const OnUpdate = Symbol("OnUpdate");
export const Parent = Symbol("Parent");
export const Copy = Symbol("Copy");
export abstract class ObjectField {
- protected [OnUpdate]?: (diff?: any) => void;
- private [Parent]?: Doc;
+ protected [OnUpdate](diff?: any) { };
+ private [Parent]?: RefField | ObjectField;
abstract [Copy](): ObjectField;
}