### 你想解决的问题 现在从 Popup 对某个站点排除脚本时,本质上还是按当前 URL / host 做匹配。 这在现有语义上没有问题:`@exclude` 只排除命中该规则的 document;如果页面里有跨域 iframe,而脚本本身又匹配这个 iframe 的 URL,脚本仍然会在 iframe 中运行。 但用户实际会有另一种需要: > 我不希望某个脚本在 `douyin.com` 这个页面里运行,包括这个页面下面后来加载出来的跨域 iframe;但在其他网站中,我仍然希望这个脚本可以正常运行在 iframe 里。 这时 `@noframes` 不合适,因为它会让脚本在所有网站的 iframe 中都不运行。 相关讨论: - https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=10281&page=2#pid103759 - #937 - #727 #727 目前讨论的是把当前页面中的多个 frame 域名单独列出来,例如 `a.com` 页面里有 `b.com`、`c.com` iframe,就分别提供对 `a.com` / `b.com` / `c.com` 的排除。 这个需求不太一样:这里希望排除的是“以当前顶层页面为范围的整个页面树”,而不是逐个维护 iframe 自己的域名。iframe 可能是动态生成的,域名也可能变化,用户通常只关心“这个脚本不要在这个站点页面里运行”。 ### 期望的解决方案 希望增加一种独立于 userscript metadata 的站点级运行范围,例如 Popup 中提供类似: - 排除在 `douyin.com` 上执行 - 排除在 `douyin.com` 上执行(包括 iframe) 第二种规则以顶层页面 URL 为判断条件: - 顶层页面命中该排除规则时,该脚本不在这个 tab 的任何子 frame 中执行,包括跨域 iframe; - 后续动态创建或导航出来的 iframe 也遵守这个规则; - iframe 自己如果以后作为顶层页面打开,仍按它自己的正常匹配规则处理; - 不改变现有 `@exclude`、`@match`、`@noframes` 的含义。 也就是说,这应该是 ScriptCat 自己的一层“top-level page scope”运行控制,而不是把父页面的 `@exclude` 语义改成会自动继承到子 frame。 ### 补充信息 这个功能主要解决 `@noframes` 太宽、普通 `@exclude` 又只按各 document URL 生效之间的空档。 例如脚本: ```js // @match https://*/* // @exclude *://*.douyin.com/* ``` 当前行为: ```text Top: https://www.douyin.com/ -> 不执行 iframe: https://example-player.com/ -> 仍可能执行 ``` 期望新增的“按顶层页面排除”规则: ```text Top: https://www.douyin.com/ -> 不执行 iframe: https://example-player.com/ -> 不执行,因为它属于这个顶层页面 ``` 但在其他顶层页面中: ```text Top: https://example.com/ iframe: https://example-player.com/ -> 仍按脚本自身规则正常执行 ``` 这样既保留现有 userscript 匹配语义,也能覆盖用户实际的站点级排除需要。
Activity