aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ScriptingBox.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-08-02 16:28:18 -0400
committerbobzel <zzzman@gmail.com>2022-08-02 16:28:18 -0400
commitcfa31b87f1c2a6597ed3cfb6a777126c58ace665 (patch)
tree25aef539a44f0825cc3d6fba66e7c7fff061ddae /src/client/views/nodes/ScriptingBox.tsx
parent131408385d49fc8d5f360c2918737da4cecc13c1 (diff)
Adjusted ScriptFields to have a rawScript, and updated ScrptingBoxes to create a scriptField even for scripts that don't compile. Updated CurrentUserUtils setup functions for clicks. Fixed TemplateMenu to work again.
Diffstat (limited to 'src/client/views/nodes/ScriptingBox.tsx')
-rw-r--r--src/client/views/nodes/ScriptingBox.tsx85
1 files changed, 47 insertions, 38 deletions
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 05ff40f22..1c9b0bc0e 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -6,7 +6,7 @@ import { Doc } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { returnEmptyString } from '../../../Utils';
import { DragManager } from '../../util/DragManager';
@@ -60,6 +60,14 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
constructor(props: any) {
super(props);
+ if (!this.compileParams.length) {
+ const params = ScriptCast(this.rootDoc[this.props.fieldKey])?.script.options.params as { [key: string]: any };
+ if (params) {
+ this.compileParams = Array.from(Object.keys(params))
+ .filter(p => !p.startsWith('_'))
+ .map(key => key + ':' + params[key]);
+ }
+ }
}
// vars included in fields that store parameters types and names and the script itself
@@ -70,30 +78,30 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
return this.compileParams.map(p => p.split(':')[1].trim());
}
@computed({ keepAlive: true }) get rawScript() {
- return StrCast(this.dataDoc[this.props.fieldKey + '-rawScript'], '');
+ return ScriptCast(this.rootDoc[this.fieldKey])?.script.originalScript ?? '';
}
@computed({ keepAlive: true }) get functionName() {
- return StrCast(this.dataDoc[this.props.fieldKey + '-functionName'], '');
+ return StrCast(this.rootDoc[this.props.fieldKey + '-functionName'], '');
}
@computed({ keepAlive: true }) get functionDescription() {
- return StrCast(this.dataDoc[this.props.fieldKey + '-functionDescription'], '');
+ return StrCast(this.rootDoc[this.props.fieldKey + '-functionDescription'], '');
}
@computed({ keepAlive: true }) get compileParams() {
- return Cast(this.dataDoc[this.props.fieldKey + '-params'], listSpec('string'), []);
+ return Cast(this.rootDoc[this.props.fieldKey + '-params'], listSpec('string'), []);
}
set rawScript(value) {
- this.dataDoc[this.props.fieldKey + '-rawScript'] = value;
+ Doc.SetInPlace(this.rootDoc, this.props.fieldKey, new ScriptField(undefined, undefined, value), true);
}
set functionName(value) {
- this.dataDoc[this.props.fieldKey + '-functionName'] = value;
+ Doc.SetInPlace(this.rootDoc, this.props.fieldKey + '-functionName', value, true);
}
set functionDescription(value) {
- this.dataDoc[this.props.fieldKey + '-functionDescription'] = value;
+ Doc.SetInPlace(this.rootDoc, this.props.fieldKey + '-functionDescription', value, true);
}
set compileParams(value) {
- this.dataDoc[this.props.fieldKey + '-params'] = new List<string>(value);
+ Doc.SetInPlace(this.rootDoc, this.props.fieldKey + '-params', new List<string>(value), true);
}
getValue(result: any, descrip: boolean) {
@@ -107,8 +115,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
@action
componentDidMount() {
- this.rawScript = ScriptCast(this.dataDoc[this.props.fieldKey])?.script?.originalScript ?? this.rawScript;
-
+ this.rawText = this.rawScript;
const observer = new _global.ResizeObserver(
action((entries: any) => {
const area = document.querySelector('textarea');
@@ -171,13 +178,13 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
const params: ScriptParam = {};
this.compileParams.forEach(p => (params[p.split(':')[0].trim()] = p.split(':')[1].trim()));
- const result = CompileScript(this.rawScript, {
+ const result = CompileScript(this.rawText, {
editable: true,
transformer: DocumentIconContainer.getTransformer(),
params,
typecheck: false,
});
- this.dataDoc[this.fieldKey] = result.compiled ? new ScriptField(result) : undefined;
+ Doc.SetInPlace(this.rootDoc, this.fieldKey, result.compiled ? new ScriptField(result, undefined, this.rawText) : new ScriptField(undefined, undefined, this.rawText), true);
this.onError(result.compiled ? undefined : result.errors);
return result.compiled;
};
@@ -187,9 +194,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
onRun = () => {
if (this.onCompile()) {
const bindings: { [name: string]: any } = {};
- this.paramsNames.forEach(key => (bindings[key] = this.dataDoc[key]));
+ this.paramsNames.forEach(key => (bindings[key] = this.rootDoc[key]));
// binds vars so user doesnt have to refer to everything as self.<var>
- ScriptCast(this.dataDoc[this.fieldKey], null)?.script.run({ self: this.rootDoc, this: this.layoutDoc, ...bindings }, this.onError);
+ ScriptCast(this.rootDoc[this.fieldKey], null)?.script.run({ self: this.rootDoc, this: this.layoutDoc, ...bindings }, this.onError);
}
};
@@ -257,14 +264,14 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
// sets field of the corresponding field key (param name) to be dropped document
@action
onDrop = (e: Event, de: DragManager.DropEvent, fieldKey: string) => {
- this.dataDoc[fieldKey] = de.complete.docDragData?.droppedDocuments[0];
+ Doc.SetInPlace(this.rootDoc, fieldKey, de.complete.docDragData?.droppedDocuments[0], true);
e.stopPropagation();
};
// deletes a param from all areas in which it is stored
@action
onDelete = (num: number) => {
- this.dataDoc[this.paramsNames[num]] = undefined;
+ Doc.SetInPlace(this.rootDoc, this.paramsNames[num], undefined, true);
this.compileParams.splice(num, 1);
return true;
};
@@ -274,7 +281,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
viewChanged = (e: React.ChangeEvent, name: string) => {
//@ts-ignore
const val = e.target.selectedOptions[0].value;
- this.dataDoc[name] = val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true';
+ Doc.SetInPlace(this.rootDoc, name, val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true', true);
};
// creates a copy of the script document
@@ -330,8 +337,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
maxHeight={72}
height={35}
fontSize={14}
- contents={this.dataDoc[parameter]?.title ?? 'undefined'}
- GetValue={() => this.dataDoc[parameter]?.title ?? 'undefined'}
+ contents={StrCast(DocCast(this.rootDoc[parameter])?.title, 'undefined')}
+ GetValue={() => StrCast(DocCast(this.rootDoc[parameter])?.title, 'undefined')}
SetValue={action((value: string) => {
const script = CompileScript(value, {
addReturn: true,
@@ -341,7 +348,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
const results = script.compiled && script.run();
if (results && results.success) {
this._errorMessage = '';
- this.dataDoc[parameter] = results.result;
+ Doc.SetInPlace(this.rootDoc, parameter, results.result, true);
return true;
}
this._errorMessage = 'invalid document';
@@ -354,7 +361,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
// rendering when a string's value can be set in applied UI
renderBasicType(parameter: string, isNum: boolean) {
- const strVal = isNum ? NumCast(this.dataDoc[parameter]).toString() : StrCast(this.dataDoc[parameter]);
+ const strVal = isNum ? NumCast(this.rootDoc[parameter]).toString() : StrCast(this.rootDoc[parameter]);
return (
<div className="scriptingBox-paramInputs" style={{ overflowY: 'hidden' }}>
<EditableView
@@ -368,7 +375,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
const setValue = isNum ? parseInt(value) : value;
if (setValue !== undefined && setValue !== ' ') {
this._errorMessage = '';
- this.dataDoc[parameter] = setValue;
+ Doc.SetInPlace(this.rootDoc, parameter, setValue, true);
return true;
}
this._errorMessage = 'invalid input';
@@ -389,7 +396,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
className="scriptingBox-viewPicker"
onPointerDown={e => e.stopPropagation()}
onChange={e => this.viewChanged(e, parameter)}
- value={typeof this.dataDoc[parameter] === 'string' ? 'S' + StrCast(this.dataDoc[parameter]) : typeof this.dataDoc[parameter] === 'number' ? 'N' + NumCast(this.dataDoc[parameter]) : 'B' + BoolCast(this.dataDoc[parameter])}>
+ value={typeof this.rootDoc[parameter] === 'string' ? 'S' + StrCast(this.rootDoc[parameter]) : typeof this.rootDoc[parameter] === 'number' ? 'N' + NumCast(this.rootDoc[parameter]) : 'B' + BoolCast(this.rootDoc[parameter])}>
{types.map(type => (
<option className="scriptingBox-viewOption" value={(typeof type === 'string' ? 'S' : typeof type === 'number' ? 'N' : 'B') + type}>
{' '}
@@ -442,7 +449,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
@action
handleFunc(pos: number) {
- const scriptString = this.rawScript.slice(0, pos - 2);
+ const scriptString = this.rawText.slice(0, pos - 2);
this._currWord = scriptString.split(' ')[scriptString.split(' ').length - 1];
this._suggestions = [StrCast(this._scriptingParams[this._currWord])];
return this._suggestions;
@@ -474,7 +481,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
}
getSuggestedParams(pos: number) {
- const firstScript = this.rawScript.slice(0, pos);
+ const firstScript = this.rawText.slice(0, pos);
const indexP = firstScript.lastIndexOf('.');
const indexS = firstScript.lastIndexOf(' ');
const func = firstScript.slice((indexP > indexS ? indexP : indexS) + 1, firstScript.length + 1);
@@ -494,8 +501,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
@action
keyHandler(e: any, pos: number) {
+ e.stopPropagation();
if (this._lastChar === 'Enter') {
- this.rawScript = this.rawScript + ' ';
+ this.rawText = this.rawText + ' ';
}
if (e.key === '(') {
this.suggestionPos();
@@ -504,7 +512,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
this._scriptSuggestedParams = this.getSuggestedParams(pos);
if (this._scriptParamsText !== undefined && this._scriptParamsText.length > 0) {
- if (this.rawScript[pos - 2] !== '(') {
+ if (this.rawText[pos - 2] !== '(') {
this._paramSuggestion = true;
}
}
@@ -515,22 +523,22 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
if (this._lastChar === '(') {
this._paramSuggestion = false;
} else if (this._lastChar === ')') {
- if (this.rawScript.slice(0, this.rawScript.length - 1).split('(').length - 1 > this.rawScript.slice(0, this.rawScript.length - 1).split(')').length - 1) {
+ if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) {
if (this._scriptParamsText.length > 0) {
this._paramSuggestion = true;
}
}
}
- } else if (this.rawScript.split('(').length - 1 <= this.rawScript.split(')').length - 1) {
+ } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) {
this._paramSuggestion = false;
}
}
- this._lastChar = e.key === 'Backspace' ? this.rawScript[this.rawScript.length - 2] : e.key;
+ this._lastChar = e.key === 'Backspace' ? this.rawText[this.rawText.length - 2] : e.key;
if (this._paramSuggestion) {
const parameters = this._scriptParamsText.split(',');
- const index = this.rawScript.lastIndexOf('(');
- const enteredParams = this.rawScript.slice(index, this.rawScript.length);
+ const index = this.rawText.lastIndexOf('(');
+ const enteredParams = this.rawText.slice(index, this.rawText.length);
const splitEntered = enteredParams.split(',');
const numEntered = splitEntered.length;
@@ -564,15 +572,16 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
handlePosChange(number: any) {
this._caretPos = number;
if (this._caretPos === 0) {
- this.rawScript = ' ' + this.rawScript;
+ this.rawText = ' ' + this.rawText;
} else if (this._spaced) {
this._spaced = false;
- if (this.rawScript[this._caretPos - 1] === ' ') {
- this.rawScript = this.rawScript.slice(0, this._caretPos - 1) + this.rawScript.slice(this._caretPos, this.rawScript.length);
+ if (this.rawText[this._caretPos - 1] === ' ') {
+ this.rawText = this.rawText.slice(0, this._caretPos - 1) + this.rawText.slice(this._caretPos, this.rawText.length);
}
}
}
+ @observable rawText: string = '';
@computed({ keepAlive: true }) get renderScriptingBox() {
TraceMobx();
return (
@@ -583,8 +592,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
placeholder="write your script here"
onFocus={this.onFocus}
onBlur={() => this._overlayDisposer?.()}
- onChange={(e: any) => (this.rawScript = e.target.value)}
- value={this.rawScript}
+ onChange={action((e: any) => (this.rawText = e.target.value))}
+ value={this.rawText}
movePopupAsYouType={true}
loadingComponent={() => <span>Loading</span>}
trigger={{