规则编辑:建议列表全量展开,目标补齐候选,删除免确认
组合框展开先给全量、本次展开输入过才过滤——按当前值过滤的话,预填的 类型会把列表滤到只剩它自己,MATCH 这类排在后面的选项等于不存在。类型 因此可以默认留空,placeholder 当示例。 目标建议由页面传入:全局规则给内置两个加用户自建的组和自有线路;附加 规则多一项本路专属组——「这个载荷走本路代理」写的就是它,放在拦截规则 前面还能做豁免。生成的专属组不列,每路三个会把列表灌成一面墙。 原文/字段切换只拦真正整行编辑的类型(isRawOnlyRule):之前用 isStructuredEditable 拦,新增时的空原文永远过不了,卡死在原文模式。 删除规则和附加规则不再二次确认——删错了有撤回,确认框只是多一步; toast 带上被删规则的原文。
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
firstMatchIndex,
|
||||
inferRuleFormat,
|
||||
insertBeforeMatch,
|
||||
isRawOnlyRule,
|
||||
isStructuredEditable,
|
||||
missingLanRules,
|
||||
moveRule,
|
||||
@@ -82,6 +83,13 @@ describe('规则字符串的拆分与拼装', () => {
|
||||
expect(isStructuredEditable('DOMAIN-REGEX,^ads?,b$,REJECT')).toBe(false)
|
||||
expect(isStructuredEditable('孤零零一段')).toBe(false)
|
||||
})
|
||||
|
||||
it('只认整行编辑的类型;空行和没写完的行不算,表单要能接回去', () => {
|
||||
expect(isRawOnlyRule('AND,((DOMAIN-SUFFIX,a.com),(DST-PORT,443)),PROXY')).toBe(true)
|
||||
expect(isRawOnlyRule('DOMAIN-REGEX,^ads?,b$,REJECT')).toBe(true)
|
||||
expect(isRawOnlyRule('')).toBe(false)
|
||||
expect(isRawOnlyRule('DOMAIN,youtube.com')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('规则表的顺序', () => {
|
||||
|
||||
+7
-3
@@ -58,10 +58,14 @@ const RAW_ONLY_TYPES = new Set([
|
||||
'PROCESS-PATH-REGEX',
|
||||
])
|
||||
|
||||
/** 这条规则是不是只能按原文整行编辑的类型(逻辑规则、载荷可含逗号的正则类)。 */
|
||||
export function isRawOnlyRule(rule: string): boolean {
|
||||
return RAW_ONLY_TYPES.has(parseRule(rule).type.toUpperCase())
|
||||
}
|
||||
|
||||
export function isStructuredEditable(rule: string): boolean {
|
||||
const parsed = parseRule(rule)
|
||||
if (RAW_ONLY_TYPES.has(parsed.type.toUpperCase())) return false
|
||||
return parsed.target !== null
|
||||
if (isRawOnlyRule(rule)) return false
|
||||
return parseRule(rule).target !== null
|
||||
}
|
||||
|
||||
/** 第一条 MATCH 的下标。它之后的规则永远到不了。没有 MATCH 返回 -1。 */
|
||||
|
||||
Reference in New Issue
Block a user