@@ -12,7 +12,7 @@ import { runScript, stopScript } from "../offscreen/client";
1212import { getRunAt } from "./utils" ;
1313import { isUserScriptsAvailable , randomMessageFlag } from "@App/pkg/utils/utils" ;
1414import { cacheInstance } from "@App/app/cache" ;
15- import { dealPatternMatches , UrlMatch } from "@App/pkg/utils/match" ;
15+ import { UrlMatch } from "@App/pkg/utils/match" ;
1616import { ExtensionContentMessageSend } from "@Packages/message/extension_message" ;
1717import { sendMessage } from "@Packages/message/client" ;
1818import { compileInjectScript , compileScriptCode } from "../content/utils" ;
@@ -22,26 +22,23 @@ import { type SystemConfig } from "@App/pkg/config/config";
2222import { type ResourceService } from "./resource" ;
2323import { LocalStorageDAO } from "@App/app/repo/localStorage" ;
2424import Logger from "@App/app/logger/logger" ;
25- import { getMetadataStr , getUserConfigStr } from "@App/pkg/utils/utils" ;
25+ import { getMetadataStr , getUserConfigStr , obtainBlackList } from "@App/pkg/utils/utils" ;
2626import type { GMInfoEnv } from "../content/types" ;
2727import { localePath } from "@App/locales/locales" ;
2828import { DocumentationSite } from "@App/app/const" ;
2929import { CACHE_KEY_REGISTRY_SCRIPT } from "@App/app/cache_key" ;
30-
31- const obtainBlackList = ( strBlacklist : string | null | undefined ) => {
32- const blacklist = strBlacklist
33- ? strBlacklist
34- . split ( "\n" )
35- . map ( ( item ) => item . trim ( ) )
36- . filter ( ( item ) => item )
37- : [ ] ;
38- return blacklist ;
39- } ;
30+ import {
31+ getApiMatchesAndGlobs ,
32+ extractUrlPatterns ,
33+ RuleType ,
34+ toUniquePatternStrings ,
35+ type URLRuleEntry ,
36+ } from "@App/pkg/utils/url_matcher" ;
4037
4138export class RuntimeService {
4239 scriptMatch : UrlMatch < string > = new UrlMatch < string > ( ) ;
4340 scriptCustomizeMatch : UrlMatch < string > = new UrlMatch < string > ( ) ;
44- blackMatch : UrlMatch < boolean > = new UrlMatch < boolean > ( ) ;
41+ blackMatch : UrlMatch < string > = new UrlMatch < string > ( ) ;
4542 scriptMatchCache : Map < string , ScriptMatchInfo > | null | undefined ;
4643
4744 logger : Logger ;
@@ -181,7 +178,8 @@ export class RuntimeService {
181178 // 监听脚本排序
182179 this . mq . subscribe < TSortScript > ( "sortScript" , async ( scripts ) => {
183180 const uuidSort = Object . fromEntries ( scripts . map ( ( { uuid, sort } ) => [ uuid , sort ] ) ) ;
184- this . scriptMatch . sort ( ( a , b ) => uuidSort [ a ] - uuidSort [ b ] ) ;
181+ this . scriptMatch . setupSorter ( uuidSort ) ;
182+ this . scriptCustomizeMatch . setupSorter ( uuidSort ) ;
185183 // 更新缓存
186184 const scriptMatchCache = await cacheInstance . get < { [ key : string ] : ScriptMatchInfo } > ( "scriptMatch" ) ;
187185 if ( ! scriptMatchCache ) {
@@ -272,15 +270,14 @@ export class RuntimeService {
272270 private loadBlacklist ( ) {
273271 // 设置黑名单match
274272 const blacklist = this . blacklist ; // 重用cache的blacklist阵列 (immutable)
275- const result = dealPatternMatches ( blacklist , {
276- exclude : true ,
277- } ) ;
278- this . blackMatch . forEach ( ( uuid ) => {
279- this . blackMatch . del ( uuid ) ;
280- } ) ;
281- result . result . forEach ( ( match ) => {
282- this . blackMatch . add ( match , true ) ;
283- } ) ;
273+
274+ const scriptUrlPatterns = extractUrlPatterns ( [ ...blacklist . map ( ( e ) => `@include ${ e } ` ) ] ) ;
275+ this . blackMatch . clearRules ( "BK" ) ;
276+ this . blackMatch . addRules ( "BK" , scriptUrlPatterns ) ;
277+ }
278+
279+ public isUrlBlacklist ( url : string ) {
280+ return this . blackMatch . urlMatch ( url ) [ 0 ] === "BK" ;
284281 }
285282
286283 // 取消脚本注册
@@ -412,10 +409,10 @@ export class RuntimeService {
412409 async getPageScriptUuidByUrl ( url : string , includeCustomize ?: boolean ) {
413410 await this . loadScriptMatchInfo ( ) ;
414411 // 匹配当前页面的脚本
415- let matchScriptUuid = this . scriptMatch . match ( url ! ) ;
412+ let matchScriptUuid = this . scriptMatch . urlMatch ( url ! ) ;
416413 // 包含自定义排除的脚本
417414 if ( includeCustomize ) {
418- const excludeScriptUuid = this . scriptCustomizeMatch . match ( url ! ) ;
415+ const excludeScriptUuid = this . scriptCustomizeMatch . urlMatch ( url ! ) ;
419416 // 自定义排除的脚本优化显示
420417 matchScriptUuid = [ ...new Set < string > ( [ ...excludeScriptUuid , ...matchScriptUuid ] ) ] ;
421418 }
@@ -432,12 +429,10 @@ export class RuntimeService {
432429 if ( ! this . isLoadScripts ) {
433430 return { flag : "" , scripts : [ ] } ;
434431 }
435-
436432 const chromeSender = sender . getSender ( ) as MessageSender ;
437433
438434 // 判断是否黑名单(针对网址,与个别脚本设定无关)
439- const isBlack = this . blackMatch . match ( chromeSender . url ! ) ;
440- if ( isBlack . length > 0 ) {
435+ if ( this . isUrlBlacklist ( chromeSender . url ! ) ) {
441436 // 如果在黑名单中, 则不加载脚本
442437 return { flag : "" , scripts : [ ] } ;
443438 }
@@ -608,13 +603,19 @@ export class RuntimeService {
608603 let messageFlag = await this . getMessageFlag ( ) ;
609604 if ( ! messageFlag ) {
610605 // 黑名单排除
606+
611607 const blacklist = this . blacklist ;
612608 const excludeMatches = [ ] ;
613- if ( blacklist . length ) {
614- const result = dealPatternMatches ( blacklist , {
615- exclude : true ,
616- } ) ;
617- excludeMatches . push ( ...result . patternResult ) ;
609+ const excludeGlobs = [ ] ;
610+ const rules = extractUrlPatterns ( [ ...blacklist . map ( ( e ) => `@include ${ e } ` ) ] ) ;
611+ for ( const rule of rules ) {
612+ if ( rule . ruleType === RuleType . MATCH_INCLUDE ) {
613+ // matches -> excludeMatches
614+ excludeMatches . push ( rule . patternString ) ;
615+ } else if ( rule . ruleType === RuleType . GLOB_INCLUDE ) {
616+ // includeGlobs -> excludeGlobs
617+ excludeGlobs . push ( rule . patternString ) ;
618+ }
618619 }
619620
620621 messageFlag = await this . getAndGenMessageFlag ( ) ;
@@ -634,6 +635,7 @@ export class RuntimeService {
634635 world : "MAIN" ,
635636 runAt : "document_start" ,
636637 excludeMatches,
638+ excludeGlobs,
637639 } ,
638640 // 注册content
639641 {
@@ -644,6 +646,7 @@ export class RuntimeService {
644646 runAt : "document_start" ,
645647 world : "USER_SCRIPT" ,
646648 excludeMatches,
649+ excludeGlobs,
647650 } ,
648651 ] ;
649652 try {
@@ -722,18 +725,13 @@ export class RuntimeService {
722725
723726 syncAddScriptMatch ( item : ScriptMatchInfo ) {
724727 // 清理一下老数据
725- this . scriptMatch . del ( item . uuid ) ;
726- this . scriptCustomizeMatch . del ( item . uuid ) ;
728+ this . scriptMatch . clearRules ( item . uuid ) ;
729+ this . scriptCustomizeMatch . clearRules ( item . uuid ) ;
727730 // 添加新的数据
728- item . matches . forEach ( ( match ) => {
729- this . scriptMatch . add ( match , item . uuid ) ;
730- } ) ;
731- item . excludeMatches . forEach ( ( match ) => {
732- this . scriptMatch . exclude ( match , item . uuid ) ;
733- } ) ;
734- item . customizeExcludeMatches . forEach ( ( match ) => {
735- this . scriptCustomizeMatch . add ( match , item . uuid ) ;
736- } ) ;
731+ this . scriptMatch . addRules ( item . uuid , item . scriptUrlPatterns ) ;
732+ if ( item . customUrlPatterns ?. length ) {
733+ this . scriptCustomizeMatch . addRules ( item . uuid , item . customUrlPatterns ! ) ;
734+ }
737735 }
738736
739737 async updateScriptStatus ( uuid : string , status : SCRIPT_STATUS ) {
@@ -752,76 +750,74 @@ export class RuntimeService {
752750 await this . loadScriptMatchInfo ( ) ;
753751 }
754752 this . scriptMatchCache ! . delete ( uuid ) ;
755- this . scriptMatch . del ( uuid ) ;
756- this . scriptCustomizeMatch . del ( uuid ) ;
753+ this . scriptMatch . clearRules ( uuid ) ;
754+ this . scriptCustomizeMatch . clearRules ( uuid ) ;
757755 this . saveScriptMatchInfo ( ) ;
758756 }
759757
760758 // 构建userScript注册信息
761759 async getAndSetUserScriptRegister ( script : Script ) {
762760 const scriptRes = await this . script . buildScriptRunResource ( script ) ;
763- // concat 浅拷贝是为了避免修改原数组
764- const matches = ( scriptRes . metadata [ "match" ] || [ ] ) . concat ( ) ;
765- matches . push ( ... ( scriptRes . metadata [ "include" ] || [ ] ) ) ;
766- if ( ! matches . length ) {
761+ const metaMatch = scriptRes . metadata [ "match" ] ;
762+ const metaInclude = scriptRes . metadata [ "include" ] ;
763+ const metaExclude = scriptRes . metadata [ "exclude" ] ;
764+ if ( ( metaMatch ? .length ?? 0 ) + ( metaInclude ?. length ?? 0 ) === 0 ) {
767765 return undefined ;
768766 }
769767
768+ // 黑名单排除
769+ const strBlacklist = ( await this . systemConfig . getBlacklist ( ) ) as string | undefined ;
770+ const blacklist = obtainBlackList ( strBlacklist ) ;
771+
772+ const scriptUrlPatterns = extractUrlPatterns ( [
773+ ...( metaMatch || [ ] ) . map ( ( e ) => `@match ${ e } ` ) ,
774+ ...( metaInclude || [ ] ) . map ( ( e ) => `@include ${ e } ` ) ,
775+ ...( metaExclude || [ ] ) . map ( ( e ) => `@exclude ${ e } ` ) ,
776+ ...( blacklist || [ ] ) . map ( ( e ) => `@exclude ${ e } ` ) ,
777+ ] ) ;
778+
779+ let customUrlPatterns : URLRuleEntry [ ] | null = null ;
780+
781+ // 自定义排除
782+ if ( script . selfMetadata && script . selfMetadata . exclude ) {
783+ customUrlPatterns = extractUrlPatterns ( [ ...( script . selfMetadata . exclude || [ ] ) . map ( ( e ) => `@exclude ${ e } ` ) ] ) ;
784+ if ( customUrlPatterns . length === 0 ) customUrlPatterns = null ;
785+ }
786+
770787 scriptRes . code = compileInjectScript ( scriptRes , scriptRes . code ) ;
771788
772- const patternMatches = dealPatternMatches ( matches ) ;
773- const scriptMatchInfo : ScriptMatchInfo = Object . assign (
774- { matches : patternMatches . result , excludeMatches : [ ] , customizeExcludeMatches : [ ] } ,
775- scriptRes
789+ const { matches , includeGlobs } = getApiMatchesAndGlobs ( scriptUrlPatterns ) ;
790+
791+ const excludeMatches = toUniquePatternStrings (
792+ scriptUrlPatterns . filter ( ( e ) => e . ruleType === RuleType . MATCH_EXCLUDE )
776793 ) ;
794+ const excludeGlobs = toUniquePatternStrings ( scriptUrlPatterns . filter ( ( e ) => e . ruleType === RuleType . GLOB_EXCLUDE ) ) ;
777795
778796 const registerScript : chrome . userScripts . RegisteredUserScript = {
779797 id : scriptRes . uuid ,
780798 js : [ { code : scriptRes . code } ] ,
781- matches : patternMatches . patternResult ,
799+ matches : matches , // primary
800+ includeGlobs : includeGlobs , // includeGlobs applied after matches
801+ excludeMatches : excludeMatches ,
802+ excludeGlobs : excludeGlobs ,
782803 allFrames : ! scriptRes . metadata [ "noframes" ] ,
783804 world : "MAIN" ,
784- excludeMatches : [ ] ,
785805 } ;
786806
787- // 排除由loadPage时决定, 不使用userScript的excludeMatches处理
788- if ( script . metadata [ "exclude" ] ) {
789- // concat 浅拷贝是为了避免修改原数组
790- const excludeMatches = script . metadata [ "exclude" ] . concat ( ) ;
791- const result = dealPatternMatches ( excludeMatches , {
792- exclude : true ,
793- } ) ;
794-
795- // registerScript.excludeMatches = result.patternResult;
796- scriptMatchInfo . excludeMatches = result . result ;
797- }
798- // 自定义排除
799- if ( script . selfMetadata && script . selfMetadata . exclude ) {
800- const excludeMatches = script . selfMetadata . exclude ;
801- const result = dealPatternMatches ( excludeMatches , {
802- exclude : true ,
803- } ) ;
804-
805- // registerScript.excludeMatches.push(...result.patternResult);
806- scriptMatchInfo . customizeExcludeMatches = result . result ;
807+ if ( scriptRes . metadata [ "run-at" ] ) {
808+ registerScript . runAt = getRunAt ( scriptRes . metadata [ "run-at" ] ) ;
807809 }
808810
809- // 黑名单排除
810- const blacklist = this . blacklist ;
811- if ( blacklist . length ) {
812- const result = dealPatternMatches ( blacklist , {
813- exclude : true ,
814- } ) ;
815- // scriptMatchInfo.excludeMatches.push(...result.result);
816- registerScript . excludeMatches ! . push ( ...result . patternResult ) ;
817- }
811+ const scriptMatchInfo = Object . assign (
812+ {
813+ scriptUrlPatterns : scriptUrlPatterns ,
814+ customUrlPatterns : customUrlPatterns ,
815+ } ,
816+ scriptRes
817+ ) as ScriptMatchInfo ;
818818
819819 // 将脚本match信息放入缓存中
820- await this . addScriptMatch ( scriptMatchInfo ) ;
821-
822- if ( scriptRes . metadata [ "run-at" ] ) {
823- registerScript . runAt = getRunAt ( scriptRes . metadata [ "run-at" ] ) ;
824- }
820+ this . addScriptMatch ( scriptMatchInfo ) ;
825821
826822 return {
827823 scriptMatchInfo,
0 commit comments