Skip to content

✨ 安装页标出不生效的指令与 GM 能力 - #1742

Merged
CodFrm merged 11 commits into
mainfrom
feat/install-compat-marks
Sep 17, 2026
Merged

CodFrm merged 11 commits into
mainfrom
feat/install-compat-marks

Conversation

@CodFrm

@CodFrm CodFrm commented Sep 14, 2026

Copy link
Copy Markdown
Member

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

背景

安装前看不出脚本里哪些声明脚本猫不会执行。以 issue 里的 @exclude-match 为例:脚本猫的匹配链路只认
@match/@include/@excludesrc/pkg/utils/url_matcher.ts),这条声明被 metadata 原样保留却从不参与匹配,
本该被排除的页面照样会运行脚本;安装页对此只字不提,装完也不会有任何提示。#931 的反馈者正是「翻文档才发现原来不兼容」。

动手时发现真正缺的不是 UI,而是没有一份「脚本猫支持什么」的数据,现有三份东西互不相识:

  • 编辑器的「未定义标签」判定取自悬浮提示表monaco-editor/langs/*.tsprompt 键,一张翻译表);
  • ESLint 的合法 header 集合取自 packages/eslint/eslint-plugin-userscripts 的覆盖,描述的是 TM/VM/GM 的支持情况;
  • GM 能力的真相只在 GMContext 注册表里,而它由装饰器在 content 上下文载入时填充。

两份列表已经漂移(allFrames/require-css 在 ESLint 覆盖里、不在悬浮提示表里)。另外 userscripts/compat-grant
compat-headers 两条规则在 plugin 的 configs.recommended 里是 off,仓库也从没设 settings.userscriptVersions
所以那两个覆盖文件今天只影响「名字合不合法」,并不做兼容性判定。

本次改动

九个提交,可分开审(4~9 为回应评审的后续提交;4 的归组已在 7 中恢复):

1. ♻️ 兼容性判定收敛为一张支持表 — 新增 src/pkg/utils/script_compat.ts 作为唯一判定来源。判定是二元的:
指令要么被脚本猫消费,要么写了也不生效,不分兼容程度。收录标准写在文件头——「会被消费」或「不消费但也不改变脚本
运行行为」(著作信息、脚本站元数据),只有会改变别家管理器下脚本行为、而脚本猫没实现的指令才刻意留在表外。
GM 能力静态镜像注册表,由新增的 GMContextApiNames() 双向守卫。编辑器的已知标签集合改用这张表,不再随语言包重建。
随之修正两处既有误报:@antifeature:<locale> 此前不在本地化后缀规则内被当成未定义标签;@definition 是脚本猫
自有指令却不在 ESLint 的合法 header 集合里。另加 parseMetadataLines,与 parseMetadata 共用 HEADER_BLOCK/META_LINE
但逐条保留行号——诊断必须与运行时解析看到同一批指令。

2. ✨ 安装页标出不生效的指令与 GM 能力 — 标记就近长在它所属的权限行上,不另起一张卡:不受支持的 @grant
直接替换权限行里原有的 chip,已知影响运行网站的指令(@exclude-match)追加到「运行网站」行,其余不生效的元数据指令(@sandbox 等)落在新增的「其他声明」行。说明走浮层(鼠标移入与键盘聚焦都能开),点击 chip
恒为跳转:展开代码卡、滚动到该行并选中。含义不只靠颜色传达,每枚 chip 带禁止图标与「不生效」的无障碍名。
两处折叠形态会藏掉标记,一并处理:权限一项没变时整卡本会塌成一行,有不生效项时不塌;移动端有标记的类别默认展开。
文案补齐 10 个语言包。

3. 🐛 不生效标记的浮层不再吞掉文档链接与相邻浮层 — 真实会话验证时发现的两处交互缺陷,见下。

4. 💄 不生效的指令统一落在「其他声明」行 — 最初 @exclude-match 靠一张名单归到「运行网站」行,那张名单本质上是不支持指令清单,别家新增的指令追不上。判定一直只认支持表(表外即不生效,@match-website-only 这类没见过的指令同样会被标出,已加用例),现在呈现也不再按名字猜归属。(维护者复核后认为原设计没有问题,已在提交 7 恢复,见下。)

5. ✨ 安装页标出仅限脚本猫的 CAT 能力CAT_* / CAT.* 能力在 GM 能力 chip 上就地加「仅限脚本猫」标签。按命名空间前缀判定(且须是脚本猫已实现的能力),不维护名单;不计入「N 项不生效」,也不影响折叠。

6. ✨ 安装页按白名单标出不生效的取值与脚本猫独有指令 — 指令名早已按支持表判定,但受支持指令的取值没有:运行时对不认得的 @run-at/@run-in/@inject-into 取值静默回退(getRunAtruntime.ts 的 run-in 判定),@run-in container-id-2 会让脚本在任何标签页都不运行;解析不出规则的 @matchextractUrlPatterns 直接丢弃。现在 script_compat.ts 给取值有限的指令列了取值白名单(@unwrap/@early-start 另接受 false,效果与不写一致),@match 交给运行时同一个解析器判定,运行时只读第一个取值的指令标出被忽略的后续取值,@early-start@run-at document-start 时标为不生效。这些取值标记落在「其他声明」行,形如 @run-at document-weird@match 的除外,见提交 7),行摘要改为「兼容性与其他脚本管理器不同」。同一行还给 @early-start@background@storageName 等脚本猫独有指令加「仅限脚本猫」标签;名单由测试对照 eslint-plugin-userscripts 收录的别家指令守卫(只对照会被消费的指令,@definition 不算)。

7. ✨ 安装页不生效标记恢复按类归行,文档链接只指向有说明的小节 — 恢复提交 4 之前的归组:TAG_GROUP 只决定摆放位置,不决定支不支持——判定仍然只认支持表,名单里没有的不生效指令一律落在「其他声明」,不会漏标;名单里的(@exclude-match)挂在它影响的「运行网站」行,读者能就地判断后果。解析不出规则的 @match 在运行网站行就地换成不生效标记,与 @grant 同一做法。浮层链接从笼统的「兼容性文档」改为「描述文档」并带小节锚点,只给文档里确有说明的条目(取值类标记,以及 @storageNameCAT_fileStorage 等「仅限脚本猫」标签,锚点表在 src/pages/install/compat_docs.ts);不支持的指令与 API 文档里本来就没有,不再给一个点过去找不到的链接。另外标记按作者原始写法呈现(@storageName),移动端卡头计数不再折行。

8. 💄 归行名单只收 Tampermonkey / Violentmonkey 的指令 — 归行名单按 TM / VM 现行文档收录,别家特有的指令与旧写法不收;FireMonkey 的 @matchAboutBlank 因此移出,仍标为不生效,落在其他声明行。目前名单只有 @exclude-match

9. 🐛 不生效标记不再被折叠藏起来 — 不支持的 @grant 始终只标在 GM 能力行,但此前有三种情况看不到标记:能力超过 8 项时排在后面的被收进「+N」、更新时属于未变动的被收进折叠桶、整行未变动时整行塌成单行。带标记的取值现在不参与截断与折叠,带标记的类别不塌行(移动端本来就默认展开有标记的类别)。

实现考虑

不在安装页跑 ESLint worker。 issue 的 implementation guidance 提到复用编辑器的 lint 链路,没有采用:eslint_config
是用户可改的(src/pkg/config/config.ts),用户关掉规则提示就没了——把安全相关的提示挂在用户的 lint 偏好上是错的;
安装页是信任决策页,要确定、要快,不该为此拉进 linter worker bundle。标记全部由 metadata 静态派生。

不扫描正文里的 GM 调用。 @grant 本来就写在 metadata 里,不需要扫正文;正则扫 GM_xxx 误报率高,属于编辑器那侧的事。

@definition 按信息类处理(不标记)。 它是脚本猫自己文档化的编辑器指令,但全仓库没有任何消费方。在它被实现或从
文档撤下之前,对着脚本猫自己的文档报警只会让人以为是 bug。这条在 script_compat.ts 里写了注释,属于已知的待决项。

代码定位要求 diff 预览也能拿到实例,为此 CodeEditor 新增 onReady(普通与 diff 两条分支都触发),revealLine
在 diff 预览里定位到修改侧。这连带修掉一个既有缺陷:此前 onEditorMount 只在普通分支触发,更新安装页(有 diff)
的代码骨架永远收不起来。真实浏览器确认它被 monaco 盖住、不影响观感,问题在 role=status + aria-busy 一直留在
无障碍树里说「正在加载代码」。tests/mocks/CodeEditor.tsx 此前无视 diff 一律回调,正是它让这个缺陷在单元测试里
看不出来,现已与真实实现对齐。

已知限制

  • 判定是二元的,按维护者口径不做「部分支持」一档。像 GM_setClipboard 只支持字符串这类行为差异不会在安装页出现。
  • 支持表的「信息类」名单是人工维护的开放集合;别家将来新增的纯展示型 header 会被标成不生效(文案是「不支持该声明,
    安装后会被忽略」,对信息类不算错,但是噪音)。新增时往 INFORMATIONAL_TAGS 补一行即可。
  • 本 PR 只做检测与呈现,不实现 @exclude-match[Compatibility] Add support for @exclude-match #1714 单独跟踪)。标记不阻断安装。
  • @inject-into auto(VM:页面注入失败时退回 content)按二元口径标为不生效:脚本猫只认 content,其余一律按页面注入。
  • 编辑器的「未定义标签」诊断只用了指令名白名单,还没用取值白名单,编辑器里写 @run-at document-weird 仍无提示。
  • @grant 不区分「别家有但脚本猫没实现」和「拼写错误」,统一一句文案。要区分需把 eslint-plugin-userscripts
    grant 数据带进安装页 bundle,收益不抵成本。

建议审查重点

  • src/pkg/utils/script_compat.tsCONSUMED_TAGS / INFORMATIONAL_TAGS 两份名单——这是全部判定的根,逐条都值得看一眼。
  • 编辑器「未定义标签」判定换源后的行为变化:原先取自悬浮提示表,现在取自支持表,两者不完全重合。
  • deriveCompatMarks 里 metadata 键与代码行的对齐方式(src/pages/install/compat.ts)。
  • CodeEditor 新增 onReadyonEditorMount 的职责划分。

关联

close #1713
相关:#931(兼容性跟踪)、#1714@exclude-match 支持本身)

验证

  • pnpm run lint:prettier / tsc / check:i18n / check:issue-templates / eslint 全通过。
  • pnpm run test:ci:4781 passed(空载)。并行满载时 src/pages/options/routes/Tools/NetworkRules/
    850ms UI budget 用例会超时(观察到 3~19 例不等),同一批用例空载连续三次全绿;这是 ⚡️ 降低网络规则跨页测试成本并固化测试约束 #1734 自己记录的既有限制
    (「本地并行运行整个 NetworkRules 目录时…会出现 worker contention 超时」),与本次改动无关。另外
    useInstallData.test.ts 的「技能安装成功后同样走按钮状态机与延时关闭」在满载下出现过一次超时,未再复现。
  • 新增用例:script_compat.test.ts(支持判定 + 与注册表/ESLint header 集合的双向一致性守卫)、
    script.test.tsparseMetadataLinesinstall/compat.test.ts(派生与定位)、CompatChip.test.tsx
    (浮层、跳转、互斥、无行号兜底)、PermissionRow/PermissionCard/CodePreview/CodeEditor/App 的接线与折叠形态。
  • 提交 7:pnpm run lint 全通过;install / pkg/utils / locales 1009 例通过;在 75bb2fe 的构建上重跑真实扩展会话,确认 @exclude-match 与写错的 @match 在运行网站行、其余在其他声明行,取值浮层链到 docs/dev/meta#run-at,不支持的指令浮层无链接,@storageName 标签链到 #storagename-,亮暗两色与 390px 移动端卡头正常。
  • 提交 6:pnpm run lint 全通过;install / pkg/utils / locales 997 例通过;在 0823786 的构建上重跑真实扩展会话,确认 @run-at document-weird@inject-into auto@exclude-match@sandbox 同在「其他声明」行、卡头计 5 项、@storagenameCAT_fileStorage 带「仅限脚本猫」、亮暗两色正常、全兼容脚本仍零标记。
  • 评审后续提交(4、5):pnpm run lint 全通过;install / script_compat / locales 相关 290 例通过(useInstallData.test.ts 的上述用例在并行时又超时一次,单独重跑通过);在 a3c3897 的构建上重跑真实扩展会话,确认 @exclude-match@sandbox 同在「其他声明」行、「运行网站」行无标记、CAT_fileStorage 带「仅限脚本猫」、亮暗两色正常,下面其余场景也都还过。未重跑全量 test:ci
  • 真实扩展会话pnpm run build 后加载 dist/ext,Playwright 驱动安装页)覆盖:三枚标记落在正确的行、
    卡头徽章计数、受支持能力不带标记、悬停浮层、鼠标移入浮层后文档链接可达、悬停切换只保留一枚浮层、点击跳转在普通
    预览与更新态内联 diff 下都滚动并选中目标行(diff 下 monaco 会自动展开折叠的 unchanged region)、更新态代码骨架
    已收起、暗色主题、全部受支持的脚本零标记。
  • 修复前基线同样在真实浏览器取得:改动前的构建上更新安装页的 code-skeleton isVisible() 恒为 true

Screenshots / 截图

以下两张摄于提交 3,缺少提交 5~7 新增的取值标记、「仅限脚本猫」标签与文档链接调整。

update-diff jump-light

安装页要标出「写了但不会生效」的指令与 GM 能力,但仓库里没有一份「脚本猫支持
什么」的数据:编辑器的未定义标签判定取自悬浮提示表(langs/*.ts 的 prompt 键,
一张翻译表),ESLint 的合法 header 集合取自 packages/eslint 对 eslint-plugin-
userscripts 的覆盖,两者互不相识且已经漂移;GM 能力的真相只在 GMContext 注册表
里,而注册表由装饰器在 content 上下文载入时填充,安装页不可能为查一次支持性把
整套 GM 实现拉进包。

新增 src/pkg/utils/script_compat.ts 作为唯一判定来源。判定是二元的:指令要么被
脚本猫消费,要么写了也不生效。收录标准写在文件头——「会被消费」或「不消费但也
不改变脚本运行行为」,只有会改变别家管理器下脚本行为、而脚本猫没实现的指令才刻
意留在表外。GM 能力静态镜像注册表,由 GMContextApiNames() 双向守卫,新增 API 漏
进表会让测试转红;不经注册表、由上下文恒定提供的 unsafeWindow / GM_info /
window.onurlchange / none 单独登记,便于审阅。

编辑器的已知标签集合改用这张表,不再随语言包重建——一条指令是否被支持与界面语言
无关。随之修正两处既有误报:@antifeature:<locale> 此前不在本地化后缀规则内被当成
未定义标签;@Definition 是脚本猫自有指令却不在 ESLint 的合法 header 集合里,编辑
器会报「不是合法 userscript header」。

另加 parseMetadataLines:与 parseMetadata 共用 HEADER_BLOCK / META_LINE,逐条保留
行号。诊断必须与运行时解析看到同一批指令,否则会对着一条运行时根本没读到的行报警。
用户安装前看不出脚本里哪些声明脚本猫不会执行。以 @exclude-match 为例:脚本猫
只识别 @match/@include/@exclude,这条声明被原样保留却从不参与匹配,本该被排除
的页面照样会运行脚本,而安装页对此只字不提,装完也不会有任何提示(#1713)。

判定沿用支持表,是二元的:脚本猫不消费就是不生效,不再分兼容程度。标记就近长在
它所属的权限行上,不另起一张卡——不受支持的 @grant 直接替换权限行里原有的 chip,
匹配类声明(@exclude-match)追加到「运行网站」行,归不到任何权限类别的(@sandbox、
@top-level-await 等)落在新增的「其他声明」行。说明走浮层,鼠标移入与键盘聚焦都能
打开;点击 chip 本身恒为跳转,展开代码卡并滚动到该声明所在行并选中。含义不只靠颜色
传达:每枚 chip 带禁止图标与「不生效」的无障碍名。

两处折叠形态会藏掉标记,一并处理:权限一项没变时整卡本会塌成一行,有不生效项时
不塌(折叠的是上次已确认过的权限,而标记是这次才出现的新信息);移动端有标记的
类别默认展开。全都没有时安装页与今天一字不改。

代码定位要求 diff 预览也能拿到实例,为此 CodeEditor 新增 onReady(普通与 diff 两条
分支都触发),revealLine 在 diff 预览里定位到修改侧。这连带修掉一个既有缺陷:此前
onEditorMount 只在普通分支触发,更新安装页(有 diff)的代码骨架永远收不起来——真实
浏览器确认过它被 monaco 盖住不影响观感,但 role=status + aria-busy 会一直留在无障碍
树里说「正在加载代码」。tests/mocks/CodeEditor.tsx 此前无视 diff 一律回调,正是它让
这个缺陷在单元测试里看不出来,现已与真实实现对齐。
真实会话验证时发现两处:浮层里有「兼容性文档」链接,但只有 chip 自己在跟踪悬停,
鼠标一离开 chip 去点链接浮层就关了,链接实际上点不到;标记 chip 常常并排,浮层宽
288px,切换悬停时旧浮层要等关闭延迟才收,两枚会同时开着互相盖住。

改用仓库已有的 useHoverMenu,把浮层本体一并纳入悬停范围;再以模块级「当前开着的
浮层」做互斥,悬停切换时立刻收掉上一枚。
@cyfung1031

cyfung1031 commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

这个做法有点古怪吧
本来是,ScriptCat里记录的是「已支持」的,所有「已支持」以外的都标记为不支持

但看截图来说,你是用记录「不支持」的方式来实现。不然怎么知道「@exclude-match」是放在 运行网站
这个做法超奇怪
那么日后如果有其他的 syntax, 例如 @match-website-only,它会怎么处理?没写在「不支持」就是支持了?还是乱放一通

@exclude-match」充其量只是一个例子。

Comment thread src/pages/install/compat.ts Outdated
Comment on lines +23 to +26
const TAG_GROUP: Readonly<Record<string, IneffectiveTagGroup>> = {
"exclude-match": "match",
matchaboutblank: "match",
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

记录不支持的syntax这个做法超白痴
不支持的有无数的多
说不定明天 TM FM 又会加一堆新syntax
这种列表的更新一定不会追得上实际

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

说得对,这张 TAG_GROUP 实际上就是一份不支持清单,已经在 94c5992 删掉了。

判定本身一直是白名单:script_compat.ts 里只登记「脚本猫会消费」和「不影响运行的信息类」指令,表外一律算不生效,不需要事先登记。当初只有「把它摆到哪一行」这一步是按名字猜的。现在表外指令统一放在「其他声明」行,@match-website-only 这种没见过的指令也会被标出来,compat.test.ts 里加了对应用例。

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好像不太对,这里的记录不支持,是因为知道这是属于 运行网站 那类的,如果是未知的,会显示到其它声明去

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CodFrm

是因为知道这是属于 运行网站 那类的

不需要 (no need)

對scriptcat來說不明意義的就標不明
需要支持才做實作

不要在 支持 & 不支持 中間加一個 "我們知道有這樣的聲明但我們不支援"
這個在已有的editor有提示

安裝頁只需要說明支持跟不支持

@cyfung1031 cyfung1031 Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我最初的論點沒有改變。仍舊認為這個 「不支持名單」是無謂不需要

倒過來那堆「不支持聲明」中少了一個 exclude-match會讓人誤以為支持

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以,按你说的吧

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已按这个方向处理(7058a825):去掉归行名单(TAG_GROUP),不再维护「知道但不支持」的中间档,支持表之外的指令一律直接落「其他声明」行。@match 解析不出规则的取值仍在运行网站行就地打标——那是取值级的 chip 替换,不属于归行。

@cyfung1031

Copy link
Copy Markdown
Collaborator

另外,如果要标记「不支持」,应该也要标记「仅限ScriptCat」(那堆CAT_XXXXXX)
其他脚本管理器不支持。只有ScriptCat支持。这些也应该要显示出来告诉一下

此前 @exclude-match 等靠一张名单归到「运行网站」行,这等于维护一份不支持指令清单,
别家新增的指令永远追不上。判定本来就只认支持表,呈现也不再按名字猜归属。
CAT_ / CAT. 是脚本猫自有命名空间,装在别的脚本管理器里不可用,在 GM 能力 chip 上就地注明。
@CodFrm

CodFrm commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

@cyfung1031 两条都已处理:

  1. 不支持清单:判定本来就是白名单(表外即不生效),问题出在 compat.ts 那张把 @exclude-match 归到「运行网站」行的名单,它确实等于一份不支持清单。已删掉(94c5992e),不生效的元数据指令现在统一放在「其他声明」行,以后新出的指令不用登记也会被标出。详见行内回复。
  2. 仅限 ScriptCatCAT_* / CAT.* 能力在 GM 能力 chip 上加了「仅限脚本猫」标签(a3c38975)。判定用命名空间前缀,且必须是脚本猫已实现的能力,不另维护名单。它不算进「N 项不生效」。这次只做了 grant。@background@crontab 这类脚本猫独有的指令在安装页已经会显示成后台/定时脚本,所以没有重复加标签;如果也要标出来,我再补。

在新构建上跑过真实扩展会话,亮暗两色都确认了。PR 描述已同步更新。

image

指令名早已按支持表判定,但受支持指令的取值没有:运行时对不认得的 @run-at / @run-in /
@inject-into 取值静默回退,@run-in container-id-2 这类写法会让脚本在任何标签页都不运行,
解析不出规则的 @match 被直接丢弃,安装页却一字不提。现在取值同样只认白名单,
@match 交给运行时同一个解析器判定,只读第一个取值的指令标出被忽略的后续取值,
@early-start 缺 @run-at document-start 时也标为不生效。

另把 @early-start、@background 等脚本猫独有的指令在「其他声明」行标出「仅限脚本猫」;
名单由测试对照 eslint-plugin-userscripts 收录的别家指令守卫。
- @exclude-match 等已知影响运行网站的指令挂回运行网站行;归组只决定摆放,
  支持与否仍由支持表判定,不认识的指令照样落在其他声明,不会漏标。
  解析不出规则的 @match 在运行网站行就地换成不生效标记,不再重复成条。
- 浮层链接改为「描述文档」并带小节锚点,只给文档里确有说明的条目;
  不支持的指令与 API 文档里本来没有,不再给一个点过去找不到的链接。
  「仅限脚本猫」标签同样链到对应小节。
- 标记按作者的原始写法呈现(@storageName 而非 @storagename)。
- 移动端卡头的不生效计数不再折行。
@matchAboutBlank 是 FireMonkey 特有的,移出运行网站行的名单;它仍按支持表标为不生效,落在其他声明行。
GM 能力超过 8 项时排在后面的不生效能力会收进「+N」;更新时属于未变动的会收进折叠桶,
整行未变动时整行塌成单行——三种情况下标记都看不到。带标记的取值现在不参与截断与折叠,
带标记的类别不塌行(移动端本来就默认展开)。
@CodFrm

CodFrm commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

@cyfung1031 更正我之前的两条回复:「归到运行网站行」的名单已经恢复(75bb2feb),不是删掉。复核后原设计没有问题,原因如下。

判定和摆放是两回事。 支不支持只看 script_compat.ts 的支持表:只登记脚本猫会读取的、或不影响运行的指令,表外的一律算不生效,不需要事先登记。compat.ts 里的 TAG_GROUP 只决定标记放在哪一行,好让读者就地看出后果。名单里没有的指令不会被当成「支持」,而是落到「其他声明」行。所以像 @match-website-only 这种没见过的写法照样会被标出来(compat.test.ts 里有用例)。这张名单只收 Tampermonkey / Violentmonkey 现行文档里的指令,别家特有的和旧写法不收,目前只有 @exclude-match

回应评审之后,另外补了这些:

  • 取值也按白名单判定(0823786c):@run-at / @run-in / @inject-into 写了不认识的值(如 @run-in container-id-2@inject-into auto),或者 @match 解析不出规则,都会标为不生效。这些情况运行时原本会静默回退或直接丢弃。
  • 「仅限脚本猫」标记:除了 CAT_* 能力,还覆盖 @early-start@background@storageName 等脚本猫独有的指令。名单由测试对照 eslint-plugin-userscripts 收录的别家指令来守卫。
  • 文档链接(75bb2feb):只给文档里确实有说明的条目,并带小节锚点。
  • 标记不会被折叠藏起来(da08a9e7):未知的 @grant 始终在 GM 能力行里就地标注,能力超过 8 项或更新时属于未变动的,也不会再被收起。

具体改动和验证记录见 PR 描述里的提交 5~9。

CodeEditor 冲突取舍:main 为全屏预览让 diff 分支也回调 onEditorMount(取
getModifiedEditor),本 PR 已把就绪信号拆成 onReady(普通与 diff 都触发),
且 mock 与注释都约定 onEditorMount 仅普通编辑器触发,故 diff 分支只保留
onReady,全屏/骨架就绪由 onReady 承担;main 为此加的 onEditorMount-diff
测试随之移除,diff 就绪已由本 PR 的 onReady 用例与 CodePreview 全屏 diff
用例覆盖。CodePreview 合并两边:保留 main 的全屏对话框,跳行排队与
revealLine 走 PR 的 handleReady/onReady;section 不带 overflow-hidden
(沿用 main #1746 的修正)。
回应评审:安装页只说支持/不支持,不再维护「知道但不支持」的中间档
归行表(TAG_GROUP),那张表永远追不上别家新增的指令。@exclude-match
等不生效指令不再挂到运行网站行,与其他指令一起在「其他声明」行呈现;
@match 解析不出规则的取值仍在运行网站行就地打标(取值级,不属归行)。
@CodFrm
CodFrm merged commit 0eeeb5d into main Sep 17, 2026
10 checks passed
@CodFrm
CodFrm deleted the feat/install-compat-marks branch September 17, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Highlight incompatible APIs in the installation UI

2 participants