追加 Hosts、路径撞名拦截、连接页表头随行滚动、GEO 借内核通路
设置页内核参数加 hosts 行,铅笔进弹窗编辑(顶层 hosts: 键, config.go:454,值单个或数组 parseHosts config.go:1131)。弹窗里随便改、 保存才一次性提交——写配置有几秒的校验重载,逐行失焦提交会把等待塞进 每次输入。没动过的行原样写回,数组不被重整形。 订阅和规则组新增时查缓存路径撞名:路径由名字净化而来,「订阅 A」和 「订阅/A」是两个名字、同一个文件,名字查重挡不住,会互相覆盖缓存。 纯函数在 shared 带测试,页面提交前拦。 连接页表头挪进滚动容器加 sticky:.scroller 声明 overflow-y 后按规范 连带拿到横向滚动上下文,表头留在外面时窄屏横向滚动两者脱节。表头 40px 的窗口偏移由 overscan 8 行吸收,不配 scrollMargin。 GEO 单文件下载先借内核的混合端口出去再退直连——内核自己更新 GEO 走 的是它的分流,Patchbay 直连 GitHub 不一定通。ECharts 拆独立 chunk, 业务代码改动不再让这 500KB 跟着换 hash。
This commit is contained in:
@@ -219,6 +219,25 @@ export function ruleProviderPath(name: string, format: string): string {
|
||||
return `./providers/rules/${safeName(name) || shortHash(name)}.${ext}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 新规则组的清单路径是否和现有规则组的撞车。
|
||||
*
|
||||
* 名字查重挡不住这种:路径由名字净化而来,「广告 A」和「广告/A」是两个名字、
|
||||
* 同一个清单文件,互相覆盖。返回撞上的那个规则组名,没撞返回 null。
|
||||
*/
|
||||
export function ruleProviderPathConflict(
|
||||
data: ConfigObject,
|
||||
selfName: string,
|
||||
path: string,
|
||||
): string | null {
|
||||
for (const [name, decl] of Object.entries(ruleProvidersOf(data))) {
|
||||
if (name === selfName) continue
|
||||
// 没写 path 的声明由内核按 url 哈希生成路径,和这里的净化路径撞不上
|
||||
if (decl.path === path) return name
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** 清单格式按来源的扩展名推断。拿不准时回到 yaml——那是内核没写 format 时的默认。 */
|
||||
export function inferRuleFormat(source: string): 'yaml' | 'text' | 'mrs' {
|
||||
const clean = (source.split(/[?#]/)[0] ?? '').toLowerCase()
|
||||
|
||||
Reference in New Issue
Block a user