✨ 新建脚本模板可自定义 - #1731
Open
CodFrm wants to merge 1 commit into
Open
Conversation
close #1722 普通/后台/定时三种新建脚本模板原本写死在 src/template/*.tpl,用户每次新建都要手改 @author / @license。现在把内置模板降级为默认值,用户可在「设置 → 开发工具 → 脚本模板」 里按类型覆写,未覆写的类型仍回落到内置模板。 - 渲染与校验内核 src/pkg/utils/script_template.ts:支持 {{name}} {{match}} {{icon}} {{domain}} {{title}} {{date}}(可写 {{date:YYYY-MM-DD}} 指定格式);取值为空的变量连同 所在行删除(沿用原 @ICON 行的处理),未识别的占位符原样保留(与 Violentmonkey 一致)。 - 保存前按类型校验:渲染后交给既有 parseScriptFromCode,普通脚本模板不得含 @background/@crontab,后台/定时模板必须含对应指令且 cron 表达式合法;不通过则不落库, 编辑器标红并给出原因。 - 模板落 chrome.storage.local 而非 sync:用户手写代码三份合计容易超过 sync 单项 8KB 配额, 而 ChromeStorage.set 不检查 lastError,超额会静默丢失。 - {{title}} 需要标签页标题,popup 的 activeTabUrl 由 { url } 扩为 { url, title }。 - lazyScriptName 拆出 nextScriptName:脚本名只生成一次,同时喂给 {{name}} 与旧的 「模板里写死 New Userscript」兼容路径。 本地验证(真实 Monaco + chrome.storage + 新建脚本流程)见 e2e/scratch/tpl-1722/report.md。
Collaborator
|
注意兩點
|
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 / 检查清单
背景
普通 / 后台 / 定时三种新建脚本模板写死在
src/template/*.tpl,用户每次新建脚本都要手改@author、@license等固定字段(#1722)。Violentmonkey 有可配置的新建模板,脚本猫没有。维护者在 issue 里定了口径:仍然只保留三个模板,把内置模板当默认值、允许用户设置,并在保存前校验模板类型是否自洽。本 PR 按此实现。
本次改动
用户可见行为:设置 → 开发工具 → 脚本模板 新增一页,按脚本类型分别编辑模板;失焦即保存,与同页 ESLint 规则 / 编辑器配置一致;「恢复默认值」按类型清除覆写;已覆写的类型在切换条上标「已修改」。未覆写的类型仍使用内置模板,改动只影响之后新建的脚本。
实现:
src/pkg/utils/script_template.ts,承担模板解析的三件事:默认模板表、变量渲染、类型校验。{{name}}(自动编号脚本名)、{{match}}、{{icon}}、{{domain}}、{{title}}、{{date}}(可写{{date:YYYY-MM-DD}},格式串复用既有的dayFormat)。取值为空的变量连同所在行删除,未识别的占位符原样保留。emptyScript()改为读配置里的模板并渲染;三个.tpl的@name由字面量New Userscript改为{{name}}。activeTabUrl由{ url }扩为{ url, title },为{{title}}提供数据源。script:background_script/script:scheduled_script,并补一个顶层script:normal_script。实现考虑
parseScriptFromCode,再比对得到的脚本类型。这样 UserScript 头是否可解析、@name是否为空、cron 表达式是否合法都由既有实现判定,不另写一套元数据校验;模板层只负责「类型对不对」这一条判断。校验不通过则不写入配置,保留草稿并在编辑器上方标红说明原因。chrome.storage.local而非sync:模板是用户手写的代码,三份合计不难超过chrome.storage.sync单项 8KB 配额,而ChromeStorage.set不检查chrome.runtime.lastError,超额会静默丢失——保存成功的 toast 会骗人。代价是模板不跨设备同步,这是本 PR 有意接受的取舍(src/pkg/config/consts.ts里已注明理由)。若要改成跨设备同步,需要先给保存路径加体积校验或让ChromeStorage上报写入失败。{{}}:仓库原有的{{match}}/{{icon}}就是这个写法,Violentmonkey 也是(其{{name}} {{url}} {{icon}} {{date}})。issue 原文提的%name%不采用。未识别占位符原样保留同样与 VM 一致,避免吃掉脚本正文里本来就有的{{...}}。lazyScriptName拆出nextScriptName(),同一个名字同时喂给{{name}}和「模板里写死New Userscript」的旧兼容路径,避免两条路径各自累加编号。旧写法保留,老用户把模板抄成字面量时仍会自动编号。已知限制
@grant、@match等字段是否合理。建议审查重点
src/pkg/utils/script_template.ts的空值删行规则:{{icon}}原本就是「取不到就删整行」,本 PR 把它推广到所有变量。若某个变量为空时更希望保留空指令行,这里是要改的地方。src/pkg/config/config.ts中lazyScriptName的签名变更(新增name参数),调用方只有emptyScript。关联
close #1722
验证
pnpm lint:prettier / tsc / check:i18n / check:issue-templates / eslint 全通过。pnpm test:ci:4613 passed。另有 1 例scripts/git-staged-snapshot.test.mjs在满载下超出 340ms 预算而失败,单独运行 306ms 通过,与本次改动无关(该用例 spawn git,不涉及本 PR 触及的文件)。src/pkg/utils/script_template.test.ts(渲染 / 回落 / 校验)、src/pages/options/routes/ScriptEditor/editorScriptLoaders.test.ts(新建脚本装配、活动标签页变量、消费activeTabUrl)、src/pages/options/routes/Setting/sections/ScriptTemplateSettings.test.tsx(保存 / 拦截 / 恢复默认 / 切换类型)、src/pages/popup/usePopupData.test.ts补handleCreateScript写入{ url, title }(删掉title后该用例转红,确认其真的守着这一行)。node e2e/session.mjs,构建后加载dist/ext)确认:真实 Monaco 编辑后落盘、新建脚本套用自定义模板、?target=initial时按活动标签页替换{{match}}/{{domain}}、普通模板含@crontab被拦下且旧值未被覆盖、恢复默认、明暗双主题。popup 点击「新建脚本」那一步在无头会话中没有真实网页标签可用,改由上述单元测试覆盖。Screenshots / 截图