aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/RichTextSchema.tsx28
-rw-r--r--src/client/util/Scripting.ts2
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx1
-rw-r--r--src/new_fields/Doc.ts23
-rw-r--r--src/new_fields/ScriptField.ts5
5 files changed, 31 insertions, 28 deletions
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 69296d8bc..71d4530f2 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -906,15 +906,13 @@ export class DashFieldView {
if (modText) {
self._fieldSpan.innerHTML = self._dashDoc![self._fieldKey] = modText;
Doc.addFieldEnumerations(self._textBoxDoc, self._fieldKey, []);
- } else if (!self._fieldSpan.innerText.startsWith(":=") && !self._fieldSpan.innerText.startsWith("=:=")) {
- self._dashDoc![self._fieldKey] = newText;
- }
-
- // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key
- if (self._fieldSpan.innerText.startsWith(":=") && self._dashDoc) {
- self._dashDoc[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2));
- } else if (self._fieldSpan.innerText.startsWith("=:=") && self._dashDoc) {
+ } // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key
+ else if (self._fieldSpan.innerText.startsWith(":=")) {
+ self._dashDoc![self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2));
+ } else if (self._fieldSpan.innerText.startsWith("=:=")) {
Doc.Layout(tbox.props.Document)[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(3));
+ } else {
+ self._dashDoc![self._fieldKey] = newText;
}
});
};
@@ -928,14 +926,9 @@ export class DashFieldView {
this._fieldCheck.style.minWidth = "12px";
this._fieldCheck.style.backgroundColor = "rgba(155, 155, 155, 0.24)";
this._fieldCheck.onchange = function (e: any) {
- // look for a document whose id === the fieldKey being displayed. If there's a match, then that document
- // holds the different enumerated values for the field in the titles of its collected documents.
- // if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down.
- const checked = e.target.checked;
- DocServer.GetRefField(self._fieldKey).then(options => self._dashDoc![self._fieldKey] = checked);
+ self._dashDoc![self._fieldKey] = e.target.checked;
}
-
this._fieldSpan = document.createElement("div");
this._fieldSpan.id = Utils.GenerateGuid();
this._fieldSpan.contentEditable = "true";
@@ -950,12 +943,11 @@ export class DashFieldView {
const setDashDoc = (doc: Doc) => {
self._dashDoc = doc;
- if (self._dashDoc && self._options?.length && !self._dashDoc[self._fieldKey]) {
+ if (self._options?.length && !self._dashDoc[self._fieldKey]) {
self._dashDoc[self._fieldKey] = StrCast(self._options[0].title);
}
- const layout = tbox.props.Document;
- // NOTE: if the field key starts with "@", then the actual field key is stored in the "@"fieldKey. Dereferencing these fields happens in ImageBox and RichTextSchema
- self._fieldKey = self._fieldKey.startsWith("@") ? StrCast(layout[StrCast(self._fieldKey).substring(1)]) : self._fieldKey;
+ // NOTE: if the field key starts with "@", then the actual field key is stored in the field 'fieldKey' (removing the @).
+ self._fieldKey = self._fieldKey.startsWith("@") ? StrCast(tbox.props.Document[StrCast(self._fieldKey).substring(1)]) : self._fieldKey;
this._labelSpan.innerHTML = `${self._fieldKey}: `;
const fieldVal = Cast(this._dashDoc?.[self._fieldKey], "boolean", null);
this._fieldCheck.style.display = (fieldVal === true || fieldVal === false) ? "inline-block" : "none";
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 0fa96963e..ce21b7fa7 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -215,6 +215,8 @@ function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, inde
export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult {
const { requiredType = "", addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options;
+ if (options.params && !options.params.this) options.params.this = Doc.name;
+ if (options.params && !options.params.self) options.params.self = Doc.name;
if (options.globals) {
Scripting.setScriptingGlobals(options.globals);
}
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 9391b153e..aa6e07968 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -400,6 +400,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
style={{
top: collapsed ? 70 : 10,
transform: `rotate(${collapsed ? 180 : 0}deg) scale(0.5) translate(${collapsed ? "-100%, -100%" : "0, 0"})`,
+ pointerEvents: collapsed ? "none" : undefined,
opacity: (collapsed && !this.props.CollectionView.props.isSelected()) ? 0 : 0.9,
left: (collapsed ? 0 : "unset"),
}}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 08efcad56..3ac297e94 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -465,8 +465,14 @@ export namespace Doc {
// Returns an expanded template layout for a target data document if there is a template relationship
// between the two. If so, the layoutDoc is expanded into a new document that inherits the properties
// of the original layout while allowing for individual layout properties to be overridden in the expanded layout.
- //
- export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateParams?: string) {
+ // templateArgs should be equivalent to the layout key that generates the template since that's where the template parameters are stored in ()'s at the end of the key.
+ // NOTE: the template will have references to "@params" -- the template arguments will be assigned to the '@params' field
+ // so that when the @params key is accessed, it will be rewritten as the key that is stored in the 'params' field and
+ // the derefence will then occur on the expandedTemplate (the original document).
+ // in the future, field references could be written as @<someparam> and then arguments would be passed in the layout key as:
+ // layout_mytemplate(somparam=somearg).
+ // then any references to @someparam would be rewritten as accesses to 'somearg' on the expandedTemplate
+ export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateArgs?: string) {
if (!WillExpandTemplateLayout(templateLayoutDoc, targetDoc) || !targetDoc) return templateLayoutDoc;
const templateField = StrCast(templateLayoutDoc.isTemplateForField); // the field that the template renders
@@ -475,9 +481,10 @@ export namespace Doc {
// If it doesn't find the expanded layout, then it makes a delegate of the template layout and
// saves it on the data doc indexed by the template layout's id.
//
- const params = templateParams?.match(/\(([a-zA-Z0-9_-]*)\)/)?.[1].replace("()", "") || "";
+ const args = templateArgs?.match(/\(([a-zA-Z0-9_-]*)\)/)?.[1].replace("()", "") || "";
+ const params = args.split("=").length > 1 ? args.split("=")[0] : "PARAMS";
const layoutFielddKey = Doc.LayoutFieldKey(templateLayoutDoc);
- const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + params + "]";
+ const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + args + "]";
let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey];
if (templateLayoutDoc.resolvedDataDoc instanceof Promise) {
expandedTemplateLayout = undefined;
@@ -487,10 +494,10 @@ export namespace Doc {
setTimeout(action(() => {
if (!targetDoc[expandedLayoutFieldKey]) {
const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]");
- newLayoutDoc["params"] = params;
+ // the template's arguments are stored in params which is derefenced to find
+ // the actual field key where the parameterized template data is stored.
+ newLayoutDoc[params] = args;
newLayoutDoc.expandedTemplate = targetDoc;
- // the template's parameters are stored in params which are derefenced to find
- // the actual field key where the template data is stored. Currently this is only used in RichTextSchema's docView
targetDoc[expandedLayoutFieldKey] = newLayoutDoc;
const dataDoc = Doc.GetProto(targetDoc);
newLayoutDoc.resolvedDataDoc = dataDoc;
@@ -512,7 +519,7 @@ export namespace Doc {
}
const existingResolvedDataDoc = childDoc[DataSym] !== Doc.GetProto(childDoc)[DataSym] && childDoc[DataSym];
const resolvedDataDoc = existingResolvedDataDoc || (Doc.AreProtosEqual(containerDataDoc, containerDoc) || !containerDataDoc || (!childDoc.isTemplateDoc && !childDoc.isTemplateForField) ? undefined : containerDataDoc);
- return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, "(" + StrCast(containerDoc["params"]) + ")"), data: resolvedDataDoc };
+ return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, "(" + StrCast(containerDoc["PARAMS"]) + ")"), data: resolvedDataDoc };
}
export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
index 606f55b7c..954c22a8d 100644
--- a/src/new_fields/ScriptField.ts
+++ b/src/new_fields/ScriptField.ts
@@ -7,6 +7,7 @@ import { Doc, Field } from "../new_fields/Doc";
import { Plugins } from "./util";
import { computedFn } from "mobx-utils";
import { ProxyField } from "./Proxy";
+import { Cast } from "./Types";
function optional(propSchema: PropSchema) {
return custom(value => {
@@ -106,7 +107,7 @@ export class ScriptField extends ObjectField {
}
public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) {
const compiled = CompileScript(script, {
- params: { this: Doc.name, source: Doc.name, _last_: "any", ...params },
+ params: { this: Doc.name, self: Doc.name, _last_: "any", ...params },
typecheck: false,
editable: true,
addReturn: addReturn,
@@ -130,7 +131,7 @@ export class ScriptField extends ObjectField {
export class ComputedField extends ScriptField {
_lastComputedResult: any;
//TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
- value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ source: doc.expandedTemplate || doc, this: doc, _last_: this._lastComputedResult }, console.log).result);
+ value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.expandedTemplate, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result);
public static MakeScript(script: string, params: object = {}) {
const compiled = ScriptField.CompileScript(script, params, false);
return compiled.compiled ? new ComputedField(compiled) : undefined;