@node-projects/web-component-designer 0.1.158 → 0.1.159

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 (35) hide show
  1. package/README.md +8 -6
  2. package/dist/elements/controls/ImageButtonListSelector.js +0 -1
  3. package/dist/elements/helper/StylesheetHelper.d.ts +1 -0
  4. package/dist/elements/helper/StylesheetHelper.js +6 -0
  5. package/dist/elements/helper/contextMenu/ContextMenu.js +4 -2
  6. package/dist/elements/helper/contextMenu/IContextMenuItem.d.ts +1 -0
  7. package/dist/elements/item/DesignItem.d.ts +19 -0
  8. package/dist/elements/item/DesignItem.js +69 -0
  9. package/dist/elements/item/IDesignItem.d.ts +7 -0
  10. package/dist/elements/services/DefaultServiceBootstrap.js +5 -1
  11. package/dist/elements/services/contentService/IContentChanged.d.ts +1 -1
  12. package/dist/elements/services/propertiesService/services/CssProperties.json +10 -1
  13. package/dist/elements/services/undoService/ChangeGroup.d.ts +1 -0
  14. package/dist/elements/services/undoService/ChangeGroup.js +1 -0
  15. package/dist/elements/services/undoService/ITransactionItem.d.ts +1 -0
  16. package/dist/elements/services/undoService/IUndoService.d.ts +2 -0
  17. package/dist/elements/services/undoService/UndoService.d.ts +4 -1
  18. package/dist/elements/services/undoService/UndoService.js +21 -3
  19. package/dist/elements/widgets/designerView/DesignContext.d.ts +7 -0
  20. package/dist/elements/widgets/designerView/DesignContext.js +9 -1
  21. package/dist/elements/widgets/designerView/IDesignContext.d.ts +7 -0
  22. package/dist/elements/widgets/designerView/designerCanvas.d.ts +2 -0
  23. package/dist/elements/widgets/designerView/designerCanvas.js +47 -2
  24. package/dist/elements/widgets/designerView/extensions/BasicStackedToolbarExtension.js +16 -2
  25. package/dist/elements/widgets/designerView/extensions/PaddingExtension.js +1 -1
  26. package/dist/elements/widgets/designerView/extensions/buttons/OptionsContextMenuButton.d.ts +8 -0
  27. package/dist/elements/widgets/designerView/extensions/buttons/OptionsContextMenuButton.js +33 -0
  28. package/dist/elements/widgets/designerView/extensions/contextMenu/ForceCssContextMenu.d.ts +8 -0
  29. package/dist/elements/widgets/designerView/extensions/contextMenu/ForceCssContextMenu.js +16 -0
  30. package/dist/elements/widgets/designerView/extensions/flex/FlexToolbarExtension.js +1 -1
  31. package/dist/elements/widgets/designerView/extensions/grid/GridToolbarExtension.js +1 -1
  32. package/dist/elements/widgets/designerView/tools/DrawElementTool.js +0 -1
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +2 -0
  35. package/package.json +1 -1
package/README.md CHANGED
@@ -58,12 +58,14 @@ Your index.html should be extended as follows:
58
58
 
59
59
  ## Similar Frameworks
60
60
 
61
- | Name | Licence | Edit Source | | |
62
- |-------------------------|----------|-------------|---|---|
63
- | web-component-designer | MIT | yes | | |
64
- | GrapeJS | BSD-3 | yes | | |
65
- | CraftJS | MIT | no | | |
66
-
61
+ | Name | Licence | Edit Source (split View) | Zooming | Transformations |
62
+ |-------------------------|----------|--------------------------|---------|---|
63
+ | web-component-designer | MIT | yes |
64
+ | GrapeJS | BSD-3 | yes |
65
+ | CraftJS | MIT | no |
66
+
67
+ TODO:
68
+ force css states via explicit class (or attr??)
67
69
 
68
70
  ## Copyright notice
69
71
 
@@ -16,7 +16,6 @@ export class ImageButtonListSelector extends BaseCustomWebComponentConstructorAp
16
16
  }
17
17
  .container {
18
18
  display: flex;
19
- flex-wrap: wrap;
20
19
  flex-direction: row;
21
20
  }
22
21
  ::slotted(button) {
@@ -0,0 +1 @@
1
+ export declare function stylesheetFromString(window: Window, text: string): any;
@@ -0,0 +1,6 @@
1
+ export function stylesheetFromString(window, text) {
2
+ //@ts-ignore
3
+ const newStylesheet = new window.CSSStyleSheet();
4
+ newStylesheet.replaceSync(text);
5
+ return newStylesheet;
6
+ }
@@ -52,7 +52,6 @@ export class ContextMenu {
52
52
  display: inline-flex;
53
53
  align-items: center;
54
54
  justify-content: center;
55
- border-right: 1px solid #aaa;
56
55
  }
57
56
 
58
57
  .context_menu li .context_menu_icon_span img {
@@ -168,7 +167,10 @@ export class ContextMenu {
168
167
  let li = document.createElement("li");
169
168
  let icon_span = document.createElement("span");
170
169
  icon_span.className = 'context_menu_icon_span';
171
- if ((item.icon ?? '') != '') {
170
+ if (item.checked === true) {
171
+ icon_span.innerHTML = '✔';
172
+ }
173
+ else if ((item.icon ?? '') != '') {
172
174
  icon_span.innerHTML = item.icon;
173
175
  }
174
176
  else {
@@ -8,5 +8,6 @@ export interface IContextMenuItem {
8
8
  readonly children?: IContextMenuItem[];
9
9
  readonly disabled?: boolean;
10
10
  readonly shortCut?: string;
11
+ readonly checked?: boolean;
11
12
  action?: (event: MouseEvent, item: IContextMenuItem, context?: any, menu?: IContextMenu) => void;
12
13
  }
@@ -8,6 +8,12 @@ import { ISize } from '../../interfaces/ISize.js';
8
8
  import { IStyleRule } from '../services/stylesheetService/IStylesheetService.js';
9
9
  import { TypedEvent } from '@node-projects/base-custom-webcomponent';
10
10
  import { IPlacementService } from '../services/placementService/IPlacementService.js';
11
+ export declare const forceHoverAttributeName = "node-projects-force-hover";
12
+ export declare const forceActiveAttributeName = "node-projects-force-active";
13
+ export declare const forceVisitedAttributeName = "node-projects-force-visited";
14
+ export declare const forceFocusAttributeName = "node-projects-force-focus";
15
+ export declare const forceFocusWithinAttributeName = "node-projects-force-focus-within";
16
+ export declare const forceFocusVisibleAttributeName = "node-projects-force-focus-visible";
11
17
  export declare class DesignItem implements IDesignItem {
12
18
  lastContainerSize: ISize;
13
19
  parsedNode: any;
@@ -100,4 +106,17 @@ export declare class DesignItem implements IDesignItem {
100
106
  _refreshIfStyleSheet(): void;
101
107
  getPlacementService(style?: CSSStyleDeclaration): IPlacementService;
102
108
  static createDesignItemFromImageBlob(serviceContainer: ServiceContainer, instanceServiceContainer: InstanceServiceContainer, data: Blob): Promise<IDesignItem>;
109
+ get hasForcedCss(): boolean;
110
+ get cssForceHover(): boolean;
111
+ set cssForceHover(value: boolean);
112
+ get cssForceActive(): boolean;
113
+ set cssForceActive(value: boolean);
114
+ get cssForceVisited(): boolean;
115
+ set cssForceVisited(value: boolean);
116
+ get cssForceFocus(): boolean;
117
+ set cssForceFocus(value: boolean);
118
+ get cssForceFocusWithin(): boolean;
119
+ set cssForceFocusWithin(value: boolean);
120
+ get cssForceFocusVisible(): boolean;
121
+ set cssForceFocusVisible(value: boolean);
103
122
  }
@@ -13,6 +13,12 @@ import { TextContentChangeAction } from '../services/undoService/transactionItem
13
13
  const hideAtDesignTimeAttributeName = 'node-projects-hide-at-design-time';
14
14
  const hideAtRunTimeAttributeName = 'node-projects-hide-at-run-time';
15
15
  const lockAtDesignTimeAttributeName = 'node-projects-lock-at-design-time';
16
+ export const forceHoverAttributeName = 'node-projects-force-hover';
17
+ export const forceActiveAttributeName = 'node-projects-force-active';
18
+ export const forceVisitedAttributeName = 'node-projects-force-visited';
19
+ export const forceFocusAttributeName = 'node-projects-force-focus';
20
+ export const forceFocusWithinAttributeName = 'node-projects-force-focus-within';
21
+ export const forceFocusVisibleAttributeName = 'node-projects-force-focus-visible';
16
22
  export class DesignItem {
17
23
  lastContainerSize;
18
24
  parsedNode;
@@ -681,4 +687,67 @@ export class DesignItem {
681
687
  reader.readAsDataURL(data);
682
688
  });
683
689
  }
690
+ get hasForcedCss() {
691
+ return this.cssForceHover || this.cssForceActive || this.cssForceVisited || this.cssForceFocus || this.cssForceFocusWithin || this.cssForceFocusVisible;
692
+ }
693
+ get cssForceHover() {
694
+ return this.element.hasAttribute(forceHoverAttributeName);
695
+ }
696
+ set cssForceHover(value) {
697
+ if (value)
698
+ this.element.setAttribute(forceHoverAttributeName, '');
699
+ else
700
+ this.element.removeAttribute(forceHoverAttributeName);
701
+ this.instanceServiceContainer.contentService.onContentChanged.emit({ changeType: 'changed', designItems: [this] });
702
+ }
703
+ get cssForceActive() {
704
+ return this.element.hasAttribute(forceActiveAttributeName);
705
+ }
706
+ set cssForceActive(value) {
707
+ if (value)
708
+ this.element.setAttribute(forceActiveAttributeName, '');
709
+ else
710
+ this.element.removeAttribute(forceActiveAttributeName);
711
+ this.instanceServiceContainer.contentService.onContentChanged.emit({ changeType: 'changed', designItems: [this] });
712
+ }
713
+ get cssForceVisited() {
714
+ return this.element.hasAttribute(forceVisitedAttributeName);
715
+ }
716
+ set cssForceVisited(value) {
717
+ if (value)
718
+ this.element.setAttribute(forceVisitedAttributeName, '');
719
+ else
720
+ this.element.removeAttribute(forceVisitedAttributeName);
721
+ this.instanceServiceContainer.contentService.onContentChanged.emit({ changeType: 'changed', designItems: [this] });
722
+ }
723
+ get cssForceFocus() {
724
+ return this.element.hasAttribute(forceFocusAttributeName);
725
+ }
726
+ set cssForceFocus(value) {
727
+ if (value)
728
+ this.element.setAttribute(forceFocusAttributeName, '');
729
+ else
730
+ this.element.removeAttribute(forceFocusAttributeName);
731
+ this.instanceServiceContainer.contentService.onContentChanged.emit({ changeType: 'changed', designItems: [this] });
732
+ }
733
+ get cssForceFocusWithin() {
734
+ return this.element.hasAttribute(forceFocusWithinAttributeName);
735
+ }
736
+ set cssForceFocusWithin(value) {
737
+ if (value)
738
+ this.element.setAttribute(forceFocusWithinAttributeName, '');
739
+ else
740
+ this.element.removeAttribute(forceFocusWithinAttributeName);
741
+ this.instanceServiceContainer.contentService.onContentChanged.emit({ changeType: 'changed', designItems: [this] });
742
+ }
743
+ get cssForceFocusVisible() {
744
+ return this.element.hasAttribute(forceFocusVisibleAttributeName);
745
+ }
746
+ set cssForceFocusVisible(value) {
747
+ if (value)
748
+ this.element.setAttribute(forceFocusVisibleAttributeName, '');
749
+ else
750
+ this.element.removeAttribute(forceFocusVisibleAttributeName);
751
+ this.instanceServiceContainer.contentService.onContentChanged.emit({ changeType: 'changed', designItems: [this] });
752
+ }
684
753
  }
@@ -62,6 +62,13 @@ export interface IDesignItem {
62
62
  getStyleFromSheetOrLocal(name: string, fallback?: string): any;
63
63
  getStyleFromSheetOrLocalOrComputed(name: string, fallback?: string): any;
64
64
  getAllStyles(): IStyleRule[];
65
+ readonly hasForcedCss: boolean;
66
+ cssForceHover: boolean;
67
+ cssForceActive: boolean;
68
+ cssForceVisited: boolean;
69
+ cssForceFocus: boolean;
70
+ cssForceFocusWithin: boolean;
71
+ cssForceFocusVisible: boolean;
65
72
  attributes(): Iterable<[name: string, value: string]>;
66
73
  getAttribute(name: string): string;
67
74
  hasAttribute(name: string): boolean;
@@ -96,6 +96,8 @@ import { GridChildResizeExtensionProvider } from '../widgets/designerView/extens
96
96
  import { AlignItemsContextMenu } from '../widgets/designerView/extensions/contextMenu/AlignItemsContextMenu.js';
97
97
  import { BasicWebcomponentPropertiesService } from './propertiesService/services/BasicWebcomponentPropertiesService.js';
98
98
  import { PreviousElementSelectExtensionProvider } from '../widgets/designerView/extensions/PreviousElementSelectExtensionProvider.js';
99
+ import { ForceCssContextMenu } from '../widgets/designerView/extensions/contextMenu/ForceCssContextMenu.js';
100
+ import { OptionsContextMenuButton } from '../widgets/designerView/extensions/buttons/OptionsContextMenuButton.js';
99
101
  export function createDefaultServiceContainer() {
100
102
  let serviceContainer = new ServiceContainer();
101
103
  let defaultPlacementService = new DefaultPlacementService();
@@ -198,7 +200,7 @@ export function createDefaultServiceContainer() {
198
200
  serviceContainer.designerPointerExtensions.push(
199
201
  //new CursorLinePointerExtensionProvider()
200
202
  );
201
- serviceContainer.designViewConfigButtons.push(new ButtonSeperatorProvider(20), new GridExtensionDesignViewConfigButtons(), new FlexboxExtensionDesignViewConfigButtons(), new ButtonSeperatorProvider(10), new InvisibleElementExtensionDesignViewConfigButtons(), new ButtonSeperatorProvider(10), new StylesheetServiceDesignViewConfigButtons(), new ButtonSeperatorProvider(10), new ToolbarExtensionsDesignViewConfigButtons(), new ButtonSeperatorProvider(30), new RoundPixelsDesignViewConfigButton());
203
+ serviceContainer.designViewConfigButtons.push(new ButtonSeperatorProvider(20), new GridExtensionDesignViewConfigButtons(), new FlexboxExtensionDesignViewConfigButtons(), new ButtonSeperatorProvider(10), new InvisibleElementExtensionDesignViewConfigButtons(), new ButtonSeperatorProvider(10), new StylesheetServiceDesignViewConfigButtons(), new ButtonSeperatorProvider(10), new ToolbarExtensionsDesignViewConfigButtons(), new ButtonSeperatorProvider(30), new RoundPixelsDesignViewConfigButton(), new ButtonSeperatorProvider(30), new OptionsContextMenuButton());
202
204
  serviceContainer.designViewToolbarButtons.push(new PointerToolButtonProvider(), new SeperatorToolProvider(22), new SelectorToolButtonProvider(), new SeperatorToolProvider(22), new ZoomToolButtonProvider(), new SeperatorToolProvider(22), new DrawToolButtonProvider(), new SeperatorToolProvider(22), new TextToolButtonProvider(), new SeperatorToolProvider(22), new TransformToolButtonProvider());
203
205
  serviceContainer.designerContextMenuExtensions = [
204
206
  new ChildContextMenu('edit', new CopyPasteContextMenu()),
@@ -207,6 +209,8 @@ export function createDefaultServiceContainer() {
207
209
  new SeperatorContextMenu(),
208
210
  new ChildContextMenu('view', new JumpToElementContextMenu(), new ZoomToElementContextMenu()),
209
211
  new SeperatorContextMenu(),
212
+ new ChildContextMenu('force', new ForceCssContextMenu()),
213
+ new SeperatorContextMenu(),
210
214
  new MultipleItemsSelectedContextMenu(),
211
215
  new PathContextMenu(),
212
216
  new RectContextMenu(),
@@ -3,7 +3,7 @@ interface IContentChangedParsed {
3
3
  changeType: 'parsed';
4
4
  }
5
5
  interface IContentChangedWithDesignItems {
6
- changeType: "added" | "removed" | "moved";
6
+ changeType: "added" | "removed" | "moved" | "changed";
7
7
  designItems: IDesignItem[];
8
8
  }
9
9
  export type IContentChanged = IContentChangedParsed | IContentChangedWithDesignItems;
@@ -316,7 +316,16 @@
316
316
  "wrap-reverse"
317
317
  ]
318
318
  },
319
- "float": {},
319
+ "float": {
320
+ "type": "list",
321
+ "values": [
322
+ "none",
323
+ "left",
324
+ "right",
325
+ "inline-start",
326
+ "inline-end"
327
+ ]
328
+ },
320
329
  "floodColor": {
321
330
  "type": "color"
322
331
  },
@@ -1,6 +1,7 @@
1
1
  import { ITransactionItem } from './ITransactionItem.js';
2
2
  import { IDesignItem } from '../../item/IDesignItem.js';
3
3
  export declare class ChangeGroup implements ITransactionItem {
4
+ redoBranches?: ITransactionItem[][];
4
5
  title: string;
5
6
  get affectedItems(): IDesignItem[];
6
7
  private commitHandler;
@@ -1,4 +1,5 @@
1
1
  export class ChangeGroup {
2
+ redoBranches;
2
3
  title;
3
4
  get affectedItems() {
4
5
  let s = new Set();
@@ -5,4 +5,5 @@ export interface ITransactionItem {
5
5
  do: () => void;
6
6
  undo: () => void;
7
7
  mergeWith(other: ITransactionItem): boolean;
8
+ redoBranches?: ITransactionItem[][];
8
9
  }
@@ -12,4 +12,6 @@ export interface IUndoService extends IService {
12
12
  redo(): any;
13
13
  getUndoEntries(count?: number): Generator<string, void, unknown>;
14
14
  getRedoEntries(count?: number): Generator<string, void, unknown>;
15
+ readonly undoCount: number;
16
+ readonly redoCount: number;
15
17
  }
@@ -7,7 +7,8 @@ export declare class UndoService implements IUndoService {
7
7
  private _redoStack;
8
8
  private _transactionStack;
9
9
  private _designerCanvas;
10
- constructor(designerCanvas: IDesignerCanvas);
10
+ private _storeRedoBranches;
11
+ constructor(designerCanvas: IDesignerCanvas, storeRedoBranches?: boolean);
11
12
  openGroup(title: string): ChangeGroup;
12
13
  private commitTransactionItem;
13
14
  private abortTransactionItem;
@@ -18,6 +19,8 @@ export declare class UndoService implements IUndoService {
18
19
  redo(): void;
19
20
  canUndo(): boolean;
20
21
  canRedo(): boolean;
22
+ get undoCount(): number;
23
+ get redoCount(): number;
21
24
  getUndoEntries(count?: number): Generator<string, void, unknown>;
22
25
  getRedoEntries(count?: number): Generator<string, void, unknown>;
23
26
  }
@@ -7,8 +7,10 @@ export class UndoService {
7
7
  _redoStack = [];
8
8
  _transactionStack = [];
9
9
  _designerCanvas;
10
- constructor(designerCanvas) {
10
+ _storeRedoBranches;
11
+ constructor(designerCanvas, storeRedoBranches = false) {
11
12
  this._designerCanvas = designerCanvas;
13
+ this._storeRedoBranches = storeRedoBranches;
12
14
  }
13
15
  openGroup(title) {
14
16
  let t = new ChangeGroup(title, (t) => this.commitTransactionItem(t), (t) => this.abortTransactionItem(t));
@@ -26,8 +28,13 @@ export class UndoService {
26
28
  this._transactionStack[this._transactionStack.length - 1].addCommitedSubchangeGroup(itm);
27
29
  }
28
30
  else {
29
- this._undoStack.push(itm);
31
+ if (this._storeRedoBranches && this._redoStack.length) {
32
+ if (itm.redoBranches == null)
33
+ itm.redoBranches = [];
34
+ itm.redoBranches.push(this._redoStack);
35
+ }
30
36
  this._redoStack = [];
37
+ this._undoStack.push(itm);
31
38
  }
32
39
  }
33
40
  if (this._transactionStack.length == 0) {
@@ -48,8 +55,13 @@ export class UndoService {
48
55
  execute(item) {
49
56
  if (this._transactionStack.length == 0) {
50
57
  item.do();
51
- this._undoStack.push(item);
58
+ if (this._storeRedoBranches && this._redoStack.length) {
59
+ if (item.redoBranches == null)
60
+ item.redoBranches = [];
61
+ item.redoBranches.push(this._redoStack);
62
+ }
52
63
  this._redoStack = [];
64
+ this._undoStack.push(item);
53
65
  }
54
66
  else {
55
67
  this._transactionStack[this._transactionStack.length - 1].execute(item);
@@ -110,6 +122,12 @@ export class UndoService {
110
122
  canRedo() {
111
123
  return this._redoStack.length > 0;
112
124
  }
125
+ get undoCount() {
126
+ return this._undoStack.length;
127
+ }
128
+ get redoCount() {
129
+ return this._redoStack.length;
130
+ }
113
131
  *getUndoEntries(count = 999) {
114
132
  for (let i = Math.min(this._undoStack.length, count) - 1; i >= 0; i--)
115
133
  yield this._undoStack[i].title;
@@ -5,6 +5,13 @@ export declare class DesignContext implements IDesignContext {
5
5
  npmPackages: string[];
6
6
  extensionOptions: {
7
7
  [key: string]: any;
8
+ gridExtensionShowOverlay: boolean;
9
+ flexboxExtensionShowOverlay: boolean;
10
+ invisibleElementExtensionShowOverlay: boolean;
11
+ enableStylesheetService: boolean;
12
+ basicStackedToolbarExtensionShowOverlay: boolean;
13
+ simulateHoverOnHover: boolean;
14
+ selectUnhitableElements: boolean;
8
15
  };
9
16
  extensionOptionsChanged: TypedEvent<void>;
10
17
  }
@@ -2,6 +2,14 @@ import { TypedEvent } from '@node-projects/base-custom-webcomponent';
2
2
  export class DesignContext {
3
3
  imports = [];
4
4
  npmPackages = [];
5
- extensionOptions = {};
5
+ extensionOptions = {
6
+ gridExtensionShowOverlay: false,
7
+ flexboxExtensionShowOverlay: false,
8
+ invisibleElementExtensionShowOverlay: false,
9
+ enableStylesheetService: false,
10
+ basicStackedToolbarExtensionShowOverlay: false,
11
+ simulateHoverOnHover: false,
12
+ selectUnhitableElements: false,
13
+ };
6
14
  extensionOptionsChanged = new TypedEvent;
7
15
  }
@@ -4,6 +4,13 @@ export interface IDesignContext {
4
4
  npmPackages: string[];
5
5
  extensionOptions: {
6
6
  [key: string]: any;
7
+ gridExtensionShowOverlay: boolean;
8
+ flexboxExtensionShowOverlay: boolean;
9
+ invisibleElementExtensionShowOverlay: boolean;
10
+ enableStylesheetService: boolean;
11
+ basicStackedToolbarExtensionShowOverlay: boolean;
12
+ simulateHoverOnHover: boolean;
13
+ selectUnhitableElements: boolean;
7
14
  };
8
15
  extensionOptionsChanged: TypedEvent<void>;
9
16
  }
@@ -126,6 +126,8 @@ export declare class DesignerCanvas extends BaseCustomWebComponentLazyAppend imp
126
126
  getNormalizedOffsetInElement(event: MouseEvent, element: Element): IPoint;
127
127
  elementsFromPoint(x: number, y: number): Element[];
128
128
  getElementAtPoint(point: IPoint, ignoreElementCallback?: (element: HTMLElement) => boolean): HTMLElement;
129
+ _patchStylesheetForDesigner(text: string): string;
130
+ private _hoverElement;
129
131
  showHoverExtension(element: Element, event: Event): void;
130
132
  private _onWheel;
131
133
  private _pointerEventHandler;
@@ -1,6 +1,6 @@
1
1
  import { EventNames } from '../../../enums/EventNames.js';
2
2
  import { InstanceServiceContainer } from '../../services/InstanceServiceContainer.js';
3
- import { DesignItem } from '../../item/DesignItem.js';
3
+ import { DesignItem, forceActiveAttributeName, forceFocusAttributeName, forceFocusVisibleAttributeName, forceFocusWithinAttributeName, forceHoverAttributeName, forceVisitedAttributeName } from '../../item/DesignItem.js';
4
4
  import { BaseCustomWebComponentLazyAppend, css, html, TypedEvent, cssFromString } from '@node-projects/base-custom-webcomponent';
5
5
  import { dragDropFormatNameBindingObject } from '../../../Constants.js';
6
6
  import { InsertAction } from '../../services/undoService/transactionItems/InsertAction.js';
@@ -339,7 +339,7 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
339
339
  if (this.instanceServiceContainer.stylesheetService) {
340
340
  styles.push(...this.instanceServiceContainer.stylesheetService
341
341
  .getStylesheets()
342
- .map(x => cssFromString(x.content)));
342
+ .map(x => cssFromString(this._patchStylesheetForDesigner(x.content))));
343
343
  }
344
344
  this._canvasShadowRoot.adoptedStyleSheets = styles;
345
345
  }
@@ -445,9 +445,23 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
445
445
  case CommandType.undo:
446
446
  this.instanceServiceContainer.undoService.undo();
447
447
  break;
448
+ case CommandType.holdUndo:
449
+ let undoEntries = this.instanceServiceContainer.undoService.getUndoEntries(20);
450
+ let undoMnu = Array.from(undoEntries).map((x, idx) => ({ title: 'undo: ' + x, action: () => { for (let i = 0; i <= idx; i++)
451
+ this.instanceServiceContainer.undoService.undo(); } }));
452
+ if (undoMnu.length > 0)
453
+ ContextMenu.show(undoMnu, command.event, { mode: 'undo' });
454
+ break;
448
455
  case CommandType.redo:
449
456
  this.instanceServiceContainer.undoService.redo();
450
457
  break;
458
+ case CommandType.holdRedo:
459
+ let redoEntries = this.instanceServiceContainer.undoService.getRedoEntries(20);
460
+ let redoMnu = Array.from(redoEntries).map((x, idx) => ({ title: 'redo: ' + x, action: () => { for (let i = 0; i <= idx; i++)
461
+ this.instanceServiceContainer.undoService.redo(); } }));
462
+ if (redoMnu.length > 0)
463
+ ContextMenu.show(redoMnu, command.event, { mode: 'undo' });
464
+ break;
451
465
  case CommandType.copy:
452
466
  this.handleCopyCommand();
453
467
  break;
@@ -1032,10 +1046,23 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
1032
1046
  currentElement = null;
1033
1047
  continue;
1034
1048
  }
1049
+ if (!this.instanceServiceContainer.designContext.extensionOptions.selectUnhitableElements && DesignItem.GetDesignItem(currentElement).getStyleFromSheetOrLocal('pointer-events') == 'none') {
1050
+ currentElement = null;
1051
+ continue;
1052
+ }
1035
1053
  break;
1036
1054
  }
1037
1055
  return currentElement;
1038
1056
  }
1057
+ _patchStylesheetForDesigner(text) {
1058
+ return text.replace(':hover', '[' + forceHoverAttributeName + ']')
1059
+ .replace(':active', '[' + forceActiveAttributeName + ']')
1060
+ .replace(':visited', '[' + forceVisitedAttributeName + ']')
1061
+ .replace(':focus', '[' + forceFocusAttributeName + ']')
1062
+ .replace(':focus-within', '[' + forceFocusWithinAttributeName + ']')
1063
+ .replace(':focus-visible', '[' + forceFocusVisibleAttributeName + ']');
1064
+ }
1065
+ _hoverElement;
1039
1066
  showHoverExtension(element, event) {
1040
1067
  const currentDesignItem = DesignItem.GetOrCreateDesignItem(element, element, this.serviceContainer, this.instanceServiceContainer);
1041
1068
  if (this._lastHoverDesignItem != currentDesignItem) {
@@ -1045,6 +1072,24 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
1045
1072
  this.extensionManager.applyExtension(currentDesignItem, ExtensionType.MouseOver, event);
1046
1073
  this._lastHoverDesignItem = currentDesignItem;
1047
1074
  }
1075
+ if (this.instanceServiceContainer.designContext.extensionOptions.simulateHoverOnHover && this._hoverElement !== element) {
1076
+ let el = this._hoverElement;
1077
+ while (el && el !== this._canvas) {
1078
+ el.removeAttribute(forceHoverAttributeName);
1079
+ el = el.parentElement;
1080
+ }
1081
+ this._hoverElement = null;
1082
+ if (element) {
1083
+ if (element.nodeType == NodeType.TextNode)
1084
+ element = element.parentElement;
1085
+ el = element;
1086
+ while (el && el !== this._canvas) {
1087
+ el.setAttribute(forceHoverAttributeName, '');
1088
+ el = el.parentElement;
1089
+ }
1090
+ this._hoverElement = element;
1091
+ }
1092
+ }
1048
1093
  }
1049
1094
  _onWheel(event) {
1050
1095
  let el = this.getElementAtPoint({ x: event.clientX, y: event.clientY });
@@ -3,11 +3,17 @@ import { AbstractExtension } from "./AbstractExtension.js";
3
3
  export const basicStackedToolbarExtensionOverlayOptionName = 'basicStackedToolbarExtensionShowOverlay';
4
4
  export class BasicStackedToolbarExtension extends AbstractExtension {
5
5
  static basicTemplate = `
6
+ <select title="position" id="position" style="pointer-events: all; height: 24px; width: 80px; padding: 0; font-weight: 900; text-transform: uppercase; margin-left: 5px; margin-right: 10px;">
7
+ <option>static</option>
8
+ <option>relative</option>
9
+ <option>absolute</option>
10
+ <option>fixed</option>
11
+ </select>
6
12
  <node-projects-image-button-list-selector id="inline" no-value-in-header property="inline">
7
13
  <img data-value="block" title="block" src="${assetsPath}images/display/block.svg">
8
14
  <img data-value="inline" title="inline" src="${assetsPath}images/display/inline.svg">
9
15
  </node-projects-image-button-list-selector>
10
- <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;">
16
+ <select title="display" id="displayType" style="pointer-events: all; height: 24px; width: 80px; padding: 0; font-weight: 900; text-transform: uppercase; margin-left: 5px; margin-right: 10px;">
11
17
  <option>block</option>
12
18
  <option>flex</option>
13
19
  <option>grid</option>
@@ -15,7 +21,7 @@ export class BasicStackedToolbarExtension extends AbstractExtension {
15
21
  `;
16
22
  static toolBars = [];
17
23
  _toolbar;
18
- _size = { width: 200, height: 30 };
24
+ _size = { width: 220, height: 30 };
19
25
  _display;
20
26
  _inline;
21
27
  constructor(extensionManager, designerView, extendedItem) {
@@ -28,6 +34,14 @@ export class BasicStackedToolbarExtension extends AbstractExtension {
28
34
  //@ts-ignore
29
35
  this._toolbar = this.createToolbar(this.constructor.template, this._size.width, this._size.height);
30
36
  BasicStackedToolbarExtension.toolBars.push(this._toolbar);
37
+ const positionEl = this._toolbar.getById('position');
38
+ if (positionEl) {
39
+ positionEl.value = cs.position;
40
+ positionEl.onchange = async () => {
41
+ await this.extendedItem.updateStyleInSheetOrLocalAsync('position', positionEl.value);
42
+ this.extensionManager.reapplyAllAppliedExtentions([this.extendedItem]);
43
+ };
44
+ }
31
45
  const displayTypeEl = this._toolbar.getById('displayType');
32
46
  if (displayTypeEl) {
33
47
  displayTypeEl.value = this._display;
@@ -10,7 +10,7 @@ export class PaddingExtension extends AbstractExtension {
10
10
  refresh() {
11
11
  const itemRect = this.designerCanvas.getNormalizedElementCoordinates(this.extendedItem.element);
12
12
  const computedStyle = getComputedStyle(this.extendedItem.element);
13
- if (computedStyle.margin !== '0px') {
13
+ if (computedStyle.padding !== '0px') {
14
14
  const left = Number.parseFloat(computedStyle.paddingLeft.replace('px', ''));
15
15
  const top = Number.parseFloat(computedStyle.paddingTop.replace('px', ''));
16
16
  const right = Number.parseFloat(computedStyle.paddingRight.replace('px', ''));
@@ -0,0 +1,8 @@
1
+ import { DesignerView } from "../../designerView.js";
2
+ import { IDesignerCanvas } from '../../IDesignerCanvas.js';
3
+ import { IDesignViewConfigButtonsProvider } from "./IDesignViewConfigButtonsProvider.js";
4
+ export declare class OptionsContextMenuButton implements IDesignViewConfigButtonsProvider {
5
+ constructor();
6
+ provideButtons(designerView: DesignerView, designerCanvas: IDesignerCanvas): HTMLElement[];
7
+ showCtxMenu(event: MouseEvent, designerCanvas: IDesignerCanvas): void;
8
+ }
@@ -0,0 +1,33 @@
1
+ import { ContextMenu } from "../../../../helper/contextMenu/ContextMenu.js";
2
+ export class OptionsContextMenuButton {
3
+ constructor() {
4
+ }
5
+ provideButtons(designerView, designerCanvas) {
6
+ const btn = document.createElement('div');
7
+ btn.innerHTML = 'O';
8
+ btn.title = 'options';
9
+ btn.className = 'toolbar-control';
10
+ btn.onclick = (e) => {
11
+ this.showCtxMenu(e, designerCanvas);
12
+ };
13
+ btn.oncontextmenu = (e) => {
14
+ e.preventDefault();
15
+ this.showCtxMenu(e, designerCanvas);
16
+ };
17
+ return [btn];
18
+ }
19
+ showCtxMenu(event, designerCanvas) {
20
+ ContextMenu.show([
21
+ {
22
+ title: 'simulate hover on hover', checked: designerCanvas.instanceServiceContainer.designContext.extensionOptions.simulateHoverOnHover, action: () => {
23
+ designerCanvas.instanceServiceContainer.designContext.extensionOptions.simulateHoverOnHover = !designerCanvas.instanceServiceContainer.designContext.extensionOptions.simulateHoverOnHover;
24
+ }
25
+ },
26
+ {
27
+ title: 'select unhitable elements', checked: designerCanvas.instanceServiceContainer.designContext.extensionOptions.selectUnhitableElements, action: () => {
28
+ designerCanvas.instanceServiceContainer.designContext.extensionOptions.selectUnhitableElements = !designerCanvas.instanceServiceContainer.designContext.extensionOptions.selectUnhitableElements;
29
+ }
30
+ }
31
+ ], event);
32
+ }
33
+ }
@@ -0,0 +1,8 @@
1
+ import { IContextMenuItem } from '../../../../helper/contextMenu/IContextMenuItem.js';
2
+ import { IDesignItem } from '../../../../item/IDesignItem.js';
3
+ import { IDesignerCanvas } from '../../IDesignerCanvas.js';
4
+ import { ContextmenuInitiator, IContextMenuExtension } from './IContextMenuExtension.js';
5
+ export declare class ForceCssContextMenu implements IContextMenuExtension {
6
+ shouldProvideContextmenu(event: MouseEvent, designerView: IDesignerCanvas, designItem: IDesignItem, initiator: ContextmenuInitiator): boolean;
7
+ provideContextMenuItems(event: MouseEvent, designerView: IDesignerCanvas, designItem: IDesignItem): IContextMenuItem[];
8
+ }
@@ -0,0 +1,16 @@
1
+ import { NodeType } from '../../../../item/NodeType.js';
2
+ export class ForceCssContextMenu {
3
+ shouldProvideContextmenu(event, designerView, designItem, initiator) {
4
+ return designItem != null && designItem.nodeType == NodeType.Element;
5
+ }
6
+ provideContextMenuItems(event, designerView, designItem) {
7
+ return [
8
+ { title: ':hover', action: () => { designItem.cssForceHover = !designItem.cssForceHover; }, checked: designItem.cssForceHover },
9
+ { title: ':active', action: () => { designItem.cssForceActive = !designItem.cssForceActive; }, checked: designItem.cssForceActive },
10
+ { title: ':visited', action: () => { designItem.cssForceVisited = !designItem.cssForceVisited; }, checked: designItem.cssForceVisited },
11
+ { title: ':focus', action: () => { designItem.cssForceFocus = !designItem.cssForceFocus; }, checked: designItem.cssForceFocus },
12
+ { title: ':focus-within', action: () => { designItem.cssForceFocusWithin = !designItem.cssForceFocusWithin; }, checked: designItem.cssForceFocusWithin },
13
+ { title: ':focus-visible', action: () => { designItem.cssForceFocusVisible = !designItem.cssForceFocusVisible; }, checked: designItem.cssForceFocusVisible },
14
+ ];
15
+ }
16
+ }
@@ -43,7 +43,7 @@ export class FlexToolbarExtension extends BasicStackedToolbarExtension {
43
43
  `;
44
44
  constructor(extensionManager, designerView, extendedItem) {
45
45
  super(extensionManager, designerView, extendedItem);
46
- this._size.width = 515;
46
+ this._size.width = 625;
47
47
  }
48
48
  extend(cache, event) {
49
49
  super.extend(cache, event);
@@ -46,7 +46,7 @@ export class GridToolbarExtension extends BasicStackedToolbarExtension {
46
46
  `;
47
47
  constructor(extensionManager, designerView, extendedItem) {
48
48
  super(extensionManager, designerView, extendedItem);
49
- this._size.width = 524;
49
+ this._size.width = 624;
50
50
  }
51
51
  extend(cache, event) {
52
52
  super.extend(cache, event);
@@ -43,7 +43,6 @@ export class DrawElementTool {
43
43
  this._createdItem.setStyle('top', roundValue(this._createdItem, evPos.y) + 'px');
44
44
  this._createdItem.setStyle('width', '0');
45
45
  this._createdItem.setStyle('height', '0');
46
- this._createdItem.element.style.overflow = 'hidden';
47
46
  designerCanvas.rootDesignItem.insertChild(this._createdItem);
48
47
  //draw via containerService??? how to draw into a grid, a stackpanel???
49
48
  designerCanvas.instanceServiceContainer.selectionService.clearSelectedElements();
package/dist/index.d.ts CHANGED
@@ -267,6 +267,7 @@ export * from "./elements/widgets/designerView/extensions/buttons/ButtonSeperato
267
267
  export * from "./elements/widgets/designerView/extensions/buttons/StylesheetServiceDesignViewConfigButtons.js";
268
268
  export * from "./elements/widgets/designerView/extensions/buttons/ToolbarExtensionsDesignViewConfigButtons.js";
269
269
  export * from "./elements/widgets/designerView/extensions/buttons/RoundPixelsDesignViewConfigButton.js";
270
+ export * from "./elements/widgets/designerView/extensions/buttons/OptionsContextMenuButton.js";
270
271
  export type { IDesignViewConfigButtonsProvider } from './elements/widgets/designerView/extensions/buttons/IDesignViewConfigButtonsProvider.js';
271
272
  export * from "./elements/widgets/designerView/extensions/EditText/EditTextExtension.js";
272
273
  export * from "./elements/widgets/designerView/extensions/EditText/EditTextExtensionProvider.js";
@@ -284,6 +285,7 @@ export * from "./elements/widgets/designerView/extensions/contextMenu/RotateLeft
284
285
  export * from "./elements/widgets/designerView/extensions/contextMenu/ZoomToElementContextMenu.js";
285
286
  export * from "./elements/widgets/designerView/extensions/contextMenu/JumpToElementContextMenu.js";
286
287
  export * from "./elements/widgets/designerView/extensions/contextMenu/AlignItemsContextMenu.js";
288
+ export * from "./elements/widgets/designerView/extensions/contextMenu/ForceCssContextMenu.js";
287
289
  export type { IDesignerPointerExtension } from "./elements/widgets/designerView/extensions/pointerExtensions/IDesignerPointerExtension.js";
288
290
  export type { IDesignerPointerExtensionProvider } from "./elements/widgets/designerView/extensions/pointerExtensions/IDesignerPointerExtensionProvider.js";
289
291
  export * from "./elements/widgets/designerView/extensions/pointerExtensions/AbstractDesignerPointerExtension.js";
package/dist/index.js CHANGED
@@ -208,6 +208,7 @@ export * from "./elements/widgets/designerView/extensions/buttons/ButtonSeperato
208
208
  export * from "./elements/widgets/designerView/extensions/buttons/StylesheetServiceDesignViewConfigButtons.js";
209
209
  export * from "./elements/widgets/designerView/extensions/buttons/ToolbarExtensionsDesignViewConfigButtons.js";
210
210
  export * from "./elements/widgets/designerView/extensions/buttons/RoundPixelsDesignViewConfigButton.js";
211
+ export * from "./elements/widgets/designerView/extensions/buttons/OptionsContextMenuButton.js";
211
212
  export * from "./elements/widgets/designerView/extensions/EditText/EditTextExtension.js";
212
213
  export * from "./elements/widgets/designerView/extensions/EditText/EditTextExtensionProvider.js";
213
214
  export * from "./elements/widgets/designerView/extensions/contextMenu/ChildContextMenu.js";
@@ -223,6 +224,7 @@ export * from "./elements/widgets/designerView/extensions/contextMenu/RotateLeft
223
224
  export * from "./elements/widgets/designerView/extensions/contextMenu/ZoomToElementContextMenu.js";
224
225
  export * from "./elements/widgets/designerView/extensions/contextMenu/JumpToElementContextMenu.js";
225
226
  export * from "./elements/widgets/designerView/extensions/contextMenu/AlignItemsContextMenu.js";
227
+ export * from "./elements/widgets/designerView/extensions/contextMenu/ForceCssContextMenu.js";
226
228
  export * from "./elements/widgets/designerView/extensions/pointerExtensions/AbstractDesignerPointerExtension.js";
227
229
  export * from "./elements/widgets/designerView/extensions/pointerExtensions/CursorLinePointerExtension.js";
228
230
  export * from "./elements/widgets/designerView/extensions/pointerExtensions/CursorLinePointerExtensionProvider.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "description": "A WYSIWYG designer webcomponent for html components",
3
3
  "name": "@node-projects/web-component-designer",
4
- "version": "0.1.158",
4
+ "version": "0.1.159",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "author": "jochen.kuehner@gmx.de",