@node-projects/web-component-designer 0.1.181 → 0.1.183

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.
@@ -24,7 +24,7 @@ export declare class DesignItem implements IDesignItem {
24
24
  nodeReplaced: TypedEvent<void>;
25
25
  get window(): Window & typeof globalThis;
26
26
  get document(): Document;
27
- get usableContainer(): ShadowRoot | Document | Element;
27
+ get usableContainer(): Element | Document | ShadowRoot;
28
28
  clone(): Promise<IDesignItem>;
29
29
  allMatching(selectors: string): Generator<IDesignItem, void, undefined>;
30
30
  replaceNode(newNode: Node): void;
@@ -605,14 +605,14 @@ export class DesignItem {
605
605
  try {
606
606
  const rules = this.instanceServiceContainer.stylesheetService?.getAppliedRules(this);
607
607
  if (rules) {
608
- return [{ selector: null, declarations: localStyles, specificity: -1 }, ...rules];
608
+ return [{ selector: null, declarations: localStyles, specificity: null }, ...rules];
609
609
  }
610
610
  }
611
611
  catch (err) {
612
612
  console.warn('getAppliedRules', err);
613
613
  }
614
614
  }
615
- styles = [{ selector: null, declarations: localStyles, specificity: -1 }];
615
+ styles = [{ selector: null, declarations: localStyles, specificity: null }];
616
616
  this._stylesCache = styles;
617
617
  clearTimeout(this._cacheClearTimer);
618
618
  this._cacheClearTimer = setTimeout(() => this._stylesCache = null, 30);
@@ -23,9 +23,17 @@ export class CssCurrentPropertiesService extends AbstractCssPropertiesService {
23
23
  async getProperties(designItem) {
24
24
  if (!designItem || designItem.nodeType != NodeType.Element)
25
25
  return [];
26
- let styles = designItem.getAllStyles();
26
+ let styles = designItem.getAllStyles().toReversed().sort((a, b) => {
27
+ if (a.specificity == null)
28
+ return -1;
29
+ if (b.specificity == null)
30
+ return 1;
31
+ if (a.specificity.A > b.specificity.A || a.specificity.B > b.specificity.B || a.specificity.C > b.specificity.C)
32
+ return -1;
33
+ return 0;
34
+ });
27
35
  let arr = styles.map(x => ({
28
- name: x.selector ?? localName, description: x.stylesheetName ?? '', properties: [
36
+ name: (x.selector ?? localName) + (x.specificity ? ' (' + x.specificity.A + '-' + x.specificity.B + '-' + x.specificity.C + ')' : ''), description: x.stylesheetName ?? '', properties: [
29
37
  ...x.declarations.map(y => ({
30
38
  name: y.name,
31
39
  renamable: true,
@@ -3,6 +3,7 @@ import { IDesignItem } from '../../item/IDesignItem.js';
3
3
  import { IDocumentStylesheet, IStyleDeclaration, IStyleRule, IStylesheet, IStylesheetService } from './IStylesheetService.js';
4
4
  import { InstanceServiceContainer } from "../InstanceServiceContainer.js";
5
5
  import { IDesignerCanvas } from "../../widgets/designerView/IDesignerCanvas.js";
6
+ import { Specificity } from "./SpecifityCalculator.js";
6
7
  export declare abstract class AbstractStylesheetService implements IStylesheetService {
7
8
  protected _stylesheets: Map<string, {
8
9
  stylesheet: IStylesheet;
@@ -45,5 +46,5 @@ export declare abstract class AbstractStylesheetService implements IStylesheetSe
45
46
  }>;
46
47
  stylesheetsChanged: TypedEvent<void>;
47
48
  static patchStylesheetSelectorForDesigner(text: string): string;
48
- protected elementMatchesASelector(designItem: IDesignItem, selectors: string[]): boolean;
49
+ protected elementMatchesASelector(designItem: IDesignItem, selectors: string[]): false | Specificity;
49
50
  }
@@ -1,5 +1,6 @@
1
1
  import { TypedEvent } from "@node-projects/base-custom-webcomponent";
2
2
  import { forceActiveAttributeName, forceFocusAttributeName, forceFocusVisibleAttributeName, forceFocusWithinAttributeName, forceHoverAttributeName, forceVisitedAttributeName } from "../../item/DesignItem.js";
3
+ import { calculateSpecifity } from "./SpecifityCalculator.js";
3
4
  export class AbstractStylesheetService {
4
5
  _stylesheets = new Map();
5
6
  _documentStylesheets = new Map();
@@ -110,17 +111,21 @@ export class AbstractStylesheetService {
110
111
  }
111
112
  elementMatchesASelector(designItem, selectors) {
112
113
  if (designItem == null)
113
- return true;
114
+ return false;
115
+ let s = null;
114
116
  for (let selector of selectors) {
115
117
  const patched = AbstractStylesheetService.patchStylesheetSelectorForDesigner(selector);
116
118
  try {
117
- if (designItem.element.matches(patched))
118
- return true;
119
+ if (designItem.element.matches(patched)) {
120
+ let spec = calculateSpecifity(selector);
121
+ if (s === null || spec.A > s.A || spec.B > s.B || spec.C > s.C)
122
+ s = spec;
123
+ }
119
124
  }
120
125
  catch (err) {
121
126
  console.warn("invalid selector: ", selector, "patched: " + patched);
122
127
  }
123
128
  }
124
- return false;
129
+ return s === null ? false : s;
125
130
  }
126
131
  }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -1,9 +1,10 @@
1
1
  import { TypedEvent } from "@node-projects/base-custom-webcomponent";
2
2
  import { IDesignItem } from "../../item/IDesignItem.js";
3
+ import { Specificity } from "./SpecifityCalculator.js";
3
4
  export interface IStyleRule {
4
5
  selector: string;
5
6
  declarations: IStyleDeclaration[];
6
- specificity: number;
7
+ specificity: Specificity;
7
8
  stylesheetName?: string;
8
9
  }
9
10
  export interface IStyleDeclaration {
@@ -0,0 +1,3 @@
1
+ export type Level = "A" | "B" | "C";
2
+ export type Specificity = Record<Level, number>;
3
+ export declare function calculateSpecifity(selector: string): Specificity;
@@ -0,0 +1,72 @@
1
+ var ParseState;
2
+ (function (ParseState) {
3
+ ParseState[ParseState["none"] = 0] = "none";
4
+ ParseState[ParseState["parseName"] = 1] = "parseName";
5
+ ParseState[ParseState["parseAttribute"] = 2] = "parseAttribute";
6
+ ParseState[ParseState["parseInFunc"] = 3] = "parseInFunc";
7
+ })(ParseState || (ParseState = {}));
8
+ //todo special cases:
9
+ //:not :is :has = inner selector specifity
10
+ //:where = 0 specifity
11
+ //:nth-child :nth-last-child = inner sel. ?
12
+ export function calculateSpecifity(selector) {
13
+ let s = { A: 0, B: 0, C: 0 };
14
+ let parseState = ParseState.none;
15
+ for (let n = 0; n < selector.length; n++) {
16
+ let c = selector[n];
17
+ if (parseState === ParseState.parseInFunc) {
18
+ if (c == ')') {
19
+ parseState = ParseState.none;
20
+ }
21
+ }
22
+ else if (parseState === ParseState.parseAttribute) {
23
+ if (c == ']') {
24
+ parseState = ParseState.none;
25
+ }
26
+ }
27
+ else {
28
+ switch (c) {
29
+ case '#':
30
+ s.A++;
31
+ parseState = ParseState.parseName;
32
+ break;
33
+ case '.':
34
+ s.B++;
35
+ parseState = ParseState.parseName;
36
+ break;
37
+ case '[':
38
+ s.B++;
39
+ parseState = ParseState.parseAttribute;
40
+ break;
41
+ case '(':
42
+ parseState = ParseState.parseInFunc;
43
+ break;
44
+ case ':':
45
+ if (selector[n + 1] !== ':') {
46
+ s.B++;
47
+ parseState = ParseState.parseName;
48
+ }
49
+ else {
50
+ s.C++;
51
+ parseState = ParseState.parseName;
52
+ n++;
53
+ }
54
+ break;
55
+ case '>':
56
+ case ' ':
57
+ case '~':
58
+ case '+':
59
+ parseState = ParseState.none;
60
+ break;
61
+ case '*':
62
+ break;
63
+ default:
64
+ if (parseState === ParseState.none) {
65
+ s.C++;
66
+ parseState = ParseState.parseName;
67
+ }
68
+ }
69
+ }
70
+ }
71
+ return s;
72
+ }
package/dist/index.d.ts CHANGED
@@ -140,6 +140,7 @@ export type { ISelectionService } from "./elements/services/selectionService/ISe
140
140
  export * from "./elements/services/selectionService/SelectionService.js";
141
141
  export type { IStyleRule, IStyleDeclaration, IStylesheet, IStylesheetService, IDocumentStylesheet } from "./elements/services/stylesheetService/IStylesheetService.js";
142
142
  export * from "./elements/services/stylesheetService/AbstractStylesheetService.js";
143
+ export * from "./elements/services/stylesheetService/SpecifityCalculator.js";
143
144
  export * from "./elements/services/undoService/ChangeGroup.js";
144
145
  export type { ITransactionItem } from "./elements/services/undoService/ITransactionItem.js";
145
146
  export type { IUndoService } from "./elements/services/undoService/IUndoService.js";
package/dist/index.js CHANGED
@@ -93,6 +93,7 @@ export * from "./elements/services/refactorService/BindingsRefactorService.js";
93
93
  export * from "./elements/services/refactorService/TextRefactorService.js";
94
94
  export * from "./elements/services/selectionService/SelectionService.js";
95
95
  export * from "./elements/services/stylesheetService/AbstractStylesheetService.js";
96
+ export * from "./elements/services/stylesheetService/SpecifityCalculator.js";
96
97
  export * from "./elements/services/undoService/ChangeGroup.js";
97
98
  export * from "./elements/services/undoService/UndoService.js";
98
99
  export * from "./elements/services/undoService/transactionItems/AttributeChangeAction.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.181",
4
+ "version": "0.1.183",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "author": "jochen.kuehner@gmx.de",