@node-projects/web-component-designer 0.1.108 → 0.1.110

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 (51) hide show
  1. package/assets/images/display/block.svg +1 -0
  2. package/assets/images/display/inline.svg +1 -0
  3. package/dist/elements/controls/ImageButtonListSelector.d.ts +9 -6
  4. package/dist/elements/controls/ImageButtonListSelector.js +25 -6
  5. package/dist/elements/item/DesignItem.d.ts +2 -0
  6. package/dist/elements/item/DesignItem.js +55 -8
  7. package/dist/elements/item/IDesignItem.d.ts +2 -0
  8. package/dist/elements/services/DefaultServiceBootstrap.js +2 -0
  9. package/dist/elements/services/dragDropService/DragDropService.js +3 -1
  10. package/dist/elements/services/placementService/DefaultPlacementService.d.ts +1 -1
  11. package/dist/elements/services/placementService/DefaultPlacementService.js +3 -1
  12. package/dist/elements/services/placementService/FlexBoxPlacementService.d.ts +1 -1
  13. package/dist/elements/services/placementService/FlexBoxPlacementService.js +5 -2
  14. package/dist/elements/services/placementService/GridPlacementService.d.ts +1 -1
  15. package/dist/elements/services/placementService/GridPlacementService.js +5 -2
  16. package/dist/elements/services/placementService/IPlacementService.d.ts +1 -1
  17. package/dist/elements/services/propertiesService/PropertyGroupsService.js +2 -2
  18. package/dist/elements/services/propertiesService/propertyEditors/ImageButtonListPropertyEditor.js +1 -1
  19. package/dist/elements/services/stylesheetService/AbstractStylesheetService.d.ts +3 -0
  20. package/dist/elements/services/stylesheetService/AbstractStylesheetService.js +23 -0
  21. package/dist/elements/services/stylesheetService/IStylesheetService.d.ts +4 -2
  22. package/dist/elements/widgets/designerView/designerCanvas.js +8 -2
  23. package/dist/elements/widgets/designerView/extensions/AbstractExtension.d.ts +1 -1
  24. package/dist/elements/widgets/designerView/extensions/AbstractExtension.js +23 -2
  25. package/dist/elements/widgets/designerView/extensions/BasicDisplayToolbarExtension.d.ts +20 -0
  26. package/dist/elements/widgets/designerView/extensions/BasicDisplayToolbarExtension.js +68 -0
  27. package/dist/elements/widgets/designerView/extensions/BasicStackedToolbarExtension.d.ts +21 -0
  28. package/dist/elements/widgets/designerView/extensions/BasicStackedToolbarExtension.js +81 -0
  29. package/dist/elements/widgets/designerView/extensions/BlockToolbarExtension.d.ts +12 -0
  30. package/dist/elements/widgets/designerView/extensions/BlockToolbarExtension.js +40 -0
  31. package/dist/elements/widgets/designerView/extensions/ExtensionManager.js +1 -0
  32. package/dist/elements/widgets/designerView/extensions/block/BlockToolbarExtension.d.ts +4 -7
  33. package/dist/elements/widgets/designerView/extensions/block/BlockToolbarExtension.js +7 -26
  34. package/dist/elements/widgets/designerView/extensions/block/BlockToolbarExtensionProvider.js +4 -2
  35. package/dist/elements/widgets/designerView/extensions/flex/FlexToolbarExtension.d.ts +5 -6
  36. package/dist/elements/widgets/designerView/extensions/flex/FlexToolbarExtension.js +63 -21
  37. package/dist/elements/widgets/designerView/extensions/flex/FlexToolbarExtensionProvider.js +4 -2
  38. package/dist/elements/widgets/designerView/extensions/grid/GridChildToolbarExtension.d.ts +3 -6
  39. package/dist/elements/widgets/designerView/extensions/grid/GridChildToolbarExtension.js +45 -56
  40. package/dist/elements/widgets/designerView/extensions/grid/GridChildToolbarExtensionProvider.d.ts +0 -1
  41. package/dist/elements/widgets/designerView/extensions/grid/GridChildToolbarExtensionProvider.js +5 -7
  42. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtension.d.ts +3 -6
  43. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtension.js +50 -29
  44. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtensionProvider.js +4 -2
  45. package/dist/elements/widgets/designerView/overlayLayerView.js +16 -1
  46. package/dist/elements/widgets/designerView/tools/PointerTool.d.ts +1 -0
  47. package/dist/elements/widgets/designerView/tools/PointerTool.js +6 -5
  48. package/dist/elements/widgets/propertyGrid/PropertyGridWithHeader.js +1 -1
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.js +1 -0
  51. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg"><rect x="5" y="5" width="14" height="14" fill="black"/></svg>
@@ -0,0 +1 @@
1
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg"><line x1="5" y1="12" x2="19" y2="12" stroke="black" stroke-width="2"/></svg>
@@ -1,17 +1,20 @@
1
- import { BaseCustomWebComponentConstructorAppend, TypedEvent } from '@node-projects/base-custom-webcomponent';
2
- export type ImageButtonListSelectorValueChangedEventArgs = {
3
- newValue?: string;
4
- oldValue?: string;
5
- };
1
+ import { BaseCustomWebComponentConstructorAppend } from '@node-projects/base-custom-webcomponent';
6
2
  export declare class ImageButtonListSelector extends BaseCustomWebComponentConstructorAppend {
7
3
  static readonly style: CSSStyleSheet;
8
4
  static readonly template: HTMLTemplateElement;
5
+ static properties: {
6
+ value: StringConstructor;
7
+ property: StringConstructor;
8
+ unsetValue: StringConstructor;
9
+ noValueInHeader: BooleanConstructor;
10
+ };
11
+ constructor();
9
12
  private _value;
10
13
  get value(): string;
11
14
  set value(value: string);
12
- valueChanged: TypedEvent<ImageButtonListSelectorValueChangedEventArgs>;
13
15
  property: string;
14
16
  unsetValue: string;
17
+ noValueInHeader: boolean;
15
18
  _updateValue(): void;
16
19
  ready(): void;
17
20
  }
@@ -1,4 +1,4 @@
1
- import { BaseCustomWebComponentConstructorAppend, css, html, TypedEvent } from '@node-projects/base-custom-webcomponent';
1
+ import { BaseCustomWebComponentConstructorAppend, css, html } from '@node-projects/base-custom-webcomponent';
2
2
  export class ImageButtonListSelector extends BaseCustomWebComponentConstructorAppend {
3
3
  static style = css `
4
4
  div {
@@ -29,23 +29,31 @@ export class ImageButtonListSelector extends BaseCustomWebComponentConstructorAp
29
29
  `;
30
30
  static template = html `
31
31
  <div>
32
- <div><span id="property"></span>: <span id="value"></span></div>
33
- <div class="container"><slot id="slot"></slot></div>
32
+ <div id="header" style="display: none"><span id="property"></span><span id="vhd">: <span id="value"></span></span></div>
33
+ <div part="container" class="container"><slot id="slot"></slot></div>
34
34
  </div>
35
35
  `;
36
+ static properties = {
37
+ value: String,
38
+ property: String,
39
+ unsetValue: String,
40
+ noValueInHeader: Boolean
41
+ };
42
+ constructor() {
43
+ super();
44
+ this._restoreCachedInititalValues();
45
+ }
36
46
  _value;
37
47
  get value() {
38
48
  return this._value;
39
49
  }
40
50
  set value(value) {
41
- const oldValue = this._value;
42
51
  this._value = value;
43
52
  this._updateValue();
44
- this.valueChanged.emit({ newValue: this._value, oldValue: oldValue });
45
53
  }
46
- valueChanged = new TypedEvent();
47
54
  property;
48
55
  unsetValue;
56
+ noValueInHeader;
49
57
  _updateValue() {
50
58
  if (this.value) {
51
59
  this._getDomElement('value').innerText = this.value;
@@ -64,12 +72,23 @@ export class ImageButtonListSelector extends BaseCustomWebComponentConstructorAp
64
72
  }
65
73
  ready() {
66
74
  this._parseAttributesToProperties();
75
+ if (this.property)
76
+ this._getDomElement('header').style.display = 'block';
77
+ if (this.noValueInHeader)
78
+ this._getDomElement('vhd').style.display = 'none';
67
79
  const slot = this._getDomElement('slot');
68
80
  slot.onclick = (e) => {
69
81
  const path = e.composedPath();
70
82
  for (let e of slot.assignedElements()) {
71
83
  if (path.indexOf(e) >= 0) {
84
+ const oldValue = this._value;
72
85
  this.value = e.dataset.value;
86
+ const valueChangedEvent = new CustomEvent('value-changed', {
87
+ detail: {
88
+ newValue: this._value, oldValue: oldValue
89
+ }
90
+ });
91
+ this.dispatchEvent(valueChangedEvent);
73
92
  }
74
93
  }
75
94
  };
@@ -78,8 +78,10 @@ export declare class DesignItem implements IDesignItem {
78
78
  static GetOrCreateDesignItem(node: Node, parsedNode: any, serviceContainer: ServiceContainer, instanceServiceContainer: InstanceServiceContainer): IDesignItem;
79
79
  static GetDesignItem(node: Node): IDesignItem;
80
80
  setStyle(name: string, value?: string | null, important?: boolean): void;
81
+ setStyleAsync(name: string, value?: string | null, important?: boolean): Promise<void>;
81
82
  removeStyle(name: string): void;
82
83
  updateStyleInSheetOrLocal(name: string, value?: string | null, important?: boolean, forceSet?: boolean): void;
84
+ updateStyleInSheetOrLocalAsync(name: string, value?: string | null, important?: boolean, forceSet?: boolean): Promise<void>;
83
85
  getStyleFromSheetOrLocal(name: string, fallback?: string): string;
84
86
  getStyleFromSheetOrLocalOrComputed(name: string, fallback?: string): string;
85
87
  getComputedStyleProperty(name: string, fallback?: string): string;
@@ -423,10 +423,39 @@ export class DesignItem {
423
423
  let nm = name;
424
424
  if (!nm.startsWith('--'))
425
425
  nm = PropertiesHelper.camelToDashCase(name);
426
- if (this.isRootItem)
427
- throw 'not allowed to set style on root item';
428
- const action = new CssStyleChangeAction(this, nm, value, this._styles.get(nm));
429
- this.instanceServiceContainer.undoService.execute(action);
426
+ if (this.isRootItem) {
427
+ throw 'not allowed to set style on root item or use async setStyle';
428
+ }
429
+ else {
430
+ const action = new CssStyleChangeAction(this, nm, value, this._styles.get(nm));
431
+ this.instanceServiceContainer.undoService.execute(action);
432
+ }
433
+ }
434
+ async setStyleAsync(name, value, important) {
435
+ let nm = name;
436
+ if (!nm.startsWith('--'))
437
+ nm = PropertiesHelper.camelToDashCase(name);
438
+ if (this.isRootItem) {
439
+ if (!this.instanceServiceContainer.stylesheetService)
440
+ throw 'not allowed to set style on root item';
441
+ else {
442
+ let rules = this.instanceServiceContainer.stylesheetService.getRules(':host');
443
+ if (rules === null || rules.length === 0) {
444
+ const cg = this.openGroup('add rule and set style: ' + name);
445
+ const sheets = this.instanceServiceContainer.stylesheetService.getStylesheets();
446
+ const rule = await this.instanceServiceContainer.stylesheetService.addRule(sheets[0], ':host');
447
+ this.instanceServiceContainer.stylesheetService.insertDeclarationIntoRule(rule, name, value, important);
448
+ cg.commit();
449
+ }
450
+ else {
451
+ this.instanceServiceContainer.stylesheetService.insertDeclarationIntoRule(rules[0], name, value, important);
452
+ }
453
+ }
454
+ }
455
+ else {
456
+ const action = new CssStyleChangeAction(this, nm, value, this._styles.get(nm));
457
+ this.instanceServiceContainer.undoService.execute(action);
458
+ }
430
459
  }
431
460
  removeStyle(name) {
432
461
  let nm = name;
@@ -454,6 +483,25 @@ export class DesignItem {
454
483
  this.instanceServiceContainer.stylesheetService.updateDeclarationValue(declarations[0], value, false);
455
484
  }
456
485
  }
486
+ async updateStyleInSheetOrLocalAsync(name, value, important, forceSet) {
487
+ let nm = name;
488
+ if (!nm.startsWith('--'))
489
+ nm = PropertiesHelper.camelToDashCase(name);
490
+ // Pre-sorted by specificity
491
+ let declarations = this.instanceServiceContainer.stylesheetService?.getDeclarations(this, nm);
492
+ if (this.hasStyle(name) || this.instanceServiceContainer.designContext.extensionOptions[enableStylesheetService] === false || !declarations?.length) {
493
+ // Set style locally
494
+ if (this.getStyle(nm) != value || forceSet) {
495
+ await this.setStyleAsync(nm, value);
496
+ }
497
+ else if (value == null) {
498
+ this.removeStyle(nm);
499
+ }
500
+ }
501
+ else {
502
+ this.instanceServiceContainer.stylesheetService.updateDeclarationValue(declarations[0], value, false);
503
+ }
504
+ }
457
505
  getStyleFromSheetOrLocal(name, fallback = null) {
458
506
  let nm = name;
459
507
  if (!nm.startsWith('--'))
@@ -488,10 +536,9 @@ export class DesignItem {
488
536
  return value ?? fallback;
489
537
  }
490
538
  getComputedStyle() {
491
- /*if (this.isRootItem) {
492
- return window.getComputedStyle((<ShadowRoot>this.node).host);
493
- }*/
494
- return window.getComputedStyle(this.element);
539
+ if (this.nodeType == NodeType.Element)
540
+ return window.getComputedStyle(this.element);
541
+ return null;
495
542
  }
496
543
  _stylesCache = null;
497
544
  _cacheClearTimer;
@@ -54,8 +54,10 @@ export interface IDesignItem {
54
54
  getStyle(name: string): string;
55
55
  hasStyle(name: string): boolean;
56
56
  setStyle(name: string, value?: string | null, important?: boolean): any;
57
+ setStyleAsync(name: string, value?: string | null, important?: boolean): Promise<void>;
57
58
  removeStyle(name: string): any;
58
59
  updateStyleInSheetOrLocal(name: string, value?: string | null, important?: boolean, forceSet?: boolean): any;
60
+ updateStyleInSheetOrLocalAsync(name: string, value?: string | null, important?: boolean, forceSet?: boolean): Promise<void>;
59
61
  getStyleFromSheetOrLocal(name: string, fallback?: string): any;
60
62
  getStyleFromSheetOrLocalOrComputed(name: string, fallback?: string): any;
61
63
  getAllStyles(): IStyleRule[];
@@ -89,6 +89,7 @@ import { GridToolbarExtensionProvider } from '../widgets/designerView/extensions
89
89
  import { FlexToolbarExtensionProvider } from '../widgets/designerView/extensions/flex/FlexToolbarExtensionProvider.js';
90
90
  import { BlockToolbarExtensionProvider } from '../widgets/designerView/extensions/block/BlockToolbarExtensionProvider.js';
91
91
  import { ChildContextMenu } from '../widgets/designerView/extensions/contextMenu/ChildContextMenu.js';
92
+ import { GridChildToolbarExtensionProvider } from '../widgets/designerView/extensions/grid/GridChildToolbarExtensionProvider.js';
92
93
  export function createDefaultServiceContainer() {
93
94
  let serviceContainer = new ServiceContainer();
94
95
  let defaultPlacementService = new DefaultPlacementService();
@@ -133,6 +134,7 @@ export function createDefaultServiceContainer() {
133
134
  new ConditionExtensionProvider(new MultipleSelectionRectExtensionProvider(), item => !(item.node instanceof SVGElement) || item.node instanceof SVGSVGElement),
134
135
  ]);
135
136
  serviceContainer.designerExtensions.set(ExtensionType.PrimarySelectionRefreshed, [
137
+ new GridChildToolbarExtensionProvider(),
136
138
  new GridToolbarExtensionProvider(),
137
139
  new FlexToolbarExtensionProvider(),
138
140
  new BlockToolbarExtensionProvider(),
@@ -15,6 +15,8 @@ export class DragDropService {
15
15
  }
16
16
  dragOver(designerCanvas, event) {
17
17
  let [newContainer] = this.getPossibleContainerForDragDrop(designerCanvas, event);
18
+ if (!newContainer)
19
+ newContainer = designerCanvas.rootDesignItem;
18
20
  if (this._dragOverExtensionItem != newContainer) {
19
21
  designerCanvas.extensionManager.removeExtension(this._dragOverExtensionItem, ExtensionType.ContainerExternalDragOverAndCanBeEntered);
20
22
  designerCanvas.extensionManager.applyExtension(newContainer, ExtensionType.ContainerExternalDragOverAndCanBeEntered, event);
@@ -40,7 +42,7 @@ export class DragDropService {
40
42
  const elementDefinition = JSON.parse(transferData);
41
43
  const di = await designerCanvas.serviceContainer.forSomeServicesTillResult("instanceService", (service) => service.getElement(elementDefinition, designerCanvas.serviceContainer, designerCanvas.instanceServiceContainer));
42
44
  const grp = di.openGroup("Insert of &lt;" + di.name + "&gt;");
43
- const containerService = designerCanvas.serviceContainer.getLastServiceWhere('containerService', x => x.serviceForContainer(newContainer, newContainer.getComputedStyle()));
45
+ const containerService = designerCanvas.serviceContainer.getLastServiceWhere('containerService', x => x.serviceForContainer(newContainer, newContainer.getComputedStyle(), di));
44
46
  containerService.enterContainer(newContainer, [di], 'drop');
45
47
  const containerPos = designerCanvas.getNormalizedElementCoordinates(newContainer.element);
46
48
  const evCoord = designerCanvas.getNormalizedEventCoordinates(event);
@@ -3,7 +3,7 @@ import type { IPlacementService } from './IPlacementService.js';
3
3
  import type { IDesignItem } from '../../item/IDesignItem.js';
4
4
  import { IPlacementView } from '../../widgets/designerView/IPlacementView.js';
5
5
  export declare class DefaultPlacementService implements IPlacementService {
6
- serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration): boolean;
6
+ serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration, item?: IDesignItem): boolean;
7
7
  isEnterableContainer(container: IDesignItem): boolean;
8
8
  canEnter(container: IDesignItem, items: IDesignItem[]): boolean;
9
9
  canLeave(container: IDesignItem, items: IDesignItem[]): boolean;
@@ -4,7 +4,9 @@ import { filterChildPlaceItems, getDesignItemCurrentPos, placeDesignItem } from
4
4
  import { ExtensionType } from '../../widgets/designerView/extensions/ExtensionType.js';
5
5
  import { straightenLine } from '../../helper/PathDataPolyfill.js';
6
6
  export class DefaultPlacementService {
7
- serviceForContainer(container, containerStyle) {
7
+ serviceForContainer(container, containerStyle, item) {
8
+ if (item != null && item.getComputedStyle()?.position == 'absolute')
9
+ return true;
8
10
  if (containerStyle.display === 'grid' || containerStyle.display === 'inline-grid' ||
9
11
  containerStyle.display === 'flex' || containerStyle.display === 'inline-flex')
10
12
  return false;
@@ -7,7 +7,7 @@ export declare class FlexBoxPlacementService implements IPlacementService {
7
7
  constructor(basePlacementService: IPlacementService);
8
8
  enterContainer(container: IDesignItem, items: IDesignItem[], mode: 'normal' | 'drop'): void;
9
9
  leaveContainer(container: IDesignItem, items: IDesignItem[]): void;
10
- serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration): boolean;
10
+ serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration, item?: IDesignItem): boolean;
11
11
  isEnterableContainer(container: IDesignItem): any;
12
12
  canEnter(container: IDesignItem, items: IDesignItem[]): any;
13
13
  canLeave(container: IDesignItem, items: IDesignItem[]): boolean;
@@ -22,9 +22,12 @@ export class FlexBoxPlacementService {
22
22
  }
23
23
  }
24
24
  }
25
- serviceForContainer(container, containerStyle) {
26
- if (containerStyle.display == 'flex' || containerStyle.display == 'inline-flex')
25
+ serviceForContainer(container, containerStyle, item) {
26
+ if (containerStyle.display == 'flex' || containerStyle.display == 'inline-flex') {
27
+ if (item != null && item.getComputedStyle()?.position == 'absolute')
28
+ return false;
27
29
  return true;
30
+ }
28
31
  return false;
29
32
  }
30
33
  isEnterableContainer(container) {
@@ -7,7 +7,7 @@ export declare class GridPlacementService implements IPlacementService {
7
7
  constructor(basePlacementService: IPlacementService);
8
8
  enterContainer(container: IDesignItem, items: IDesignItem[], mode: 'normal' | 'drop'): void;
9
9
  leaveContainer(container: IDesignItem, items: IDesignItem[]): void;
10
- serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration): boolean;
10
+ serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration, item?: IDesignItem): boolean;
11
11
  isEnterableContainer(container: IDesignItem): any;
12
12
  canEnter(container: IDesignItem, items: IDesignItem[]): any;
13
13
  canLeave(container: IDesignItem, items: IDesignItem[]): boolean;
@@ -26,9 +26,12 @@ export class GridPlacementService {
26
26
  }
27
27
  }
28
28
  }
29
- serviceForContainer(container, containerStyle) {
30
- if (containerStyle.display == 'grid' || containerStyle.display == 'inline-grid')
29
+ serviceForContainer(container, containerStyle, item) {
30
+ if (containerStyle.display == 'grid' || containerStyle.display == 'inline-grid') {
31
+ if (item != null && item.getComputedStyle()?.position == 'absolute')
32
+ return false;
31
33
  return true;
34
+ }
32
35
  return false;
33
36
  }
34
37
  isEnterableContainer(container) {
@@ -3,7 +3,7 @@ import { IDesignItem } from '../../item/IDesignItem.js';
3
3
  import { IPlacementView } from '../../widgets/designerView/IPlacementView.js';
4
4
  import { IPoint } from '../../../interfaces/IPoint.js';
5
5
  export interface IPlacementService extends IService {
6
- serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration): boolean;
6
+ serviceForContainer(container: IDesignItem, containerStyle: CSSStyleDeclaration, item?: IDesignItem): boolean;
7
7
  isEnterableContainer(container: IDesignItem): boolean;
8
8
  canEnter(container: IDesignItem, items: IDesignItem[]): boolean;
9
9
  canLeave(container: IDesignItem, items: IDesignItem[]): boolean;
@@ -53,8 +53,8 @@ export class PropertyGroupsService {
53
53
  let lst = this._pgList;
54
54
  if (designItems[0].element instanceof SVGElement)
55
55
  lst = this._svgPgList;
56
- if (designItems[0].element.parentElement) {
57
- const parentStyle = getComputedStyle(designItems[0].element.parentElement);
56
+ if (designItems[0].parent) {
57
+ const parentStyle = designItems[0].parent.getComputedStyle();
58
58
  if (parentStyle.display.includes('grid'))
59
59
  lst = [...lst, this._gridChild[0]];
60
60
  else if (parentStyle.display.includes('flex'))
@@ -31,7 +31,7 @@ export class ImageButtonListPropertyEditor extends BasePropertyEditor {
31
31
  selector.appendChild(button);
32
32
  }
33
33
  }
34
- selector.valueChanged.on((e) => this._valueChanged(e.newValue));
34
+ selector.addEventListener('value-changed', (e) => this._valueChanged(selector.value));
35
35
  this.element = selector;
36
36
  }
37
37
  refreshValue(valueType, value) {
@@ -18,12 +18,15 @@ export declare abstract class AbstractStylesheetService implements IStylesheetSe
18
18
  }>;
19
19
  protected _instanceServiceContainer: InstanceServiceContainer;
20
20
  constructor(designerCanvas: IDesignerCanvas);
21
+ abstract getRules(rule: string): IStyleRule[];
22
+ abstract addRule(stylesheet: IStylesheet, rule: string): Promise<IStyleRule>;
21
23
  setStylesheets(stylesheets: IStylesheet[]): Promise<void>;
22
24
  setDocumentStylesheets(stylesheets: IDocumentStylesheet[]): Promise<void>;
23
25
  internalSetStylesheets(stylesheets: IStylesheet[], targetMap: Map<string, {
24
26
  stylesheet: IStylesheet;
25
27
  ast: any;
26
28
  }>): Promise<void>;
29
+ protected internalReparseStylesheet(name: string): Promise<void>;
27
30
  protected abstract internalParse(style: string): Promise<any>;
28
31
  getStylesheets(): IStylesheet[];
29
32
  abstract getAppliedRules(designItem: IDesignItem): IStyleRule[];
@@ -62,6 +62,27 @@ export class AbstractStylesheetService {
62
62
  this._allStylesheets.set(s[0], s[1]);
63
63
  }
64
64
  }
65
+ async internalReparseStylesheet(name) {
66
+ let lst = this._allStylesheets;
67
+ if (this._documentStylesheets.has(name))
68
+ lst = this._documentStylesheets;
69
+ if (this._stylesheets.has(name))
70
+ lst = this._stylesheets;
71
+ const ss = lst.get(name);
72
+ let ast = null;
73
+ try {
74
+ ast = await this.internalParse(ss.stylesheet.content);
75
+ }
76
+ catch (err) {
77
+ console.warn("error parsing stylesheet", name, err);
78
+ }
79
+ const v = {
80
+ stylesheet: ss.stylesheet,
81
+ ast: ast
82
+ };
83
+ this._stylesheets.set(name, v);
84
+ this._allStylesheets.set(name, v);
85
+ }
65
86
  //TODO: rename to externalStylesheets
66
87
  getStylesheets() {
67
88
  let stylesheets = [];
@@ -80,6 +101,8 @@ export class AbstractStylesheetService {
80
101
  stylesheetChanged = new TypedEvent();
81
102
  stylesheetsChanged = new TypedEvent();
82
103
  elementMatchesASelector(designItem, selectors) {
104
+ if (designItem == null)
105
+ return true;
83
106
  for (let selector of selectors) {
84
107
  if (selector == ':host') {
85
108
  selector = DesignerCanvas.cssprefixConstant;
@@ -23,6 +23,7 @@ export interface IDocumentStylesheet extends IStylesheet {
23
23
  export interface IStylesheetService {
24
24
  setStylesheets(stylesheets: IStylesheet[]): Promise<void>;
25
25
  getStylesheets(): IStylesheet[];
26
+ getRules(selector: string): IStyleRule[];
26
27
  setDocumentStylesheets(stylesheets: IDocumentStylesheet[]): Promise<void>;
27
28
  getAppliedRules(designItem: IDesignItem): IStyleRule[];
28
29
  getDeclarations(designItem: IDesignItem, styleName: string): IStyleDeclaration[];
@@ -30,8 +31,9 @@ export interface IStylesheetService {
30
31
  updateDeclarationValueWithoutUndo(declaration: IStyleDeclaration, value: string, important: boolean): any;
31
32
  insertDeclarationIntoRule(rule: IStyleRule, property: string, value: string, important: boolean): boolean;
32
33
  removeDeclarationFromRule(rule: IStyleRule, property: string): boolean;
33
- updateCompleteStylesheet(name: string, newStyle: string): void;
34
- updateCompleteStylesheetWithoutUndo(name: string, newStyle: string): void;
34
+ updateCompleteStylesheet(name: string, newStyle: string): Promise<void>;
35
+ updateCompleteStylesheetWithoutUndo(name: string, newStyle: string): Promise<void>;
36
+ addRule(stylesheet: IStylesheet, selector: string): Promise<IStyleRule>;
35
37
  stylesheetChanged: TypedEvent<{
36
38
  name: string;
37
39
  newStyle: string;
@@ -638,8 +638,8 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
638
638
  this.clickOverlay.addEventListener(EventNames.DragLeave, event => this._onDragLeave(event));
639
639
  this.clickOverlay.addEventListener(EventNames.DragOver, event => this._onDragOver(event));
640
640
  this.clickOverlay.addEventListener(EventNames.Drop, event => this._onDrop(event));
641
- this.clickOverlay.addEventListener(EventNames.KeyDown, this.onKeyDown, true);
642
- this.clickOverlay.addEventListener(EventNames.KeyUp, this.onKeyUp, true);
641
+ this.clickOverlay.addEventListener(EventNames.KeyDown, this.onKeyDown);
642
+ this.clickOverlay.addEventListener(EventNames.KeyUp, this.onKeyUp);
643
643
  this.clickOverlay.addEventListener(EventNames.DblClick, this._onDblClick, true);
644
644
  this.clickOverlay.addEventListener('zoom', (e) => {
645
645
  this.zoomFactor = this.zoomFactor + (e.detail.diff / 10);
@@ -849,6 +849,8 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
849
849
  }
850
850
  _onDblClick(event) {
851
851
  event.preventDefault();
852
+ if (event.target === this.overlayLayer)
853
+ return;
852
854
  if (this.serviceContainer.globalContext.tool == null || this.serviceContainer.globalContext.tool === this.serviceContainer.designerTools.get(NamedTools.Pointer)) {
853
855
  this.extensionManager.removeExtension(this.instanceServiceContainer.selectionService.primarySelection, ExtensionType.PrimarySelectionRefreshed);
854
856
  this.extensionManager.applyExtension(this.instanceServiceContainer.selectionService.primarySelection, ExtensionType.Doubleclick, event);
@@ -880,6 +882,8 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
880
882
  }
881
883
  }
882
884
  onKeyUp(event) {
885
+ if (this._ignoreEvent === event)
886
+ return;
883
887
  if (this._moveGroup) {
884
888
  this._moveGroup.commit();
885
889
  this._moveGroup = null;
@@ -887,6 +891,8 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
887
891
  event.preventDefault();
888
892
  }
889
893
  onKeyDown(event) {
894
+ if (this._ignoreEvent === event)
895
+ return;
890
896
  if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey)
891
897
  this.executeCommand({ type: CommandType.undo, ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey });
892
898
  else if ((event.ctrlKey || event.metaKey) && event.key === 'z' && event.shiftKey)
@@ -7,7 +7,7 @@ import { OverlayLayer } from './OverlayLayer.js';
7
7
  import { IPoint } from '../../../../interfaces/IPoint.js';
8
8
  export type toolbarObject = SVGForeignObjectElement & {
9
9
  updatePosition: (position: IPoint) => void;
10
- getById: <T>(id: string) => T;
10
+ getById: <T extends HTMLElement>(id: string) => T;
11
11
  };
12
12
  export declare abstract class AbstractExtension extends AbstractExtensionBase implements IDesignerExtension {
13
13
  protected extendedItem: IDesignItem;
@@ -11,8 +11,18 @@ export class AbstractExtension extends AbstractExtensionBase {
11
11
  }
12
12
  createToolbar(template, width, height, overlayLayer = OverlayLayer.Foreground) {
13
13
  const element = template.content.cloneNode(true);
14
- element.querySelectorAll('*').forEach(x => x.onpointerdown = (e) => {
15
- this.designerCanvas.ignoreEvent(e);
14
+ element.querySelectorAll('*').forEach(x => {
15
+ x.onpointerdown = (e) => {
16
+ this.designerCanvas.ignoreEvent(e);
17
+ };
18
+ if (x instanceof HTMLInputElement) {
19
+ x.addEventListener('keydown', (e) => {
20
+ this.designerCanvas.ignoreEvent(e);
21
+ }, { capture: true });
22
+ x.addEventListener('keyup', (e) => {
23
+ this.designerCanvas.ignoreEvent(e);
24
+ }, { capture: true });
25
+ }
16
26
  });
17
27
  const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
18
28
  foreignObject.classList.add('svg-toolbar-container');
@@ -23,6 +33,17 @@ export class AbstractExtension extends AbstractExtensionBase {
23
33
  foreignObject.style.transformBox = 'fill-box';
24
34
  this._addOverlay(foreignObject, overlayLayer);
25
35
  foreignObject.updatePosition = (position) => {
36
+ foreignObject.style.scale = '' + 1 / this.designerCanvas.zoomFactor;
37
+ const rect = this.overlayLayerView.getBoundingClientRect();
38
+ const innerRect = foreignObject.children[0].getBoundingClientRect();
39
+ const scaleFactor = this.designerCanvas.scaleFactor;
40
+ const effectiveRectWidth = (rect.width / scaleFactor) - this.designerCanvas.canvasOffset.x * scaleFactor;
41
+ if (innerRect.width + (position.x * scaleFactor) > effectiveRectWidth) {
42
+ position.x = (effectiveRectWidth - innerRect.width) / scaleFactor;
43
+ }
44
+ if (position.x < -this.designerCanvas.canvasOffset.x) {
45
+ position.x = -this.designerCanvas.canvasOffset.x;
46
+ }
26
47
  foreignObject.setAttribute('x', '' + position.x);
27
48
  foreignObject.setAttribute('y', '' + position.y);
28
49
  };
@@ -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,21 @@
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 static toolBars: toolbarObject[];
8
+ protected _toolbar: toolbarObject;
9
+ protected _size: {
10
+ width: number;
11
+ height: number;
12
+ };
13
+ protected _display: string;
14
+ protected _inline: string;
15
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
16
+ extend(cache: Record<string | symbol, any>, event: MouseEvent): void;
17
+ updateDisplayValue(): Promise<void>;
18
+ refresh(cache: Record<string | symbol, any>, event?: MouseEvent): void;
19
+ protected _addStyleButton(styleAndControlName: string): void;
20
+ dispose(): void;
21
+ }