@node-projects/web-component-designer 0.0.60 → 0.0.64

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 (26) hide show
  1. package/ACKNOWLEDGMENTS +5 -0
  2. package/dist/elements/controls/SimpleSplitView.d.ts +11 -0
  3. package/dist/elements/controls/SimpleSplitView.js +66 -0
  4. package/dist/elements/controls/SimpleSplitView2.d.ts +11 -0
  5. package/dist/elements/controls/SimpleSplitView2.js +63 -0
  6. package/dist/elements/controls/aa.d.ts +24 -0
  7. package/dist/elements/controls/aa.js +98 -0
  8. package/dist/elements/documentContainer.d.ts +10 -0
  9. package/dist/elements/documentContainer.js +88 -12
  10. package/dist/elements/services/htmlParserService/NodeHtmlParserService.js +2 -0
  11. package/dist/elements/services/undoService/UndoService.js +3 -0
  12. package/dist/elements/widgets/codeView/ICodeView.d.ts +2 -0
  13. package/dist/elements/widgets/codeView/code-view-ace.d.ts +2 -1
  14. package/dist/elements/widgets/codeView/code-view-ace.js +3 -1
  15. package/dist/elements/widgets/codeView/code-view-code-mirror.d.ts +2 -1
  16. package/dist/elements/widgets/codeView/code-view-code-mirror.js +3 -1
  17. package/dist/elements/widgets/codeView/code-view-monaco.d.ts +2 -1
  18. package/dist/elements/widgets/codeView/code-view-monaco.js +11 -1
  19. package/dist/elements/widgets/designerView/IDesignerCanvas.d.ts +2 -0
  20. package/dist/elements/widgets/designerView/designerCanvas.d.ts +2 -1
  21. package/dist/elements/widgets/designerView/designerCanvas.js +3 -1
  22. package/dist/elements/widgets/designerView/designerView.d.ts +2 -1
  23. package/dist/elements/widgets/designerView/designerView.js +6 -2
  24. package/dist/elements/widgets/designerView/overlayLayerView.d.ts +1 -0
  25. package/dist/elements/widgets/designerView/overlayLayerView.js +6 -0
  26. package/package.json +39 -39
@@ -0,0 +1,5 @@
1
+ # Acknowledgments
2
+
3
+ - Thanks to @notwaldorf who created the original `wizzywid` project (MIT License).
4
+ https://github.com/PolymerLabs/wizzywid
5
+ This was a start for this whole project (even if mostly nothing of the original code is left)
@@ -0,0 +1,11 @@
1
+ import { BaseCustomWebComponentConstructorAppend } from "@node-projects/base-custom-webcomponent";
2
+ export declare class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
3
+ static readonly style: CSSStyleSheet;
4
+ static readonly template: HTMLTemplateElement;
5
+ static properties: {
6
+ orientation: StringConstructor;
7
+ };
8
+ orientation: 'vertical' | 'horizontal';
9
+ constructor();
10
+ ready(): void;
11
+ }
@@ -0,0 +1,66 @@
1
+ import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
2
+ export class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
3
+ static style = css `
4
+ :host {
5
+ display: block;
6
+ }
7
+ #split {
8
+ position: relative;
9
+ height: 100%;
10
+ width: 100%;
11
+ grid-template-rows: calc(var(--split) * 1%) 5px calc((100 - var(--split)) * 1%);
12
+ display: grid;
13
+ align-items: center;
14
+ }
15
+ #splitter {
16
+ user-select: none;
17
+ }
18
+ :host(:not([orientation="vertical"])) > div > #splitter {
19
+ cursor: ew-resize;
20
+ width: 5px;
21
+ }
22
+ :host([orientation="vertical"]) > div > #splitter {
23
+ cursor: ns-resize;
24
+ height: 5px;
25
+ }`;
26
+ static template = html `
27
+ <div id="split" style="--split: 50;">
28
+ <slot name="top"></slot>
29
+ <div id="splitter"></div>
30
+ <slot name="bottom"></slot>
31
+ </div>`;
32
+ static properties = {
33
+ orientation: String
34
+ };
35
+ orientation = 'vertical';
36
+ constructor() {
37
+ super();
38
+ }
39
+ ready() {
40
+ this._parseAttributesToProperties();
41
+ this.setAttribute('orientation', this.orientation);
42
+ const split = this._getDomElement("split");
43
+ const splitter = this._getDomElement("splitter");
44
+ let start = null;
45
+ splitter.addEventListener('pointerdown', (e) => {
46
+ splitter.setPointerCapture(e.pointerId);
47
+ start = true;
48
+ });
49
+ splitter.addEventListener('pointerup', (e) => {
50
+ splitter.releasePointerCapture(e.pointerId);
51
+ start = null;
52
+ });
53
+ splitter.addEventListener('pointermove', (e) => {
54
+ if (start !== null) {
55
+ let splitValue = parseFloat(split.style.getPropertyValue('--split'));
56
+ if (this.orientation === 'horizontal')
57
+ splitValue += e.movementX * 100 / split.clientWidth;
58
+ else
59
+ splitValue += e.movementY * 100 / split.clientHeight;
60
+ if (!isNaN(splitValue))
61
+ split.style.setProperty("--split", splitValue);
62
+ }
63
+ });
64
+ }
65
+ }
66
+ customElements.define('node-projects-simple-split-view', SimpleSplitView);
@@ -0,0 +1,11 @@
1
+ import { BaseCustomWebComponentConstructorAppend } from "@node-projects/base-custom-webcomponent";
2
+ export declare class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
3
+ static readonly style: CSSStyleSheet;
4
+ static readonly template: HTMLTemplateElement;
5
+ static properties: {
6
+ orientation: StringConstructor;
7
+ };
8
+ orientation: 'vertical' | 'horizontal';
9
+ constructor();
10
+ ready(): void;
11
+ }
@@ -0,0 +1,63 @@
1
+ import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
2
+ export class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
3
+ static style = css `
4
+ :host {
5
+ display: block;
6
+ }
7
+ #split {
8
+ position: relative;
9
+ height: 100%;
10
+ width: 100%;
11
+ grid-template-rows: calc(var(--split) * 1%) 5px calc((100 - var(--split)) * 1%);
12
+ display: grid;
13
+ align-items: center;
14
+ }
15
+ :host(:not([orientation="vertical"])) > div > #splitter {
16
+ cursor: ew-resize;
17
+ width: 5px;
18
+ }
19
+ :host([orientation="vertical"]) > div > #splitter {
20
+ cursor: ns-resize;
21
+ height: 5px;
22
+ }`;
23
+ static template = html `
24
+ <div id="split" style="--split: 50;">
25
+ <slot name="top"></slot>
26
+ <div id="splitter"></div>
27
+ <slot name="bottom"></slot>
28
+ </div>`;
29
+ static properties = {
30
+ orientation: String
31
+ };
32
+ orientation = 'vertical';
33
+ constructor() {
34
+ super();
35
+ }
36
+ ready() {
37
+ this._parseAttributesToProperties();
38
+ this.setAttribute('orientation', this.orientation);
39
+ const split = this._getDomElement("split");
40
+ const splitter = this._getDomElement("splitter");
41
+ let start = null;
42
+ splitter.addEventListener('pointerdown', (e) => {
43
+ splitter.setPointerCapture(e.pointerId);
44
+ start = true;
45
+ });
46
+ splitter.addEventListener('pointerup', (e) => {
47
+ splitter.releasePointerCapture(e.pointerId);
48
+ start = null;
49
+ });
50
+ splitter.addEventListener('pointermove', (e) => {
51
+ if (start !== null) {
52
+ let splitValue = parseFloat(split.style.getPropertyValue('--split'));
53
+ if (this.orientation === 'horizontal')
54
+ splitValue += e.movementX * 100 / split.clientWidth;
55
+ else
56
+ splitValue += e.movementY * 100 / split.clientHeight;
57
+ if (!isNaN(splitValue))
58
+ split.style.setProperty("--split", splitValue);
59
+ }
60
+ });
61
+ }
62
+ }
63
+ customElements.define('node-projects-simple-split-view', SimpleSplitView);
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Split View is an image comparison component
3
+ *
4
+ * <split-view>
5
+ * <picture slot="top">[...]</picture>
6
+ * <picture slot="bottom">[...]</picture>
7
+ * </split-view>
8
+ *
9
+ * Options are;
10
+ *
11
+ * start (number) The point where the comparison line should start (0 = left, 1000 = right)
12
+ * mode (string) A CSS mix-blend-mode to use for comparison
13
+ */
14
+ import { BaseCustomWebComponentConstructorAppend } from "@node-projects/base-custom-webcomponent";
15
+ export declare class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
16
+ static readonly style: CSSStyleSheet;
17
+ static readonly template: HTMLTemplateElement;
18
+ static properties: {
19
+ start: NumberConstructor;
20
+ };
21
+ constructor();
22
+ start: number;
23
+ ready(): void;
24
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Split View is an image comparison component
3
+ *
4
+ * <split-view>
5
+ * <picture slot="top">[...]</picture>
6
+ * <picture slot="bottom">[...]</picture>
7
+ * </split-view>
8
+ *
9
+ * Options are;
10
+ *
11
+ * start (number) The point where the comparison line should start (0 = left, 1000 = right)
12
+ * mode (string) A CSS mix-blend-mode to use for comparison
13
+ */
14
+ import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
15
+ export class SimpleSplitView extends BaseCustomWebComponentConstructorAppend {
16
+ static style = css `
17
+ :host {
18
+ display: block;
19
+ }
20
+ :host([hidden]) { display: none }
21
+ .split {
22
+ position: relative;
23
+ height: 100%;
24
+ display: grid;
25
+ align-items: center;
26
+ --split: 100;
27
+ }
28
+ .top,
29
+ .bottom {
30
+ position: absolute;
31
+ top: 0;
32
+ left: 0;
33
+ right: 0;
34
+ bottom: 0;
35
+ }
36
+ .bottom {
37
+ background-color: red;
38
+ }
39
+ .top {
40
+ z-index: 2;
41
+ right: calc(8px + (((100% - 16px) / 100) * (100 - var(--split))));
42
+ overflow: hidden;
43
+ border-right: 1px solid white;
44
+ }
45
+ input {
46
+ position: absolute;
47
+ width: 100%;
48
+ height: 100%;
49
+ margin: 0;
50
+ padding: 0;
51
+ z-index: 3;
52
+ background-color: transparent;
53
+ -webkit-appearance: none;
54
+ }
55
+ input[type="range"]:focus {
56
+ outline: var(--outline, -webkit-focus-ring-color auto 1px);
57
+ }`;
58
+ static template = html `
59
+ <div class="split" id="split" role="img" aria-label="Comparison of two images">
60
+ <div class="bottom" id="bottom" aria-label="First image to compare">
61
+ <slot name="bottom"></slot>
62
+ </div>
63
+ <div class="top" id="top" aria-label="Second image to compare">
64
+ <slot name="top"></slot>
65
+ </div>
66
+ <label id="label" for="slider">Slide left and right to compare images</label>
67
+ <input type="range" role="slider" min="0" max="100" value="50" name="slider" id="slider" aria-labelledby="label" aria-valuemin="0" aria-valuemax="100">
68
+ </div>`;
69
+ static properties = {
70
+ start: Number
71
+ };
72
+ constructor() {
73
+ super();
74
+ }
75
+ start;
76
+ ready() {
77
+ this._parseAttributesToProperties();
78
+ const splitter = this._getDomElement("split");
79
+ const slider = this._getDomElement("slider");
80
+ const label = this._getDomElement("label");
81
+ const top = this._getDomElement("top");
82
+ const splitViewLabelText = this.getAttribute("split-view-label") || 'Comparison of two images';
83
+ const sliderLabelText = this.getAttribute("slider-label") || 'Press left and right to compare images';
84
+ const mode = this.getAttribute("mode") || "normal";
85
+ slider.addEventListener("input", (event) => {
86
+ const split = +event.target.value;
87
+ splitter.style.setProperty("--split", split);
88
+ slider.setAttribute('aria-valuenow', split);
89
+ });
90
+ splitter.style.setProperty("--split", this.start);
91
+ slider.setAttribute('aria-valuenow', this.start);
92
+ slider.value = this.start;
93
+ splitter.setAttribute('aria-label', splitViewLabelText);
94
+ label.innerText = sliderLabelText;
95
+ top.style.mixBlendMode = mode;
96
+ }
97
+ }
98
+ customElements.define('node-projects-simple-split-view', SimpleSplitView);
@@ -7,6 +7,7 @@ import { IDemoView } from './widgets/demoView/IDemoView';
7
7
  import { IUiCommandHandler } from "../commandHandling/IUiCommandHandler";
8
8
  import { IUiCommand } from "../commandHandling/IUiCommand";
9
9
  import { IDisposable } from "../interfaces/IDisposable";
10
+ import { ISelectionChangedEvent } from "./services/selectionService/ISelectionChangedEvent.js";
10
11
  export declare class DocumentContainer extends BaseCustomWebComponentLazyAppend implements IUiCommandHandler, IDisposable {
11
12
  designerView: DesignerView;
12
13
  codeView: ICodeView & HTMLElement;
@@ -16,8 +17,17 @@ export declare class DocumentContainer extends BaseCustomWebComponentLazyAppend
16
17
  private _content;
17
18
  private _tabControl;
18
19
  private _selectionPosition;
20
+ private _splitDiv;
21
+ private _designerDiv;
22
+ private _codeDiv;
23
+ private refreshInSplitViewDebounced;
24
+ private _disableChangeNotificationDesigner;
25
+ private _disableChangeNotificationEditor;
19
26
  static get style(): CSSStyleSheet;
20
27
  constructor(serviceContainer: ServiceContainer, content?: string);
28
+ refreshInSplitView(): Promise<void>;
29
+ designerSelectionChanged(e: ISelectionChangedEvent): void;
30
+ designerContentChanged(): void;
21
31
  dispose(): void;
22
32
  executeCommand(command: IUiCommand): void;
23
33
  canExecuteCommand(command: IUiCommand): boolean;
@@ -1,6 +1,7 @@
1
- import { BaseCustomWebComponentLazyAppend, css } from "@node-projects/base-custom-webcomponent";
1
+ import { BaseCustomWebComponentLazyAppend, css, debounce } from "@node-projects/base-custom-webcomponent";
2
2
  import { DesignerTabControl } from "./controls/DesignerTabControl";
3
3
  import { DesignerView } from "./widgets/designerView/designerView";
4
+ import { SimpleSplitView } from './controls/SimpleSplitView';
4
5
  export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
5
6
  designerView;
6
7
  codeView;
@@ -10,6 +11,12 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
10
11
  _content = '';
11
12
  _tabControl;
12
13
  _selectionPosition;
14
+ _splitDiv;
15
+ _designerDiv;
16
+ _codeDiv;
17
+ refreshInSplitViewDebounced;
18
+ _disableChangeNotificationDesigner;
19
+ _disableChangeNotificationEditor;
13
20
  static get style() {
14
21
  return css `
15
22
  div {
@@ -19,11 +26,13 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
19
26
  }
20
27
  node-projects-designer-view {
21
28
  height: 100%;
22
- /*overflow: auto;*/
23
- }`;
29
+ overflow: hidden;
30
+ }
31
+ `;
24
32
  }
25
33
  constructor(serviceContainer, content) {
26
34
  super();
35
+ this.refreshInSplitViewDebounced = debounce(this.refreshInSplitView, 200);
27
36
  this._serviceContainer = serviceContainer;
28
37
  if (content != null)
29
38
  this._content = content;
@@ -32,12 +41,33 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
32
41
  div.appendChild(this._tabControl);
33
42
  this.designerView = new DesignerView();
34
43
  this.designerView.setAttribute('exportparts', 'canvas');
35
- this.designerView.title = 'Designer';
36
- this._tabControl.appendChild(this.designerView);
44
+ this.designerView.slot = 'top';
45
+ this._designerDiv = document.createElement("div");
46
+ this._tabControl.appendChild(this._designerDiv);
47
+ this._designerDiv.title = 'Designer';
48
+ this._designerDiv.appendChild(this.designerView);
37
49
  this.designerView.initialize(this._serviceContainer);
50
+ this.designerView.instanceServiceContainer.selectionService.onSelectionChanged.on(e => this.designerSelectionChanged(e));
51
+ this.designerView.designerCanvas.onContentChanged.on(() => this.designerContentChanged());
38
52
  this.codeView = new serviceContainer.config.codeViewWidget();
39
- this.codeView.title = 'Code';
40
- this._tabControl.appendChild(this.codeView);
53
+ this.codeView.slot = 'bottom';
54
+ this._codeDiv = document.createElement("div");
55
+ this._tabControl.appendChild(this._codeDiv);
56
+ this._codeDiv.title = 'Code';
57
+ this._codeDiv.appendChild(this.codeView);
58
+ this.codeView.onTextChanged.on(text => {
59
+ if (!this._disableChangeNotificationDesigner) {
60
+ this._disableChangeNotificationEditor = true;
61
+ if (this._tabControl.selectedIndex === 2) {
62
+ this._content = text;
63
+ this.refreshInSplitViewDebounced();
64
+ }
65
+ }
66
+ });
67
+ this._splitDiv = new SimpleSplitView();
68
+ this._splitDiv.style.height = '100%';
69
+ this._splitDiv.title = 'Split';
70
+ this._tabControl.appendChild(this._splitDiv);
41
71
  this.demoView = new serviceContainer.config.demoViewWidget();
42
72
  this.demoView.title = 'Preview';
43
73
  this._tabControl.appendChild(this.demoView);
@@ -46,6 +76,40 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
46
76
  this._tabControl.selectedIndex = 0;
47
77
  });
48
78
  }
79
+ async refreshInSplitView() {
80
+ await this.designerView.parseHTML(this._content);
81
+ this._disableChangeNotificationEditor = false;
82
+ }
83
+ designerSelectionChanged(e) {
84
+ if (this._tabControl.selectedIndex === 2) {
85
+ let primarySelection = this.instanceServiceContainer.selectionService.primarySelection;
86
+ if (primarySelection) {
87
+ let designItemsAssignmentList = new Map();
88
+ this._content = this.designerView.getHTML(designItemsAssignmentList);
89
+ this._selectionPosition = designItemsAssignmentList.get(primarySelection);
90
+ this.codeView.setSelection(this._selectionPosition);
91
+ this._selectionPosition = null;
92
+ }
93
+ }
94
+ }
95
+ designerContentChanged() {
96
+ if (!this._disableChangeNotificationEditor) {
97
+ this._disableChangeNotificationDesigner = true;
98
+ if (this._tabControl.selectedIndex === 2) {
99
+ let primarySelection = this.instanceServiceContainer.selectionService.primarySelection;
100
+ let designItemsAssignmentList = new Map();
101
+ this._content = this.designerView.getHTML(designItemsAssignmentList);
102
+ this.codeView.update(this._content);
103
+ if (primarySelection) {
104
+ this._selectionPosition = designItemsAssignmentList.get(primarySelection);
105
+ if (this._selectionPosition)
106
+ this.codeView.setSelection(this._selectionPosition);
107
+ this._selectionPosition = null;
108
+ }
109
+ }
110
+ this._disableChangeNotificationDesigner = false;
111
+ }
112
+ }
49
113
  dispose() {
50
114
  this.codeView.dispose();
51
115
  }
@@ -69,7 +133,9 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
69
133
  this.designerView.parseHTML(this._content);
70
134
  else if (this._tabControl.selectedIndex === 1)
71
135
  this.codeView.update(this._content);
72
- else if (this._tabControl.selectedIndex === 2)
136
+ else if (this._tabControl.selectedIndex === 2) {
137
+ }
138
+ else if (this._tabControl.selectedIndex === 3)
73
139
  this.demoView.display(this._serviceContainer, this.designerView.instanceServiceContainer, this._content);
74
140
  }
75
141
  }
@@ -91,11 +157,16 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
91
157
  this._content = this.designerView.getHTML(designItemsAssignmentList);
92
158
  this._selectionPosition = designItemsAssignmentList.get(primarySelection);
93
159
  }
94
- else if (i.oldIndex === 1)
160
+ else if (i.oldIndex === 1) {
95
161
  this._content = this.codeView.getText();
96
- if (i.newIndex === 0)
162
+ }
163
+ else if (i.oldIndex === 2) {
164
+ this._designerDiv.appendChild(this.designerView);
165
+ this._codeDiv.appendChild(this.codeView);
166
+ }
167
+ if (i.newIndex === 0 || i.newIndex === 2)
97
168
  this.designerView.parseHTML(this._content);
98
- else if (i.newIndex === 1) {
169
+ if (i.newIndex === 1 || i.newIndex === 2) {
99
170
  this.codeView.update(this._content);
100
171
  if (this._selectionPosition) {
101
172
  this.codeView.setSelection(this._selectionPosition);
@@ -105,8 +176,13 @@ export class DocumentContainer extends BaseCustomWebComponentLazyAppend {
105
176
  this.codeView.focusEditor();
106
177
  }
107
178
  }
108
- else if (i.newIndex === 2)
179
+ if (i.newIndex === 2) {
180
+ this._splitDiv.appendChild(this.designerView);
181
+ this._splitDiv.appendChild(this.codeView);
182
+ }
183
+ if (i.newIndex === 3) {
109
184
  this.demoView.display(this._serviceContainer, this.designerView.instanceServiceContainer, this._content);
185
+ }
110
186
  });
111
187
  if (this._content)
112
188
  this.content = this._content;
@@ -62,6 +62,8 @@ export class NodeHtmlParserService {
62
62
  designItem.setStyle(s.name, s.value);
63
63
  }
64
64
  }
65
+ if (element instanceof HTMLElement || element instanceof SVGElement)
66
+ element.style.pointerEvents = 'auto';
65
67
  designItem.hideAtDesignTime = hideAtDesignTime;
66
68
  designItem.hideAtRunTime = hideAtRunTime;
67
69
  designItem.lockAtDesignTime = lockAtDesignTime;
@@ -42,6 +42,7 @@ export class UndoService {
42
42
  this._transactionStack[this._transactionStack.length - 1].execute(item);
43
43
  }
44
44
  this._designerCanvas.extensionManager.refreshAllExtensions(item.affectedItems);
45
+ this._designerCanvas.onContentChanged.emit();
45
46
  }
46
47
  clear() {
47
48
  this._undoStack = [];
@@ -63,6 +64,7 @@ export class UndoService {
63
64
  throw err;
64
65
  }
65
66
  this._designerCanvas.extensionManager.refreshAllExtensions(item.affectedItems);
67
+ this._designerCanvas.onContentChanged.emit();
66
68
  }
67
69
  redo() {
68
70
  if (!this.canRedo())
@@ -79,6 +81,7 @@ export class UndoService {
79
81
  throw err;
80
82
  }
81
83
  this._designerCanvas.extensionManager.refreshAllExtensions(item.affectedItems);
84
+ this._designerCanvas.onContentChanged.emit();
82
85
  }
83
86
  canUndo() {
84
87
  return this._undoStack.length > 0;
@@ -1,9 +1,11 @@
1
1
  import { IUiCommandHandler } from "../../../commandHandling/IUiCommandHandler";
2
2
  import { IDisposable } from "../../../interfaces/IDisposable";
3
3
  import { IStringPosition } from "../../services/htmlWriterService/IStringPosition";
4
+ import { TypedEvent } from '@node-projects/base-custom-webcomponent';
4
5
  export interface ICodeView extends IUiCommandHandler, IDisposable {
5
6
  update(code: string): any;
6
7
  getText(): any;
7
8
  setSelection(position: IStringPosition): any;
8
9
  focusEditor(): any;
10
+ onTextChanged: TypedEvent<string>;
9
11
  }
@@ -1,4 +1,4 @@
1
- import { BaseCustomWebComponentLazyAppend } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentLazyAppend, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  import { ICodeView } from "./ICodeView";
3
3
  import { IStringPosition } from '../../services/htmlWriterService/IStringPosition';
4
4
  import { IUiCommand } from '../../../commandHandling/IUiCommand';
@@ -7,6 +7,7 @@ export declare class CodeViewAce extends BaseCustomWebComponentLazyAppend implem
7
7
  canvasElement: HTMLElement;
8
8
  elementsToPackages: Map<string, string>;
9
9
  code: string;
10
+ onTextChanged: TypedEvent<string>;
10
11
  private _aceEditor;
11
12
  private _editor;
12
13
  static readonly style: CSSStyleSheet;
@@ -1,4 +1,4 @@
1
- import { BaseCustomWebComponentLazyAppend, css } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentLazyAppend, css, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  import { CommandType } from '../../../commandHandling/CommandType';
3
3
  class CodeViewAceCompleter {
4
4
  getCompletions(editor, session, pos, prefix, callback) {
@@ -18,6 +18,7 @@ export class CodeViewAce extends BaseCustomWebComponentLazyAppend {
18
18
  canvasElement;
19
19
  elementsToPackages;
20
20
  code;
21
+ onTextChanged = new TypedEvent();
21
22
  _aceEditor;
22
23
  _editor;
23
24
  static style = css `
@@ -111,6 +112,7 @@ export class CodeViewAce extends BaseCustomWebComponentLazyAppend {
111
112
  });
112
113
  let config = { attributes: true, childList: true, characterData: true };
113
114
  observer.observe(this.shadowRoot.querySelector('.ace_content'), config);
115
+ this._aceEditor.on('change', () => this.onTextChanged.emit(this._aceEditor.getValue()));
114
116
  }
115
117
  update(code) {
116
118
  this._aceEditor.setValue(code);
@@ -1,4 +1,4 @@
1
- import { BaseCustomWebComponentLazyAppend } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentLazyAppend, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  import { ICodeView } from "./ICodeView";
3
3
  import { IStringPosition } from '../../services/htmlWriterService/IStringPosition';
4
4
  import { IUiCommand } from '../../../commandHandling/IUiCommand';
@@ -7,6 +7,7 @@ export declare class CodeViewCodeMirror extends BaseCustomWebComponentLazyAppend
7
7
  canvasElement: HTMLElement;
8
8
  elementsToPackages: Map<string, string>;
9
9
  code: string;
10
+ onTextChanged: TypedEvent<string>;
10
11
  private _codeMirrorEditor;
11
12
  private _editor;
12
13
  static readonly style: CSSStyleSheet;
@@ -1,9 +1,10 @@
1
- import { BaseCustomWebComponentLazyAppend, css, html } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentLazyAppend, css, html, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  import { CommandType } from '../../../commandHandling/CommandType';
3
3
  export class CodeViewCodeMirror extends BaseCustomWebComponentLazyAppend {
4
4
  canvasElement;
5
5
  elementsToPackages;
6
6
  code;
7
+ onTextChanged = new TypedEvent();
7
8
  _codeMirrorEditor;
8
9
  _editor;
9
10
  static style = css `
@@ -82,6 +83,7 @@ export class CodeViewCodeMirror extends BaseCustomWebComponentLazyAppend {
82
83
  //@ts-ignore
83
84
  this._codeMirrorEditor = CodeMirror(this._editor, config);
84
85
  this._codeMirrorEditor.setSize('100%', '100%');
86
+ this._codeMirrorEditor.on('change', () => this.onTextChanged.emit(this._codeMirrorEditor.getValue()));
85
87
  }
86
88
  update(code) {
87
89
  this._codeMirrorEditor.setValue(code);
@@ -1,4 +1,4 @@
1
- import { BaseCustomWebComponentLazyAppend } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentLazyAppend, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  import { ICodeView } from "./ICodeView";
3
3
  import { IActivateable } from '../../../interfaces/IActivateable';
4
4
  import { IStringPosition } from '../../services/htmlWriterService/IStringPosition';
@@ -9,6 +9,7 @@ export declare class CodeViewMonaco extends BaseCustomWebComponentLazyAppend imp
9
9
  canvasElement: HTMLElement;
10
10
  elementsToPackages: Map<string, string>;
11
11
  code: string;
12
+ onTextChanged: TypedEvent<string>;
12
13
  private _monacoEditor;
13
14
  private _editor;
14
15
  static readonly style: CSSStyleSheet;
@@ -1,4 +1,4 @@
1
- import { BaseCustomWebComponentLazyAppend, css, html } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentLazyAppend, css, html, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  import { CommandType } from '../../../commandHandling/CommandType';
3
3
  export class CodeViewMonaco extends BaseCustomWebComponentLazyAppend {
4
4
  dispose() {
@@ -7,6 +7,7 @@ export class CodeViewMonaco extends BaseCustomWebComponentLazyAppend {
7
7
  canvasElement;
8
8
  elementsToPackages;
9
9
  code;
10
+ onTextChanged = new TypedEvent();
10
11
  _monacoEditor;
11
12
  _editor;
12
13
  static style = css `
@@ -69,6 +70,15 @@ export class CodeViewMonaco extends BaseCustomWebComponentLazyAppend {
69
70
  }
70
71
  });
71
72
  this._monacoEditor.layout();
73
+ let changeContentListener = this._monacoEditor.getModel().onDidChangeContent(e => {
74
+ this.onTextChanged.emit(this._monacoEditor.getValue());
75
+ });
76
+ this._monacoEditor.onDidChangeModel(e => {
77
+ changeContentListener.dispose();
78
+ changeContentListener = this._monacoEditor.getModel().onDidChangeContent(e => {
79
+ this.onTextChanged.emit(this._monacoEditor.getValue());
80
+ });
81
+ });
72
82
  });
73
83
  }
74
84
  focusEditor() {
@@ -8,6 +8,7 @@ import { IUiCommandHandler } from "../../../commandHandling/IUiCommandHandler";
8
8
  import { IPoint } from "../../../interfaces/IPoint";
9
9
  import { OverlayLayerView } from "./overlayLayerView";
10
10
  import { IRect } from "../../../interfaces/IRect.js";
11
+ import { TypedEvent } from "@node-projects/base-custom-webcomponent";
11
12
  export interface IDesignerCanvas extends IPlacementView, IUiCommandHandler {
12
13
  readonly serviceContainer: ServiceContainer;
13
14
  readonly instanceServiceContainer: InstanceServiceContainer;
@@ -19,6 +20,7 @@ export interface IDesignerCanvas extends IPlacementView, IUiCommandHandler {
19
20
  readonly shadowRoot: ShadowRoot;
20
21
  readonly alignOnGrid: boolean;
21
22
  readonly alignOnSnap: boolean;
23
+ readonly onContentChanged: TypedEvent<void>;
22
24
  zoomFactor: number;
23
25
  eatEvents: Element;
24
26
  initialize(serviceContainer: ServiceContainer): any;
@@ -1,7 +1,7 @@
1
1
  import { ServiceContainer } from '../../services/ServiceContainer';
2
2
  import { InstanceServiceContainer } from '../../services/InstanceServiceContainer';
3
3
  import { IDesignItem } from '../../item/IDesignItem';
4
- import { BaseCustomWebComponentLazyAppend } from '@node-projects/base-custom-webcomponent';
4
+ import { BaseCustomWebComponentLazyAppend, TypedEvent } from '@node-projects/base-custom-webcomponent';
5
5
  import { IDesignerCanvas } from './IDesignerCanvas';
6
6
  import { Snaplines } from './Snaplines';
7
7
  import { ContextMenuHelper } from '../../helper/contextMenu/ContextMenuHelper';
@@ -28,6 +28,7 @@ export declare class DesignerCanvas extends BaseCustomWebComponentLazyAppend imp
28
28
  private _zoomFactor;
29
29
  get zoomFactor(): number;
30
30
  set zoomFactor(value: number);
31
+ onContentChanged: TypedEvent<void>;
31
32
  private _canvas;
32
33
  private _canvasContainer;
33
34
  private _outercanvas2;
@@ -3,7 +3,7 @@ import { InstanceServiceContainer } from '../../services/InstanceServiceContaine
3
3
  import { UndoService } from '../../services/undoService/UndoService';
4
4
  import { SelectionService } from '../../services/selectionService/SelectionService';
5
5
  import { DesignItem } from '../../item/DesignItem';
6
- import { BaseCustomWebComponentLazyAppend, css, html } from '@node-projects/base-custom-webcomponent';
6
+ import { BaseCustomWebComponentLazyAppend, css, html, TypedEvent } from '@node-projects/base-custom-webcomponent';
7
7
  import { dragDropFormatName } from '../../../Constants';
8
8
  import { ContentService } from '../../services/contentService/ContentService';
9
9
  import { InsertAction } from '../../services/undoService/transactionItems/InsertAction';
@@ -42,6 +42,7 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
42
42
  this._zoomFactor = value;
43
43
  this.zoomFactorChanged();
44
44
  }
45
+ onContentChanged = new TypedEvent();
45
46
  // Private Variables
46
47
  _canvas;
47
48
  _canvasContainer;
@@ -330,6 +331,7 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
330
331
  }
331
332
  setDesignItems(designItems) {
332
333
  this.instanceServiceContainer.undoService.clear();
334
+ this.overlayLayer.removeAllOverlays();
333
335
  DomHelper.removeAllChildnodes(this.overlayLayer);
334
336
  this.rootDesignItem.clearChildren();
335
337
  this.addDesignItems(designItems);
@@ -11,11 +11,12 @@ export declare class DesignerView extends BaseCustomWebComponentConstructorAppen
11
11
  set serviceContainer(value: ServiceContainer);
12
12
  get instanceServiceContainer(): InstanceServiceContainer;
13
13
  set instanceServiceContainer(value: InstanceServiceContainer);
14
+ private _designerCanvas;
15
+ get designerCanvas(): DesignerCanvas;
14
16
  private _zoomInput;
15
17
  private _lowertoolbar;
16
18
  static readonly style: CSSStyleSheet;
17
19
  static readonly template: HTMLTemplateElement;
18
- private _designerCanvas;
19
20
  constructor();
20
21
  private _onWheel;
21
22
  get designerWidth(): string;
@@ -16,6 +16,10 @@ export class DesignerView extends BaseCustomWebComponentConstructorAppend {
16
16
  set instanceServiceContainer(value) {
17
17
  this._designerCanvas.instanceServiceContainer = value;
18
18
  }
19
+ _designerCanvas;
20
+ get designerCanvas() {
21
+ return this._designerCanvas;
22
+ }
19
23
  _zoomInput;
20
24
  _lowertoolbar;
21
25
  static style = css `
@@ -99,7 +103,6 @@ export class DesignerView extends BaseCustomWebComponentConstructorAppend {
99
103
  <div title="snap to elements" id="alignSnap" class="toolbar-control snap-guide"></div>
100
104
  </div>
101
105
  </div>`;
102
- _designerCanvas;
103
106
  constructor() {
104
107
  super();
105
108
  const outer = this._getDomElement('outer');
@@ -196,13 +199,14 @@ export class DesignerView extends BaseCustomWebComponentConstructorAppend {
196
199
  }
197
200
  }
198
201
  getHTML(designItemsAssignmentList) {
199
- this.instanceServiceContainer.selectionService.setSelectedElements(null);
202
+ //this.instanceServiceContainer.selectionService.setSelectedElements(null);
200
203
  return DomConverter.ConvertToString([...this._designerCanvas.rootDesignItem.children()], designItemsAssignmentList);
201
204
  }
202
205
  async parseHTML(html) {
203
206
  const parserService = this.serviceContainer.htmlParserService;
204
207
  if (!html) {
205
208
  this.instanceServiceContainer.undoService.clear();
209
+ this._designerCanvas.overlayLayer.removeAllOverlays();
206
210
  DomHelper.removeAllChildnodes(this._designerCanvas.overlayLayer);
207
211
  this._designerCanvas.rootDesignItem.clearChildren();
208
212
  }
@@ -15,6 +15,7 @@ export declare class OverlayLayerView extends BaseCustomWebComponentConstructorA
15
15
  addOverlay(element: SVGGraphicsElement, overlayLayer?: OverlayLayer): void;
16
16
  removeOverlay(element: SVGGraphicsElement): void;
17
17
  removeAllNodesWithClass(className: string): void;
18
+ removeAllOverlays(): void;
18
19
  createPoint(): DOMPointInit;
19
20
  elementFromPoint(x: number, y: number): Element;
20
21
  drawLine(x1: number, y1: number, x2: number, y2: number, className?: string, line?: SVGLineElement, overlayLayer?: OverlayLayer): SVGLineElement;
@@ -80,6 +80,12 @@ export class OverlayLayerView extends BaseCustomWebComponentConstructorAppend {
80
80
  e.parentNode.removeChild(e);
81
81
  }
82
82
  }
83
+ removeAllOverlays() {
84
+ const nodes = this._svg.querySelectorAll('svg > g > *');
85
+ for (const e of nodes) {
86
+ e.parentNode.removeChild(e);
87
+ }
88
+ }
83
89
  createPoint() {
84
90
  //@ts-ignore
85
91
  return this._svg.createSVGPoint();
package/package.json CHANGED
@@ -1,39 +1,39 @@
1
- {
2
- "description": "A UI designer for Polymer apps",
3
- "name": "@node-projects/web-component-designer",
4
- "version": "0.0.60",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "author": "",
8
- "license": "MIT",
9
- "scripts": {
10
- "tsc": "tsc",
11
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
12
- },
13
- "dependencies": {
14
- "@node-projects/base-custom-webcomponent": "^0.3.5",
15
- "construct-style-sheets-polyfill": "^3.0.4"
16
- },
17
- "devDependencies": {
18
- "@node-projects/lean-he-esm": "^3.3.0",
19
- "@node-projects/node-html-parser-esm": "^2.4.1",
20
- "@types/codemirror": "^5.60.5",
21
- "@types/jquery": "^3.5.9",
22
- "@types/jquery.fancytree": "0.0.7",
23
- "ace-builds": "^1.4.13",
24
- "codemirror": "^5.64.0",
25
- "esprima-next": "^5.7.0",
26
- "html2canvas": "*",
27
- "jest": "^27.4.3",
28
- "jquery": "^3.6.0",
29
- "jquery.fancytree": "^2.38.0",
30
- "monaco-editor": "^0.30.1",
31
- "ts-jest": "^27.1.0",
32
- "typescript": "^4.5.2",
33
- "typescript-lit-html-plugin": "^0.9.0"
34
- },
35
- "repository": {
36
- "type": "git",
37
- "url": "git+https://github.com/node-projects/web-component-designer.git"
38
- }
39
- }
1
+ {
2
+ "description": "A UI designer for Polymer apps",
3
+ "name": "@node-projects/web-component-designer",
4
+ "version": "0.0.64",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "author": "",
8
+ "license": "MIT",
9
+ "scripts": {
10
+ "tsc": "tsc",
11
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
12
+ },
13
+ "dependencies": {
14
+ "@node-projects/base-custom-webcomponent": "^0.3.7",
15
+ "construct-style-sheets-polyfill": "^3.0.4"
16
+ },
17
+ "devDependencies": {
18
+ "@node-projects/lean-he-esm": "^3.3.0",
19
+ "@node-projects/node-html-parser-esm": "^2.4.1",
20
+ "@types/codemirror": "^5.60.5",
21
+ "@types/jquery": "^3.5.9",
22
+ "@types/jquery.fancytree": "0.0.7",
23
+ "ace-builds": "^1.4.13",
24
+ "codemirror": "^5.64.0",
25
+ "esprima-next": "^5.7.0",
26
+ "html2canvas": "*",
27
+ "jest": "^27.4.3",
28
+ "jquery": "^3.6.0",
29
+ "jquery.fancytree": "^2.38.0",
30
+ "monaco-editor": "^0.30.1",
31
+ "ts-jest": "^27.1.1",
32
+ "typescript": "^4.5.2",
33
+ "typescript-lit-html-plugin": "^0.9.0"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/node-projects/web-component-designer.git"
38
+ }
39
+ }