@node-projects/web-component-designer-visualization-addons 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +19 -0
  2. package/dist/blockly/BlocklyJavascriptHelper.d.ts +2 -0
  3. package/dist/blockly/BlocklyJavascriptHelper.js +35 -0
  4. package/dist/blockly/BlocklyScriptEditor.d.ts +16 -0
  5. package/dist/blockly/BlocklyScriptEditor.js +106 -0
  6. package/dist/blockly/BlocklyToolbox.d.ts +1117 -0
  7. package/dist/blockly/BlocklyToolbox.js +980 -0
  8. package/dist/blockly/components/Console.d.ts +0 -0
  9. package/dist/blockly/components/Console.js +26 -0
  10. package/dist/blockly/components/Debugger.d.ts +0 -0
  11. package/dist/blockly/components/Debugger.js +15 -0
  12. package/dist/blockly/components/GetState.d.ts +0 -0
  13. package/dist/blockly/components/GetState.js +21 -0
  14. package/dist/blockly/components/GetSubProperty.d.ts +0 -0
  15. package/dist/blockly/components/GetSubProperty.js +27 -0
  16. package/dist/blockly/components/OpenScreen.d.ts +0 -0
  17. package/dist/blockly/components/OpenScreen.js +31 -0
  18. package/dist/blockly/components/QuerySelector.d.ts +0 -0
  19. package/dist/blockly/components/QuerySelector.js +30 -0
  20. package/dist/blockly/components/QuerySelectorAll.d.ts +0 -0
  21. package/dist/blockly/components/QuerySelectorAll.js +30 -0
  22. package/dist/blockly/components/Return.d.ts +0 -0
  23. package/dist/blockly/components/Return.js +21 -0
  24. package/dist/blockly/components/SetElement.d.ts +0 -0
  25. package/dist/blockly/components/SetElement.js +44 -0
  26. package/dist/blockly/components/SetState.d.ts +0 -0
  27. package/dist/blockly/components/SetState.js +26 -0
  28. package/dist/blockly/components/StartEvent.d.ts +0 -0
  29. package/dist/blockly/components/StartEvent.js +23 -0
  30. package/dist/blockly/components/components.d.ts +11 -0
  31. package/dist/blockly/components/components.js +11 -0
  32. package/dist/blockly/components/fields/FieldObjectId.d.ts +1 -0
  33. package/dist/blockly/components/fields/FieldObjectId.js +6 -0
  34. package/dist/components/BindingsEditor.d.ts +49 -0
  35. package/dist/components/BindingsEditor.js +298 -0
  36. package/dist/components/BindingsEditorHistoric.d.ts +14 -0
  37. package/dist/components/BindingsEditorHistoric.js +97 -0
  38. package/dist/components/PropertyGridExt.d.ts +0 -0
  39. package/dist/components/PropertyGridExt.js +1 -0
  40. package/dist/components/ScriptEditor.d.ts +28 -0
  41. package/dist/components/ScriptEditor.js +254 -0
  42. package/dist/components/VisualizationPropertyGrid.d.ts +12 -0
  43. package/dist/components/VisualizationPropertyGrid.js +104 -0
  44. package/dist/helpers/BindingsHelper.d.ts +47 -0
  45. package/dist/helpers/BindingsHelper.js +642 -0
  46. package/dist/index.d.ts +21 -0
  47. package/dist/index.js +22 -0
  48. package/dist/interfaces/IScriptMultiplexValue.d.ts +15 -0
  49. package/dist/interfaces/IScriptMultiplexValue.js +15 -0
  50. package/dist/interfaces/VisualisationElementScript.d.ts +5 -0
  51. package/dist/interfaces/VisualisationElementScript.js +1 -0
  52. package/dist/interfaces/VisualizationBinding.d.ts +20 -0
  53. package/dist/interfaces/VisualizationBinding.js +4 -0
  54. package/dist/interfaces/VisualizationHandler.d.ts +24 -0
  55. package/dist/interfaces/VisualizationHandler.js +2 -0
  56. package/dist/interfaces/VisualizationShell.d.ts +13 -0
  57. package/dist/interfaces/VisualizationShell.js +1 -0
  58. package/dist/interfaces/VisualizationUiHandler.d.ts +5 -0
  59. package/dist/interfaces/VisualizationUiHandler.js +2 -0
  60. package/dist/scripting/Script.d.ts +6 -0
  61. package/dist/scripting/Script.js +5 -0
  62. package/dist/scripting/ScriptCommands.d.ts +192 -0
  63. package/dist/scripting/ScriptCommands.js +1 -0
  64. package/dist/scripting/ScriptSystem.d.ts +23 -0
  65. package/dist/scripting/ScriptSystem.js +224 -0
  66. package/dist/services/BindableObjectDragDropService.d.ts +16 -0
  67. package/dist/services/BindableObjectDragDropService.js +145 -0
  68. package/dist/services/BindingsService.d.ts +11 -0
  69. package/dist/services/BindingsService.js +46 -0
  70. package/dist/services/PropertyGridDragDropService.d.ts +7 -0
  71. package/dist/services/PropertyGridDragDropService.js +10 -0
  72. package/dist/services/ScriptRefactorService.d.ts +9 -0
  73. package/dist/services/ScriptRefactorService.js +79 -0
  74. package/dist/services/SignalPropertyEditor.d.ts +7 -0
  75. package/dist/services/SignalPropertyEditor.js +43 -0
  76. package/dist/setupVisuService.d.ts +0 -0
  77. package/dist/setupVisuService.js +1 -0
  78. package/package.json +29 -0
@@ -0,0 +1,254 @@
1
+ import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
2
+ import { ContextMenu } from "@node-projects/web-component-designer";
3
+ import { typeInfoFromJsonSchema } from "@node-projects/propertygrid.webcomponent";
4
+ import { defaultOptions } from "@node-projects/web-component-designer-widgets-wunderbaum";
5
+ import { Wunderbaum } from 'wunderbaum';
6
+ //@ts-ignore
7
+ import wunderbaumStyle from 'wunderbaum/dist/wunderbaum.css' assert { type: 'css' };
8
+ import { VisualizationPropertyGrid } from "./VisualizationPropertyGrid";
9
+ import '@node-projects/splitview.webcomponent';
10
+ export class SimpleScriptEditor extends BaseCustomWebComponentConstructorAppend {
11
+ static style = css `
12
+ :host {
13
+ background: white;
14
+ }
15
+ .list{
16
+ display: grid;
17
+ grid-template-columns: 1fr 40px;
18
+ width: calc(100% - 6px);
19
+ box-sizing: border-box;
20
+ margin: 3px;
21
+ }
22
+
23
+ .list button{
24
+ padding: 5px 10px;
25
+ box-sizing: border-box;
26
+ display: flex;
27
+ justify-content: center;
28
+ margin-right: 5px;
29
+ margin-left: 5px;
30
+ }
31
+
32
+ node-projects-visualization-property-grid {
33
+ width: 100%;
34
+ height: 100%;
35
+ }
36
+ `;
37
+ static template = html `
38
+ <div style="width:100%; height:100%; overflow: hidden;">
39
+ <node-projects-split-view style="height: 100%; width: 100%; position: relative;" orientation="horizontal">
40
+ <div style="width: 40%; position: relative;">
41
+ <div style="width:calc(100% - 4px); height:calc(100% - 4px)">
42
+ <div id="commandList" style="overflow-x: hidden; overflow-y: auto; width:100%; height: calc(100% - 34px);"></div>
43
+ <div class="list">
44
+ <select id="possibleCommands" style="width: 100%"></select>
45
+ <button @click="[[this.addItem()]]">Add</button>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ <div style="width: 60%; position: relative;">
50
+ <node-projects-visualization-property-grid id="propertygrid"></node-projects-visualization-property-grid>
51
+ </div>
52
+ </node-projects-split-view>
53
+ </div>
54
+ `;
55
+ static is = 'node-projects-simple-script-editor';
56
+ serviceContainer;
57
+ visualizationHandler;
58
+ visualizationShell;
59
+ scriptCommandsTypeInfo;
60
+ propertiesTypeInfo;
61
+ _script;
62
+ _commandListDiv;
63
+ _commandListFancyTree;
64
+ _possibleCommands;
65
+ _propertygrid;
66
+ constructor() {
67
+ super();
68
+ this._restoreCachedInititalValues();
69
+ this._commandListDiv = this._getDomElement('commandList');
70
+ this._possibleCommands = this._getDomElement('possibleCommands');
71
+ this._propertygrid = this._getDomElement('propertygrid');
72
+ this.shadowRoot.adoptedStyleSheets = [wunderbaumStyle, SimpleScriptEditor.style];
73
+ }
74
+ async ready() {
75
+ this.addPossibleCommands();
76
+ this._parseAttributesToProperties();
77
+ this._bindingsParse(null, true);
78
+ this._assignEvents();
79
+ let editComplex = async (data) => {
80
+ let pg = new VisualizationPropertyGrid();
81
+ pg.visualizationHandler = this.visualizationHandler;
82
+ pg.visualizationShell = this.visualizationShell;
83
+ pg.serviceContainer = this.serviceContainer;
84
+ pg.getTypeInfo = (obj, type) => typeInfoFromJsonSchema(this.propertiesTypeInfo, obj, type);
85
+ pg.showHead = false;
86
+ pg.typeName = 'IScriptMultiplexValue';
87
+ pg.title = 'Complex for "' + data.propertyPath + '"';
88
+ if (typeof data.value === 'object')
89
+ pg.selectedObject = data.value ?? {};
90
+ else
91
+ pg.selectedObject = {};
92
+ let res = await this.visualizationShell.openConfirmation(pg, { x: 100, y: 100, width: 300, height: 300, parent: this });
93
+ if (res) {
94
+ this._propertygrid.setPropertyValue(data.propertyPath, pg.selectedObject);
95
+ this._propertygrid.refresh();
96
+ }
97
+ };
98
+ this._propertygrid.visualizationHandler = this.visualizationHandler;
99
+ this._propertygrid.visualizationShell = this.visualizationShell;
100
+ this._propertygrid.serviceContainer = this.serviceContainer;
101
+ this._propertygrid.getTypeInfo = (obj, type) => typeInfoFromJsonSchema(this.scriptCommandsTypeInfo, obj, type);
102
+ this._propertygrid.getSpecialEditorForType = async (property, currentValue, propertyPath, wbRender, additionalInfo) => {
103
+ if (typeof currentValue === 'object' && currentValue !== null) {
104
+ let rB = document.createElement('button');
105
+ rB.style.height = 'calc(100% - 6px)';
106
+ rB.style.position = 'relative';
107
+ rB.style.display = 'flex';
108
+ rB.style.justifyContent = 'center';
109
+ rB.style.width = '20px';
110
+ rB.style.boxSizing = 'content-box';
111
+ rB.innerText = 'del';
112
+ rB.onclick = () => {
113
+ this._propertygrid.setPropertyValue(propertyPath, undefined);
114
+ this._propertygrid.refresh();
115
+ };
116
+ wbRender.nodeElem.insertAdjacentElement('afterbegin', rB);
117
+ let d = document.createElement('div');
118
+ d.style.display = 'flex';
119
+ let sp = document.createElement('span');
120
+ sp.innerText = 'complex: ' + JSON.stringify(currentValue);
121
+ sp.style.overflow = 'hidden';
122
+ sp.style.whiteSpace = 'nowrap';
123
+ sp.style.textOverflow = 'ellipsis';
124
+ sp.style.flexGrow = '1';
125
+ sp.title = JSON.stringify(currentValue);
126
+ d.appendChild(sp);
127
+ let b = document.createElement('button');
128
+ b.innerText = '...';
129
+ b.onclick = () => {
130
+ editComplex({ value: currentValue, propertyPath });
131
+ };
132
+ d.appendChild(b);
133
+ wbRender.nodeElem.style.display = 'flex';
134
+ return d;
135
+ }
136
+ else {
137
+ let b = document.createElement('button');
138
+ b.style.height = 'calc(100% - 6px)';
139
+ b.style.position = 'relative';
140
+ b.style.display = 'flex';
141
+ b.style.justifyContent = 'center';
142
+ b.style.width = '20px';
143
+ b.style.boxSizing = 'content-box';
144
+ b.title = 'complex';
145
+ b.style.opacity = '0.2';
146
+ b.innerText = '...';
147
+ b.onclick = () => {
148
+ editComplex({ value: currentValue, propertyPath });
149
+ };
150
+ wbRender.nodeElem.insertAdjacentElement('afterbegin', b);
151
+ wbRender.nodeElem.style.display = 'flex';
152
+ }
153
+ return null;
154
+ };
155
+ this._propertygrid.propertyNodeContextMenu.on((data) => {
156
+ ContextMenu.show([{
157
+ title: 'edit complex value',
158
+ action: async () => {
159
+ editComplex(data);
160
+ }
161
+ },
162
+ {
163
+ title: 'remove complex value',
164
+ action: async () => {
165
+ this._propertygrid.setPropertyValue(data.propertyPath, undefined);
166
+ this._propertygrid.refresh();
167
+ }
168
+ }], data.event);
169
+ });
170
+ }
171
+ //Converter from TypscriptJsonSchema to our Property list...
172
+ async addPossibleCommands() {
173
+ let commands = Object.keys(this.scriptCommandsTypeInfo.definitions);
174
+ for (let c of commands) {
175
+ if (c == 'ScriptCommands')
176
+ continue;
177
+ let option = document.createElement('option');
178
+ option.innerText = c;
179
+ this._possibleCommands.add(option);
180
+ }
181
+ }
182
+ loadScript(script) {
183
+ this._script = script;
184
+ let commandListTreeItems = [];
185
+ for (let c of this._script.commands) {
186
+ commandListTreeItems.push(this.createTreeItem(c));
187
+ }
188
+ ;
189
+ this._commandListFancyTree = new Wunderbaum({
190
+ ...defaultOptions,
191
+ element: this._commandListDiv,
192
+ icon: false,
193
+ source: commandListTreeItems,
194
+ activate: (e) => {
195
+ this._propertygrid.selectedObject = e.node.data.data.item;
196
+ },
197
+ render: (e) => {
198
+ if (e.isNew) {
199
+ let span = e.nodeElem;
200
+ span.oncontextmenu = (ev) => {
201
+ e.node.setActive();
202
+ if (e.node.data.contextMenu) {
203
+ e.node.data.contextMenu(ev, e.node.data, e.node);
204
+ }
205
+ ev.preventDefault();
206
+ return false;
207
+ };
208
+ }
209
+ },
210
+ dnd: {
211
+ guessDropEffect: true,
212
+ preventRecursion: true,
213
+ preventVoidMoves: false,
214
+ serializeClipboardData: false,
215
+ dragStart: (e) => {
216
+ e.event.dataTransfer.effectAllowed = "move";
217
+ e.event.dataTransfer.dropEffect = "move";
218
+ return true;
219
+ },
220
+ dragEnter: (e) => {
221
+ e.event.dataTransfer.dropEffect = 'move';
222
+ return true;
223
+ },
224
+ dragOver: (e) => {
225
+ e.event.dataTransfer.dropEffect = 'move';
226
+ },
227
+ drop: async (e) => {
228
+ e.sourceNode.moveTo(e.node, e.region == 'before' ? 'before' : 'after');
229
+ }
230
+ }
231
+ });
232
+ }
233
+ createTreeItem(currentItem) {
234
+ let cti = {
235
+ title: currentItem.type,
236
+ data: { item: currentItem },
237
+ contextMenu: (e, data, node) => {
238
+ ContextMenu.show([{ title: 'Remove Item', action: (e) => node.remove() }], e);
239
+ }
240
+ };
241
+ return cti;
242
+ }
243
+ addItem() {
244
+ const cmdName = this._possibleCommands.value;
245
+ const command = { type: cmdName };
246
+ const ti = this.createTreeItem(command);
247
+ this._commandListFancyTree.addChildren(ti);
248
+ }
249
+ getScriptCommands() {
250
+ let children = this._commandListFancyTree.root.children;
251
+ return children.map(x => x.data.data.item);
252
+ }
253
+ }
254
+ customElements.define(SimpleScriptEditor.is, SimpleScriptEditor);
@@ -0,0 +1,12 @@
1
+ /// <reference types="wunderbaum" />
2
+ import { IProperty, PropertyGrid } from '@node-projects/propertygrid.webcomponent';
3
+ import { WbRenderEventType } from "types";
4
+ import { VisualizationHandler } from '../interfaces/VisualizationHandler';
5
+ import { VisualizationShell } from '../interfaces/VisualizationShell';
6
+ import { ServiceContainer } from '@node-projects/web-component-designer';
7
+ export declare class VisualizationPropertyGrid extends PropertyGrid {
8
+ serviceContainer: ServiceContainer;
9
+ visualizationHandler: VisualizationHandler;
10
+ visualizationShell: VisualizationShell;
11
+ getEditorForType(property: IProperty, currentValue: any, propertyPath: string, wbRender: WbRenderEventType, additionalInfo?: any): Promise<HTMLElement>;
12
+ }
@@ -0,0 +1,104 @@
1
+ import { PropertyGrid } from '@node-projects/propertygrid.webcomponent';
2
+ import { BindableObjectsBrowser } from '@node-projects/web-component-designer-widgets-wunderbaum';
3
+ import { CodeViewMonaco } from '@node-projects/web-component-designer-codeview-monaco';
4
+ export class VisualizationPropertyGrid extends PropertyGrid {
5
+ serviceContainer;
6
+ visualizationHandler;
7
+ visualizationShell;
8
+ async getEditorForType(property, currentValue, propertyPath, wbRender, additionalInfo) {
9
+ switch (property.format) {
10
+ case 'screen': {
11
+ let editor = document.createElement('select');
12
+ editor.style.width = '100%';
13
+ for (let v of await this.visualizationHandler.getAllNames('screen')) {
14
+ const op = document.createElement('option');
15
+ op.value = v;
16
+ op.innerText = v;
17
+ editor.appendChild(op);
18
+ }
19
+ editor.onchange = () => {
20
+ this.setPropertyValue(propertyPath, editor.value);
21
+ };
22
+ editor.value = currentValue;
23
+ return editor;
24
+ }
25
+ case 'signal': {
26
+ let cnt = document.createElement('div');
27
+ cnt.style.display = 'flex';
28
+ let inp = document.createElement('input');
29
+ inp.value = currentValue ?? '';
30
+ inp.style.flexGrow = '1';
31
+ inp.style.width = '0';
32
+ inp.onchange = (e) => this.setPropertyValue(propertyPath, inp.value);
33
+ inp.onfocus = (e) => {
34
+ inp.selectionStart = 0;
35
+ inp.selectionEnd = inp.value?.length;
36
+ };
37
+ cnt.appendChild(inp);
38
+ let btn = document.createElement('button');
39
+ btn.textContent = '...';
40
+ btn.onclick = async () => {
41
+ let b = new BindableObjectsBrowser();
42
+ b.initialize(this.serviceContainer);
43
+ b.title = 'select signal...';
44
+ const abortController = new AbortController();
45
+ b.objectDoubleclicked.on(() => {
46
+ abortController.abort();
47
+ inp.value = b.selectedObject.fullName;
48
+ this.setPropertyValue(propertyPath, inp.value);
49
+ });
50
+ let res = await this.visualizationShell.openConfirmation(b, { x: 100, y: 100, width: 400, height: 300, parent: this, abortSignal: abortController.signal });
51
+ if (res) {
52
+ inp.value = b.selectedObject.fullName;
53
+ this.setPropertyValue(propertyPath, inp.value);
54
+ }
55
+ };
56
+ cnt.appendChild(btn);
57
+ return cnt;
58
+ }
59
+ case 'html':
60
+ case 'script': {
61
+ let editor = document.createElement('div');
62
+ editor.style.boxSizing = 'border-box';
63
+ editor.style.width = '100%';
64
+ editor.style.display = 'flex';
65
+ let inp = document.createElement('textarea');
66
+ inp.style.boxSizing = 'border-box';
67
+ inp.value = currentValue ?? '';
68
+ inp.style.width = '100%';
69
+ inp.onblur = e => { this.setPropertyValue(propertyPath, inp.value); };
70
+ editor.appendChild(inp);
71
+ let btn = document.createElement('button');
72
+ btn.innerHTML = '...';
73
+ btn.style.boxSizing = 'border-box';
74
+ btn.onclick = async () => {
75
+ let cvm = new CodeViewMonaco();
76
+ if (property.format == 'html') {
77
+ cvm.language = 'html';
78
+ }
79
+ else {
80
+ let monacoInfo = {
81
+ content: `declare global {
82
+ var context: { event: Event, element: Element };
83
+ }`, filePath: 'global.d.ts'
84
+ };
85
+ //@ts-ignore
86
+ monaco.languages.typescript.typescriptDefaults.setExtraLibs([monacoInfo]);
87
+ cvm.language = 'javascript';
88
+ }
89
+ cvm.code = inp.value;
90
+ cvm.style.position = 'relative';
91
+ let res = await this.visualizationShell.openConfirmation(cvm, { x: 200, y: 200, width: 600, height: 400, parent: this });
92
+ if (res) {
93
+ inp.value = cvm.getText();
94
+ this.setPropertyValue(propertyPath, inp.value);
95
+ }
96
+ };
97
+ editor.appendChild(btn);
98
+ return editor;
99
+ }
100
+ }
101
+ return super.getEditorForType(property, currentValue, propertyPath, wbRender, additionalInfo);
102
+ }
103
+ }
104
+ customElements.define("node-projects-visualization-property-grid", VisualizationPropertyGrid);
@@ -0,0 +1,47 @@
1
+ import { VisualizationBinding } from "../interfaces/VisualizationBinding.js";
2
+ import { BindingTarget } from "@node-projects/web-component-designer/dist/elements/item/BindingTarget.js";
3
+ import { State, VisualizationHandler } from "../interfaces/VisualizationHandler.js";
4
+ export declare const bindingPrefixProperty = "bind-prop:";
5
+ export declare const bindingPrefixAttribute = "bind-attr:";
6
+ export declare const bindingPrefixClass = "bind-class:";
7
+ export declare const bindingPrefixCss = "bind-css:";
8
+ export declare const bindingPrefixCssVar = "bind-cssvar:";
9
+ export declare const bindingPrefixContent = "bind-content:";
10
+ export declare const bindingsInCssRegex: RegExp;
11
+ export type namedBinding = [name: string, binding: VisualizationBinding];
12
+ export declare function isLit(element: Element): boolean;
13
+ export declare function parseBindingString(id: string): {
14
+ parts: string[];
15
+ signals: string[];
16
+ };
17
+ export declare class IndirectSignal {
18
+ private parts;
19
+ private signals;
20
+ private values;
21
+ private unsubscribeList;
22
+ private unsubscribeTargetValue;
23
+ private combinedName;
24
+ private disposed;
25
+ private valueChangedCb;
26
+ private visualizationHandler;
27
+ constructor(visualizationHandler: VisualizationHandler, id: string, valueChangedCb: (value: State) => void);
28
+ private parseIndirectBinding;
29
+ handleValueChanged(value: any, index: number): void;
30
+ dispose(): void;
31
+ setState(value: any): void;
32
+ }
33
+ export declare class BindingsHelper {
34
+ _visualizationHandler: VisualizationHandler;
35
+ constructor(visualizationHandler: VisualizationHandler);
36
+ parseBinding(element: Element, name: string, value: string, bindingTarget: BindingTarget, prefix: string): namedBinding;
37
+ serializeBinding(element: Element, targetName: string, binding: VisualizationBinding): [name: string, value: string];
38
+ getBindingAttributeName(element: Element, propertyName: string, propertyTarget: BindingTarget): string;
39
+ getBindings(element: Element): Generator<namedBinding, void, unknown>;
40
+ applyAllBindings(rootElement: ParentNode, relativeSignalPath: string, root: HTMLElement): (() => void)[];
41
+ applyBinding(element: Element, binding: namedBinding, relativeSignalPath: string, root: HTMLElement): () => void;
42
+ private addTwoWayBinding;
43
+ private static parseValueWithType;
44
+ handleValueChanged(element: Element, binding: namedBinding, value: any, valuesObject: any[], index: number, signalVarNames: string[], noParse: boolean): void;
45
+ static camelToDotCase(text: string): string;
46
+ static dotToCamelCase(text: string): string;
47
+ }