@node-projects/web-component-designer 0.1.123 → 0.1.125

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 (43) hide show
  1. package/dist/elements/item/DesignItem.d.ts +5 -1
  2. package/dist/elements/item/DesignItem.js +30 -8
  3. package/dist/elements/item/IDesignItem.d.ts +2 -1
  4. package/dist/elements/services/copyPasteService/CopyPasteAsJsonService.js +4 -2
  5. package/dist/elements/services/copyPasteService/CopyPasteService.js +4 -2
  6. package/dist/elements/services/selectionService/ISelectionChangedEvent copy.d.ts +6 -0
  7. package/dist/elements/services/selectionService/ISelectionChangedEvent copy.js +1 -0
  8. package/dist/elements/widgets/designerView/extensions/AbstractToolbarExtension.d.ts +9 -0
  9. package/dist/elements/widgets/designerView/extensions/AbstractToolbarExtension.js +30 -0
  10. package/dist/elements/widgets/designerView/extensions/BasicDisplayToolbarExtension.d.ts +20 -0
  11. package/dist/elements/widgets/designerView/extensions/BasicDisplayToolbarExtension.js +68 -0
  12. package/dist/elements/widgets/designerView/extensions/BlockToolbarExtension.d.ts +12 -0
  13. package/dist/elements/widgets/designerView/extensions/BlockToolbarExtension.js +40 -0
  14. package/dist/elements/widgets/designerView/extensions/ConditionExtensionProvider.d.ts +13 -0
  15. package/dist/elements/widgets/designerView/extensions/ConditionExtensionProvider.js +18 -0
  16. package/dist/elements/widgets/designerView/extensions/EditText/EditTextExtension.d.ts +1 -0
  17. package/dist/elements/widgets/designerView/extensions/EditText/EditTextExtension.js +12 -3
  18. package/dist/elements/widgets/designerView/extensions/EditText/EditTextExtensionProvider.js +2 -0
  19. package/dist/elements/widgets/designerView/extensions/EditTextExtension.d.ts +18 -0
  20. package/dist/elements/widgets/designerView/extensions/EditTextExtension.js +107 -0
  21. package/dist/elements/widgets/designerView/extensions/GridToolbarExtension.d.ts +12 -0
  22. package/dist/elements/widgets/designerView/extensions/GridToolbarExtension.js +58 -0
  23. package/dist/elements/widgets/designerView/extensions/block/FlexToolbarExtension.d.ts +12 -0
  24. package/dist/elements/widgets/designerView/extensions/block/FlexToolbarExtension.js +34 -0
  25. package/dist/elements/widgets/designerView/extensions/block/FlexToolbarExtensionProvider.d.ts +9 -0
  26. package/dist/elements/widgets/designerView/extensions/block/FlexToolbarExtensionProvider.js +12 -0
  27. package/dist/elements/widgets/designerView/extensions/flex/GridToolbarExtension.d.ts +12 -0
  28. package/dist/elements/widgets/designerView/extensions/flex/GridToolbarExtension.js +66 -0
  29. package/dist/elements/widgets/designerView/extensions/flex/GridToolbarExtensionProvider.d.ts +10 -0
  30. package/dist/elements/widgets/designerView/extensions/flex/GridToolbarExtensionProvider.js +17 -0
  31. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtension copy.d.ts +12 -0
  32. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtension copy.js +66 -0
  33. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtensionProvider copy.d.ts +10 -0
  34. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtensionProvider copy.js +17 -0
  35. package/dist/elements/widgets/designerView/extensions/grid/ResizeExtension.d.ts +28 -0
  36. package/dist/elements/widgets/designerView/extensions/grid/ResizeExtension.js +355 -0
  37. package/dist/elements/widgets/designerView/extensions/grid/ResizeExtensionProvider.d.ts +12 -0
  38. package/dist/elements/widgets/designerView/extensions/grid/ResizeExtensionProvider.js +20 -0
  39. package/dist/elements/widgets/designerView/extensions/svg/RectExtensionProvider copy.d.ts +9 -0
  40. package/dist/elements/widgets/designerView/extensions/svg/RectExtensionProvider copy.js +14 -0
  41. package/dist/elements/widgets/designerView/extensions/svg/SvgBaseExtension.d.ts +30 -0
  42. package/dist/elements/widgets/designerView/extensions/svg/SvgBaseExtension.js +181 -0
  43. package/package.json +1 -1
@@ -70,7 +70,11 @@ export declare class DesignItem implements IDesignItem {
70
70
  static createDesignItemFromInstance(node: Node, serviceContainer: ServiceContainer, instanceServiceContainer: InstanceServiceContainer): DesignItem;
71
71
  querySelectorAll(selectors: string): NodeListOf<HTMLElement>;
72
72
  removeDesignerAttributesAndStylesFromChildren(): void;
73
- updateChildrenFromNodesChildren(): void;
73
+ _internalUpdateChildrenFromNodesChildren(): any[];
74
+ _backupWhenEditContent: any;
75
+ _inEditContent: boolean;
76
+ editContent(): void;
77
+ editContentFinish(): void;
74
78
  constructor(node: Node, parsedNode: any, serviceContainer: ServiceContainer, instanceServiceContainer: InstanceServiceContainer);
75
79
  setView(node: Element): void;
76
80
  openGroup(title: string): ChangeGroup;
@@ -339,7 +339,10 @@ export class DesignItem {
339
339
  }
340
340
  node.draggable = false; //even if it should be true, for better designer exp.
341
341
  }
342
- designItem.updateChildrenFromNodesChildren();
342
+ designItem._childArray = designItem._internalUpdateChildrenFromNodesChildren();
343
+ for (let c of designItem._childArray) {
344
+ c._parent = designItem;
345
+ }
343
346
  return designItem;
344
347
  }
345
348
  querySelectorAll(selectors) {
@@ -360,25 +363,44 @@ export class DesignItem {
360
363
  e.style.pointerEvents = '';
361
364
  }
362
365
  }
363
- updateChildrenFromNodesChildren() {
364
- this._childArray = [];
366
+ _internalUpdateChildrenFromNodesChildren() {
367
+ const newChilds = [];
365
368
  if (this.nodeType == NodeType.Element) {
366
369
  if (this.element instanceof HTMLTemplateElement) {
367
370
  for (const c of this.element.content.childNodes) {
368
371
  const di = DesignItem.createDesignItemFromInstance(c, this.serviceContainer, this.instanceServiceContainer);
369
- this._childArray.push(di);
370
- di._parent = this;
372
+ newChilds.push(di);
371
373
  }
372
374
  }
373
375
  else {
374
376
  for (const c of this.element.childNodes) {
375
377
  const di = DesignItem.createDesignItemFromInstance(c, this.serviceContainer, this.instanceServiceContainer);
376
- this._childArray.push(di);
377
- di._parent = this;
378
+ newChilds.push(di);
378
379
  }
379
380
  }
380
381
  }
381
- this._refreshIfStyleSheet();
382
+ return newChilds;
383
+ }
384
+ _backupWhenEditContent;
385
+ _inEditContent = false;
386
+ editContent() {
387
+ this._inEditContent = true;
388
+ this._backupWhenEditContent = [...this.element.childNodes];
389
+ const nn = this.element.innerHTML;
390
+ this.element.innerHTML = '';
391
+ this.element.innerHTML = nn;
392
+ this.element.setAttribute('contenteditable', '');
393
+ }
394
+ editContentFinish() {
395
+ if (this._inEditContent) {
396
+ this._inEditContent = false;
397
+ this.element.removeAttribute('contenteditable');
398
+ this.element.innerHTML = '';
399
+ for (let n of this._backupWhenEditContent) {
400
+ this.element.appendChild(n);
401
+ }
402
+ this._backupWhenEditContent = null;
403
+ }
382
404
  }
383
405
  constructor(node, parsedNode, serviceContainer, instanceServiceContainer) {
384
406
  this.node = node;
@@ -37,7 +37,8 @@ export interface IDesignItem {
37
37
  remove(): any;
38
38
  clearChildren(): any;
39
39
  removeDesignerAttributesAndStylesFromChildren(): any;
40
- updateChildrenFromNodesChildren(): any;
40
+ editContent(): any;
41
+ editContentFinish(): any;
41
42
  readonly hasContent: boolean;
42
43
  content: string;
43
44
  innerHTML?: string;
@@ -1,10 +1,12 @@
1
1
  import { DomConverter } from "../../widgets/designerView/DomConverter.js";
2
2
  import { copyToClipboard, getFromClipboard, getTextFromClipboard } from "../../helper/ClipboardHelper.js";
3
3
  import { DesignItem } from "../../item/DesignItem.js";
4
+ import { filterChildPlaceItems } from "../../helper/LayoutHelper.js";
4
5
  export class CopyPasteAsJsonService {
5
6
  async copyItems(designItems) {
6
- const copyText = DomConverter.ConvertToString(designItems, false);
7
- const positions = designItems.map(x => x.instanceServiceContainer.designerCanvas.getNormalizedElementCoordinates(x.element));
7
+ const items = filterChildPlaceItems(designItems);
8
+ const copyText = DomConverter.ConvertToString(items, false);
9
+ const positions = items.map(x => x.instanceServiceContainer.designerCanvas.getNormalizedElementCoordinates(x.element));
8
10
  let data = { html: copyText, positions: positions };
9
11
  copyToClipboard([["application/json", JSON.stringify(data)]]);
10
12
  }
@@ -1,10 +1,12 @@
1
1
  import { DomConverter } from "../../widgets/designerView/DomConverter.js";
2
2
  import { copyToClipboard, getFromClipboard, getTextFromClipboard } from "../../helper/ClipboardHelper.js";
3
+ import { filterChildPlaceItems } from "../../helper/LayoutHelper.js";
3
4
  export const positionsJsonMime = 'web text/positions';
4
5
  export class CopyPasteService {
5
6
  async copyItems(designItems) {
6
- const copyText = DomConverter.ConvertToString(designItems, false);
7
- const positions = designItems.map(x => x.instanceServiceContainer.designerCanvas.getNormalizedElementCoordinates(x.element));
7
+ const items = filterChildPlaceItems(designItems);
8
+ const copyText = DomConverter.ConvertToString(items, false);
9
+ const positions = items.map(x => x.instanceServiceContainer.designerCanvas.getNormalizedElementCoordinates(x.element));
8
10
  copyToClipboard([["text/html", copyText], [positionsJsonMime, JSON.stringify(positions)]]);
9
11
  }
10
12
  async getPasteItems(serviceContainer, instanceServiceContainer) {
@@ -0,0 +1,6 @@
1
+ import { IDesignItem } from '../../item/IDesignItem.js';
2
+ export interface ISelectionChangedEvent {
3
+ oldSelectedElements: IDesignItem[];
4
+ selectedElements: IDesignItem[];
5
+ event?: Event;
6
+ }
@@ -0,0 +1,9 @@
1
+ import { AbstractExtension } from "./AbstractExtension.js";
2
+ import { IPoint } from "../../../../interfaces/IPoint.js";
3
+ export declare abstract class AbstractToolbarExtension extends AbstractExtension {
4
+ abstract template: HTMLTemplateElement;
5
+ protected _toolbarContainer: SVGForeignObjectElement;
6
+ extend(cache: Record<string | symbol, any>, event: MouseEvent): void;
7
+ refresh(cache: Record<string | symbol, any>, event?: MouseEvent): void;
8
+ protected updateToolbarPosition(position: IPoint): void;
9
+ }
@@ -0,0 +1,30 @@
1
+ import { OverlayLayer } from "../OverlayLayer.js";
2
+ import { AbstractExtension } from "./AbstractExtension.js";
3
+ export class AbstractToolbarExtension extends AbstractExtension {
4
+ _toolbarContainer;
5
+ extend(cache, event) {
6
+ const element = this.template.content.cloneNode(true);
7
+ element.querySelectorAll('*').forEach(x => x.onpointerdown = (e) => {
8
+ this.designerCanvas.ignoreEvent(e);
9
+ });
10
+ const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
11
+ this._toolbarContainer = foreignObject;
12
+ foreignObject.classList.add('svg-toolbar-container');
13
+ foreignObject.setAttribute('width', '1');
14
+ foreignObject.setAttribute('height', '1');
15
+ foreignObject.appendChild(element);
16
+ this.refresh(cache, event);
17
+ this._addOverlay(foreignObject, OverlayLayer.Foreground);
18
+ }
19
+ refresh(cache, event) {
20
+ if (event) {
21
+ const pos = this.designerCanvas.getNormalizedEventCoordinates(event);
22
+ this._toolbarContainer.setAttribute('x', '' + (pos.x - 16));
23
+ this._toolbarContainer.setAttribute('y', '' + (pos.y - 36));
24
+ }
25
+ }
26
+ updateToolbarPosition(position) {
27
+ this._toolbarContainer.setAttribute('x', '' + position.x);
28
+ this._toolbarContainer.setAttribute('y', '' + position.y);
29
+ }
30
+ }
@@ -0,0 +1,20 @@
1
+ import { AbstractExtension, toolbarObject } from "./AbstractExtension.js";
2
+ import { IExtensionManager } from "./IExtensionManger.js";
3
+ import { IDesignerCanvas } from "../IDesignerCanvas.js";
4
+ import { IDesignItem } from "../../../item/IDesignItem.js";
5
+ export declare class BasicStackedToolbarExtension extends AbstractExtension {
6
+ protected static basicTemplate: string;
7
+ protected _toolbar: toolbarObject;
8
+ protected _size: {
9
+ width: number;
10
+ height: number;
11
+ };
12
+ protected _display: string;
13
+ protected _inline: string;
14
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
15
+ extend(cache: Record<string | symbol, any>, event: MouseEvent): void;
16
+ updateDisplayValue(): Promise<void>;
17
+ refresh(cache: Record<string | symbol, any>, event?: MouseEvent): void;
18
+ protected _addStyleButton(styleAndControlName: string): void;
19
+ dispose(): void;
20
+ }
@@ -0,0 +1,68 @@
1
+ import { assetsPath } from "../../../../Constants.js";
2
+ import { AbstractExtension } from "./AbstractExtension.js";
3
+ export class BasicStackedToolbarExtension extends AbstractExtension {
4
+ static basicTemplate = `
5
+ <node-projects-image-button-list-selector id="inline" no-value-in-header property="inline">
6
+ <img data-value="block" title="block" src="${assetsPath}images/display/block.svg">
7
+ <img data-value="inline" title="inline" src="${assetsPath}images/display/inline.svg">
8
+ </node-projects-image-button-list-selector>
9
+ <select title="display" id="displayType" style="pointer-events: all; height: 24px; width: 70px; padding: 0; font-weight: 900; text-transform: uppercase; margin-left: 5px; margin-right: 10px;">
10
+ <option>block</option>
11
+ <option>flex</option>
12
+ <option>grid</option>
13
+ </select>
14
+ `;
15
+ _toolbar;
16
+ _size = { width: 200, height: 30 };
17
+ _display;
18
+ _inline;
19
+ constructor(extensionManager, designerView, extendedItem) {
20
+ super(extensionManager, designerView, extendedItem);
21
+ }
22
+ extend(cache, event) {
23
+ const cs = getComputedStyle(this.extendedItem.element);
24
+ this._display = cs.display.replace('inline-', '').replace('inline', 'block');
25
+ this._inline = cs.display.startsWith('inline') ? 'inline' : 'block';
26
+ //@ts-ignore
27
+ this._toolbar = this.createToolbar(this.constructor.template, this._size.width, this._size.height);
28
+ const displayTypeEl = this._toolbar.getById('displayType');
29
+ displayTypeEl.value = this._display;
30
+ displayTypeEl.onchange = async () => {
31
+ this._display = displayTypeEl.value;
32
+ await this.updateDisplayValue();
33
+ this.extensionManager.reapplyAllAppliedExtentions([this.extendedItem]);
34
+ };
35
+ const inlineEl = this._toolbar.getById('inline');
36
+ inlineEl.value = this._inline;
37
+ inlineEl.addEventListener('value-changed', async () => {
38
+ this._inline = inlineEl.value;
39
+ if (this._inline && cs.position === 'absolute')
40
+ this.extendedItem.setStyle('position', 'static');
41
+ await this.updateDisplayValue();
42
+ this.extensionManager.reapplyAllAppliedExtentions([this.extendedItem]);
43
+ });
44
+ }
45
+ async updateDisplayValue() {
46
+ let v = (this._inline == 'inline' ? 'inline ' : '') + this._display;
47
+ if (v === 'inline block')
48
+ v = 'inline';
49
+ await this.extendedItem.updateStyleInSheetOrLocalAsync('display', v);
50
+ }
51
+ refresh(cache, event) {
52
+ if (event) {
53
+ const pos = this.designerCanvas.getNormalizedEventCoordinates(event);
54
+ this._toolbar.updatePosition({ x: (pos.x - (16 / this.designerCanvas.zoomFactor)), y: (pos.y - (44 / this.designerCanvas.zoomFactor)) });
55
+ }
56
+ }
57
+ _addStyleButton(styleAndControlName) {
58
+ const cs = getComputedStyle(this.extendedItem.element);
59
+ const ctl = this._toolbar.getById(styleAndControlName);
60
+ ctl.addEventListener('value-changed', async () => {
61
+ await this.extendedItem.updateStyleInSheetOrLocalAsync(styleAndControlName, ctl.value);
62
+ });
63
+ ctl.value = cs[styleAndControlName];
64
+ }
65
+ dispose() {
66
+ this._removeAllOverlays();
67
+ }
68
+ }
@@ -0,0 +1,12 @@
1
+ import { IDesignItem } from '../../../../item/IDesignItem.js';
2
+ import { IDesignerCanvas } from '../../IDesignerCanvas.js';
3
+ import { AbstractExtension } from "../AbstractExtension.js";
4
+ import { IExtensionManager } from '../IExtensionManger.js';
5
+ export declare class BlockToolbarExtension extends AbstractExtension {
6
+ private static template;
7
+ private _toolbar;
8
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
9
+ extend(cache: Record<string | symbol, any>, event: MouseEvent): void;
10
+ refresh(cache: Record<string | symbol, any>, event?: MouseEvent): void;
11
+ dispose(): void;
12
+ }
@@ -0,0 +1,40 @@
1
+ import { html } from "@node-projects/base-custom-webcomponent";
2
+ import { AbstractExtension } from "../AbstractExtension.js";
3
+ import { assetsPath } from "../../../../../Constants.js";
4
+ export class BlockToolbarExtension extends AbstractExtension {
5
+ static template = html `
6
+ <div style="height: 100%; width: 100%;">
7
+ <node-projects-image-button-list-selector>
8
+ <img data-value="block" title="block" src="${assetsPath}images/display/block.svg">
9
+ <img data-value="inline" title="inline" src="${assetsPath}images/display/inline.svg">
10
+ </node-projects-image-button-list-selector>
11
+ <select title="display" id="displayType" style="pointer-events: all; height: 24px; width: 70px; padding: 0; font-weight: 900; text-transform: uppercase; margin-right: 10px;">
12
+ <option selected>block</option>
13
+ <option>flex</option>
14
+ <option>grid</option>
15
+ </select>
16
+ </div>
17
+ `;
18
+ _toolbar;
19
+ constructor(extensionManager, designerView, extendedItem) {
20
+ super(extensionManager, designerView, extendedItem);
21
+ }
22
+ extend(cache, event) {
23
+ this._toolbar = this.createToolbar(BlockToolbarExtension.template, 200, 30);
24
+ const displayTypeEl = this._toolbar.getById('displayType');
25
+ displayTypeEl.onchange = () => {
26
+ this.extendedItem.updateStyleInSheetOrLocal('display', displayTypeEl.value);
27
+ this.extensionManager.reapplyAllAppliedExtentions([this.extendedItem]);
28
+ };
29
+ this.refresh(cache, event);
30
+ }
31
+ refresh(cache, event) {
32
+ if (event) {
33
+ const pos = this.designerCanvas.getNormalizedEventCoordinates(event);
34
+ this._toolbar.updatePosition({ x: (pos.x - (16 / this.designerCanvas.zoomFactor)), y: (pos.y - (44 / this.designerCanvas.zoomFactor)) });
35
+ }
36
+ }
37
+ dispose() {
38
+ this._removeAllOverlays();
39
+ }
40
+ }
@@ -0,0 +1,13 @@
1
+ import { IDesignerExtensionProvider } from './IDesignerExtensionProvider.js';
2
+ import { IDesignItem } from '../../../item/IDesignItem.js';
3
+ import { IDesignerCanvas } from '../IDesignerCanvas.js';
4
+ import { IDesignerExtension } from './IDesignerExtension.js';
5
+ import { IExtensionManager } from './IExtensionManger.js';
6
+ export declare class ConditionExtensionProvider implements IDesignerExtensionProvider {
7
+ constructor(extensionProvider: IDesignerExtensionProvider, condition: (designItem: IDesignItem) => boolean);
8
+ extensionProvider: IDesignerExtensionProvider;
9
+ condition: (designItem: IDesignItem) => boolean;
10
+ style: CSSStyleSheet;
11
+ shouldExtend(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): boolean;
12
+ getExtension(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): IDesignerExtension;
13
+ }
@@ -0,0 +1,18 @@
1
+ export class ConditionExtensionProvider {
2
+ constructor(extensionProvider, condition) {
3
+ this.extensionProvider = extensionProvider;
4
+ this.condition = condition;
5
+ this.style = extensionProvider.style;
6
+ }
7
+ extensionProvider;
8
+ condition;
9
+ style;
10
+ shouldExtend(extensionManager, designerView, designItem) {
11
+ if (!this.condition(designItem))
12
+ return false;
13
+ return this.extensionProvider.shouldExtend(extensionManager, designerView, designItem);
14
+ }
15
+ getExtension(extensionManager, designerView, designItem) {
16
+ return this.extensionProvider.getExtension(extensionManager, designerView, designItem);
17
+ }
18
+ }
@@ -10,6 +10,7 @@ export declare class EditTextExtension extends AbstractExtension implements hand
10
10
  private _foreignObject;
11
11
  private _path;
12
12
  private _toolbar;
13
+ private _selectionChangedListener;
13
14
  constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
14
15
  extend(): void;
15
16
  refresh(): void;
@@ -35,6 +35,7 @@ export class EditTextExtension extends AbstractExtension {
35
35
  _foreignObject;
36
36
  _path;
37
37
  _toolbar;
38
+ _selectionChangedListener;
38
39
  constructor(extensionManager, designerView, extendedItem) {
39
40
  super(extensionManager, designerView, extendedItem);
40
41
  }
@@ -44,6 +45,12 @@ export class EditTextExtension extends AbstractExtension {
44
45
  this.extendedItem.instanceServiceContainer.selectionService.clearSelectedElements();
45
46
  this.extendedItem.removeDesignerAttributesAndStylesFromChildren();
46
47
  this.extendedItem.element.setAttribute('contenteditable', '');
48
+ //@ts-ignore
49
+ this.extendedItem.editContent();
50
+ this._selectionChangedListener = this.extendedItem.instanceServiceContainer.selectionService.onSelectionChanged.on(() => {
51
+ this.commitchanges();
52
+ this.extensionManager.removeExtensionInstance(this.extendedItem, this);
53
+ });
47
54
  this.extendedItem.element.focus();
48
55
  let itemRect = this.extendedItem.element.getBoundingClientRect();
49
56
  this._toolbar = this.createToolbar(EditTextExtension.template, 300, 24);
@@ -80,14 +87,16 @@ export class EditTextExtension extends AbstractExtension {
80
87
  this._path.setAttribute("d", data);
81
88
  }
82
89
  dispose() {
90
+ this._selectionChangedListener.dispose();
83
91
  this._removeAllOverlays();
84
- this.extendedItem.element.removeAttribute('contenteditable');
92
+ this.extendedItem.editContentFinish();
85
93
  this.designerCanvas.clickOverlay.style.pointerEvents = 'auto';
86
94
  }
87
95
  commitchanges() {
88
96
  this._removeAllOverlays();
89
- this.extendedItem.element.removeAttribute('contenteditable');
90
- this.extendedItem.updateChildrenFromNodesChildren();
97
+ const newHTML = this.extendedItem.element.innerHTML;
98
+ this.extendedItem.editContentFinish();
99
+ this.extendedItem.innerHTML = newHTML;
91
100
  this.designerCanvas.clickOverlay.style.pointerEvents = 'auto';
92
101
  }
93
102
  handlesPointerEvent(designerCanvas, event, currentElement) {
@@ -2,6 +2,8 @@ import { EditTextExtension } from "./EditTextExtension.js";
2
2
  import { css } from '@node-projects/base-custom-webcomponent';
3
3
  export class EditTextExtensionProvider {
4
4
  shouldExtend(extensionManager, designerView, designItem) {
5
+ if (designItem.isRootItem)
6
+ return false;
5
7
  if (designItem.name === 'input')
6
8
  return false;
7
9
  return true;
@@ -0,0 +1,18 @@
1
+ import { IDesignItem } from '../../../../item/IDesignItem.js';
2
+ import { IDesignerCanvas } from '../../IDesignerCanvas.js';
3
+ import { AbstractExtension } from "../AbstractExtension.js";
4
+ import { IExtensionManager } from '../IExtensionManger.js';
5
+ export type handlesPointerEvent = {
6
+ handlesPointerEvent(designerCanvas: IDesignerCanvas, event: PointerEvent, currentElement: Element): boolean;
7
+ };
8
+ export declare class EditTextExtension extends AbstractExtension implements handlesPointerEvent {
9
+ private static template;
10
+ private _foreignObject;
11
+ private _path;
12
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
13
+ extend(): void;
14
+ refresh(): void;
15
+ dispose(): void;
16
+ handlesPointerEvent(designerCanvas: IDesignerCanvas, event: PointerEvent, currentElement: Element): boolean;
17
+ _formatSelection(type: string, value?: string): void;
18
+ }
@@ -0,0 +1,107 @@
1
+ import { html } from "@node-projects/base-custom-webcomponent";
2
+ import { AbstractExtension } from "../AbstractExtension.js";
3
+ import { OverlayLayer } from "../OverlayLayer.js";
4
+ import { getDesignerCanvasNormalizedTransformedCornerDOMPoints } from "../../../../helper/TransformHelper.js";
5
+ import { shadowrootGetSelection, wrapSelectionInSpans } from "../../../../helper/SelectionHelper.js";
6
+ import { FontPropertyEditor } from "../../../../services/propertiesService/propertyEditors/FontPropertyEditor.js";
7
+ export class EditTextExtension extends AbstractExtension {
8
+ static template = html `
9
+ <div style="height: 24px; display: flex; gap: 2px;">
10
+ <button data-command="font-weight" data-command-parameter="800" style="pointer-events: all; height: 24px; width: 24px; padding: 0; font-weight: 900;">b</button>
11
+ <button data-command="font-style" data-command-parameter="italic" style="pointer-events: all; height: 24px; width: 24px; padding: 0;"><em>i</em></button>
12
+ <button data-command="text-decoration" data-command-parameter="underline" style="pointer-events: all; height: 24px; width: 24px; padding: 0;"><ins>u</ins></button>
13
+ <button data-command="text-decoration" data-command-parameter="line-through" style="pointer-events: all; height: 24px; width: 24px; padding: 0;"><del>s</del></button>
14
+ <button data-command="text-decoration" data-command-parameter="overline" style="pointer-events: all; height: 24px; width: 24px; padding: 0;"><span style="text-decoration: overline">o</span></button>
15
+ <select data-command="fontSize" style="pointer-events: all; height: 24px; width: 60px; padding: 0;">
16
+ <option>8px</option>
17
+ <option>9px</option>
18
+ <option>10px</option>
19
+ <option>11px</option>
20
+ <option>12px</option>
21
+ <option>14px</option>
22
+ <option>16px</option>
23
+ <option>18px</option>
24
+ <option>20px</option>
25
+ <option>24px</option>
26
+ <option>28px</option>
27
+ <option>32px</option>
28
+ <option>36px</option>
29
+ </select>
30
+ <select id="fontFamily" data-command="font-family" style="pointer-events: all; height: 24px; width: 90px; padding: 0;">
31
+
32
+ </select>
33
+ </div>
34
+ `;
35
+ _foreignObject;
36
+ _path;
37
+ constructor(extensionManager, designerView, extendedItem) {
38
+ super(extensionManager, designerView, extendedItem);
39
+ }
40
+ extend() {
41
+ //TODO: -> check what to do with extensions, do not loose edit on mouse click,...
42
+ //maybe use a html edit framework
43
+ this.extendedItem.instanceServiceContainer.selectionService.clearSelectedElements();
44
+ this.extendedItem.removeDesignerAttributesAndStylesFromChildren();
45
+ this.extendedItem.element.setAttribute('contenteditable', '');
46
+ this.extendedItem.element.focus();
47
+ let itemRect = this.extendedItem.element.getBoundingClientRect();
48
+ const elements = EditTextExtension.template.content.cloneNode(true);
49
+ FontPropertyEditor.addFontsToSelect(elements.querySelector('#fontFamily'));
50
+ elements.querySelectorAll('button').forEach(x => x.onpointerdown = (e) => {
51
+ this.designerCanvas.ignoreEvent(e);
52
+ this._formatSelection(x.dataset['command'], x.dataset['commandParameter']);
53
+ });
54
+ elements.querySelectorAll('select').forEach(x => x.onpointerdown = (e) => this.designerCanvas.ignoreEvent(e));
55
+ elements.querySelectorAll('select').forEach(x => x.onchange = () => this._formatSelection(x.dataset['command'], x.value));
56
+ //Button overlay
57
+ const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
58
+ this._foreignObject = foreignObject;
59
+ foreignObject.setAttribute('x', '' + (itemRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor);
60
+ foreignObject.setAttribute('y', '' + ((itemRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor - 30));
61
+ foreignObject.setAttribute('width', '300');
62
+ foreignObject.setAttribute('height', '24');
63
+ foreignObject.appendChild(elements);
64
+ this._addOverlay(foreignObject, OverlayLayer.Foreground);
65
+ //TODO - nice way to disable click overlay
66
+ this.designerCanvas.clickOverlay.style.pointerEvents = 'none';
67
+ //overlay to detect click outside
68
+ this._path = document.createElementNS("http://www.w3.org/2000/svg", "path");
69
+ this._path.setAttribute('class', 'svg-edit-text-clickoutside');
70
+ this._path.setAttribute('fill-rule', 'evenodd');
71
+ this._path.style.pointerEvents = 'auto';
72
+ this._path.onpointerdown = (e) => {
73
+ this.extensionManager.removeExtensionInstance(this.extendedItem, this);
74
+ };
75
+ this._addOverlay(this._path, OverlayLayer.Background);
76
+ let points = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
77
+ let outsideRect = { width: this.designerCanvas.containerBoundingRect.width / this.designerCanvas.scaleFactor, height: this.designerCanvas.containerBoundingRect.height / this.designerCanvas.scaleFactor };
78
+ let data = "M0 0 L" + outsideRect.width + " 0 L" + outsideRect.width + ' ' + outsideRect.height + " L0 " + outsideRect.height + " Z ";
79
+ data += "M" + points[0].x + " " + points[0].y + " L" + points[1].x + " " + points[1].y + " L" + points[3].x + " " + points[3].y + " L" + points[2].x + " " + points[2].y + " Z";
80
+ this._path.setAttribute("d", data);
81
+ }
82
+ refresh() {
83
+ let points = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
84
+ let outsideRect = { width: this.designerCanvas.containerBoundingRect.width / this.designerCanvas.scaleFactor, height: this.designerCanvas.containerBoundingRect.height / this.designerCanvas.scaleFactor };
85
+ let data = "M0 0 L" + outsideRect.width + " 0 L" + outsideRect.width + ' ' + outsideRect.height + " L0 " + outsideRect.height + " Z ";
86
+ data += "M" + points[0].x + " " + points[0].y + " L" + points[1].x + " " + points[1].y + " L" + points[3].x + " " + points[3].y + " L" + points[2].x + " " + points[2].y + " Z";
87
+ this._path.setAttribute("d", data);
88
+ }
89
+ dispose() {
90
+ this._removeAllOverlays();
91
+ this.extendedItem.element.removeAttribute('contenteditable');
92
+ this.extendedItem.updateChildrenFromNodesChildren();
93
+ this.designerCanvas.clickOverlay.style.pointerEvents = 'auto';
94
+ }
95
+ handlesPointerEvent(designerCanvas, event, currentElement) {
96
+ const p = event.composedPath();
97
+ const stylo = this._foreignObject.querySelector('stylo-editor');
98
+ return p.indexOf(stylo) >= 0;
99
+ }
100
+ _formatSelection(type, value) {
101
+ const selection = shadowrootGetSelection(this.designerCanvas.rootDesignItem.element.shadowRoot);
102
+ const spans = wrapSelectionInSpans(selection);
103
+ for (const span of spans)
104
+ span.style[type] = value;
105
+ this.extendedItem.element.focus();
106
+ }
107
+ }
@@ -0,0 +1,12 @@
1
+ import { IDesignItem } from '../../../../item/IDesignItem.js';
2
+ import { IDesignerCanvas } from '../../IDesignerCanvas.js';
3
+ import { AbstractExtension } from "../AbstractExtension.js";
4
+ import { IExtensionManager } from '../IExtensionManger.js';
5
+ export declare class GridToolbarExtension extends AbstractExtension {
6
+ private static template;
7
+ private _foreignObject;
8
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
9
+ extend(cache: Record<string | symbol, any>, event: MouseEvent): void;
10
+ refresh(cache: Record<string | symbol, any>, event?: MouseEvent): void;
11
+ dispose(): void;
12
+ }
@@ -0,0 +1,58 @@
1
+ import { html } from "@node-projects/base-custom-webcomponent";
2
+ import { AbstractExtension } from "../AbstractExtension.js";
3
+ import { OverlayLayer } from "../OverlayLayer.js";
4
+ export class GridToolbarExtension extends AbstractExtension {
5
+ static template = html `
6
+ <div style="height: 30px; width: 200px;">
7
+ <span>GRID</span>
8
+ <select id="gridType" style="pointer-events: all; height: 24px; width: 60px; padding: 0;">
9
+ <option>1x1</option>
10
+ <option>1x16</option>
11
+ <option>2x8</option>
12
+ <option>4x4</option>
13
+ <option>8x2</option>
14
+ <option>16x1</option>
15
+ <option>custom</option>
16
+ </select>
17
+ </div>
18
+ `;
19
+ _foreignObject;
20
+ constructor(extensionManager, designerView, extendedItem) {
21
+ super(extensionManager, designerView, extendedItem);
22
+ }
23
+ extend(cache, event) {
24
+ const element = GridToolbarExtension.template.content.cloneNode(true);
25
+ element.querySelectorAll('*').forEach(x => x.onpointerdown = (e) => {
26
+ this.designerCanvas.ignoreEvent(e);
27
+ //this._formatSelection(x.dataset['command'], x.dataset['commandParameter'])
28
+ });
29
+ //element.querySelectorAll('select').forEach(x => x.onpointerdown = (e) => this.designerCanvas.ignoreEvent(e));
30
+ const gridTypeEl = element.querySelector('#gridType');
31
+ gridTypeEl.onchange = () => {
32
+ const parts = gridTypeEl.value.split('x');
33
+ this.extendedItem.updateStyleInSheetOrLocal('grid-template-columns', '1fr '.repeat(parseInt(parts[0])).trim());
34
+ this.extendedItem.updateStyleInSheetOrLocal('grid-template-rows', '1fr '.repeat(parseInt(parts[1])).trim());
35
+ };
36
+ //elements.querySelectorAll('select').forEach(x => x.onchange = () => this._formatSelection(x.dataset['command'], x.value));
37
+ //overlay
38
+ const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
39
+ this._foreignObject = foreignObject;
40
+ foreignObject.classList.add('svg-toolbar');
41
+ foreignObject.setAttribute('width', '1');
42
+ foreignObject.setAttribute('height', '1');
43
+ foreignObject.appendChild(element);
44
+ this.refresh(cache, event);
45
+ this._addOverlay(foreignObject, OverlayLayer.Foreground);
46
+ }
47
+ refresh(cache, event) {
48
+ if (event) {
49
+ const pos = this.designerCanvas.getNormalizedEventCoordinates(event);
50
+ //debugger;
51
+ this._foreignObject.setAttribute('x', '' + (pos.x - 16));
52
+ this._foreignObject.setAttribute('y', '' + (pos.y - 36));
53
+ }
54
+ }
55
+ dispose() {
56
+ this._removeAllOverlays();
57
+ }
58
+ }
@@ -0,0 +1,12 @@
1
+ import { IDesignItem } from '../../../../item/IDesignItem.js';
2
+ import { IDesignerCanvas } from '../../IDesignerCanvas.js';
3
+ import { AbstractExtension } from "../AbstractExtension.js";
4
+ import { IExtensionManager } from '../IExtensionManger.js';
5
+ export declare class FlexToolbarExtension extends AbstractExtension {
6
+ private static template;
7
+ private _toolbar;
8
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
9
+ extend(cache: Record<string | symbol, any>, event: MouseEvent): void;
10
+ refresh(cache: Record<string | symbol, any>, event?: MouseEvent): void;
11
+ dispose(): void;
12
+ }