🐛 修复 Popup 全局关闭提示时有时无、且当前页脚本列表为空 - #1694
Open
CodFrm wants to merge 3 commits into
Open
Conversation
Popup 的页面状态判定把「本 tab 有没有 content script 报到」排在全局开关之前, 于是一个全局事实被标签页级、且会陈旧的证据否决: - 注入证据存放在 session cache 的 tabLoaded:<tabId>,只在标签页关闭时、 或 onBeforeNavigate 且 runCountMap.has(tabId) && !isLoadScripts 时才清理。 runCountMap 是 Service Worker 的内存 Map,SW 一被回收就空了。 - 结果:关掉全局开关后刷新页面,SW 还活着 → 记录被清 → 有提示; SW 中途重启过 → 记录留存 → 判为 ok → 没提示。新标签页则总是有提示。 同一个开关状态下提示时有时无。 改为把 userscripts-unavailable / scripts-disabled 两个「扩展整体没跑起来」的 判据移到注入证据之前——它们与哪个标签页无关,不该被某个 tab 的历史否决。 同时收窄 #1687 引入的空列表规则:原本任何非 ok 状态都返回空的 scriptList, 现在只有 restricted(浏览器保留页、自家扩展商店)保持空——那里脚本猫永远触及 不到。其余状态的抑制原因都可以解除(开开关、开开发者模式、移出黑名单、给文件 访问权限、刷新页面),照常列出按网址匹配的脚本,用户才知道解除后哪些会生效; 顶部提示已经说明了它们现在为什么没跑。
Collaborator
|
@CodFrm 你的AI 是實際跑瀏覽器的操作嗎?感覺不太可信 |
Member
Author
我是自己用的时候发现的这个bug,修复验证交给AI 有时候自己也会看代码和再验证 |
Collaborator
重工审计结论已基于原始 head
PR 标题、正文和 API 契约未修改。 |
Member
Author
|
@cyfung1031 改错了吧,这样就是个空列表,只是因为当时的情况不能运行脚本,展示还是要展示吧 |
This reverts commit a07dfd4.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
背景
用户报告:关掉全局「启用脚本」开关后,Popup 顶部的「脚本已全局关闭,开启上方开关并刷新页面后生效」
有时显示有时不显示;而一旦显示,「当前页运行脚本」列表就是空的。
两个现象来自
PopupService的两段代码。提示时有时无 ——
getPageStatus()把「本 tab 有没有 content script 报到」排在全局开关判据之前,于是一个全局事实被标签页级、且会陈旧的证据否决:
注入证据存放在 session cache 的
tabLoaded:<tabId>,清理时机有两处:标签页关闭(clearData),以及
webNavigation.onBeforeNavigate且runCountMap.has(tabId) && !isLoadScripts。runCountMap是 Service Worker 里的内存 Map,SW 一被回收就空了,而tabLoaded在chrome.storage.session里活着。于是关开关后刷新页面:ok→ 没有提示;同一个开关状态下,提示出不出现取决于 SW 有没有被回收过——这就是「有时候显示有时候不显示」。
列表为空 ——
getPopupData()对任何非ok状态直接返回scriptList: []。这是 #1687(#1689)为了「
chrome://等触及不到的页面上不该列脚本」加的,但当时按「所有非 ok 状态」一刀切,把「扩展被关掉」「在黑名单里」这些原因可以解除的情况也一起清空了。
本次改动
src/app/service/service_worker/popup.ts,两处:getPageStatus():把userscripts-unavailable/scripts-disabled移到注入证据之前。这两个是「扩展整体没跑起来」(
registerUserscripts()直接 return,content script 根本没注册),与哪个标签页无关,不该被某个 tab 的历史记录否决。
getPopupData():空列表规则由pageStatus !== "ok"收窄为pageStatus === "restricted"。改动后的行为:
okscripts-disabled/userscripts-unavailable/blacklist/file-access-denied/not-injectedrestricted(浏览器保留页、自家扩展商店)实现考虑
restricted/blacklist依旧最先判——它们是「无论如何都不会注入」的确定结论;接着才是两个全局判据;注入证据退到它们之后,只用于区分
ok与not-injected,以及给扩展商店页 /
file://权限一个更准确的原因。file://权限查询与商店域名单仍然不能否定已注入成功的事实(Firefox 上该查询与实际可注入性并不总是一致),这部分未动。
给文件访问权限、刷新页面——这些解除后脚本就会在本页跑,列出来用户才知道解除后会生效,
而顶部提示已经说明了它们现在为什么没跑。只有
restricted是解除不了的,保持空列表。scriptMatchEnable在waitInit()阶段预热,不受
isLoadScripts/isUserScriptsAvailable影响,因此全局关闭时仍能列出匹配脚本(已在真实 Chrome 中确认,见下)。
关掉开关不会杀死已注入页面上正在跑的脚本,该页仍应为 ok。它的出发点(关开关不会杀死已在跑的脚本)没错,但
tabLoaded只能证明「本 tab 曾经报到过」,刷新之后它依然为真,无法区分「脚本还在跑」和「刷新后再也不会跑」,用它压掉提示会误导用户。
新契约是「提示不取决于标签页新旧」,并把该测试改写为对应用例。
已知限制
file-access-denied列出脚本这一条只有单元测试证据,没有在浏览器里构造「
file://页 + 未授予文件访问 + 带@match file:///*的脚本」这一组合。onBeforeNavigate里那段带条件的缓存清理。它现在不再影响提示,但仍然决定
tabScript:<tabId>运行计数何时被清;那是另一件事,本次不扩大范围。建议审查重点
getPageStatus()的新顺序:确认把两个全局判据提到注入证据之前,没有让「实际能运行的页面」被误报(关键在于这两个条件成立时 content script 确实没注册)。
restricted是否是唯一应该保持空列表的状态([BUG] popup当前页运行脚本展示的并不是实际运行的脚本 #1687 的原始诉求是chrome://)。runNum来自tabScript:<tabId>缓存,关开关前跑过的页面仍会显示「运行中」——这是准确的(那些脚本确实还活着),但请确认这是期望的呈现。
参考
src/app/service/service_worker/popup.ts:getPageStatus()/getPopupData()src/app/service/service_worker/runtime.ts:isLoadScripts的enable_script监听与unregisterUserscripts()关联
chrome://的处理。验证
单元测试(TDD):两轮先写 RED 再实现。
真实 Chrome 手工验证(
pnpm run build后用e2e/session.mjs驱动,本地脚本@match http://127.0.0.1:8971/*):scripts-disabled+ 列出脚本(改动前:ok,无提示)tabLoaded键)scripts-disabled+ 列出脚本(改动前:有提示、空列表)*://127.0.0.1/*)blacklist+ 列出脚本not-injected+ 列出脚本ok+ 列出脚本restricted)关开关后直接观察到
tabLoaded:<tabId>仍然存在,这正是旧代码返回ok、吞掉提示的那一步。Screenshots / 截图
未附图(终端会话截图无法直接上传)。改动后 Popup 在全局关闭状态下的实际渲染文本,
取自会话中真实 Popup 页面(把被测标签页设为窗口活动标签后重载
popup.html):