aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/CurrentUserUtils.ts10
-rw-r--r--src/client/util/DragManager.ts1
-rw-r--r--src/client/util/DropConverter.ts3
-rw-r--r--src/client/util/Import & Export/DirectoryImportBox.tsx36
-rw-r--r--src/client/util/InteractionUtils.tsx34
-rw-r--r--src/client/util/LinkManager.ts3
-rw-r--r--src/client/util/ScriptManager.ts104
-rw-r--r--src/client/util/Scripting.ts66
-rw-r--r--src/client/util/SettingsManager.tsx7
9 files changed, 211 insertions, 53 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 9ce162897..7b867ed02 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -808,6 +808,7 @@ export class CurrentUserUtils {
this.setupDefaultPresentation(doc); // presentation that's initially triggered
await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels
doc.globalLinkDatabase = Docs.Prototypes.MainLinkDocument();
+ doc.globalScriptDatabase = Docs.Prototypes.MainScriptDocument();
// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet
doc["dockedBtn-undo"] && reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(doc["dockedBtn-undo"] as Doc).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true });
@@ -840,6 +841,9 @@ export class CurrentUserUtils {
}
}
-Scripting.addGlobal(function setupMobileInkingDoc(userDoc: Doc) { return CurrentUserUtils.setupMobileInkingDoc(userDoc); });
-Scripting.addGlobal(function setupMobileUploadDoc(userDoc: Doc) { return CurrentUserUtils.setupMobileUploadDoc(userDoc); });
-Scripting.addGlobal(function createNewWorkspace() { return MainView.Instance.createNewWorkspace(); });
+Scripting.addGlobal(function setupMobileInkingDoc(userDoc: Doc) { return CurrentUserUtils.setupMobileInkingDoc(userDoc); },
+ "initializes the Mobile inking document", "(userDoc: Doc)");
+Scripting.addGlobal(function setupMobileUploadDoc(userDoc: Doc) { return CurrentUserUtils.setupMobileUploadDoc(userDoc); },
+ "initializes the Mobile upload document", "(userDoc: Doc)");
+Scripting.addGlobal(function createNewWorkspace() { return MainView.Instance.createNewWorkspace(); },
+ "creates a new workspace when called");
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 597b72e0c..21564c92e 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -134,7 +134,6 @@ export namespace DragManager {
dropAction: dropActionType;
removeDropProperties?: string[];
userDropAction: dropActionType;
- embedDoc?: boolean;
moveDocument?: MoveFunction;
removeDocument?: RemoveFunction;
isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 752c1cfc5..ea1769d85 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -76,4 +76,5 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
data.droppedDocuments[i] = dbox;
});
}
-Scripting.addGlobal(function convertToButtons(dragData: any) { convertDropDataToButtons(dragData as DragManager.DocumentDragData); }); \ No newline at end of file
+Scripting.addGlobal(function convertToButtons(dragData: any) { convertDropDataToButtons(dragData as DragManager.DocumentDragData); },
+ "converts the dropped data to buttons", "(dragData: any)"); \ No newline at end of file
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 25c556697..af6c57e68 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -1,33 +1,33 @@
-import "fs";
-import React = require("react");
-import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../fields/Doc";
-import { action, observable, runInAction, computed, reaction, IReactionDisposer } from "mobx";
-import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
-import Measure, { ContentRect } from "react-measure";
import { library } from '@fortawesome/fontawesome-svg-core';
+import { faCloudUploadAlt, faPlus, faTag } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faTag, faPlus, faCloudUploadAlt } from '@fortawesome/free-solid-svg-icons';
-import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents";
+import { BatchedArray } from "array-batcher";
+import "fs";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from "./ImportMetadataEntry";
-import { Utils } from "../../../Utils";
-import { DocumentManager } from "../DocumentManager";
+import * as path from 'path';
+import Measure, { ContentRect } from "react-measure";
+import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../fields/Doc";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
-import { Cast, BoolCast, NumCast } from "../../../fields/Types";
import { listSpec } from "../../../fields/Schema";
-import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import "./DirectoryImportBox.scss";
-import { Networking } from "../../Network";
-import { BatchedArray } from "array-batcher";
-import * as path from 'path';
+import { BoolCast, Cast, NumCast } from "../../../fields/Types";
import { AcceptibleMedia, Upload } from "../../../server/SharedMediaTypes";
+import { Utils } from "../../../Utils";
+import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
+import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents";
+import { Networking } from "../../Network";
+import { FieldView, FieldViewProps } from "../../views/nodes/FieldView";
+import { DocumentManager } from "../DocumentManager";
+import "./DirectoryImportBox.scss";
+import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from "./ImportMetadataEntry";
+import React = require("react");
const unsupported = ["text/html", "text/plain"];
@observer
-export default class DirectoryImportBox extends React.Component<FieldViewProps> {
+export class DirectoryImportBox extends React.Component<FieldViewProps> {
private selector = React.createRef<HTMLInputElement>();
@observable private top = 0;
@observable private left = 0;
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 81f9b9362..aeb0f670d 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -89,42 +89,40 @@ export namespace InteractionUtils {
return myTouches;
}
- export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: string, bezier: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean) {
- var pts = "";
- if (shape) {
- //if any of the shape are true
- const shapePts = makePolygon(shape, points);
- pts = shapePts.reduce((acc: string, pt: { X: number, Y: number }) => acc + `${pt.X * scalex - left * scalex},${pt.Y * scaley - top * scaley} `, "");
+ export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: number, strokeWidth: number, bezier: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean) {
+ let pts: { X: number; Y: number; }[] = [];
+ if (shape) { //if any of the shape are true
+ pts = makePolygon(shape, points);
}
else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) {
//pointer is up (first and last points are the same)
- const newPoints: number[][] = [];
- const newPts: { X: number; Y: number; }[] = [];
- //convert to [][] for fitcurve module
- for (var i = 0; i < points.length - 1; i++) {
- newPoints.push([points[i].X, points[i].Y]);
- }
+ points.pop();
+ const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]);
+
const bezierCurves = fitCurve(newPoints, parseInt(bezier));
for (var i = 0; i < bezierCurves.length; i++) {
for (var t = 0; t < 1; t += 0.01) {
const point = beziercurve(t, bezierCurves[i]);
- newPts.push({ X: point[0], Y: point[1] });
+ pts.push({ X: point[0], Y: point[1] });
}
}
- pts = newPts.reduce((acc: string, pt: { X: number, Y: number }) => acc + `${pt.X * scalex - left * scalex},${pt.Y * scaley - top * scaley} `, "");
} else {
- //in the middle of drawing
- pts = points.reduce((acc: string, pt: { X: number, Y: number }) => acc + `${pt.X * scalex - left * scalex},${pt.Y * scaley - top * scaley} `, "");
+ pts = points;
}
+ const strpts = pts.reduce((acc: string, pt: { X: number, Y: number }) => acc +
+ `${(pt.X - left - width / 2) * scalex + width / 2},
+ ${(pt.Y - top - width / 2) * scaley + width / 2} `, "");
+
return (
<polyline
- points={pts}
+ points={strpts}
style={{
filter: drawHalo ? "url(#dangerShine)" : undefined,
fill: "none",
+ opacity: strokeWidth !== width ? 0.5 : undefined,
pointerEvents: pevents as any,
stroke: color ?? "rgb(0, 0, 0)",
- strokeWidth: parseInt(width),
+ strokeWidth: strokeWidth,
strokeLinejoin: "round",
strokeLinecap: "round"
}}
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 95528e25a..47b2541bd 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -205,4 +205,5 @@ export class LinkManager {
}
}
-Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }); \ No newline at end of file
+Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
+ "creates a link to inputted document", "(doc: any)"); \ No newline at end of file
diff --git a/src/client/util/ScriptManager.ts b/src/client/util/ScriptManager.ts
new file mode 100644
index 000000000..785e63d9a
--- /dev/null
+++ b/src/client/util/ScriptManager.ts
@@ -0,0 +1,104 @@
+import { Doc, DocListCast } from "../../fields/Doc";
+import { List } from "../../fields/List";
+import { Scripting } from "./Scripting";
+import { StrCast, Cast } from "../../fields/Types";
+import { listSpec } from "../../fields/Schema";
+import { Docs } from "../documents/Documents";
+
+export class ScriptManager {
+
+ static _initialized = false;
+ private static _instance: ScriptManager;
+ public static get Instance(): ScriptManager {
+ return this._instance || (this._instance = new this());
+ }
+ private constructor() {
+ if (!ScriptManager._initialized) {
+ ScriptManager._initialized = true;
+ this.getAllScripts().forEach(scriptDoc => ScriptManager.addScriptToGlobals(scriptDoc));
+ }
+ }
+
+ public get ScriptManagerDoc(): Doc | undefined {
+ return Docs.Prototypes.MainScriptDocument();
+ }
+ public getAllScripts(): Doc[] {
+ const sdoc = ScriptManager.Instance.ScriptManagerDoc;
+ if (sdoc) {
+ const docs = DocListCast(sdoc.data);
+ return docs;
+ }
+ return [];
+ }
+
+ public addScript(scriptDoc: Doc): boolean {
+
+ console.log("in add script method");
+
+ const scriptList = this.getAllScripts();
+ scriptList.push(scriptDoc);
+ if (ScriptManager.Instance.ScriptManagerDoc) {
+ ScriptManager.Instance.ScriptManagerDoc.data = new List<Doc>(scriptList);
+ ScriptManager.addScriptToGlobals(scriptDoc);
+ console.log("script added");
+ return true;
+ }
+ return false;
+ }
+
+ public deleteScript(scriptDoc: Doc): boolean {
+
+ console.log("in delete script method");
+
+ if (scriptDoc.name) {
+ Scripting.removeGlobal(StrCast(scriptDoc.name));
+ }
+ const scriptList = this.getAllScripts();
+ const index = scriptList.indexOf(scriptDoc);
+ if (index > -1) {
+ scriptList.splice(index, 1);
+ if (ScriptManager.Instance.ScriptManagerDoc) {
+ ScriptManager.Instance.ScriptManagerDoc.data = new List<Doc>(scriptList);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static addScriptToGlobals(scriptDoc: Doc): void {
+
+ Scripting.removeGlobal(StrCast(scriptDoc.name));
+
+ const params = Cast(scriptDoc["data-params"], listSpec("string"), []);
+ console.log(params);
+ const paramNames = params.reduce((o: string, p: string) => {
+ if (params.indexOf(p) === params.length - 1) {
+ o = o + p.split(":")[0].trim();
+ } else {
+ o = o + p.split(":")[0].trim() + ",";
+ }
+ return o;
+ }, "" as string);
+
+ const f = new Function(paramNames, StrCast(scriptDoc.script));
+
+ console.log(scriptDoc.script);
+
+ Object.defineProperty(f, 'name', { value: StrCast(scriptDoc.name), writable: false });
+
+ let parameters = "(";
+ params.forEach((element: string, i: number) => {
+ if (i === params.length - 1) {
+ parameters = parameters + element + ")";
+ } else {
+ parameters = parameters + element + ", ";
+ }
+ });
+
+ if (parameters === "(") {
+ Scripting.addGlobal(f, StrCast(scriptDoc.description));
+ } else {
+ Scripting.addGlobal(f, StrCast(scriptDoc.description), parameters);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index ab577315c..e6cf50de3 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -10,6 +10,8 @@ export { ts };
// @ts-ignore
import * as typescriptlib from '!!raw-loader!./type_decls.d';
import { Doc, Field } from '../../fields/Doc';
+import { Cast } from "../../fields/Types";
+import { listSpec } from "../../fields/Schema";
export interface ScriptSucccess {
success: true;
@@ -49,19 +51,34 @@ export function isCompileError(toBeDetermined: CompileResult): toBeDetermined is
export namespace Scripting {
export function addGlobal(global: { name: string }): void;
export function addGlobal(name: string, global: any): void;
- export function addGlobal(nameOrGlobal: any, global?: any) {
- let n: string;
+
+ export function addGlobal(global: { name: string }, decription?: string, params?: string): void;
+
+ export function addGlobal(first: any, second?: any, third?: string) {
+ let n: any;
let obj: any;
- if (global !== undefined && typeof nameOrGlobal === "string") {
- n = nameOrGlobal;
- obj = global;
- } else if (nameOrGlobal && typeof nameOrGlobal.name === "string") {
- n = nameOrGlobal.name;
- obj = nameOrGlobal;
+
+ if (second !== undefined) {
+ if (typeof first === "string") {
+ n = first;
+ obj = second;
+ } else {
+ obj = first;
+ n = first.name;
+ _scriptingDescriptions[n] = second;
+ if (third !== undefined) {
+ _scriptingParams[n] = third;
+ }
+ }
+ } else if (first && typeof first.name === "string") {
+ n = first.name;
+ obj = first;
} else {
throw new Error("Must either register an object with a name, or give a name and an object");
}
- if (_scriptingGlobals.hasOwnProperty(n)) {
+ if (n === undefined || n === "undefined") {
+ return false;
+ } else if (_scriptingGlobals.hasOwnProperty(n)) {
throw new Error(`Global with name ${n} is already registered, choose another name`);
}
_scriptingGlobals[n] = obj;
@@ -75,6 +92,20 @@ export namespace Scripting {
scriptingGlobals = globals;
}
+ export function removeGlobal(name: string) {
+ if (getGlobals().includes(name)) {
+ delete _scriptingGlobals[name];
+ if (_scriptingDescriptions[name]){
+ delete _scriptingDescriptions[name];
+ }
+ if (_scriptingParams[name]){
+ delete _scriptingParams[name];
+ }
+ return true;
+ }
+ return false;
+ }
+
export function resetScriptingGlobals() {
scriptingGlobals = _scriptingGlobals;
}
@@ -85,7 +116,19 @@ export namespace Scripting {
}
export function getGlobals() {
- return Object.keys(scriptingGlobals);
+ return Object.keys(_scriptingGlobals);
+ }
+
+ export function getGlobalObj() {
+ return _scriptingGlobals;
+ }
+
+ export function getDescriptions(){
+ return _scriptingDescriptions;
+ }
+
+ export function getParameters(){
+ return _scriptingParams;
}
}
@@ -95,6 +138,8 @@ export function scriptingGlobal(constructor: { new(...args: any[]): any }) {
const _scriptingGlobals: { [name: string]: any } = {};
let scriptingGlobals: { [name: string]: any } = _scriptingGlobals;
+const _scriptingDescriptions: { [name: string]: any } = {};
+const _scriptingParams: { [name: string]: any } = {};
function Run(script: string | undefined, customParams: string[], diagnostics: any[], originalScript: string, options: ScriptOptions): CompileResult {
const errors = diagnostics.filter(diag => diag.category === ts.DiagnosticCategory.Error);
@@ -133,6 +178,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
}
return { success: true, result };
} catch (error) {
+
if (batch) {
batch.end();
}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 0e15197c4..9888cce48 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -10,6 +10,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Networking } from "../Network";
import { CurrentUserUtils } from "./CurrentUserUtils";
import { Utils } from "../../Utils";
+import { Doc } from "../../fields/Doc";
library.add(fa.faWindowClose);
@@ -78,6 +79,10 @@ export default class SettingsManager extends React.Component<{}> {
this.errorText = "";
this.successText = "";
}
+ @action
+ noviceToggle = (event: any) => {
+ Doc.UserDoc().noviceMode = !Doc.UserDoc().noviceMode;
+ }
private get settingsInterface() {
return (
@@ -91,7 +96,7 @@ export default class SettingsManager extends React.Component<{}> {
<div className="settings-body">
<div className="settings-type">
<button onClick={this.onClick} value="password">reset password</button>
- <button onClick={this.onClick} value="data">reset data</button>
+ <button onClick={this.noviceToggle} value="data">{`toggle ${Doc.UserDoc().noviceMode ? "developer" : "novice"} mode`}</button>
<button onClick={() => window.location.assign(Utils.prepend("/logout"))}>
{CurrentUserUtils.GuestWorkspace ? "Exit" : "Log Out"}
</button>