aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-04-06 21:58:50 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-04-06 21:58:50 -0400
commit8b02394f24e4f15674bf18192f49ee2385d67655 (patch)
tree8840293a778b6d25ae79c016c7d15dbaf4da7746 /src
parent68131598cebf0edbccef98d8bcfdba202161ec00 (diff)
cleaned up some scripting. added childClicks to UserDoc to extend menu of OnClick options. switched containingCollection to thisContainer for onclick scripts
Diffstat (limited to 'src')
-rw-r--r--src/client/util/Scripting.ts16
-rw-r--r--src/client/views/ScriptBox.tsx2
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx4
-rw-r--r--src/client/views/collections/CollectionView.tsx11
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/new_fields/Doc.ts19
-rw-r--r--src/server/authentication/models/current_user_utils.ts12
8 files changed, 46 insertions, 32 deletions
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index ce21b7fa7..cf04c44ca 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -195,14 +195,14 @@ export type Transformer = {
getVars?: () => { capturedVariables: { [name: string]: Field } }
};
export interface ScriptOptions {
- requiredType?: string;
- addReturn?: boolean;
- params?: { [name: string]: string };
- capturedVariables?: { [name: string]: Field };
- typecheck?: boolean;
- editable?: boolean;
- traverser?: TraverserParam;
- transformer?: Transformer;
+ requiredType?: string; // does function required a typed return value
+ addReturn?: boolean; // does the compiler automatically add a return statement
+ params?: { [name: string]: string }; // list of function parameters and their types
+ capturedVariables?: { [name: string]: Field }; // list of captured variables
+ typecheck?: boolean; // should the compiler perform typechecking
+ editable?: boolean; // can the script edit Docs
+ traverser?: TraverserParam;
+ transformer?: Transformer; // does the editor display a text label by each document that can be used as a captured document reference
globals?: { [name: string]: any };
}
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index cc5d7640e..1e81bb80b 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -121,6 +121,6 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
overlayDisposer();
}
}} showDocumentIcons />;
- overlayDisposer = OverlayView.Instance.addWindow(scriptingBox, { x: 400, y: 200, width: 500, height: 400, title: title });
+ overlayDisposer = OverlayView.Instance.addWindow(scriptingBox, { x: 400, y: 200, width: 500, height: 400, title });
}
}
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 4b005ba42..53de2fbbe 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -30,8 +30,8 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
}
componentDidMount() {
const childDetailed = this.props.Document.childDetailed; // bcz: needs to be here to make sure the childDetailed layout template has been loaded when the first item is clicked;
- const childText = "const alias = getAlias(this); Doc.ApplyTemplateTo(containingCollection.childDetailed, alias, 'layout_detailView'); alias.layoutKey='layout_detailedView'; alias.dropAction='alias'; alias.removeDropProperties=new List<string>(['dropAction']); useRightSplit(alias, shiftKey); ";
- this.props.Document.onChildClick = ScriptField.MakeScript(childText, { this: Doc.name, heading: "string", containingCollection: Doc.name, shiftKey: "boolean" });
+ const childText = "const alias = getAlias(this); Doc.ApplyTemplateTo(thisContainer.childDetailed, alias, 'layout_detailView'); alias.layoutKey='layout_detailedView'; alias.dropAction='alias'; alias.removeDropProperties=new List<string>(['dropAction']); useRightSplit(alias, shiftKey); ";
+ this.props.Document.onChildClick = ScriptField.MakeScript(childText, { this: Doc.name, heading: "string", thisContainer: Doc.name, shiftKey: "boolean" });
this.props.Document._fitToBox = true;
if (!this.props.Document.onViewDefClick) {
this.props.Document.onViewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" });
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index c1234c500..d7224fa4b 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -43,6 +43,7 @@ import { listSpec } from '../../../new_fields/Schema';
import { Docs } from '../../documents/Documents';
import { ScriptField, ComputedField } from '../../../new_fields/ScriptField';
import { InteractionUtils } from '../../util/InteractionUtils';
+import { ObjectField } from '../../../new_fields/ObjectField';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -259,7 +260,15 @@ export class CollectionView extends Touchable<FieldViewProps> {
const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
- onClicks.push({ description: "Edit onChildClick script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Child Clicked...", this.props.Document, "onChildClick", obj.x, obj.y) });
+ const funcs = [{ key: "onChildClick", name: "On Child Clicked", script: undefined as any as ScriptField }];
+ DocListCast(Cast(Doc.UserDoc().childClickFuncs, Doc, null).data).forEach(childClick =>
+ funcs.push({ key: "onChildClick", name: StrCast(childClick.title), script: ScriptCast(childClick.script) }));
+ funcs.map(func => onClicks.push({
+ description: `Edit ${func.name} script`, icon: "edit", event: (obj: any) => {
+ func.script && (this.props.Document[func.key] = ObjectField.MakeCopy(func.script));
+ ScriptBox.EditButtonScript(func.name + "...", this.props.Document, func.key, obj.x, obj.y, { thisContainer: Doc.name });
+ }
+ }));
!existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
const more = ContextMenu.Instance.findByDescription("More...");
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 4a0eb3aa4..9bade1c82 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -43,14 +43,14 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
get target() { return this.props.CollectionView.props.Document; }
_templateCommand = {
params: ["target", "source"], title: "=> item view",
- script: "setChildLayout(this.target, this.source?.[0])",
- immediate: (source: Doc[]) => Doc.setChildLayout(this.target, source?.[0]),
+ script: "target.childLayout = getDocTemplate(this.source?.[0])",
+ immediate: (source: Doc[]) => this.target.childLayout = Doc.getDocTemplate(source?.[0]),
initialize: emptyFunction,
};
_narrativeCommand = {
params: ["target", "source"], title: "=> click item view",
- script: "setChildDetailedLayout(this.target, this.source?.[0])",
- immediate: (source: Doc[]) => Doc.setChildDetailedLayout(this.target, source?.[0]),
+ script: "this.target.childDetailed = getDocTemplate(this.source?.[0])",
+ immediate: (source: Doc[]) => this.target.childDetailed = Doc.getDocTemplate(source?.[0]),
initialize: emptyFunction,
};
_contentCommand = {
@@ -353,7 +353,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
const c = {
params: ["target"], title: CollectionViewType.stringFor(vtype),
script: `this.target._viewType = ${NumCast(this.props.CollectionView.props.Document._viewType)}`,
- immediate: (source: Doc[]) => Doc.setChildLayout(this.target, source?.[0]),
+ immediate: (source: Doc[]) => this.target = Doc.getTemplateDoc(source?.[0]),
initialize: emptyFunction,
};
DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title),
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9ca914bbe..f374b5803 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -295,8 +295,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const func = () => this.onClickHandler!.script.run({
this: this.props.Document,
self: Cast(this.props.Document.rootDocument, Doc, null) || this.props.Document,
- containingCollection: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey
- }, console.log) && !this.props.Document.isButton && this.select(false);
+ thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey
+ }, console.log);// && !this.props.Document.isButton && this.select(false);
if (this.props.Document !== Doc.UserDoc().undoBtn && this.props.Document !== Doc.UserDoc().redoBtn) {
UndoManager.RunInBatch(func, "on click");
} else func();
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 85926e393..964b2e316 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -80,7 +80,7 @@ export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
}
export async function DocCastAsync(field: FieldResult): Promise<Opt<Doc>> {
- return Cast(field, Doc);
+ return await Cast(field, Doc);
}
export function DocListCast(field: FieldResult): Doc[] {
@@ -787,15 +787,10 @@ export namespace Doc {
brushManager.BrushedDoc.clear();
}
- export function setChildLayout(target: Doc, source?: Doc) {
- target.childLayout = source && source.isTemplateDoc ? source : source &&
- source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory :
- source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined;
- }
- export function setChildDetailedLayout(target: Doc, source?: Doc) {
- target.childDetailed = source && source.isTemplateDoc ? source : source &&
- source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory :
- source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined;
+ export function getDocTemplate(doc?: Doc) {
+ return doc?.isTemplateDoc ? doc :
+ Cast(doc?.dragFactory, Doc, null)?.isTemplateDoc ? doc?.dragFactory :
+ Cast(doc?.layout, Doc, null)?.isTemplateDoc ? doc?.layout : undefined;
}
export function matchFieldValue(doc: Doc, key: string, value: any): boolean {
@@ -904,8 +899,7 @@ export namespace Doc {
Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; });
Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
-Scripting.addGlobal(function setChildLayout(target: any, source: any) { Doc.setChildLayout(target, source); });
-Scripting.addGlobal(function setChildDetailedLayout(target: any, source: any) { Doc.setChildDetailedLayout(target, source); });
+Scripting.addGlobal(function getDocTemplate(doc?: any) { Doc.getDocTemplate(doc); });
Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); });
Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); });
Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); });
@@ -917,6 +911,7 @@ Scripting.addGlobal(function undo() { return UndoManager.Undo(); });
Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
Scripting.addGlobal(function DOC(id: string) { console.log("Can't parse a document id in a script"); return "invalid"; });
Scripting.addGlobal(function assignDoc(doc: Doc, field: string, id: string) { return Doc.assignDocToField(doc, field, id); });
+Scripting.addGlobal(function docCast(doc: FieldResult): any { return DocCastAsync(doc); });
Scripting.addGlobal(function curPresentationItem() {
const curPres = Doc.UserDoc().curPresentation as Doc;
return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)];
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 302e00b63..529f8d56d 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -14,7 +14,7 @@ import { Utils } from "../../../Utils";
import { nullAudio, ImageField } from "../../../new_fields/URLField";
import { DragManager } from "../../../client/util/DragManager";
import { InkingControl } from "../../../client/views/InkingControl";
-import { Scripting } from "../../../client/util/Scripting";
+import { Scripting, CompileScript } from "../../../client/util/Scripting";
import { CollectionViewType } from "../../../client/views/collections/CollectionView";
import { makeTemplate } from "../../../client/util/DropConverter";
import { RichTextField } from "../../../new_fields/RichTextField";
@@ -345,6 +345,13 @@ export class CurrentUserUtils {
doc.optionalRightCollection = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "New mobile uploads" }));
}
+ static setupChildClicks(doc: Doc) {
+ const openInTarget = Docs.Create.TextDocument("", { title: "On Child Clicked (open in target)" });
+ const text = "docCast(thisContainer.target).then((target) => { target && docCast(this.source).then((source) => { target.proto.data = new List([source || this]); } ); } )";
+ openInTarget.script = ScriptField.MakeScript(text, { thisContainer: Doc.name });
+ doc.childClickFuncs = Docs.Create.TreeDocument([openInTarget], { title: "on Child Click function templates" });
+ }
+
static updateUserDocument(doc: Doc) {
doc.title = Doc.CurrentUserEmail;
new InkingControl();
@@ -355,7 +362,10 @@ export class CurrentUserUtils {
(doc.expandingButtons === undefined) && CurrentUserUtils.setupExpandingButtons(doc);
(doc.curPresentation === undefined) && CurrentUserUtils.setupDefaultPresentation(doc);
(doc.sidebarButtons === undefined) && CurrentUserUtils.setupSidebarButtons(doc);
+ (doc.childClickFuncs === undefined) && CurrentUserUtils.setupChildClicks(doc);
+ // this is equivalent to using PrefetchProxies to make sure all the childClickFuncs have been retrieved.
+ PromiseValue(Cast(doc.childClickFuncs, Doc)).then(func => func && PromiseValue(func.data).then(DocListCast));
// this is equivalent to using PrefetchProxies to make sure the recentlyClosed doc is ready
PromiseValue(Cast(doc.recentlyClosed, Doc)).then(recent => recent && PromiseValue(recent.data).then(DocListCast));
// this is equivalent to using PrefetchProxies to make sure all the sidebarButtons and noteType internal Doc's have been retrieved.