@linkdesk/plugin-sdk 0.1.25 → 0.1.27
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/eslint/checks/css-selectors.d.ts +71 -0
- package/dist/eslint/checks/css-selectors.d.ts.map +1 -1
- package/dist/eslint/checks/css-selectors.js +172 -0
- package/dist/eslint/checks/css-selectors.js.map +1 -1
- package/dist/eslint/checks/selector-form.d.ts +52 -0
- package/dist/eslint/checks/selector-form.d.ts.map +1 -0
- package/dist/eslint/checks/selector-form.js +127 -0
- package/dist/eslint/checks/selector-form.js.map +1 -0
- package/dist/eslint/checks/token-scope.d.ts +63 -0
- package/dist/eslint/checks/token-scope.d.ts.map +1 -0
- package/dist/eslint/checks/token-scope.js +157 -0
- package/dist/eslint/checks/token-scope.js.map +1 -0
- package/dist/eslint/index.d.ts +10 -0
- package/dist/eslint/index.d.ts.map +1 -1
- package/dist/eslint/index.js +8 -0
- package/dist/eslint/index.js.map +1 -1
- package/dist/eslint/lint.d.ts +12 -0
- package/dist/eslint/lint.d.ts.map +1 -1
- package/dist/eslint/lint.js +52 -3
- package/dist/eslint/lint.js.map +1 -1
- package/package.json +1 -1
|
@@ -44,4 +44,75 @@ export declare const lineAt: (text: string, index: number) => number;
|
|
|
44
44
|
export declare function bareClassDefinitions(cleaned: string): BareClassDefinition[];
|
|
45
45
|
/** 列举 `@keyframes` 名(关键帧名同样是全局标识符——第二条命名空间) */
|
|
46
46
|
export declare function keyframeDefinitions(cleaned: string): KeyframeDefinition[];
|
|
47
|
+
/** 剥**伪元素**(`::x` / `::x(...)`)——伪类(`:x`)与 `:root` 一律**保留** */
|
|
48
|
+
export declare const stripPseudoElements: (compound: string) => string;
|
|
49
|
+
/** 一个选择器的 compound 序列(剥伪元素后按组合符切) */
|
|
50
|
+
export declare function compoundsOf(compound: string): string[];
|
|
51
|
+
/** 该 compound 有没有**名字锚**(`.x` 或 `#x`)——**`(...)` 内不算锚**(那是过滤器不是主体,R0);
|
|
52
|
+
* 属性选择器整段剥掉(`[class*=".x"]` 里的 `.x` 是**字符串字面量**,不是类选择器)。 */
|
|
53
|
+
export declare function hasNameAnchor(compound: string): boolean;
|
|
54
|
+
/** 选择器形态(`formOf()` 的返回值域) */
|
|
55
|
+
export interface SelectorForm {
|
|
56
|
+
kind: "anchored" | "anchorless";
|
|
57
|
+
/** `anchorless` 时有效:true = **A 段**(顶层无锚)· false = **B 段**(限定无锚);带锚恒 false */
|
|
58
|
+
top: boolean;
|
|
59
|
+
/** 剥伪元素后**没有 compound 了**(`::-webkit-scrollbar` / `::before`)——**是有意的形态站点** */
|
|
60
|
+
purePseudo: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* **选择器形态谓词**——本轴判「形态」的**唯一入口**(S2/S3 共用同一份口径)。
|
|
64
|
+
* @param compound 逗号切开后的**一份**选择器(compound 序列)
|
|
65
|
+
*/
|
|
66
|
+
export declare function formOf(compound: string): SelectorForm;
|
|
67
|
+
/** 该 compound 里有没有 **id 选择器**(`#x`)——R2/S2 对 id 与元素**同罪**(32 号档 §四)。
|
|
68
|
+
* 属性选择器整段剥掉(`[href^="#"]` 不算);`(...)` 保留(`:has(#x)` 是真提及)。 */
|
|
69
|
+
export declare function hasIdSelector(compound: string): boolean;
|
|
70
|
+
/** 该选择器(**含 `(...)` 内容**)里有没有 `ldk-*` 类——**R3 的「提及」口径**(`:has(.ldk-x)` 也算) */
|
|
71
|
+
export declare function mentionsLdkClass(selector: string): boolean;
|
|
72
|
+
/** 该选择器(含 `(...)`)里有没有 `<prefix>` 开头的类——R3 的「自带自有命名空间」那一半 */
|
|
73
|
+
export declare function hasOwnPrefixedClass(selector: string, prefix: string): boolean;
|
|
74
|
+
/** 把 `@keyframes … { … }` **整块**换成等长空白(保留换行)——关键帧体内的 `from` / `to` / `0%`
|
|
75
|
+
* **不是选择器**(不排除它们会造出一堆假站点)。用**大括号配平**扫描而不是正则。 */
|
|
76
|
+
export declare function maskKeyframes(cleaned: string): string;
|
|
77
|
+
/** 一处**选择器形态站点**(同一条规则块里的多个选择器各出一份) */
|
|
78
|
+
export interface SelectorFormSite {
|
|
79
|
+
/** 逗号切开后的那一份选择器文本(compound 序列) */
|
|
80
|
+
selector: string;
|
|
81
|
+
/** 1-based;= 该规则块选择器首个非空白字符所在行 */
|
|
82
|
+
line: number;
|
|
83
|
+
form: SelectorForm;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 列举一张样式表里的**选择器形态站点**——判据 S2/S3 的**同一个遍历**(与壳门禁同源)。
|
|
87
|
+
* 入参 = `stripComments(src)` 的输出。
|
|
88
|
+
* · **递归进 at-rule**(`@media` / `@supports` 内的规则**同样是顶层**);
|
|
89
|
+
* · **跳过 `@keyframes` 体内**(`maskKeyframes()` 整块抹白);
|
|
90
|
+
* · 空规则体跳过(与 `bareClassDefinitions()` 同口径)。
|
|
91
|
+
*/
|
|
92
|
+
export declare function selectorFormSites(cleaned: string): SelectorFormSite[];
|
|
93
|
+
/** 定义点的作用域形态:`doc`(文档级)· `class`(类限定)· `id`(id 限定)· `other`(元素/通配/属性) */
|
|
94
|
+
export type TokenScope = "doc" | "class" | "id" | "other";
|
|
95
|
+
/** 剥**伪元素**(`:hover` / `:root` / `[data-theme=…]` 都保留)——**由上面的形态谓词区定义并导出**
|
|
96
|
+
* (E6#109o-b 起它与 `formOf()` 是同一件事的一半,故上移;此处不再重复定义)。 */
|
|
97
|
+
/** 一个 compound 的作用域形态 */
|
|
98
|
+
export declare function tokenScopeOf(compound: string): TokenScope;
|
|
99
|
+
/** compound 里的类名(剥属性选择器后再抓 `.x` —— `[class*=".x"]` 这类不算) */
|
|
100
|
+
export declare function classesInCompound(compound: string): string[];
|
|
101
|
+
/** V5 的判定体:该 compound 里有没有 `${prefix}` 开头的类(本仓前缀 = `<pluginId>-`) */
|
|
102
|
+
export declare function hasOwnClass(compound: string, prefix: string): boolean;
|
|
103
|
+
/** 一个自定义属性(token)的定义点 */
|
|
104
|
+
export interface TokenDefinition {
|
|
105
|
+
/** 名字(**不含**前导 `--`) */
|
|
106
|
+
name: string;
|
|
107
|
+
/** 1-based;= 该规则块选择器首个非空白字符所在行(与 `BareClassDefinition.line` 同款) */
|
|
108
|
+
line: number;
|
|
109
|
+
/** 逗号切开后的那一份选择器文本(compound 原文,供报点回显与 V5 判「有没有自有类」) */
|
|
110
|
+
selector: string;
|
|
111
|
+
scope: TokenScope;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 列举一张样式表里的**自定义属性定义点**(同一条规则块里的多个选择器各出一份 —— 与类名轴同款)。
|
|
115
|
+
* 入参 = `stripComments(src)` 的输出。`var(--x)` 前一个字符是 `(` ⇒ 天然不命中「定义」。
|
|
116
|
+
*/
|
|
117
|
+
export declare function tokenDefinitions(cleaned: string): TokenDefinition[];
|
|
47
118
|
//# sourceMappingURL=css-selectors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-selectors.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/css-selectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,0BAA0B,CAAA,MAAM,WAAW,mBAAmB;IAC5D,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,2BAA2B;AAC3B,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,uCAAuC;AACvC,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED,sBAAsB;AACtB,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAcnD;AAED,6CAA6C;AAC7C,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,MAAiD,CAAC;AAKvG;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAiB3E;AAED,+CAA+C;AAC/C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAMzE"}
|
|
1
|
+
{"version":3,"file":"css-selectors.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/css-selectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,4 +67,176 @@ export function keyframeDefinitions(cleaned) {
|
|
|
67
67
|
}
|
|
68
68
|
return out;
|
|
69
69
|
}
|
|
70
|
+
/* ══════════════════════════════════════════════════════════════════════════
|
|
71
|
+
选择器形态谓词 —— E6#109o-b(轮次 1.26 · 件 7 落地)新增
|
|
72
|
+
══════════════════════════════════════════════════════════════════════════
|
|
73
|
+
|
|
74
|
+
🔴 与壳仓 `scripts/lib/css-selectors.mjs` **同源**(口径文本一致;那边 `formOf()` 是同一套
|
|
75
|
+
判定式,壳门禁与运行时探针共用它)。跨包无法 import ⇒ 各写一份,由壳门禁 `--self-test`
|
|
76
|
+
的 `锚⑧` 用**锚词**把两份钉在一起。
|
|
77
|
+
规则正文 = 32-任务-选择器形态轴门禁与落地.md §一(R0)/§三.1。一句话:
|
|
78
|
+
**类名与 id 是「名字锚」;元素 / 通配 / 属性 / 伪类 / 伪元素不是**——后者
|
|
79
|
+
**不需要与任何人同名**就能命中别人的元素(一条 `button { }` 静默改掉所有人的按钮)。
|
|
80
|
+
|
|
81
|
+
🔴 **为什么不复用 `subjectOf()` / `hasAncestor()`(1.25 实测的 F3)**:
|
|
82
|
+
· `hasAncestor(".a :focus-visible")` 回 **false**(它连伪类一起剥 ⇒ 只剩 `.a` 一个 part)
|
|
83
|
+
· `subjectOf(".a :focus-visible")` 回 **".a"** ⇒ 既有「独立定义」口径把 `.x :pseudo`
|
|
84
|
+
算成 `.x` 的一次顶层定义。那是**轴 ① 的既有偏差,本轴不许改它**(改它 = 动「宿主 258 /
|
|
85
|
+
共享组件 89」两串全系列读数 + 18 仓 CI)⇒ 两条尺子在这一层**有意并存**。
|
|
86
|
+
本轴只剥**伪元素**(`::x`)、**伪类(`:x`)保留** ⇒ `.a :focus-visible` 有两个 compound
|
|
87
|
+
⇒ 判「不是顶层无锚」(否则插件写 `.my-root :focus-visible { }` 会被判成**假红**)。
|
|
88
|
+
|
|
89
|
+
🔴 **锚词(跨包同源用)**:`纯伪类/纯伪元素主体 ⇒ 无锚(不是无主体)` /
|
|
90
|
+
`` `.a :focus-visible` 不是顶层无锚(F3 反面) `` —— 壳门禁 `--self-test` 的 `锚⑧` 用这两句
|
|
91
|
+
把本文件与壳的 `lib/css-selectors.mjs` 钉在一起(照 1.24 `锚⑦` 先例)。
|
|
92
|
+
*/
|
|
93
|
+
/** 剥**伪元素**(`::x` / `::x(...)`)——伪类(`:x`)与 `:root` 一律**保留** */
|
|
94
|
+
export const stripPseudoElements = (compound) => String(compound).replace(/::[a-zA-Z-]+(\([^)]*\))?/g, "");
|
|
95
|
+
/** 一个选择器的 compound 序列(剥伪元素后按组合符切) */
|
|
96
|
+
export function compoundsOf(compound) {
|
|
97
|
+
return stripPseudoElements(compound).trim().split(/[\s>+~]+/).filter(Boolean);
|
|
98
|
+
}
|
|
99
|
+
/** 该 compound 有没有**名字锚**(`.x` 或 `#x`)——**`(...)` 内不算锚**(那是过滤器不是主体,R0);
|
|
100
|
+
* 属性选择器整段剥掉(`[class*=".x"]` 里的 `.x` 是**字符串字面量**,不是类选择器)。 */
|
|
101
|
+
export function hasNameAnchor(compound) {
|
|
102
|
+
return /[.#][-_a-zA-Z]/.test(String(compound).replace(/\[[^\]]*\]/g, "").replace(/\([^)]*\)/g, ""));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* **选择器形态谓词**——本轴判「形态」的**唯一入口**(S2/S3 共用同一份口径)。
|
|
106
|
+
* @param compound 逗号切开后的**一份**选择器(compound 序列)
|
|
107
|
+
*/
|
|
108
|
+
export function formOf(compound) {
|
|
109
|
+
const compounds = compoundsOf(compound);
|
|
110
|
+
if (compounds.length === 0)
|
|
111
|
+
return { kind: "anchorless", top: true, purePseudo: true };
|
|
112
|
+
if (compounds.some(hasNameAnchor))
|
|
113
|
+
return { kind: "anchored", top: false, purePseudo: false };
|
|
114
|
+
if (compounds.length === 1)
|
|
115
|
+
return { kind: "anchorless", top: true, purePseudo: false };
|
|
116
|
+
return { kind: "anchorless", top: false, purePseudo: false };
|
|
117
|
+
}
|
|
118
|
+
/** 该 compound 里有没有 **id 选择器**(`#x`)——R2/S2 对 id 与元素**同罪**(32 号档 §四)。
|
|
119
|
+
* 属性选择器整段剥掉(`[href^="#"]` 不算);`(...)` 保留(`:has(#x)` 是真提及)。 */
|
|
120
|
+
export function hasIdSelector(compound) {
|
|
121
|
+
return /#[-_a-zA-Z]/.test(String(compound).replace(/\[[^\]]*\]/g, ""));
|
|
122
|
+
}
|
|
123
|
+
/** 该选择器(**含 `(...)` 内容**)里有没有 `ldk-*` 类——**R3 的「提及」口径**(`:has(.ldk-x)` 也算) */
|
|
124
|
+
export function mentionsLdkClass(selector) {
|
|
125
|
+
return /\.ldk-[\w-]*/.test(String(selector));
|
|
126
|
+
}
|
|
127
|
+
/** 该选择器(含 `(...)`)里有没有 `<prefix>` 开头的类——R3 的「自带自有命名空间」那一半 */
|
|
128
|
+
export function hasOwnPrefixedClass(selector, prefix) {
|
|
129
|
+
const p = String(prefix).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
130
|
+
return new RegExp(`\\.${p}[\\w-]*`).test(String(selector));
|
|
131
|
+
}
|
|
132
|
+
/** 把 `@keyframes … { … }` **整块**换成等长空白(保留换行)——关键帧体内的 `from` / `to` / `0%`
|
|
133
|
+
* **不是选择器**(不排除它们会造出一堆假站点)。用**大括号配平**扫描而不是正则。 */
|
|
134
|
+
export function maskKeyframes(cleaned) {
|
|
135
|
+
let out = "";
|
|
136
|
+
let i = 0;
|
|
137
|
+
const src = String(cleaned);
|
|
138
|
+
const blank = (s) => s.replace(/[^\n]/g, " ");
|
|
139
|
+
while (i < src.length) {
|
|
140
|
+
const at = src.indexOf("@keyframes", i);
|
|
141
|
+
if (at < 0) {
|
|
142
|
+
out += src.slice(i);
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
out += src.slice(i, at);
|
|
146
|
+
const brace = src.indexOf("{", at);
|
|
147
|
+
if (brace < 0) {
|
|
148
|
+
out += src.slice(at);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
let depth = 0;
|
|
152
|
+
let j = brace;
|
|
153
|
+
for (; j < src.length; j++) {
|
|
154
|
+
if (src[j] === "{")
|
|
155
|
+
depth++;
|
|
156
|
+
else if (src[j] === "}") {
|
|
157
|
+
depth--;
|
|
158
|
+
if (depth === 0) {
|
|
159
|
+
j++;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
out += blank(src.slice(at, j));
|
|
165
|
+
i = j;
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 列举一张样式表里的**选择器形态站点**——判据 S2/S3 的**同一个遍历**(与壳门禁同源)。
|
|
171
|
+
* 入参 = `stripComments(src)` 的输出。
|
|
172
|
+
* · **递归进 at-rule**(`@media` / `@supports` 内的规则**同样是顶层**);
|
|
173
|
+
* · **跳过 `@keyframes` 体内**(`maskKeyframes()` 整块抹白);
|
|
174
|
+
* · 空规则体跳过(与 `bareClassDefinitions()` 同口径)。
|
|
175
|
+
*/
|
|
176
|
+
export function selectorFormSites(cleaned) {
|
|
177
|
+
const masked = maskKeyframes(cleaned);
|
|
178
|
+
const out = [];
|
|
179
|
+
for (const m of masked.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
|
180
|
+
const sel = m[1].trim();
|
|
181
|
+
if (sel.startsWith("@") || !m[2].trim())
|
|
182
|
+
continue;
|
|
183
|
+
const line = lineAt(masked, m.index + (m[1].length - m[1].trimStart().length));
|
|
184
|
+
for (const one of splitSelector(sel))
|
|
185
|
+
out.push({ selector: one, line, form: formOf(one) });
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
/** 文档级主体((a)):`:root` / `html` / `body` / `[data-theme…]` / 通配 `*`。
|
|
190
|
+
* ⚠️ 只看**主体**(最后一个 compound、且**只剥伪元素**)——`:root` 本身是**伪类**,
|
|
191
|
+
* 用 `subjectOf()`(连伪类一起剥)会把 `:root` 剥成空串 ⇒ 这里单独剥 `::x` 形态。
|
|
192
|
+
* ⚠️ `* .foo` 的主体是 `.foo`(定义落在 `.foo` 上)⇒ 不是文档级;`*::before` 剥完是 `*` ⇒ 是。 */
|
|
193
|
+
const DOC_SUBJECT = /^(:root|html|body|\[data-theme|\*)/i;
|
|
194
|
+
/** 剥**伪元素**(`:hover` / `:root` / `[data-theme=…]` 都保留)——**由上面的形态谓词区定义并导出**
|
|
195
|
+
* (E6#109o-b 起它与 `formOf()` 是同一件事的一半,故上移;此处不再重复定义)。 */
|
|
196
|
+
/** 一个 compound 的作用域形态 */
|
|
197
|
+
export function tokenScopeOf(compound) {
|
|
198
|
+
const subject = stripPseudoElements(String(compound)).trim().split(/[\s>+~]+/).filter(Boolean).pop() ?? "";
|
|
199
|
+
if (!subject)
|
|
200
|
+
return "doc"; // 纯伪元素形态(`::selection`)——无主体 ⇒ 文档级
|
|
201
|
+
if (DOC_SUBJECT.test(subject))
|
|
202
|
+
return "doc";
|
|
203
|
+
if (subject.startsWith("#"))
|
|
204
|
+
return "id";
|
|
205
|
+
if (subject.includes("."))
|
|
206
|
+
return "class";
|
|
207
|
+
return "other";
|
|
208
|
+
}
|
|
209
|
+
/** compound 里的类名(剥属性选择器后再抓 `.x` —— `[class*=".x"]` 这类不算) */
|
|
210
|
+
export function classesInCompound(compound) {
|
|
211
|
+
const noAttr = String(compound).replace(/\[[^\]]*\]/g, "");
|
|
212
|
+
return [...noAttr.matchAll(/\.(-?[_a-zA-Z][\w-]*)/g)].map((m) => m[1]);
|
|
213
|
+
}
|
|
214
|
+
/** V5 的判定体:该 compound 里有没有 `${prefix}` 开头的类(本仓前缀 = `<pluginId>-`) */
|
|
215
|
+
export function hasOwnClass(compound, prefix) {
|
|
216
|
+
return classesInCompound(compound).some((c) => c.startsWith(prefix));
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 列举一张样式表里的**自定义属性定义点**(同一条规则块里的多个选择器各出一份 —— 与类名轴同款)。
|
|
220
|
+
* 入参 = `stripComments(src)` 的输出。`var(--x)` 前一个字符是 `(` ⇒ 天然不命中「定义」。
|
|
221
|
+
*/
|
|
222
|
+
export function tokenDefinitions(cleaned) {
|
|
223
|
+
const out = [];
|
|
224
|
+
for (const m of cleaned.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
|
225
|
+
const sel = m[1].trim();
|
|
226
|
+
if (sel.startsWith("@") || !m[2].trim())
|
|
227
|
+
continue; // @media 等 at-rule 头 / 空规则体
|
|
228
|
+
const names = [];
|
|
229
|
+
for (const d of m[2].matchAll(/(?:^|[;{\s])--([a-zA-Z0-9][\w-]*)\s*:/g))
|
|
230
|
+
names.push(d[1]);
|
|
231
|
+
if (names.length === 0)
|
|
232
|
+
continue;
|
|
233
|
+
const line = lineAt(cleaned, m.index + (m[1].length - m[1].trimStart().length));
|
|
234
|
+
for (const one of splitSelector(sel)) {
|
|
235
|
+
const scope = tokenScopeOf(one);
|
|
236
|
+
for (const name of names)
|
|
237
|
+
out.push({ name, line, selector: one, scope });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
70
242
|
//# sourceMappingURL=css-selectors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-selectors.js","sourceRoot":"","sources":["../../../src/eslint/checks/css-selectors.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"css-selectors.js","sourceRoot":"","sources":["../../../src/eslint/checks/css-selectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type CheckViolation } from "./scan.js";
|
|
2
|
+
import { type SelectorForm } from "./css-selectors.js";
|
|
3
|
+
import { type PluginIdResolution } from "./plugin-prefix.js";
|
|
4
|
+
/** 判级文案——**与壳仓 `scripts/lib/css-selectors.mjs` 同源口径**(跨包不能 import ⇒ 只能钉文本:
|
|
5
|
+
* 壳门禁 `--self-test` 的 `锚⑧` 用锚词把两份的形态口径钉在一起)。 */
|
|
6
|
+
export declare const SELECTOR_FORM_WHY: {
|
|
7
|
+
readonly S2: string;
|
|
8
|
+
readonly S3: string;
|
|
9
|
+
};
|
|
10
|
+
export type SelectorFormCode = "S2" | "S3";
|
|
11
|
+
/** 一处不合规站点 */
|
|
12
|
+
export interface SelectorFormSite {
|
|
13
|
+
/** 工程相对路径(正斜杠) */
|
|
14
|
+
file: string;
|
|
15
|
+
/** 1-based(规则块选择器首行) */
|
|
16
|
+
line: number;
|
|
17
|
+
/** compound 原文(供报点回显) */
|
|
18
|
+
selector: string;
|
|
19
|
+
form: SelectorForm;
|
|
20
|
+
code: SelectorFormCode;
|
|
21
|
+
why: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SelectorFormReport {
|
|
24
|
+
root: string;
|
|
25
|
+
pluginId: string | null;
|
|
26
|
+
/** 非 null ⇒ fail-closed(拿不到前缀 ⇒ S3 判不了「自有命名空间」是哪一族) */
|
|
27
|
+
error: string | null;
|
|
28
|
+
/** S2 的站点(禁无锚) */
|
|
29
|
+
anchorless: SelectorFormSite[];
|
|
30
|
+
/** S3 的站点(跨方命中不带自有锚) */
|
|
31
|
+
crossParty: SelectorFormSite[];
|
|
32
|
+
/** 腿报点 = fail-closed + S2 + S3 */
|
|
33
|
+
violations: CheckViolation[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 判一处选择器站点的级别。**判定式只此一处**(壳仓 `scripts/lib/css-selectors.mjs` 的
|
|
37
|
+
* `formOf()` 是同一套形态口径的镜像——壳门禁判据⑩⑪ 与运行时探针共用那一份)。
|
|
38
|
+
* 顺序:先 S2(更根本——它说的是「这个选择器根本没有落点」),再 S3。
|
|
39
|
+
*/
|
|
40
|
+
export declare function judgeSelectorForm(site: {
|
|
41
|
+
selector: string;
|
|
42
|
+
pluginId: string;
|
|
43
|
+
}): {
|
|
44
|
+
code: SelectorFormCode;
|
|
45
|
+
why: string;
|
|
46
|
+
} | null;
|
|
47
|
+
/**
|
|
48
|
+
* 跑本仓选择器形态判据。返回结构化报告(审计工具 / lint 打印用)——**同一份实现,没有第二条判据路径**。
|
|
49
|
+
* ⚠️ `resolution` 可复用调用方已经取过的 `pluginId`(`lint.ts` 与另两条腿共用一次解析)。
|
|
50
|
+
*/
|
|
51
|
+
export declare function runSelectorFormCheck(root: string, resolution?: PluginIdResolution): SelectorFormReport;
|
|
52
|
+
//# sourceMappingURL=selector-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-form.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/selector-form.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAmF,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAExI,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEpF;iDACiD;AACjD,eAAO,MAAM,iBAAiB;;;CAWpB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,cAAc;AACd,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,gBAAgB,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uDAAuD;IACvD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kBAAkB;IAClB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,wBAAwB;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,kCAAkC;IAClC,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWjD;AAcD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,kBAAgD,GAC3D,kBAAkB,CA4CpB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-css-namespace 腿·**选择器形态判据**(E6#109o-b · 轮次 1.26)。
|
|
3
|
+
*
|
|
4
|
+
* ── 规则一句话 ──
|
|
5
|
+
* **类名与 id 是「名字锚」;元素 / 通配 / 属性 / 伪类 / 伪元素不是** —— 后者
|
|
6
|
+
* **不需要与任何人同名**就能命中别人的元素:一条 `button { border: none }` 静默改掉宿主与其他
|
|
7
|
+
* 插件的所有按钮,而且**不报错、只是长得不对**(与 `.badge` 案同一形态,只是少了「同名」这个前提)。
|
|
8
|
+
* 规则正文 = 32-任务-选择器形态轴门禁与落地.md §一(R0–R3)/§三.2。
|
|
9
|
+
*
|
|
10
|
+
* ── 两条判据 ──
|
|
11
|
+
* S2 🔴 **禁无锚选择器**(含 **id**,一视同仁):`formOf()` 判 `anchorless`(顶层**或**限定一律禁)
|
|
12
|
+
* ⇒ 红。**id 与元素同罪**:id 是全局的、可猜的,优先级还高于类(32 号档 §四 裁决 (b))。
|
|
13
|
+
* 正确解法只有一条:**挂在自己的根类之下**(`.serial-monitor-root input { … }`)。
|
|
14
|
+
* S3 🔴 **跨方命中必须自带自有命名空间**:选择器里**出现任何 `ldk-*` 类**(**含 `:has(…)` 内的提及**)
|
|
15
|
+
* ⇒ 该选择器**必须同时含至少一个 `.<pluginId>-*` 类**;否则红。
|
|
16
|
+
* ⚠️ **管形态、不管意图**:**不禁止**插件改共享组件外观(那是**合法特性**,文档口径的
|
|
17
|
+
* scoped 调优)——它只要求「带着自家前缀作锚」,即「调优必须在地盘里发生」。
|
|
18
|
+
*
|
|
19
|
+
* ── 为什么这两条值得一条腿(不是理论风险)──
|
|
20
|
+
* 插件视图的一张样式表里同时装着宿主 + 共享组件 + **所有已加载插件**的 CSS(实机读数:池文档
|
|
21
|
+
* 27 张表 / 4,280 条规则)⇒ 无锚选择器命中「该文档里**所有那一类元素**」,与谁渲染无关。
|
|
22
|
+
* 1.25 实测:**插件侧存量 0**(官方 18 仓 + 壳内夹具)⇒ 这两条是**纯预防性、零重发成本**——
|
|
23
|
+
* 但宿主侧那 17 处基线(`*` reset / `html`·`body` / `[data-theme]` / `*:focus-visible` /
|
|
24
|
+
* `::-webkit-scrollbar` 一族 / `input[type=number]`·`select`)正是「无锚选择器能改所有人」的活证明:
|
|
25
|
+
* 它们**有意**共享(插件依赖它们),所以宿主侧走「文件级登记 + 条数守卫」(判据⑩),
|
|
26
|
+
* 插件侧则**一条都不许**——插件没有「我改的是大家的按钮、这是有意的」这种正当性。
|
|
27
|
+
*
|
|
28
|
+
* ── 口径与豁免 ──
|
|
29
|
+
* · 形态一律用 `css-selectors.ts` 的 `formOf()`——**不许**用 `hasAncestor()`/`subjectOf()`
|
|
30
|
+
* (F3:它们把 `.x :pseudo` 误判成 `.x` 的一次顶层定义 ⇒ 假红;那条偏差属轴 ①、已冻结)。
|
|
31
|
+
* · 知情绕行 = 标准 disable 注释(`CHECK_IDS.cssNamespace`,与类名 / 关键帧 / token 判据**同一个 id**)。
|
|
32
|
+
* · **fail-closed**:拿不到 `pluginId` ⇒ 红(S3 判不了「自有命名空间」是哪一族;照 `plugin-prefix.ts`
|
|
33
|
+
* 既有纪律——**静默放过 = 门禁变瞎子**)。
|
|
34
|
+
*/
|
|
35
|
+
import { resolve } from "node:path";
|
|
36
|
+
import { collectCssUnits } from "./scan.js";
|
|
37
|
+
import { selectorFormSites, formOf, hasIdSelector, mentionsLdkClass, hasOwnPrefixedClass } from "./css-selectors.js";
|
|
38
|
+
import { isDisabled, CHECK_IDS } from "./disable.js";
|
|
39
|
+
import { resolvePluginIdForCss } from "./plugin-prefix.js";
|
|
40
|
+
/** 判级文案——**与壳仓 `scripts/lib/css-selectors.mjs` 同源口径**(跨包不能 import ⇒ 只能钉文本:
|
|
41
|
+
* 壳门禁 `--self-test` 的 `锚⑧` 用锚词把两份的形态口径钉在一起)。 */
|
|
42
|
+
export const SELECTOR_FORM_WHY = {
|
|
43
|
+
S2: "插件 CSS 里的**无锚选择器**(元素 / 通配 / 属性 / 伪类 / 伪元素 / **id** 一视同仁;顶层或限定一律禁)" +
|
|
44
|
+
"——插件视图的一张样式表里同时装着宿主 + 共享组件 + **所有已加载插件**的 CSS," +
|
|
45
|
+
"**这类选择器不需要与任何人同名**就能命中「该文档里所有那一类元素」:一条 `button { }` 改掉所有人的按钮," +
|
|
46
|
+
"而且**不报错、只是长得不对**。(id 与元素同罪:id 是全局的、可猜的,优先级还高于类。)",
|
|
47
|
+
S3: "选择器里出现 `ldk-*` 类(**含 `:has(…)` 内的提及**),却**没有自带一个 `.<pluginId>-*` 类**" +
|
|
48
|
+
"——`ldk-` 整个命名空间属宿主(类名 / 关键帧 / token 同一句,硬约束 23 ②);**跨方命中必须带着自家" +
|
|
49
|
+
"前缀作锚**:调优要在地盘里发生。⚠️ 本条**管形态、不管意图**——改共享组件外观本身是**合法特性**" +
|
|
50
|
+
"(scoped 调优),只要写在自己的根类之下就合规。",
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* 判一处选择器站点的级别。**判定式只此一处**(壳仓 `scripts/lib/css-selectors.mjs` 的
|
|
54
|
+
* `formOf()` 是同一套形态口径的镜像——壳门禁判据⑩⑪ 与运行时探针共用那一份)。
|
|
55
|
+
* 顺序:先 S2(更根本——它说的是「这个选择器根本没有落点」),再 S3。
|
|
56
|
+
*/
|
|
57
|
+
export function judgeSelectorForm(site) {
|
|
58
|
+
const form = formOf(site.selector);
|
|
59
|
+
// S2:无锚(顶层或限定)**或**含 id ⇒ 红
|
|
60
|
+
if (form.kind === "anchorless" || hasIdSelector(site.selector)) {
|
|
61
|
+
return { code: "S2", why: SELECTOR_FORM_WHY.S2 };
|
|
62
|
+
}
|
|
63
|
+
// S3:出现 `ldk-*` 提及(含 `:has(…)` 内)⇒ 必须同时含本仓前缀类
|
|
64
|
+
if (mentionsLdkClass(site.selector) && !hasOwnPrefixedClass(site.selector, `${site.pluginId}-`)) {
|
|
65
|
+
return { code: "S3", why: SELECTOR_FORM_WHY.S3 };
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/** 一处站点的报点文案 */
|
|
70
|
+
function messageOf(site, pluginId) {
|
|
71
|
+
const head = `[${site.code}] \`${site.selector}\` ← 本仓 pluginId = "${pluginId}"`;
|
|
72
|
+
const fix = site.code === "S2"
|
|
73
|
+
? `改法:挂在自己插件的根类之下——\`.${pluginId}-root input { … }\`、\`.${pluginId}-root div { … }\`;` +
|
|
74
|
+
`id 选择器同理(要选中自己的元素就用类)。`
|
|
75
|
+
: `改法:把自有根类加进这条选择器——\`.${pluginId}-root .ldk-badge { … }\`(**这就是 scoped 调优的` +
|
|
76
|
+
`正确形态**:想改共享组件的样子完全可以,只要写在自己的地盘里)。`;
|
|
77
|
+
return `${head}——${site.why} ${fix}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 跑本仓选择器形态判据。返回结构化报告(审计工具 / lint 打印用)——**同一份实现,没有第二条判据路径**。
|
|
81
|
+
* ⚠️ `resolution` 可复用调用方已经取过的 `pluginId`(`lint.ts` 与另两条腿共用一次解析)。
|
|
82
|
+
*/
|
|
83
|
+
export function runSelectorFormCheck(root, resolution = resolvePluginIdForCss(root)) {
|
|
84
|
+
const absRoot = resolve(root);
|
|
85
|
+
const report = {
|
|
86
|
+
root: absRoot,
|
|
87
|
+
pluginId: resolution.pluginId,
|
|
88
|
+
error: resolution.error,
|
|
89
|
+
anchorless: [],
|
|
90
|
+
crossParty: [],
|
|
91
|
+
violations: [],
|
|
92
|
+
};
|
|
93
|
+
// ── fail-closed(不可豁免):拿不到前缀 ⇒ S3 判不了「自有命名空间」是哪一族 ──
|
|
94
|
+
if (resolution.error || !resolution.pluginId) {
|
|
95
|
+
report.violations.push({
|
|
96
|
+
file: "plugin.json",
|
|
97
|
+
line: 1,
|
|
98
|
+
message: `拿不到本仓前缀:${resolution.error}。**选择器形态判据不许静默放过**——S3(跨方命中必须自带自有命名空间)` +
|
|
99
|
+
`要先知道「自有」是哪一族,拿不到 \`pluginId\` 就判不了(fail-closed)。在插件工程根修好 plugin.json` +
|
|
100
|
+
`(或显式声明 pluginId);身份问题不受 disable 注释管辖。`,
|
|
101
|
+
});
|
|
102
|
+
return report;
|
|
103
|
+
}
|
|
104
|
+
const pluginId = resolution.pluginId;
|
|
105
|
+
for (const unit of collectCssUnits(absRoot, [CHECK_IDS.cssNamespace])) {
|
|
106
|
+
for (const s of selectorFormSites(unit.cleaned)) {
|
|
107
|
+
const verdict = judgeSelectorForm({ selector: s.selector, pluginId });
|
|
108
|
+
if (!verdict)
|
|
109
|
+
continue;
|
|
110
|
+
// 知情绕行:同一个 check id(与类名 / 关键帧 / token 判据同一套 disable 机制)
|
|
111
|
+
if (isDisabled(unit.disabled, s.line, CHECK_IDS.cssNamespace))
|
|
112
|
+
continue;
|
|
113
|
+
const site = {
|
|
114
|
+
file: unit.rel,
|
|
115
|
+
line: s.line,
|
|
116
|
+
selector: s.selector,
|
|
117
|
+
form: s.form,
|
|
118
|
+
code: verdict.code,
|
|
119
|
+
why: verdict.why,
|
|
120
|
+
};
|
|
121
|
+
(verdict.code === "S2" ? report.anchorless : report.crossParty).push(site);
|
|
122
|
+
report.violations.push({ file: unit.rel, line: s.line, message: messageOf(site, pluginId) });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return report;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=selector-form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-form.js","sourceRoot":"","sources":["../../../src/eslint/checks/selector-form.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type CheckViolation } from "./scan.js";
|
|
2
|
+
import { type TokenScope } from "./css-selectors.js";
|
|
3
|
+
import { type PluginIdResolution } from "./plugin-prefix.js";
|
|
4
|
+
/** 判级文案——**与壳仓 `scripts/lib/css-selectors.mjs` 的 `TOKEN_WHY` 逐字一致**
|
|
5
|
+
* (跨包不能 import ⇒ 只能钉文案:壳门禁 `--self-test` 的 `锚⑦` 用锚词把两份钉在一起)。 */
|
|
6
|
+
export declare const TOKEN_WHY: {
|
|
7
|
+
readonly V2: string;
|
|
8
|
+
readonly V1: string;
|
|
9
|
+
readonly V5: string;
|
|
10
|
+
readonly V6: string;
|
|
11
|
+
};
|
|
12
|
+
export type TokenScopeCode = "V1" | "V2" | "V5" | "V6";
|
|
13
|
+
/** 一处 token 定义点的判级结果 */
|
|
14
|
+
export interface TokenScopeSite {
|
|
15
|
+
/** 工程相对路径(正斜杠) */
|
|
16
|
+
file: string;
|
|
17
|
+
/** 1-based(规则块选择器首行) */
|
|
18
|
+
line: number;
|
|
19
|
+
/** 名字(不含前导 `--`) */
|
|
20
|
+
name: string;
|
|
21
|
+
/** compound 原文(供报点回显;V5 用它判「有没有自有类」) */
|
|
22
|
+
selector: string;
|
|
23
|
+
scope: TokenScope;
|
|
24
|
+
level: "red" | "yellow";
|
|
25
|
+
code: TokenScopeCode;
|
|
26
|
+
why: string;
|
|
27
|
+
}
|
|
28
|
+
export interface TokenScopeReport {
|
|
29
|
+
root: string;
|
|
30
|
+
pluginId: string | null;
|
|
31
|
+
/** 非 null ⇒ fail-closed(拿不到前缀 ⇒ 本腿判不了「有主 / 无主」,一律红) */
|
|
32
|
+
error: string | null;
|
|
33
|
+
/** 🔴 必须改的(进腿报点 ⇒ CI 严格腿判红) */
|
|
34
|
+
red: TokenScopeSite[];
|
|
35
|
+
/** 🟡 建议改的(只打印,不拦) */
|
|
36
|
+
yellow: TokenScopeSite[];
|
|
37
|
+
/** 腿报点 = fail-closed + 全部红 */
|
|
38
|
+
violations: CheckViolation[];
|
|
39
|
+
/** 黄灯建议(`lint.ts` 打印用;**不进** `LintLeg.violations` ⇒ 不拦 CI) */
|
|
40
|
+
advisories: CheckViolation[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 判一个定义点的级别。**判定式只此一处**(壳仓 `scripts/lib/css-selectors.mjs` 的
|
|
44
|
+
* `judgeTokenScope()` 是同一套判定式的镜像——壳门禁与运行时探针共用那一份)。
|
|
45
|
+
* 顺序 = **先出最具体的那条**:同一站点可能同时命中 V2 与 V1(`:root { --ldk-x: … }`)——不重复报,
|
|
46
|
+
* 报对该方最可操作的那一条(名字层比作用域层更根本)。
|
|
47
|
+
*/
|
|
48
|
+
export declare function judgePluginTokenScope(site: {
|
|
49
|
+
name: string;
|
|
50
|
+
scope: TokenScope;
|
|
51
|
+
selector: string;
|
|
52
|
+
pluginId: string;
|
|
53
|
+
}): {
|
|
54
|
+
level: "red" | "yellow";
|
|
55
|
+
code: TokenScopeCode;
|
|
56
|
+
why: string;
|
|
57
|
+
} | null;
|
|
58
|
+
/**
|
|
59
|
+
* 跑本仓 token 作用域判据。返回结构化报告(审计工具 / lint 打印用)——**同一份实现,没有第二条判据路径**。
|
|
60
|
+
* ⚠️ `resolution` 可复用调用方已经取过的 `pluginId`(`lint.ts` 与前缀腿共用一次解析)。
|
|
61
|
+
*/
|
|
62
|
+
export declare function runTokenScopeCheck(root: string, resolution?: PluginIdResolution): TokenScopeReport;
|
|
63
|
+
//# sourceMappingURL=token-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-scope.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/token-scope.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEpF,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEpF;iEACiE;AACjE,eAAO,MAAM,SAAS;;;;;CAeZ,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvD,wBAAwB;AACxB,MAAM,WAAW,cAAc;IAC7B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uDAAuD;IACvD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,+BAA+B;IAC/B,GAAG,EAAE,cAAc,EAAE,CAAC;IACtB,sBAAsB;IACtB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,8BAA8B;IAC9B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,8DAA8D;IAC9D,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcxE;AAuBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,kBAAgD,GAC3D,gBAAgB,CAqDlB"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-css-namespace 腿·**自定义属性(token)作用域判据**(E6#109n-b · 轮次 1.24)。
|
|
3
|
+
*
|
|
4
|
+
* ── 规则一句话 ──
|
|
5
|
+
* **作用域才是命名空间。** 自定义属性名不需要前缀 —— 它**住在哪棵子树里**才是它属于谁:
|
|
6
|
+
* (a) **文档级**(`:root` / `html` / `body` / `[data-theme=…]` / 通配 `*`)只有**宿主契约块**能写;
|
|
7
|
+
* (b) 其余定义必须挂在**自有命名空间**的子树下(插件 = `.<pluginId>-*`);
|
|
8
|
+
* (c) 浮层宿主根 `#ld-float-layer` 一族 = portal 面例外(放宽「元素归谁」,不放宽「名字归谁」);
|
|
9
|
+
* (d) 名字层只有一句:**任何一方不得定义 `ldk-` 开头的自定义属性**。
|
|
10
|
+
* 规则正文:31-任务-token轴门禁与清账.md §一(`docs/02-Electron架构/E6_插件生态与发布/01-插件独立构建/样式命名空间归一化/`)。
|
|
11
|
+
*
|
|
12
|
+
* ── 为什么插件侧必须有这条腿(不是理论风险)──
|
|
13
|
+
* 1.23 实测(真跑的池文档):宿主 94 个契约名里 **83 个只有样式表提供、引擎不写 inline**
|
|
14
|
+
* ——默认主题是壳的**空兜底配方**(`colors: {}`)⇒ `commitTokens({})` 的差集清理把主题键全清掉、
|
|
15
|
+
* 值回落 `src/index.css` 的硬兜底(那是设计)。**后果**:插件在 `:root` 写一个宿主契约名就能
|
|
16
|
+
* **全局改写宿主的颜色 / 圆角 / z-index**(级联实验实证:`--success` / `--error` / `--z-dropdown` /
|
|
17
|
+
* `--badge-text` / `--bg-window` / `--radius-md` 全被改写),而且这个「屏蔽」随主题变化
|
|
18
|
+
* ⇒ **看着时好时坏**——最坏的一类 bug。这正是 `marketplace` 那次 `--status-connected` 覆写事故的形态。
|
|
19
|
+
*
|
|
20
|
+
* ── 四条判据(分级依据 = 22 号档 §10.3「判红只给 ① 本仓可答 ② 有真害」)──
|
|
21
|
+
* V2 🔴 定义了 `ldk-*` 自定义属性(**任何作用域**)——`ldk-` 整个命名空间属宿主,
|
|
22
|
+
* 与类名 / 关键帧**同一句**(CLAUDE.md 硬约束 23 ②)。
|
|
23
|
+
* V1 🔴 文档级 + 名字**不带本仓前缀** ⇒ 全局改写宿主 / 他方(真害已实测,见上)。
|
|
24
|
+
* V5 🔴 类限定 + 该 compound 里**没有**任何 `.<pluginId>-*` 类 ⇒ 定义落到了宿主 / 他方元素上
|
|
25
|
+
* (与件 7 的 R3「跨方命中必须有自有根类作祖先」同形)。
|
|
26
|
+
* V6 🟡 文档级 + 名字**自带本仓前缀** ⇒ 无人同吃、近乎无害 ⇒ **只报不拦**
|
|
27
|
+
* (判红只给「有真害」——升格成红 = 假红,而假红会让真红失效)。
|
|
28
|
+
*
|
|
29
|
+
* ── 级别与豁免 ──
|
|
30
|
+
* · 🔴 红进腿报点(`violations`)⇒ 插件仓 CI 的**严格腿**判红(`ci-verify.mjs` 的 strictLegs
|
|
31
|
+
* 是 fail-closed 的:SDK 新增一条腿自动进严格档)。
|
|
32
|
+
* · 🟡 黄进 `advisories`:**打印但不进腿报点** ⇒ 不拦 CI(这正是「只报不拦」的结构实现)。
|
|
33
|
+
* · 知情绕行 = 标准 disable 注释(`CHECK_IDS.cssNamespace`,与类名 / 关键帧判据**同一个 id**)。
|
|
34
|
+
* ⚠️ **身份层不可豁免**:拿不到 `pluginId` ⇒ fail-closed 红(没有前缀就无从判「有主 / 无主」)。
|
|
35
|
+
* · 口径与壳仓同源:定义点、作用域形态、多选择器规则的切分**都调 `css-selectors.ts` 的同一份实现**
|
|
36
|
+
* (`tokenDefinitions()` / `hasOwnClass()`)——不许各写一份近似版(22 号档 §一 层 3:尺子不止一把
|
|
37
|
+
* 就是本系列的病根)。
|
|
38
|
+
*/
|
|
39
|
+
import { resolve } from "node:path";
|
|
40
|
+
import { collectCssUnits } from "./scan.js";
|
|
41
|
+
import { tokenDefinitions, hasOwnClass } from "./css-selectors.js";
|
|
42
|
+
import { isDisabled, CHECK_IDS } from "./disable.js";
|
|
43
|
+
import { resolvePluginIdForCss } from "./plugin-prefix.js";
|
|
44
|
+
/** 判级文案——**与壳仓 `scripts/lib/css-selectors.mjs` 的 `TOKEN_WHY` 逐字一致**
|
|
45
|
+
* (跨包不能 import ⇒ 只能钉文案:壳门禁 `--self-test` 的 `锚⑦` 用锚词把两份钉在一起)。 */
|
|
46
|
+
export const TOKEN_WHY = {
|
|
47
|
+
V2: "自定义属性名以 `ldk-` 开头——`ldk-` **整个命名空间属宿主**(与类名 / 关键帧同一句,CLAUDE.md 硬约束 23 ②)," +
|
|
48
|
+
"任何一方都不得定义(占名即「宿主契约名被他人改写」的入口)。",
|
|
49
|
+
V1: "非宿主方在**文档级**(`:root` / `html` / `body` / `[data-theme=…]` / `*`)定义了**不带自有前缀**的自定义属性" +
|
|
50
|
+
"——1.23 实测:宿主 94 个契约名里 **83 个只有样式表提供、引擎不写 inline**(默认主题是空兜底配方 ⇒ " +
|
|
51
|
+
"差集清理把主题键全清掉)⇒ **一条 `:root` 就能全局改写宿主的颜色 / 圆角 / z-index**," +
|
|
52
|
+
"而且这个「屏蔽」随主题变化=时好时坏(`marketplace` 那次 `--status-connected` 覆写事故正是此形态)。",
|
|
53
|
+
V5: "插件的**类限定**自定义属性定义**不含本仓 `pluginId` 前缀的类**(`.<pluginId>-*`)" +
|
|
54
|
+
"——定义落到了宿主 / 他方元素上(与件 7 的 R3「跨方命中必须有自有根类作祖先」同形)。",
|
|
55
|
+
V6: "插件的**文档级**定义、但名字自带本仓前缀(`<pluginId>-`)——无人同吃、**近乎无害**(🟡 只报不拦," +
|
|
56
|
+
"22 号档 §10.3:判红只给「本仓可答 + 有真害」),建议改挂自有根类。",
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* 判一个定义点的级别。**判定式只此一处**(壳仓 `scripts/lib/css-selectors.mjs` 的
|
|
60
|
+
* `judgeTokenScope()` 是同一套判定式的镜像——壳门禁与运行时探针共用那一份)。
|
|
61
|
+
* 顺序 = **先出最具体的那条**:同一站点可能同时命中 V2 与 V1(`:root { --ldk-x: … }`)——不重复报,
|
|
62
|
+
* 报对该方最可操作的那一条(名字层比作用域层更根本)。
|
|
63
|
+
*/
|
|
64
|
+
export function judgePluginTokenScope(site) {
|
|
65
|
+
const prefix = `${site.pluginId}-`;
|
|
66
|
+
if (site.name.startsWith("ldk-"))
|
|
67
|
+
return { level: "red", code: "V2", why: TOKEN_WHY.V2 };
|
|
68
|
+
if (site.scope === "doc") {
|
|
69
|
+
return site.name.startsWith(prefix)
|
|
70
|
+
? { level: "yellow", code: "V6", why: TOKEN_WHY.V6 }
|
|
71
|
+
: { level: "red", code: "V1", why: TOKEN_WHY.V1 };
|
|
72
|
+
}
|
|
73
|
+
if (site.scope === "class") {
|
|
74
|
+
if (hasOwnClass(site.selector, prefix))
|
|
75
|
+
return null; // 自有类之下 ⇒ 合规(那里的名字随你)
|
|
76
|
+
return { level: "red", code: "V5", why: TOKEN_WHY.V5 };
|
|
77
|
+
}
|
|
78
|
+
// id((c) portal 面)/ other(元素·通配·属性形态,归件 7 的选择器形态轴)⇒ 本轴不判
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
/** 一处站点的报点文案(红 / 黄共用;`level` 决定抬头与措辞) */
|
|
82
|
+
function messageOf(site, pluginId) {
|
|
83
|
+
const head = site.level === "red"
|
|
84
|
+
? `[${site.code}] ${site.selector} { --${site.name}: … } ← 本仓 pluginId = "${pluginId}"`
|
|
85
|
+
: `[${site.code}] ${site.selector} { --${site.name}: … } ← 🟡 建议(不拦 build)`;
|
|
86
|
+
const fix = site.code === "V1"
|
|
87
|
+
? `改成挂在自有根类之下(如 \`.${pluginId}-root { --${site.name}: … }\`)——**那里的名字不需要前缀**;` +
|
|
88
|
+
`要改宿主契约的样子请走主题(主题的配方键),不要在 CSS 里覆写宿主契约名。`
|
|
89
|
+
: site.code === "V2"
|
|
90
|
+
? `换成自有语义名(\`ldk-\` 名字空间归宿主)。`
|
|
91
|
+
: site.code === "V5"
|
|
92
|
+
? `把定义搬到自有根类之下(\`.<pluginId>-*\`)——顶层 \`.ldk-*\` 是宿主 / 共享组件的地盘,` +
|
|
93
|
+
`跨方命中必须有自己的根类作祖先。注意 \`.${pluginId}-root .ldk-x { … }\` 这类 **scoped 调优是合规的**` +
|
|
94
|
+
`(compound 里有自有类),本判据只拦「一个自有类都没有」的形态。`
|
|
95
|
+
: `把它搬进本插件的根类之下(形如 \`.${pluginId}-root { --${site.name}: … }\`)——` +
|
|
96
|
+
`同文档同 bundle 时视觉完全一样,但作用域从「整个文档」缩回「我自己的子树」。`;
|
|
97
|
+
return `${head}——${site.why} 改法:${fix}`;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 跑本仓 token 作用域判据。返回结构化报告(审计工具 / lint 打印用)——**同一份实现,没有第二条判据路径**。
|
|
101
|
+
* ⚠️ `resolution` 可复用调用方已经取过的 `pluginId`(`lint.ts` 与前缀腿共用一次解析)。
|
|
102
|
+
*/
|
|
103
|
+
export function runTokenScopeCheck(root, resolution = resolvePluginIdForCss(root)) {
|
|
104
|
+
const absRoot = resolve(root);
|
|
105
|
+
const report = {
|
|
106
|
+
root: absRoot,
|
|
107
|
+
pluginId: resolution.pluginId,
|
|
108
|
+
error: resolution.error,
|
|
109
|
+
red: [],
|
|
110
|
+
yellow: [],
|
|
111
|
+
violations: [],
|
|
112
|
+
advisories: [],
|
|
113
|
+
};
|
|
114
|
+
// ── fail-closed(不可豁免):拿不到前缀 ⇒ 判不了「有主 / 无主」 ──
|
|
115
|
+
if (resolution.error || !resolution.pluginId) {
|
|
116
|
+
report.violations.push({
|
|
117
|
+
file: "plugin.json",
|
|
118
|
+
line: 1,
|
|
119
|
+
message: `拿不到本仓前缀:${resolution.error}。**token 作用域判据不许静默放过**——它要判的正是「名字是不是你自己的」,` +
|
|
120
|
+
`拿不到 \`pluginId\` 就判不了(fail-closed)。在插件工程根修好 plugin.json(或显式声明 pluginId);` +
|
|
121
|
+
`身份问题不受 disable 注释管辖。`,
|
|
122
|
+
});
|
|
123
|
+
return report;
|
|
124
|
+
}
|
|
125
|
+
const pluginId = resolution.pluginId;
|
|
126
|
+
for (const unit of collectCssUnits(absRoot, [CHECK_IDS.cssNamespace])) {
|
|
127
|
+
for (const def of tokenDefinitions(unit.cleaned)) {
|
|
128
|
+
const verdict = judgePluginTokenScope({ name: def.name, scope: def.scope, selector: def.selector, pluginId });
|
|
129
|
+
if (!verdict)
|
|
130
|
+
continue;
|
|
131
|
+
// 知情绕行:同一个 check id(与类名 / 关键帧判据同一套 disable 机制)——红黄同样静默
|
|
132
|
+
if (isDisabled(unit.disabled, def.line, CHECK_IDS.cssNamespace))
|
|
133
|
+
continue;
|
|
134
|
+
const site = {
|
|
135
|
+
file: unit.rel,
|
|
136
|
+
line: def.line,
|
|
137
|
+
name: def.name,
|
|
138
|
+
selector: def.selector,
|
|
139
|
+
scope: def.scope,
|
|
140
|
+
level: verdict.level,
|
|
141
|
+
code: verdict.code,
|
|
142
|
+
why: verdict.why,
|
|
143
|
+
};
|
|
144
|
+
const message = messageOf(site, pluginId);
|
|
145
|
+
if (verdict.level === "red") {
|
|
146
|
+
report.red.push(site);
|
|
147
|
+
report.violations.push({ file: unit.rel, line: def.line, message });
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
report.yellow.push(site);
|
|
151
|
+
report.advisories.push({ file: unit.rel, line: def.line, message });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return report;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=token-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-scope.js","sourceRoot":"","sources":["../../../src/eslint/checks/token-scope.ts"],"names":[],"mappings":"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"}
|
package/dist/eslint/index.d.ts
CHANGED
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
* 🔴 E6#109h-b①:`runPluginPrefixCheck` 是**唯一一个对内 check 的具名导出**,专供壳仓只读审计工具
|
|
13
13
|
* `scripts/plugin-css-prefix-audit.mjs`(改名轮 ③–⑦ 生成「旧名 → 新名」映射、⑧ 全量复核)。
|
|
14
14
|
* **它不是第二条判据路径**:`lint.ts` 的腿用的是**同一个函数**——工具与腿同源,改一处两边一起变。
|
|
15
|
+
*
|
|
16
|
+
* 🔴 E6#109n-b(1.24):同一纪律再加一个 —— `runTokenScopeCheck`(token 作用域判据;审计工具用它出
|
|
17
|
+
* 18 仓的 token 段读数)。**同样不是第二条判据路径**(腿用的就是它)。
|
|
18
|
+
*
|
|
19
|
+
* 🔴 E6#109o-b(1.26):再加一个 —— `runSelectorFormCheck`(选择器形态判据 S2/S3;审计工具用它出
|
|
20
|
+
* 18 仓的「无锚 / 跨方命中」两段读数)。**同样不是第二条判据路径**(腿用的就是它)。
|
|
15
21
|
*/
|
|
16
22
|
export { linkdeskPluginLintConfig } from "./preset.js";
|
|
17
23
|
export type { PluginLintOptions } from "./preset.js";
|
|
@@ -19,4 +25,8 @@ export { runPluginLint, renderPluginLintReport } from "./lint.js";
|
|
|
19
25
|
export type { PluginLintReport, LintLeg } from "./lint.js";
|
|
20
26
|
export { runPluginPrefixCheck, resolvePluginIdForCss } from "./checks/plugin-prefix.js";
|
|
21
27
|
export type { PluginPrefixReport, PrefixSite, PluginIdResolution, PluginIdSource } from "./checks/plugin-prefix.js";
|
|
28
|
+
export { runTokenScopeCheck, judgePluginTokenScope } from "./checks/token-scope.js";
|
|
29
|
+
export type { TokenScopeReport, TokenScopeSite, TokenScopeCode } from "./checks/token-scope.js";
|
|
30
|
+
export { runSelectorFormCheck, judgeSelectorForm, SELECTOR_FORM_WHY } from "./checks/selector-form.js";
|
|
31
|
+
export type { SelectorFormReport, SelectorFormSite, SelectorFormCode } from "./checks/selector-form.js";
|
|
22
32
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACxF,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACpF,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACvG,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/eslint/index.js
CHANGED
|
@@ -12,8 +12,16 @@
|
|
|
12
12
|
* 🔴 E6#109h-b①:`runPluginPrefixCheck` 是**唯一一个对内 check 的具名导出**,专供壳仓只读审计工具
|
|
13
13
|
* `scripts/plugin-css-prefix-audit.mjs`(改名轮 ③–⑦ 生成「旧名 → 新名」映射、⑧ 全量复核)。
|
|
14
14
|
* **它不是第二条判据路径**:`lint.ts` 的腿用的是**同一个函数**——工具与腿同源,改一处两边一起变。
|
|
15
|
+
*
|
|
16
|
+
* 🔴 E6#109n-b(1.24):同一纪律再加一个 —— `runTokenScopeCheck`(token 作用域判据;审计工具用它出
|
|
17
|
+
* 18 仓的 token 段读数)。**同样不是第二条判据路径**(腿用的就是它)。
|
|
18
|
+
*
|
|
19
|
+
* 🔴 E6#109o-b(1.26):再加一个 —— `runSelectorFormCheck`(选择器形态判据 S2/S3;审计工具用它出
|
|
20
|
+
* 18 仓的「无锚 / 跨方命中」两段读数)。**同样不是第二条判据路径**(腿用的就是它)。
|
|
15
21
|
*/
|
|
16
22
|
export { linkdeskPluginLintConfig } from "./preset.js";
|
|
17
23
|
export { runPluginLint, renderPluginLintReport } from "./lint.js";
|
|
18
24
|
export { runPluginPrefixCheck, resolvePluginIdForCss } from "./checks/plugin-prefix.js";
|
|
25
|
+
export { runTokenScopeCheck, judgePluginTokenScope } from "./checks/token-scope.js";
|
|
26
|
+
export { runSelectorFormCheck, judgeSelectorForm, SELECTOR_FORM_WHY } from "./checks/selector-form.js";
|
|
19
27
|
//# sourceMappingURL=index.js.map
|
package/dist/eslint/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAExF,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEpF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/eslint/lint.d.ts
CHANGED
|
@@ -23,6 +23,18 @@ export interface PluginLintReport {
|
|
|
23
23
|
pluginId: string | null;
|
|
24
24
|
/** pluginId 走了「目录名兜底」时的提示行——**必须打印**(详案 15 §一:让作者知道门禁用的是目录名) */
|
|
25
25
|
pluginIdNote: string | null;
|
|
26
|
+
/** 🟡 token 作用域的黄灯建议(V6:文档级但名字带自有前缀)——**只打印、不拦**(E6#109n-b) */
|
|
27
|
+
tokenAdvisories: CheckViolation[];
|
|
28
|
+
/** token 作用域判据的计数(红 = 进了腿报点;黄 = advisories) */
|
|
29
|
+
tokenCounts: {
|
|
30
|
+
red: number;
|
|
31
|
+
yellow: number;
|
|
32
|
+
};
|
|
33
|
+
/** 选择器形态判据的计数(E6#109o-b):S2 禁无锚 / S3 跨方命中不带自有锚——**都进腿报点** */
|
|
34
|
+
selectorFormCounts: {
|
|
35
|
+
anchorless: number;
|
|
36
|
+
crossParty: number;
|
|
37
|
+
};
|
|
26
38
|
}
|
|
27
39
|
export declare function runPluginLint(root: string, options?: PluginLintOptions): Promise<PluginLintReport>;
|
|
28
40
|
/** 打印报告(人机双通道的即时反馈环);返回进程退出码(真 error 才 1,WARN 永不 fail)。 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/eslint/lint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/eslint/lint.ts"],"names":[],"mappings":"AA4BA,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQ/E,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gEAAgE;IAChE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+DAA+D;IAC/D,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,+CAA+C;IAC/C,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,6DAA6D;IAC7D,kBAAkB,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAChE;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6G5G;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAwDvE"}
|
package/dist/eslint/lint.js
CHANGED
|
@@ -6,6 +6,15 @@
|
|
|
6
6
|
* (`checks/reserved-classes.ts`,随包清单)。两者**同一个 checkId / 同一条腿**,报点按 `文件:行`
|
|
7
7
|
* 去重(前缀优先)——详见该腿的组装处注释。
|
|
8
8
|
*
|
|
9
|
+
* 🔴 E6#109n-b(1.24)再加第三条:**token(自定义属性)作用域**(`checks/token-scope.ts`)——
|
|
10
|
+
* 文档级只有宿主契约块能写、其余定义必须挂在自有命名空间的类之下、任何方不得定义 `ldk-*`
|
|
11
|
+
* 自定义属性。红进腿报点(CI 严格腿判红),🟡 黄(V6)只打印不拦。规则正文见 31 号档 §一。
|
|
12
|
+
*
|
|
13
|
+
* 🔴 E6#109o-b(1.26)再加第四条:**选择器形态**(`checks/selector-form.ts`)——
|
|
14
|
+
* S2 禁无锚选择器(元素/通配/属性/伪类/伪元素/**id** 一视同仁;顶层或限定一律禁)·
|
|
15
|
+
* S3 跨方命中(选择器里出现 `ldk-*` 提及)必须自带自有 `.<pluginId>-*` 锚。两条全红、进腿报点。
|
|
16
|
+
* 规则正文见 32 号档 §一(R0–R3);1.25 实测插件侧存量 **0**(18 仓 + 夹具)⇒ 纯预防、零重发成本。
|
|
17
|
+
*
|
|
9
18
|
* 对标壳 check 同款双轨(07 §六·载体双轨):eslint(12 项注册规则,全 WARN)管 ts/tsx;
|
|
10
19
|
* css-hardcode / font-scale / spacing-grid / css-namespace 四条移植脚本管整工程(eslint 到不了 .css,
|
|
11
20
|
* ts/tsx 的 rgb()/hsl() 也归 css-hardcode 补)。jscpd = 项目级可选(文档引导,不进编排)。
|
|
@@ -23,6 +32,8 @@ import { runFontScaleCheck } from "./checks/font-scale.js";
|
|
|
23
32
|
import { runSpacingGridCheck } from "./checks/spacing-grid.js";
|
|
24
33
|
import { runReservedClassCheck } from "./checks/reserved-classes.js";
|
|
25
34
|
import { runPluginPrefixCheck } from "./checks/plugin-prefix.js";
|
|
35
|
+
import { runTokenScopeCheck } from "./checks/token-scope.js";
|
|
36
|
+
import { runSelectorFormCheck } from "./checks/selector-form.js";
|
|
26
37
|
import {} from "./checks/scan.js";
|
|
27
38
|
/** 示例用的门禁 id(打印知情绕行格式);伪 id 与 check 脚本 CHECK_IDS 同源 */
|
|
28
39
|
const LEG_HINT_ID = "linkdesk/no-hardcoded-hex";
|
|
@@ -80,17 +91,38 @@ export async function runPluginLint(root, options = {}) {
|
|
|
80
91
|
*/
|
|
81
92
|
const prefix = runPluginPrefixCheck(absRoot);
|
|
82
93
|
const reserved = runReservedClassCheck(absRoot);
|
|
94
|
+
/**
|
|
95
|
+
* 🔴 E6#109n-b(1.24):命名空间腿再加一条判据 —— **token(自定义属性)作用域**。
|
|
96
|
+
* · 红(V1/V2/V5)进本腿报点 ⇒ CI 严格腿判红;
|
|
97
|
+
* · 🟡 黄(V6:文档级但名字带自有前缀)进 `tokenAdvisories`**只打印、不拦**(22 号档 §10.3)。
|
|
98
|
+
* ⚠️ 去重口径:(`文件:行`)已被前一条判据占用时**不重复报**——同一处 CSS 同时命中
|
|
99
|
+
* 「裸类名不带前缀」与「token 作用域」的概率低,但 fail-closed 那条(`plugin.json:1`)
|
|
100
|
+
* 必然重叠(前缀腿已报同一件事)⇒ 以先出的为准。
|
|
101
|
+
*/
|
|
102
|
+
const tokenScope = runTokenScopeCheck(absRoot);
|
|
103
|
+
/**
|
|
104
|
+
* 🔴 E6#109o-b(1.26):命名空间腿再加一条 —— **选择器形态**(S2 禁无锚 / S3 跨方命中)。
|
|
105
|
+
* 两条**都进本腿报点**(CI 严格腿判红):无锚选择器命中「该文档里所有那一类元素」,与谁渲染无关。
|
|
106
|
+
* ⚠️ 去重口径:与前面几条腿**同一处 `文件:行` 不重复报**(以先出的为准)。特别注意 F3 形态
|
|
107
|
+
* `.ldk-side-panel :focus-visible`——**前缀腿也会报同一行**(`subjectOf()` 把它算成
|
|
108
|
+
* `ldk-side-panel` 的一次定义,那是轴 ① 的既有偏差、本轮不许改)⇒ 这里让前缀腿的话先说。
|
|
109
|
+
*/
|
|
110
|
+
const selectorForm = runSelectorFormCheck(absRoot);
|
|
83
111
|
const prefixKeys = new Set(prefix.violations.map((v) => `${v.file}:${v.line}`));
|
|
112
|
+
const tokenKeys = new Set(tokenScope.violations.map((v) => `${v.file}:${v.line}`));
|
|
113
|
+
const formKeys = new Set(selectorForm.violations.map((v) => `${v.file}:${v.line}`));
|
|
84
114
|
const namespace = [
|
|
85
|
-
...prefix.violations,
|
|
86
|
-
...
|
|
115
|
+
...prefix.violations, // 前缀腿(含 fail-closed)
|
|
116
|
+
...selectorForm.violations.filter((v) => !prefixKeys.has(`${v.file}:${v.line}`)), // 形态腿(同点不重复报)
|
|
117
|
+
...tokenScope.violations.filter((v) => !prefixKeys.has(`${v.file}:${v.line}`)), // token 腿(同点不重复报)
|
|
118
|
+
...reserved.filter((v) => !prefixKeys.has(`${v.file}:${v.line}`) && !tokenKeys.has(`${v.file}:${v.line}`) && !formKeys.has(`${v.file}:${v.line}`)),
|
|
87
119
|
];
|
|
88
120
|
const legs = [
|
|
89
121
|
{ id: "linkdesk/no-hardcoded-hex(css + rgb/hsl 腿)", label: "check-css-hardcode", violations: css },
|
|
90
122
|
{ id: "linkdesk/no-hardcoded-font-size", label: "check-font-scale", violations: font },
|
|
91
123
|
{ id: "linkdesk/no-nonstandard-spacing", label: "check-spacing-grid", violations: spacing },
|
|
92
124
|
{
|
|
93
|
-
id: "linkdesk/no-reserved-class-name(裸定义类名/关键帧必须带本仓 <pluginId>-
|
|
125
|
+
id: "linkdesk/no-reserved-class-name(裸定义类名/关键帧必须带本仓 <pluginId>- 前缀;宿主保留名、token 作用域、选择器形态同 id)",
|
|
94
126
|
label: "check-css-namespace",
|
|
95
127
|
violations: namespace,
|
|
96
128
|
},
|
|
@@ -104,6 +136,9 @@ export async function runPluginLint(root, options = {}) {
|
|
|
104
136
|
tsconfigUsed: tsconfig ? tsconfig : null,
|
|
105
137
|
pluginId: prefix.pluginId,
|
|
106
138
|
pluginIdNote: prefix.pluginIdNote,
|
|
139
|
+
tokenAdvisories: tokenScope.advisories,
|
|
140
|
+
tokenCounts: { red: tokenScope.red.length, yellow: tokenScope.yellow.length },
|
|
141
|
+
selectorFormCounts: { anchorless: selectorForm.anchorless.length, crossParty: selectorForm.crossParty.length },
|
|
107
142
|
};
|
|
108
143
|
}
|
|
109
144
|
/** 打印报告(人机双通道的即时反馈环);返回进程退出码(真 error 才 1,WARN 永不 fail)。 */
|
|
@@ -137,6 +172,20 @@ export function renderPluginLintReport(report) {
|
|
|
137
172
|
// 命名空间腿的前缀来源(E6#109h-b①)——目录名兜底时必须让作者看见(不许静默)
|
|
138
173
|
if (report.pluginIdNote)
|
|
139
174
|
lines.push(`\nℹ 命名空间腿的前缀来源:${report.pluginIdNote}`);
|
|
175
|
+
// 🟡 token 作用域的黄灯建议(E6#109n-b)——**只报不拦**:不进腿报点,故不影响 CI 结论
|
|
176
|
+
if (report.tokenAdvisories.length > 0) {
|
|
177
|
+
lines.push(`\n🟡 check-css-namespace(token 作用域):${report.tokenAdvisories.length} 处**建议**(不拦 build)——` +
|
|
178
|
+
`文档级定义但名字自带本仓前缀(V6):没人跟你抢这个名字,但「写在 \`:root\`」这件事本身没有理由;` +
|
|
179
|
+
`搬进自己的根类之下,作用域从整个文档缩回自己的子树。`);
|
|
180
|
+
for (const v of report.tokenAdvisories)
|
|
181
|
+
lines.push(` ${v.file}:${v.line} ${v.message}`);
|
|
182
|
+
}
|
|
183
|
+
// 选择器形态判据的计数(E6#109o-b)——两条都进腿报点 ⇒ 这里只在**零违规**时补一句确认
|
|
184
|
+
const sf = report.selectorFormCounts;
|
|
185
|
+
if (sf.anchorless === 0 && sf.crossParty === 0) {
|
|
186
|
+
lines.push(`\n✅ check-css-namespace(选择器形态 · S2/S3):无锚选择器 0 / 跨方命中不带自有锚 0` +
|
|
187
|
+
`——插件 CSS 里没有「不需要同名就能撞」的选择器(元素/通配/属性/伪类/伪元素/id 一视同仁)。`);
|
|
188
|
+
}
|
|
140
189
|
lines.push(`\n门禁 = 警告不是封锁(07 §六·三档):未处理偏离可修可绕——知情绕行写标准注释\n` +
|
|
141
190
|
` // eslint-disable-next-line ${LEG_HINT_ID} -- 理由 (行级)\n` +
|
|
142
191
|
` /* eslint-disable ${LEG_HINT_ID} -- 内容画布 */ (文件级:内容/画布整文件豁免)\n` +
|
package/dist/eslint/lint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/eslint/lint.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/eslint/lint.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linkdesk/plugin-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "@linkdesk/plugin-sdk——LinkDesk 插件作者 SDK(对标 @types/vscode):window.linkdesk.* 类型 + 一键 build(.linkdesk-plugin) + dev 宿主 + plugin.json 验证 + eslint 门禁(E6#54d)。作者 npm i 后零壳源码依赖。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|