@projectwallace/css-layer-tree 2.1.0 → 2.1.2
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.
- package/dist/index.d.mts +21 -0
- package/dist/index.mjs +124 -0
- package/package.json +59 -59
- package/dist/css-layer-tree.js +0 -125
- package/index.d.ts +0 -18
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CSSNode } from "@projectwallace/css-parser";
|
|
2
|
+
|
|
3
|
+
//#region src/TreeNode.d.ts
|
|
4
|
+
type Location = {
|
|
5
|
+
line: number;
|
|
6
|
+
column: number;
|
|
7
|
+
start: number;
|
|
8
|
+
end: number;
|
|
9
|
+
};
|
|
10
|
+
type TreeNode = {
|
|
11
|
+
name: string;
|
|
12
|
+
is_anonymous: boolean;
|
|
13
|
+
locations: Location[];
|
|
14
|
+
children: TreeNode[];
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/index.d.ts
|
|
18
|
+
declare function layer_tree_from_ast(ast: CSSNode): TreeNode[];
|
|
19
|
+
declare function layer_tree(css: string): TreeNode[];
|
|
20
|
+
//#endregion
|
|
21
|
+
export { type Location, type TreeNode, layer_tree, layer_tree_from_ast };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { AT_RULE, LAYER_NAME, parse, traverse } from "@projectwallace/css-parser";
|
|
2
|
+
//#region src/TreeNode.ts
|
|
3
|
+
var LayerTreeNode = class LayerTreeNode {
|
|
4
|
+
name;
|
|
5
|
+
is_anonymous;
|
|
6
|
+
children;
|
|
7
|
+
locations;
|
|
8
|
+
constructor(name) {
|
|
9
|
+
this.name = name;
|
|
10
|
+
this.is_anonymous = false;
|
|
11
|
+
this.children = /* @__PURE__ */ new Map();
|
|
12
|
+
this.locations = [];
|
|
13
|
+
}
|
|
14
|
+
add_child(path, name, location) {
|
|
15
|
+
let current = this;
|
|
16
|
+
path.forEach((segment) => {
|
|
17
|
+
current = current.children.get(segment);
|
|
18
|
+
});
|
|
19
|
+
if (current.children.has(name)) {
|
|
20
|
+
if (location !== void 0) current.children.get(name).locations.push(location);
|
|
21
|
+
} else {
|
|
22
|
+
const new_node = new LayerTreeNode(name);
|
|
23
|
+
if (location !== void 0) new_node.locations.push(location);
|
|
24
|
+
new_node.is_anonymous = name.startsWith("__anonymous");
|
|
25
|
+
current.children.set(name, new_node);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
to_plain_object() {
|
|
29
|
+
return {
|
|
30
|
+
name: this.name,
|
|
31
|
+
is_anonymous: this.is_anonymous,
|
|
32
|
+
locations: this.locations,
|
|
33
|
+
children: Array.from(this.children.values(), (child) => child.to_plain_object())
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/index.ts
|
|
39
|
+
function get_layer_names(name) {
|
|
40
|
+
return name.split(".").map((s) => s.trim());
|
|
41
|
+
}
|
|
42
|
+
function create_location(node) {
|
|
43
|
+
return {
|
|
44
|
+
line: node.line,
|
|
45
|
+
column: node.column,
|
|
46
|
+
start: node.start,
|
|
47
|
+
end: node.end
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function layer_tree_from_ast(ast) {
|
|
51
|
+
let current_stack = [];
|
|
52
|
+
let root = new LayerTreeNode("root");
|
|
53
|
+
let anonymous_counter = 0;
|
|
54
|
+
function get_anonymous_id() {
|
|
55
|
+
anonymous_counter++;
|
|
56
|
+
return `__anonymous-${anonymous_counter}__`;
|
|
57
|
+
}
|
|
58
|
+
traverse(ast, {
|
|
59
|
+
enter(node) {
|
|
60
|
+
if (node.type !== AT_RULE) return;
|
|
61
|
+
if (node.name === "layer") if (node.prelude) {
|
|
62
|
+
let groups = node.prelude.text.split(",").map((s) => s.trim());
|
|
63
|
+
if (!node.has_block) for (let name of groups) {
|
|
64
|
+
let parts = get_layer_names(name);
|
|
65
|
+
for (let i = 0; i < parts.length; i++) {
|
|
66
|
+
let path = parts.slice(0, i);
|
|
67
|
+
let layer_name = parts[i];
|
|
68
|
+
if (layer_name) {
|
|
69
|
+
let loc = i === parts.length - 1 ? create_location(node) : void 0;
|
|
70
|
+
root.add_child(path, layer_name, loc);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
let layer_names = [];
|
|
76
|
+
for (let child of node.prelude.children) if (child.type === LAYER_NAME) layer_names.push(child.text);
|
|
77
|
+
for (let i = 0; i < layer_names.length; i++) {
|
|
78
|
+
let layer_name = layer_names[i];
|
|
79
|
+
if (!layer_name) continue;
|
|
80
|
+
let path = layer_names.slice(0, i);
|
|
81
|
+
let loc = i === layer_names.length - 1 ? create_location(node) : void 0;
|
|
82
|
+
root.add_child(current_stack.concat(path), layer_name, loc);
|
|
83
|
+
}
|
|
84
|
+
current_stack.push(...layer_names);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
let name = get_anonymous_id();
|
|
88
|
+
root.add_child(current_stack, name, create_location(node));
|
|
89
|
+
current_stack.push(name);
|
|
90
|
+
}
|
|
91
|
+
else if (node.name === "import" && node.prelude) {
|
|
92
|
+
for (let child of node.prelude.children) if (child.type === LAYER_NAME) {
|
|
93
|
+
if (child.name?.trim()) for (let layer_name of get_layer_names(child.name)) {
|
|
94
|
+
root.add_child(current_stack, layer_name, create_location(node));
|
|
95
|
+
current_stack.push(layer_name);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
let name = get_anonymous_id();
|
|
99
|
+
root.add_child([], name, create_location(node));
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
leave(node) {
|
|
106
|
+
if (node.type !== AT_RULE) return;
|
|
107
|
+
if (node.name === "layer") if (node.prelude && node.has_block) {
|
|
108
|
+
let layer_count = 0;
|
|
109
|
+
for (let child of node.prelude.children) if (child.type === LAYER_NAME) layer_count++;
|
|
110
|
+
for (let i = 0; i < layer_count; i++) current_stack.pop();
|
|
111
|
+
} else current_stack.pop();
|
|
112
|
+
else if (node.name === "import") current_stack.length = 0;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return root.to_plain_object().children;
|
|
116
|
+
}
|
|
117
|
+
function layer_tree(css) {
|
|
118
|
+
return layer_tree_from_ast(parse(css, {
|
|
119
|
+
parse_selectors: false,
|
|
120
|
+
parse_values: false
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
export { layer_tree, layer_tree_from_ast };
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
2
|
+
"name": "@projectwallace/css-layer-tree",
|
|
3
|
+
"version": "2.1.2",
|
|
4
|
+
"description": "Discover the composition of your CSS @layers in a tree-based format.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/projectwallace/css-layer-tree.git"
|
|
8
|
+
},
|
|
9
|
+
"author": {
|
|
10
|
+
"name": "Bart Veneman"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/projectwallace/css-layer-tree",
|
|
13
|
+
"issues": "https://github.com/projectwallace/css-layer-tree/issues",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18.0.0"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "./dist/index.mjs",
|
|
20
|
+
"types": "./dist/index.d.mts",
|
|
21
|
+
"exports": {
|
|
22
|
+
"types": "./dist/index.d.mts",
|
|
23
|
+
"default": "./dist/index.mjs"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsdown",
|
|
27
|
+
"test": "vitest",
|
|
28
|
+
"check": "tsc --noEmit",
|
|
29
|
+
"lint": "oxlint"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@codecov/rollup-plugin": "^1.9.1",
|
|
33
|
+
"oxlint": "^1.51.0",
|
|
34
|
+
"prettier": "^3.3.3",
|
|
35
|
+
"publint": "^0.3.18",
|
|
36
|
+
"tsdown": "^0.21.0",
|
|
37
|
+
"typescript": "5.9.3",
|
|
38
|
+
"vitest": "^4.0.0"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
43
|
+
"keywords": [
|
|
44
|
+
"css",
|
|
45
|
+
"stylesheet",
|
|
46
|
+
"layer",
|
|
47
|
+
"layers",
|
|
48
|
+
"composition",
|
|
49
|
+
"architecture",
|
|
50
|
+
"tree"
|
|
51
|
+
],
|
|
52
|
+
"prettier": {
|
|
53
|
+
"semi": false,
|
|
54
|
+
"useTabs": true,
|
|
55
|
+
"printWidth": 140,
|
|
56
|
+
"singleQuote": true
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@projectwallace/css-parser": "^0.13.5"
|
|
60
|
+
}
|
|
61
61
|
}
|
package/dist/css-layer-tree.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { traverse as g, AT_RULE as m, LAYER_NAME as f, parse as b } from "@projectwallace/css-parser";
|
|
2
|
-
class _ {
|
|
3
|
-
/** @param {string} name */
|
|
4
|
-
constructor(t) {
|
|
5
|
-
this.name = t, this.is_anonymous = !1, this.children = /* @__PURE__ */ new Map(), this.locations = [];
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* @param {string[]} path
|
|
9
|
-
* @param {string} name
|
|
10
|
-
* @param {T} location
|
|
11
|
-
*/
|
|
12
|
-
add_child(t, r, n) {
|
|
13
|
-
let a = this;
|
|
14
|
-
if (t.forEach((e) => {
|
|
15
|
-
a = a.children.get(e);
|
|
16
|
-
}), a.children.has(r))
|
|
17
|
-
n !== void 0 && a.children.get(r).locations.push(n);
|
|
18
|
-
else {
|
|
19
|
-
const e = new _(r);
|
|
20
|
-
n !== void 0 && e.locations.push(n), e.is_anonymous = r.startsWith("__anonymous"), a.children.set(r, e);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* @typedef PlainObject
|
|
25
|
-
* @property {string} name
|
|
26
|
-
* @property {boolean} is_anonymous
|
|
27
|
-
* @property {T[]} locations
|
|
28
|
-
* @property {PlainObject[]} children
|
|
29
|
-
*/
|
|
30
|
-
/**
|
|
31
|
-
* Convert the tree to a plain object for easy testing
|
|
32
|
-
* @returns {PlainObject}
|
|
33
|
-
*/
|
|
34
|
-
to_plain_object() {
|
|
35
|
-
return {
|
|
36
|
-
name: this.name,
|
|
37
|
-
is_anonymous: this.is_anonymous,
|
|
38
|
-
locations: this.locations,
|
|
39
|
-
children: Array.from(this.children.values(), (t) => t.to_plain_object())
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function h(s) {
|
|
44
|
-
return s.split(".").map((t) => t.trim());
|
|
45
|
-
}
|
|
46
|
-
function u(s) {
|
|
47
|
-
return {
|
|
48
|
-
line: s.line,
|
|
49
|
-
column: s.column,
|
|
50
|
-
start: s.start,
|
|
51
|
-
end: s.end
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function k(s) {
|
|
55
|
-
let t = [], r = new _("root"), n = 0;
|
|
56
|
-
function a() {
|
|
57
|
-
return n++, `__anonymous-${n}__`;
|
|
58
|
-
}
|
|
59
|
-
return g(s, {
|
|
60
|
-
enter(e) {
|
|
61
|
-
if (e.type === m) {
|
|
62
|
-
if (e.name === "layer")
|
|
63
|
-
if (e.prelude) {
|
|
64
|
-
let i = e.prelude.text.split(",").map((l) => l.trim());
|
|
65
|
-
if (e.has_block)
|
|
66
|
-
for (let l of e.prelude.children)
|
|
67
|
-
l.type === f && (r.add_child(t, l.text, u(e)), t.push(l.text));
|
|
68
|
-
else
|
|
69
|
-
for (let l of i) {
|
|
70
|
-
let o = h(l);
|
|
71
|
-
for (let c = 0; c < o.length; c++) {
|
|
72
|
-
let d = o.slice(0, c), p = o[c];
|
|
73
|
-
if (p) {
|
|
74
|
-
let y = c === o.length - 1 ? u(e) : void 0;
|
|
75
|
-
r.add_child(d, p, y);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
let i = a();
|
|
81
|
-
r.add_child(t, i, u(e)), t.push(i);
|
|
82
|
-
}
|
|
83
|
-
else if (e.name === "import" && e.prelude) {
|
|
84
|
-
for (let i of e.prelude.children)
|
|
85
|
-
if (i.type === f) {
|
|
86
|
-
if (i.name.trim())
|
|
87
|
-
for (let l of h(i.name))
|
|
88
|
-
r.add_child(t, l, u(e)), t.push(l);
|
|
89
|
-
else {
|
|
90
|
-
let l = a();
|
|
91
|
-
r.add_child([], l, u(e));
|
|
92
|
-
}
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
leave(e) {
|
|
99
|
-
if (e.type === m)
|
|
100
|
-
if (e.name === "layer")
|
|
101
|
-
if (e.prelude && e.has_block) {
|
|
102
|
-
for (let i of e.prelude.children)
|
|
103
|
-
if (i.type === f) {
|
|
104
|
-
let l = h(i.text);
|
|
105
|
-
for (let o = 0; o < l.length; o++)
|
|
106
|
-
t.pop();
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
} else
|
|
110
|
-
t.pop();
|
|
111
|
-
else e.name === "import" && (t.length = 0);
|
|
112
|
-
}
|
|
113
|
-
}), r.to_plain_object().children;
|
|
114
|
-
}
|
|
115
|
-
function v(s) {
|
|
116
|
-
let t = b(s, {
|
|
117
|
-
parse_selectors: !1,
|
|
118
|
-
parse_values: !1
|
|
119
|
-
});
|
|
120
|
-
return k(t);
|
|
121
|
-
}
|
|
122
|
-
export {
|
|
123
|
-
v as layer_tree,
|
|
124
|
-
k as layer_tree_from_ast
|
|
125
|
-
};
|
package/index.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type CssNode } from "css-tree";
|
|
2
|
-
|
|
3
|
-
export type Location = {
|
|
4
|
-
line: number;
|
|
5
|
-
column: number;
|
|
6
|
-
start: number;
|
|
7
|
-
end: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type TreeNode = {
|
|
11
|
-
name: string;
|
|
12
|
-
is_anonymous: boolean;
|
|
13
|
-
children: TreeNode[];
|
|
14
|
-
locations: Location[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function layer_tree_from_ast(ast: CssNode): TreeNode[];
|
|
18
|
-
export function layer_tree(css: string): TreeNode[];
|