@@ -524,6 +524,7 @@ if (binaryInfo != null && binaryInfo.length > 0) {
524524 }
525525
526526 const leadingTemplate = takeLeadingTemplate ( x )
527+ const leadingTemplateIsNameOnly = ! ! leadingTemplate && / ^ \s * = / . test ( leadingTemplate . rest )
527528 if ( leadingTemplate ) {
528529 x = leadingTemplate . rest
529530 }
@@ -808,7 +809,7 @@ if (binaryInfo != null && binaryInfo.length > 0) {
808809 style,
809810 scriptname,
810811 updatetime,
811- toggleKey : leadingTemplate ?. key || '' ,
812+ toggleKey : ! leadingTemplateIsNameOnly ? leadingTemplate ?. key || '' : '' ,
812813 ori : x ,
813814 num : y ,
814815 } )
@@ -819,7 +820,9 @@ if (binaryInfo != null && binaryInfo.length > 0) {
819820 mark = getMark ( y , body )
820821 noteK = isNoteK ( x )
821822 jsurl = getJsInfo ( x , / s c r i p t - p a t h \s * = \s * / )
822- jsname = / [ = , ] \s * t y p e \s * = \s * / . test ( x )
823+ jsname = leadingTemplateIsNameOnly
824+ ? leadingTemplate . key
825+ : / [ = , ] \s * t y p e \s * = \s * / . test ( x )
823826 ? x . split ( / \s * = / ) [ 0 ] . replace ( / ^ # / , '' )
824827 : / , \s * t a g \s * = \s * / . test ( x )
825828 ? getJsInfo ( x , / , \s * t a g \s * = \s * / )
@@ -848,7 +851,7 @@ if (binaryInfo != null && binaryInfo.length > 0) {
848851 ability = getJsInfo ( x , / [ = , \s ] \s * a b i l i t y \s * = \s * / )
849852 engine = getJsInfo ( x , / [ = , \s ] \s * e n g i n e \s * = \s * / )
850853 jsenable = getJsInfo ( x , / [ = , \s ] \s * e n a b l e d ? \s * = \s * / )
851- jsenable = jsenable || ( leadingTemplate ?. key ? `{${ leadingTemplate . key } }` : '' )
854+ jsenable = jsenable || ( ! leadingTemplateIsNameOnly && leadingTemplate ?. key ? `{${ leadingTemplate . key } }` : '' )
852855 getTemplateKeys ( jsenable ) . forEach ( key => surgeRuleToggleArgs . set ( key , true ) )
853856 updatetime = getJsInfo ( x , / [ = , \s ] \s * s c r i p t - u p d a t e - i n t e r v a l \s * = \s * / )
854857 timeout = getJsInfo ( x , / [ = , \s ] \s * t i m e o u t \s * = \s * / )
@@ -903,6 +906,7 @@ if (binaryInfo != null && binaryInfo.length > 0) {
903906 eventname,
904907 engine,
905908 jsenable,
909+ namePrefix : ! leadingTemplateIsNameOnly ? leadingTemplate ?. key || '' : '' ,
906910 ori : x ,
907911 num : y ,
908912 } )
@@ -1162,8 +1166,9 @@ if (binaryInfo != null && binaryInfo.length > 0) {
11621166 applySurgeArgumentsDesc ( loonSgArg , modInfoObj [ 'arguments-desc' ] )
11631167 for ( let i = 0 ; i < loonSgArg . length ; i ++ ) {
11641168 let key = argumentKeyRenameMap . get ( loonSgArg [ i ] . key ) || loonSgArg [ i ] . key
1165- let type = loonSgArg [ i ] . type
1166- let value = formatLoonArgumentValue ( loonSgArg [ i ] )
1169+ let isRuleToggle = surgeRuleToggleArgs . has ( loonSgArg [ i ] . key ) || surgeRuleToggleArgs . has ( key )
1170+ let type = isRuleToggle ? 'switch' : loonSgArg [ i ] . type
1171+ let value = formatLoonArgumentValue ( loonSgArg [ i ] , type , isRuleToggle )
11671172 let tag = loonSgArg [ i ] . tag
11681173 loonArg . push ( key + '=' + type + ',' + value + ',' + tag )
11691174 }
@@ -1537,6 +1542,9 @@ if (binaryInfo != null && binaryInfo.length > 0) {
15371542 cronexp = formatCronexp ( cronexp , targetApp )
15381543
15391544 jsname = reJsValue ( njsnametarget || 'null' , njsname , jsname , ori , jsname )
1545+ if ( isLooniOS && jsBox [ i ] . namePrefix && ! jsname . startsWith ( jsBox [ i ] . namePrefix ) ) {
1546+ jsname = jsBox [ i ] . namePrefix + jsname
1547+ }
15401548
15411549 timeout = reJsValue ( timeoutt || 'null' , timeoutv , jsname , ori , timeout )
15421550
@@ -2076,7 +2084,12 @@ function splitFirstTopLevel(str, sep) {
20762084function quoteIfNeeded ( str ) {
20772085 str = `${ str ?? '' } ` . trim ( )
20782086 if ( / ^ ' .* ' $ / . test ( str ) ) str = `"${ str . slice ( 1 , - 1 ) } "`
2079- return / , / . test ( str ) && ! / ^ " .* " $ / . test ( str ) ? `"${ str } "` : str
2087+ return / [ \s , ] / . test ( str ) && ! / ^ " .* " $ / . test ( str ) ? `"${ str } "` : str
2088+ }
2089+
2090+ function quoteLoonInputValue ( str ) {
2091+ str = stripWrapQuote ( `${ str ?? '' } ` . trim ( ) )
2092+ return `"${ str } "`
20802093}
20812094
20822095function getSwitchDefault ( value ) {
@@ -2086,17 +2099,27 @@ function getSwitchDefault(value) {
20862099 return / ^ t r u e $ / i. test ( value ) ? 'true' : 'false'
20872100}
20882101
2102+ function getToggleSwitchDefault ( value ) {
2103+ value = stripWrapQuote ( `${ value ?? '' } ` . trim ( ) )
2104+ . split ( ',' ) [ 0 ]
2105+ . trim ( )
2106+ return / ^ ( f a l s e | 0 | o f f | n o | # ) ? $ / i. test ( value ) ? 'false' : 'true'
2107+ }
2108+
20892109function getSurgeArgumentDefault ( item , isRuleToggle = false ) {
20902110 const value = `${ item . value ?? '' } ` . trim ( )
20912111 if ( isRuleToggle ) return getSwitchDefault ( value ) == 'true' ? '' : '#'
20922112 if ( item . type == 'switch' ) return getSwitchDefault ( value )
20932113 return quoteIfNeeded ( splitTopLevel ( value , ',' ) [ 0 ] || value )
20942114}
20952115
2096- function formatLoonArgumentValue ( item ) {
2116+ function formatLoonArgumentValue ( item , type = item . type , isRuleToggle = false ) {
20972117 const value = `${ item . value ?? '' } ` . trim ( )
2098- if ( item . type == 'switch' ) return getSwitchDefault ( value ) == 'true' ? 'true,false' : 'false,true'
2099- return quoteIfNeeded ( value )
2118+ if ( type == 'switch' ) {
2119+ const switchDefault = isRuleToggle ? getToggleSwitchDefault ( value ) : getSwitchDefault ( value )
2120+ return switchDefault == 'true' ? 'true,false' : 'false,true'
2121+ }
2122+ return quoteLoonInputValue ( value )
21002123}
21012124
21022125function isLoonArgumentList ( str ) {
@@ -2143,7 +2166,9 @@ function collectArgumentKeyRenameMap(box) {
21432166 for ( let i = 0 ; i < box . length ; i ++ ) {
21442167 if ( isJsonObjectArgument ( box [ i ] . jsarg ) ) {
21452168 formatLoonJsonArgument ( box [ i ] . jsarg )
2169+ continue
21462170 }
2171+ parseSurgeTemplateArgumentPairs ( box [ i ] . jsarg )
21472172 }
21482173}
21492174
@@ -2203,17 +2228,24 @@ function getSurgeTemplateArgumentKeys(str) {
22032228 . filter ( Boolean )
22042229}
22052230
2206- function getSurgeTemplateArgumentListKeys ( str ) {
2231+ function parseSurgeTemplateArgumentPairs ( str , renameMap = argumentKeyRenameMap ) {
22072232 str = stripWrapQuote ( str )
2208- if ( ! / \{ \{ \{ [ ^ { } ] + \} \} \} / . test ( str ) || ! / & / . test ( str ) ) return [ ]
2233+ if ( ! / \{ \{ \{ [ ^ { } ] + \} \} \} / . test ( str ) || ! / & / . test ( str ) && ! / ^ \s * [ ^ = \s ] + \s * = / . test ( str ) ) return [ ]
22092234 const items = splitTopLevel ( str , '&' )
2210- const keys = [ ]
2235+ const pairs = [ ]
22112236 for ( let i = 0 ; i < items . length ; i ++ ) {
2212- const matched = items [ i ] . match ( / ^ \s * ( [ ^ = \s ] + ) \s * = \s * " ? \{ \{ \{ ( [ ^ { } ] + ) \} \} \} " ? \s * $ / )
2237+ const matched = items [ i ] . match ( / ^ \s * ( [ ^ = \s ] + ) \s * = \s * [ " ' ] ? \{ \{ \{ ( [ ^ { } ] + ) \} \} \} [ " ' ] ? \s * $ / )
22132238 if ( ! matched ) return [ ]
2214- keys . push ( matched [ 2 ] . trim ( ) )
2239+ const scriptKey = matched [ 1 ] . trim ( )
2240+ const templateKey = matched [ 2 ] . trim ( )
2241+ if ( scriptKey && templateKey ) renameMap . set ( templateKey , scriptKey )
2242+ pairs . push ( { scriptKey, templateKey } )
22152243 }
2216- return keys
2244+ return pairs
2245+ }
2246+
2247+ function getSurgeTemplateArgumentListKeys ( str ) {
2248+ return parseSurgeTemplateArgumentPairs ( str ) . map ( item => item . scriptKey )
22172249}
22182250
22192251function normalizeScriptArgument ( jsarg , targetApp ) {
@@ -2301,6 +2333,26 @@ function escapeRegExp(str) {
23012333 return `${ str } ` . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' )
23022334}
23032335
2336+ function normalizeArgumentsDescLine ( str ) {
2337+ return `${ str ?? '' } `
2338+ . trim ( )
2339+ . replace ( / ^ [ \- * • ] + \s * / , '' )
2340+ . replace ( / ^ \d + \s * [ \. \) 、 ] \s * / , '' )
2341+ . replace ( / ^ [ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ] \s * / , '' )
2342+ }
2343+
2344+ function parseSurgeArgumentsDescLine ( str , keys = [ ] ) {
2345+ const line = normalizeArgumentsDescLine ( str )
2346+ if ( ! line ) return null
2347+ const keyPattern = keys . length > 0 ? keys . map ( escapeRegExp ) . join ( '|' ) : '[^::\\n]+'
2348+ const matched = line . match ( new RegExp ( `^(${ keyPattern } )\\s*[::]\\s*([\\s\\S]+)$` ) )
2349+ if ( ! matched ) return null
2350+ return {
2351+ key : matched [ 1 ] . trim ( ) ,
2352+ desc : matched [ 2 ] . trim ( ) ,
2353+ }
2354+ }
2355+
23042356function parseSurgeArgumentsDesc ( str , keys = [ ] ) {
23052357 str = `${ str ?? '' } ` . replace ( / \\ n / g, '\n' )
23062358 const map = { }
@@ -2314,6 +2366,12 @@ function parseSurgeArgumentsDesc(str, keys = []) {
23142366 const value = str . slice ( start , end ) . trim ( )
23152367 if ( key && value ) map [ key ] = value
23162368 }
2369+ str . split ( / \r ? \n / ) . forEach ( line => {
2370+ const parsed = parseSurgeArgumentsDescLine ( line , keys )
2371+ if ( parsed ?. key && parsed ?. desc && ! map [ parsed . key ] ) {
2372+ map [ parsed . key ] = parsed . desc
2373+ }
2374+ } )
23172375 return map
23182376}
23192377
0 commit comments