iter(g239): 焦点描边令牌化,outline 收敛为三档复合令牌并纳入审计第十四类

This commit is contained in:
HIsheR
2026-10-26 21:37:57 +08:00
parent 9e85ef3f12
commit 53338960be
7 changed files with 73 additions and 25 deletions
+26
View File
@@ -76,6 +76,11 @@ export const KIND_META = [
label: '位移字面值',
hint: 'transform 的 translate 写死 px 位移,应改用 --ua-translate-* 档位(负号用 calc(-1 * var(...)),百分比居中豁免)',
},
{
key: 'outline-literal',
label: '焦点描边字面值',
hint: 'outline 写死宽度与色值,应改用 --ua-focus-outline(_inset/_soft) 三档(outline: none 豁免)',
},
];
/*** 作用:需要扫描的 CSS 属性白名单(其余属性本轮不动;用白名单顺带避开伪类选择器误判) ***/
@@ -485,6 +490,20 @@ function migrateLeading(core) {
return { kind: 'leading-literal', value: token };
}
/*** 作用:outline 焦点描边字面值 → 三档复合令牌(none 是「移除描边」语义不入表;outline-offset 是逐控件几何微调,不走此表) ***/
const OUTLINE_TOKENS = new Map([
['2px solid var(--ua-color-accent)', 'var(--ua-focus-outline)'],
['1.5px solid var(--ua-color-accent-soft)', 'var(--ua-focus-outline-inset)'],
['2px solid color-mix(in srgb, var(--ua-color-accent) var(--ua-alpha-mid), transparent)', 'var(--ua-focus-outline-soft)'],
]);
/*** 作用:迁移单条 outline:整值命中三档即换令牌,其余写法留给门禁拦截 ***/
function migrateOutline(core) {
const token = OUTLINE_TOKENS.get(squash(core));
if (!token) return null;
return { kind: 'outline-literal', value: token };
}
/*** 作用:迁移单条 transform:px 位移逐个换 --ua-translate-* 档位,负号转 calc(-1 * var(...));百分比居中与 0 天然不入表 ***/
function migrateTranslate(core) {
let hits = 0;
@@ -540,6 +559,8 @@ export function migrateDeclaration(prop, rawValue) {
result = migrateZ(core);
} else if (prop === 'transform') {
result = migrateTranslate(core); // 位移量走独立档位,不与内距梯子混用
} else if (prop === 'outline') {
result = migrateOutline(core); // 焦点描边整值收敛三档
} else {
result = migrateMix(core) ?? migrateBorder(prop, core); // 其余属性:先收敛 color-mix 浓度,再收敛纯黑 rgba 边
}
@@ -623,6 +644,11 @@ function detect(prop, rawValue, key) {
const stripped = value.replace(/var\(--ua-translate-[\w-]+\)/g, ' '); // 已令牌化的位移先剔除
return (stripped.match(/-?\d+(\.\d+)?px\b/gi) ?? []).length; // 百分比(居中/轨道)与 0 不算漂移
}
if (key === 'outline-literal') {
if (prop !== 'outline') return 0;
if (value === 'none') return 0; // 移除描边是语义写法,不算漂移
return /^var\(/.test(value) ? 0 : /\d+(\.\d+)?px\b/.test(value) ? 1 : 0; // 整值已走令牌不算漂移
}
return 0;
}