aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/DocumentManager.ts78
-rw-r--r--src/client/util/DragManager.ts38
-rw-r--r--src/client/util/History.ts4
-rw-r--r--src/client/util/RichTextSchema.tsx16
-rw-r--r--src/client/util/Scripting.ts10
-rw-r--r--src/client/util/SearchUtil.ts5
-rw-r--r--src/client/util/SelectionManager.ts51
-rw-r--r--src/client/util/SerializationHelper.ts14
-rw-r--r--src/client/util/TooltipTextMenu.tsx8
-rw-r--r--src/client/util/type_decls.d161
10 files changed, 206 insertions, 179 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 51f5fbe9f..ff0c1560b 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,11 +1,14 @@
import { computed, observable } from 'mobx';
import { DocumentView } from '../views/nodes/DocumentView';
-import { Doc, DocListCast } from '../../new_fields/Doc';
+import { Doc, DocListCast, Opt } from '../../new_fields/Doc';
import { FieldValue, Cast, NumCast, BoolCast } from '../../new_fields/Types';
import { listSpec } from '../../new_fields/Schema';
import { undoBatch } from './UndoManager';
import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { Id } from '../../new_fields/RefField';
+import { CollectionView } from '../views/collections/CollectionView';
+import { CollectionPDFView } from '../views/collections/CollectionPDFView';
+import { CollectionVideoView } from '../views/collections/CollectionVideoView';
+import { Id } from '../../new_fields/FieldSymbols';
export class DocumentManager {
@@ -27,31 +30,33 @@ export class DocumentManager {
// this.DocumentViews = new Array<DocumentView>();
}
- public getDocumentViewById(id: string): DocumentView | null {
+ public getDocumentViewById(id: string, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | null {
let toReturn: DocumentView | null = null;
+ let passes = preferredCollection ? [preferredCollection, undefined] : [undefined];
- //gets document view that is in a freeform canvas collection
- DocumentManager.Instance.DocumentViews.map(view => {
- if (view.props.Document[Id] === id) {
- toReturn = view;
- return;
- }
- });
- if (!toReturn) {
+ for (let i = 0; i < passes.length; i++) {
DocumentManager.Instance.DocumentViews.map(view => {
- let doc = view.props.Document.proto;
- if (doc && doc[Id] === id) {
+ if (view.props.Document[Id] === id && (!passes[i] || view.props.ContainingCollectionView === preferredCollection)) {
toReturn = view;
+ return;
}
});
+ if (!toReturn) {
+ DocumentManager.Instance.DocumentViews.map(view => {
+ let doc = view.props.Document.proto;
+ if (doc && doc[Id] === id && (!passes[i] || view.props.ContainingCollectionView === preferredCollection)) {
+ toReturn = view;
+ }
+ });
+ }
}
return toReturn;
}
- public getDocumentView(toFind: Doc): DocumentView | null {
- return this.getDocumentViewById(toFind[Id]);
+ public getDocumentView(toFind: Doc, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | null {
+ return this.getDocumentViewById(toFind[Id], preferredCollection);
}
public getDocumentViews(toFind: Doc): DocumentView[] {
@@ -110,26 +115,51 @@ export class DocumentManager {
}
@undoBatch
- public jumpToDocument = async (doc: Doc): Promise<void> => {
- const page = NumCast(doc.page, undefined);
+ public jumpToDocument = async (docDelegate: Doc, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number, docContext?: Doc): Promise<void> => {
+ let doc = Doc.GetProto(docDelegate);
const contextDoc = await Cast(doc.annotationOn, Doc);
if (contextDoc) {
+ const page = NumCast(doc.page, linkPage || 0);
const curPage = NumCast(contextDoc.curPage, page);
if (page !== curPage) contextDoc.curPage = page;
}
- let docView = DocumentManager.Instance.getDocumentView(doc);
- if (docView) {
+
+ let docView: DocumentView | null;
+ // using forceDockFunc as a flag for splitting linked to doc to the right...can change later if needed
+ if (!forceDockFunc && (docView = DocumentManager.Instance.getDocumentView(doc))) {
+ docView.props.Document.libraryBrush = true;
+ if (linkPage !== undefined) docView.props.Document.curPage = linkPage;
docView.props.focus(docView.props.Document);
} else {
if (!contextDoc) {
- CollectionDockingView.Instance.AddRightSplit(Doc.MakeDelegate(doc));
+ if (docContext) {
+ let targetContextView: DocumentView | null;
+ if (!forceDockFunc && docContext && (targetContextView = DocumentManager.Instance.getDocumentView(docContext))) {
+ docContext.panTransformType = "Ease";
+ targetContextView.props.focus(docDelegate);
+ } else {
+ (dockFunc || CollectionDockingView.Instance.AddRightSplit)(docContext);
+ setTimeout(() => {
+ this.jumpToDocument(docDelegate, forceDockFunc, dockFunc, linkPage);
+ }, 10);
+ }
+ } else {
+ const actualDoc = Doc.MakeAlias(docDelegate);
+ actualDoc.libraryBrush = true;
+ if (linkPage !== undefined) actualDoc.curPage = linkPage;
+ (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc);
+ }
} else {
- let contextView = DocumentManager.Instance.getDocumentView(contextDoc);
- if (contextView) {
+ let contextView: DocumentView | null;
+ docDelegate.libraryBrush = true;
+ if (!forceDockFunc && (contextView = DocumentManager.Instance.getDocumentView(contextDoc))) {
contextDoc.panTransformType = "Ease";
- contextView.props.focus(contextDoc);
+ contextView.props.focus(docDelegate);
} else {
- CollectionDockingView.Instance.AddRightSplit(contextDoc);
+ (dockFunc || CollectionDockingView.Instance.AddRightSplit)(contextDoc);
+ setTimeout(() => {
+ this.jumpToDocument(docDelegate, forceDockFunc, dockFunc, linkPage);
+ }, 10);
}
}
}
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 29f0bc557..ab00fabe1 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,13 +1,14 @@
-import { action, runInAction } from "mobx";
+import { action, runInAction, observable } from "mobx";
import { Doc, DocListCastAsync } from "../../new_fields/Doc";
import { Cast } from "../../new_fields/Types";
import { emptyFunction } from "../../Utils";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import * as globalCssVariables from "../views/globalCssVariables.scss";
import { URLField } from "../../new_fields/URLField";
+import { SelectionManager } from "./SelectionManager";
export type dropActionType = "alias" | "copy" | undefined;
-export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: () => Doc | Promise<Doc>, moveFunc?: DragManager.MoveFunction, dropAction?: dropActionType) {
+export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: () => Doc | Promise<Doc>, moveFunc?: DragManager.MoveFunction, dropAction?: dropActionType, options?: any, dontHideOnDrop?: boolean) {
let onRowMove = async (e: PointerEvent) => {
e.stopPropagation();
e.preventDefault();
@@ -17,6 +18,8 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
var dragData = new DragManager.DocumentDragData([await docFunc()]);
dragData.dropAction = dropAction;
dragData.moveDocument = moveFunc;
+ dragData.options = options;
+ dragData.dontHideOnDrop = dontHideOnDrop;
DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
};
let onRowUp = (): void => {
@@ -27,7 +30,7 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
// if (this.props.isSelected() || this.props.isTopMost) {
if (e.button === 0) {
e.stopPropagation();
- if (e.shiftKey) {
+ if (e.shiftKey && CollectionDockingView.Instance) {
CollectionDockingView.Instance.StartOtherDrag([await docFunc()], e);
} else {
document.addEventListener("pointermove", onRowMove);
@@ -42,7 +45,7 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc) {
let srcTarg = sourceDoc.proto;
let draggedDocs: Doc[] = [];
- let draggedFromDocs: Doc[] = []
+ let draggedFromDocs: Doc[] = [];
if (srcTarg) {
let linkToDocs = await DocListCastAsync(srcTarg.linkedToDocs);
let linkFromDocs = await DocListCastAsync(srcTarg.linkedFromDocs);
@@ -182,10 +185,10 @@ export namespace DragManager {
export class EmbedDragData {
constructor(embeddableSourceDoc: Doc) {
this.embeddableSourceDoc = embeddableSourceDoc;
- this.urlField = Cast(embeddableSourceDoc.data, URLField)!;
+ this.urlField = embeddableSourceDoc.data instanceof URLField ? embeddableSourceDoc.data : undefined;
}
embeddableSourceDoc: Doc;
- urlField: URLField;
+ urlField?: URLField;
[id: string]: any;
}
@@ -200,13 +203,14 @@ export namespace DragManager {
export let AbortDrag: () => void = emptyFunction;
function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
+ eles = eles.filter(e => e);
if (!dragDiv) {
dragDiv = document.createElement("div");
dragDiv.className = "dragManager-dragDiv";
dragDiv.style.pointerEvents = "none";
DragManager.Root().appendChild(dragDiv);
}
-
+ SelectionManager.SetIsDragging(true);
let scaleXs: number[] = [];
let scaleYs: number[] = [];
let xs: number[] = [];
@@ -256,6 +260,13 @@ export namespace DragManager {
// pdfBox.replaceChild(img, pdfBox.children[0])
// }
// }
+ let set = dragElement.getElementsByTagName('*');
+ for (let i = 0; i < set.length; i++)
+ if (set[i].hasAttribute("style")) {
+ let s = set[i];
+ (s as any).style.pointerEvents = "none";
+ }
+
dragDiv.appendChild(dragElement);
return dragElement;
@@ -274,12 +285,11 @@ export namespace DragManager {
let lastX = downX;
let lastY = downY;
const moveHandler = (e: PointerEvent) => {
- e.stopPropagation();
- e.preventDefault();
+ e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop
if (dragData instanceof DocumentDragData) {
dragData.userDropAction = e.ctrlKey || e.altKey ? "alias" : undefined;
}
- if (e.shiftKey) {
+ if (e.shiftKey && CollectionDockingView.Instance) {
AbortDrag();
CollectionDockingView.Instance.StartOtherDrag(docs, {
pageX: e.pageX,
@@ -294,12 +304,12 @@ export namespace DragManager {
lastX = e.pageX;
lastY = e.pageY;
dragElements.map((dragElement, i) => (dragElement.style.transform =
- `translate(${(xs[i] += moveX)}px, ${(ys[i] += moveY)}px)
- scale(${scaleXs[i]}, ${scaleYs[i]})`)
+ `translate(${(xs[i] += moveX)}px, ${(ys[i] += moveY)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`)
);
};
let hideDragElements = () => {
+ SelectionManager.SetIsDragging(false);
dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
eles.map(ele => (ele.hidden = false));
};
@@ -325,7 +335,7 @@ export namespace DragManager {
}
function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
- let removed = dragEles.map(dragEle => {
+ let removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
// let parent = dragEle.parentElement;
// if (parent) parent.removeChild(dragEle);
let ret = [dragEle, dragEle.style.width, dragEle.style.height];
@@ -351,7 +361,7 @@ export namespace DragManager {
x: e.x,
y: e.y,
data: dragData,
- mods: e.ctrlKey ? "Control" : ""
+ mods: e.altKey ? "AltKey" : ""
}
})
);
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index 92d2b2b44..545ea8629 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -1,7 +1,7 @@
import { Doc, Opt, Field } from "../../new_fields/Doc";
import { DocServer } from "../DocServer";
-import { Main } from "../views/Main";
import { RouteStore } from "../../server/RouteStore";
+import { MainView } from "../views/MainView";
export namespace HistoryUtil {
export interface DocInitializerList {
@@ -114,7 +114,7 @@ export namespace HistoryUtil {
const field = await DocServer.GetRefField(url.docId);
await Promise.all(Object.keys(url.initializers).map(id => initDoc(id, url.initializers[id])));
if (field instanceof Doc) {
- Main.Instance.openWorkspace(field, true);
+ MainView.Instance.openWorkspace(field, true);
}
}
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 742ac5434..2b82a09a2 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -97,13 +97,13 @@ export const nodes: { [index: string]: NodeSpec } = {
title: dom.getAttribute("title"),
alt: dom.getAttribute("alt"),
width: Math.min(100, Number(dom.getAttribute("width"))),
- }
+ };
}
}],
// TODO if we don't define toDom, something weird happens: dragging the image will not move it but clone it. Why?
toDOM(node) {
- const attrs = { style: `width: ${node.attrs.width}` }
- return ["img", { ...node.attrs, ...attrs }]
+ const attrs = { style: `width: ${node.attrs.width}` };
+ return ["img", { ...node.attrs, ...attrs }];
}
},
@@ -401,7 +401,7 @@ export class ImageResizeView {
const currentX = e.pageX;
const diffInPx = currentX - startX;
self._outer.style.width = `${startWidth + diffInPx}`;
- }
+ };
const onpointerup = () => {
document.removeEventListener("pointermove", onpointermove);
@@ -410,11 +410,11 @@ export class ImageResizeView {
view.state.tr.setNodeMarkup(getPos(), null,
{ src: node.attrs.src, width: self._outer.style.width })
.setSelection(view.state.selection));
- }
+ };
- document.addEventListener("pointermove", onpointermove)
- document.addEventListener("pointerup", onpointerup)
- }
+ document.addEventListener("pointermove", onpointermove);
+ document.addEventListener("pointerup", onpointerup);
+ };
this._outer.appendChild(this._handle);
this._outer.appendChild(this._img);
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index e45f61c11..40e2ad6bb 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -12,6 +12,7 @@ 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';
+import { ScriptField, ComputedField } from '../../fields/ScriptField';
export interface ScriptSucccess {
success: true;
@@ -41,11 +42,11 @@ export type CompileResult = CompiledScript | CompileError;
function Run(script: string | undefined, customParams: string[], diagnostics: any[], originalScript: string, options: ScriptOptions): CompileResult {
const errors = diagnostics.some(diag => diag.category === ts.DiagnosticCategory.Error);
- if (errors || !script) {
+ if ((options.typecheck !== false && errors) || !script) {
return { compiled: false, errors: diagnostics };
}
- let fieldTypes = [Doc, ImageField, PdfField, VideoField, AudioField, List, RichTextField];
+ let fieldTypes = [Doc, ImageField, PdfField, VideoField, AudioField, List, RichTextField, ScriptField, ComputedField, CompileScript];
let paramNames = ["Docs", ...fieldTypes.map(fn => fn.name)];
let params: any[] = [Docs, ...fieldTypes];
let compiledFunction = new Function(...paramNames, `return ${script}`);
@@ -131,10 +132,11 @@ export interface ScriptOptions {
addReturn?: boolean;
params?: { [name: string]: string };
capturedVariables?: { [name: string]: Field };
+ typecheck?: boolean;
}
export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult {
- const { requiredType = "", addReturn = false, params = {}, capturedVariables = {} } = options;
+ const { requiredType = "", addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options;
let host = new ScriptingCompilerHost;
let paramNames: string[] = [];
if ("this" in params || "this" in capturedVariables) {
@@ -158,7 +160,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
${addReturn ? `return ${script};` : script}
})`;
host.writeFile("file.ts", funcScript);
- host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
+ if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
let program = ts.createProgram(["file.ts"], {}, host);
let testResult = program.emit();
let outputText = host.readFile("file.js");
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 4ccff0d1b..28ec8ca14 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -1,7 +1,7 @@
import * as rp from 'request-promise';
import { DocServer } from '../DocServer';
import { Doc } from '../../new_fields/Doc';
-import { Id } from '../../new_fields/RefField';
+import { Id } from '../../new_fields/FieldSymbols';
export namespace SearchUtil {
export function Search(query: string, returnDocs: true): Promise<Doc[]>;
@@ -20,6 +20,7 @@ export namespace SearchUtil {
export async function GetAliasesOfDocument(doc: Doc): Promise<Doc[]> {
const proto = await Doc.GetT(doc, "proto", Doc, true);
const protoId = (proto || doc)[Id];
- return Search(`{!join from=id to=proto_i}id:${protoId}`, true);
+ return Search(`proto_i:"${protoId}"`, true);
+ // return Search(`{!join from=id to=proto_i}id:${protoId}`, true);
}
} \ No newline at end of file
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 8c92c2023..b26032b04 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,4 +1,4 @@
-import { observable, action } from "mobx";
+import { observable, action, runInAction } from "mobx";
import { Doc } from "../../new_fields/Doc";
import { DocumentView } from "../views/nodes/DocumentView";
import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
@@ -6,44 +6,44 @@ import { NumCast } from "../../new_fields/Types";
export namespace SelectionManager {
class Manager {
- @observable
- SelectedDocuments: Array<DocumentView> = [];
+ @observable IsDragging: boolean = false;
+ @observable SelectedDocuments: Array<DocumentView> = [];
@action
- SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
+ SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
// if doc is not in SelectedDocuments, add it
if (!ctrlPressed) {
this.DeselectAll();
}
- if (manager.SelectedDocuments.indexOf(doc) === -1) {
- manager.SelectedDocuments.push(doc);
- doc.props.whenActiveChanged(true);
+ if (manager.SelectedDocuments.indexOf(docView) === -1) {
+ manager.SelectedDocuments.push(docView);
+ docView.props.whenActiveChanged(true);
+ }
+ }
+ @action
+ DeselectDoc(docView: DocumentView): void {
+ let ind = manager.SelectedDocuments.indexOf(docView);
+ if (ind !== -1) {
+ manager.SelectedDocuments.splice(ind, 1);
+ docView.props.whenActiveChanged(false);
}
}
-
@action
DeselectAll(): void {
manager.SelectedDocuments.map(dv => dv.props.whenActiveChanged(false));
manager.SelectedDocuments = [];
FormattedTextBox.InputBoxOverlay = undefined;
}
- @action
- ReselectAll() {
- let sdocs = manager.SelectedDocuments.map(d => d);
- manager.SelectedDocuments = [];
- return sdocs;
- }
- @action
- ReselectAll2(sdocs: DocumentView[]) {
- sdocs.map(s => SelectionManager.SelectDoc(s, true));
- }
}
const manager = new Manager();
- export function SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
- manager.SelectDoc(doc, ctrlPressed);
+ export function DeselectDoc(docView: DocumentView): void {
+ manager.DeselectDoc(docView);
+ }
+ export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
+ manager.SelectDoc(docView, ctrlPressed);
}
export function IsSelected(doc: DocumentView): boolean {
@@ -62,14 +62,13 @@ export namespace SelectionManager {
if (found) manager.SelectDoc(found, false);
}
- export function ReselectAll() {
- let sdocs = manager.ReselectAll();
- setTimeout(() => manager.ReselectAll2(sdocs), 0);
- }
+ export function SetIsDragging(dragging: boolean) { runInAction(() => manager.IsDragging = dragging); }
+ export function GetIsDragging() { return manager.IsDragging; }
+
export function SelectedDocuments(): Array<DocumentView> {
return manager.SelectedDocuments;
}
- export function ViewsSortedVertically(): DocumentView[] {
+ export function ViewsSortedHorizontally(): DocumentView[] {
let sorted = SelectionManager.SelectedDocuments().slice().sort((doc1, doc2) => {
if (NumCast(doc1.props.Document.x) > NumCast(doc2.props.Document.x)) return 1;
if (NumCast(doc1.props.Document.x) < NumCast(doc2.props.Document.x)) return -1;
@@ -77,7 +76,7 @@ export namespace SelectionManager {
});
return sorted;
}
- export function ViewsSortedHorizontally(): DocumentView[] {
+ export function ViewsSortedVertically(): DocumentView[] {
let sorted = SelectionManager.SelectedDocuments().slice().sort((doc1, doc2) => {
if (NumCast(doc1.props.Document.y) > NumCast(doc2.props.Document.y)) return 1;
if (NumCast(doc1.props.Document.y) < NumCast(doc2.props.Document.y)) return -1;
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 7ded85e43..a7246d7c4 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -45,13 +45,17 @@ export namespace SerializationHelper {
throw Error(`type '${obj.__type}' not registered. Make sure you register it using a @Deserializable decorator`);
}
- const value = deserialize(serializationTypes[obj.__type], obj);
+ const type = serializationTypes[obj.__type];
+ const value = deserialize(type.ctor, obj);
+ if (type.afterDeserialize) {
+ type.afterDeserialize(value);
+ }
serializing -= 1;
return value;
}
}
-let serializationTypes: { [name: string]: any } = {};
+let serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void } } = {};
let reverseMap: { [ctor: string]: string } = {};
export interface DeserializableOpts {
@@ -59,9 +63,9 @@ export interface DeserializableOpts {
withFields(fields: string[]): Function;
}
-export function Deserializable(name: string): DeserializableOpts;
+export function Deserializable(name: string, afterDeserialize?: (obj: any) => void): DeserializableOpts;
export function Deserializable(constructor: { new(...args: any[]): any }): void;
-export function Deserializable(constructor: { new(...args: any[]): any } | string): DeserializableOpts | void {
+export function Deserializable(constructor: { new(...args: any[]): any } | string, afterDeserialize?: (obj: any) => void): DeserializableOpts | void {
function addToMap(name: string, ctor: { new(...args: any[]): any }) {
const schema = getDefaultModelSchema(ctor) as any;
if (schema.targetClass !== ctor) {
@@ -69,7 +73,7 @@ export function Deserializable(constructor: { new(...args: any[]): any } | strin
setDefaultModelSchema(ctor, newSchema);
}
if (!(name in serializationTypes)) {
- serializationTypes[name] = ctor;
+ serializationTypes[name] = { ctor, afterDeserialize };
reverseMap[ctor.name] = name;
} else {
throw new Error(`Name ${name} has already been registered as deserializable`);
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index b860f6758..ab6cd246a 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -23,12 +23,12 @@ const { openPrompt, TextField } = require("./ProsemirrorCopy/prompt.js");
import { View } from "@react-pdf/renderer";
import { DragManager } from "./DragManager";
import { Doc, Opt, Field } from "../../new_fields/Doc";
-import { Id } from "../../new_fields/RefField";
import { Utils } from "../northstar/utils/Utils";
import { DocServer } from "../DocServer";
import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import { DocumentManager } from "./DocumentManager";
+import { Id } from "../../new_fields/FieldSymbols";
const SVG = "http://www.w3.org/2000/svg";
@@ -196,7 +196,6 @@ export class TooltipTextMenu {
let node = this.view.state.selection.$from.nodeAfter;
let link = node && node.marks.find(m => m.type.name === "link");
if (link) {
- console.log("Link to : " + link.attrs.href);
let href: string = link.attrs.href;
if (href.indexOf(DocServer.prepend("/doc/")) === 0) {
let docid = href.replace(DocServer.prepend("/doc/"), "");
@@ -205,10 +204,11 @@ export class TooltipTextMenu {
if (DocumentManager.Instance.getDocumentView(f)) {
DocumentManager.Instance.getDocumentView(f)!.props.focus(f);
}
- else CollectionDockingView.Instance.AddRightSplit(f);
+ else if (CollectionDockingView.Instance) CollectionDockingView.Instance.AddRightSplit(f);
}
}));
}
+ // TODO This should have an else to handle external links
e.stopPropagation();
e.preventDefault();
}
@@ -227,7 +227,7 @@ export class TooltipTextMenu {
{
handlers: {
dragComplete: action(() => {
- let m = dragData.droppedDocuments as Doc[];
+ let m = dragData.droppedDocuments;
this.makeLink(DocServer.prepend("/doc/" + m[0][Id]));
}),
},
diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index 47c3481b2..2cbe1dd40 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -119,107 +119,88 @@ interface URL {
username: string;
toJSON(): string;
}
-
-declare type FieldId = string;
-
-declare abstract class Field {
- Id: FieldId;
- abstract ToScriptString(): string;
- abstract TrySetValue(value: any): boolean;
- abstract GetValue(): any;
- abstract Copy(): Field;
+interface PromiseLike<T> {
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
}
-
-declare abstract class BasicField<T> extends Field {
- constructor(data: T);
- Data: T;
- TrySetValue(value: any): boolean;
- GetValue(): any;
+interface Promise<T> {
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
+ catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}
-declare class TextField extends BasicField<string>{
- constructor();
- constructor(data: string);
- ToScriptString(): string;
- Copy(): Field;
-}
-declare class ImageField extends BasicField<URL>{
+declare const Update: unique symbol;
+declare const Self: unique symbol;
+declare const SelfProxy: unique symbol;
+declare const HandleUpdate: unique symbol;
+declare const Id: unique symbol;
+declare const OnUpdate: unique symbol;
+declare const Parent: unique symbol;
+declare const Copy: unique symbol;
+declare const ToScriptString: unique symbol;
+
+declare abstract class RefField {
+ readonly [Id]: FieldId;
+
constructor();
- constructor(data: URL);
- ToScriptString(): string;
- Copy(): Field;
}
-declare class HtmlField extends BasicField<string>{
- constructor();
- constructor(data: string);
- ToScriptString(): string;
- Copy(): Field;
+
+declare type FieldId = string;
+
+declare abstract class ObjectField {
+ abstract [Copy](): ObjectField;
}
-declare class NumberField extends BasicField<number>{
- constructor();
- constructor(data: number);
- ToScriptString(): string;
- Copy(): Field;
+
+declare abstract class URLField extends ObjectField {
+ readonly url: URL;
+
+ constructor(url: string);
+ constructor(url: URL);
}
-declare class WebField extends BasicField<URL>{
+
+declare class AudioField extends URLField { [Copy](): ObjectField; }
+declare class VideoField extends URLField { [Copy](): ObjectField; }
+declare class ImageField extends URLField { [Copy](): ObjectField; }
+declare class WebField extends URLField { [Copy](): ObjectField; }
+declare class PdfField extends URLField { [Copy](): ObjectField; }
+
+declare const ComputedField: any;
+declare const CompileScript: any;
+
+// @ts-ignore
+declare type Extract<T, U> = T extends U ? T : never;
+declare type Field = number | string | boolean | ObjectField | RefField;
+declare type FieldWaiting<T extends RefField = RefField> = T extends undefined ? never : Promise<T | undefined>;
+declare type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<Extract<T, RefField>>;
+
+declare type Opt<T> = T | undefined;
+declare class Doc extends RefField {
constructor();
- constructor(data: URL);
- ToScriptString(): string;
- Copy(): Field;
+
+ [key: string]: FieldResult;
+ // [ToScriptString](): string;
}
-declare class ListField<T> extends BasicField<T[]>{
- constructor();
- constructor(data: T[]);
- ToScriptString(): string;
- Copy(): Field;
-}
-declare class Key extends Field {
- constructor(name:string);
- Name: string;
- TrySetValue(value: any): boolean;
- GetValue(): any;
- Copy(): Field;
- ToScriptString(): string;
-}
-declare type FIELD_WAITING = null;
-declare type Opt<T> = T | undefined;
-declare type FieldValue<T> = Opt<T> | FIELD_WAITING;
-// @ts-ignore
-declare class Document extends Field {
- TrySetValue(value: any): boolean;
- GetValue(): any;
- Copy(): Field;
- ToScriptString(): string;
-
- Width(): number;
- Height(): number;
- Scale(): number;
- Title: string;
-
- Get(key: Key): FieldValue<Field>;
- GetAsync(key: Key, callback: (field: Field) => void): boolean;
- GetOrCreateAsync<T extends Field>(key: Key, ctor: { new(): T }, callback: (field: T) => void): void;
- GetT<T extends Field>(key: Key, ctor: { new(): T }): FieldValue<T>;
- GetOrCreate<T extends Field>(key: Key, ctor: { new(): T }): T;
- GetData<T, U extends Field & { Data: T }>(key: Key, ctor: { new(): U }, defaultVal: T): T;
- GetHtml(key: Key, defaultVal: string): string;
- GetNumber(key: Key, defaultVal: number): number;
- GetText(key: Key, defaultVal: string): string;
- GetList<T extends Field>(key: Key, defaultVal: T[]): T[];
- Set(key: Key, field: Field | undefined): void;
- SetData<T, U extends Field & { Data: T }>(key: Key, value: T, ctor: { new(): U }): void;
- SetText(key: Key, value: string): void;
- SetNumber(key: Key, value: number): void;
- GetPrototype(): FieldValue<Document>;
- GetAllPrototypes(): Document[];
- MakeDelegate(): Document;
-}
-
-declare const KeyStore: {
- [name: string]: Key;
+
+declare class ListImpl<T extends Field> extends ObjectField {
+ constructor(fields?: T[]);
+ [index: number]: T | (T extends RefField ? Promise<T> : never);
+ [Copy](): ObjectField;
}
// @ts-ignore
declare const console: any;
-declare const Documents: any;
+interface DocumentOptions { }
+
+declare const Docs: {
+ ImageDocument(url: string, options?: DocumentOptions): Doc;
+ VideoDocument(url: string, options?: DocumentOptions): Doc;
+ // HistogramDocument(url:string, options?:DocumentOptions);
+ TextDocument(options?: DocumentOptions): Doc;
+ PdfDocument(url: string, options?: DocumentOptions): Doc;
+ WebDocument(url: string, options?: DocumentOptions): Doc;
+ HtmlDocument(html: string, options?: DocumentOptions): Doc;
+ KVPDocument(document: Doc, options?: DocumentOptions): Doc;
+ FreeformDocument(documents: Doc[], options?: DocumentOptions): Doc;
+ SchemaDocument(columns: string[], documents: Doc[], options?: DocumentOptions): Doc;
+ TreeDocument(documents: Doc[], options?: DocumentOptions): Doc;
+ StackingDocument(documents: Doc[], options?: DocumentOptions): Doc;
+};