1
1
import assertNever from "assert-never" ;
2
2
import { debounce } from "lodash" ;
3
- import { CustomSelectorsForPattern } from "../../typings/StorageSchema" ;
3
+ import { CustomSelector } from "../../typings/StorageSchema" ;
4
4
import { notify } from "./notify" ;
5
5
import { withLockedStorageAccess } from "./withLockedStorageValue" ;
6
+ import { filterInPlace } from "./arrayUtils" ;
6
7
7
8
let notifySuccess = false ;
8
- const modifiedSelectors = new Set < string > ( ) ;
9
9
let batchUpdatePromise : Promise < void > | undefined ;
10
10
let batchUpdatePromiseResolve : ( ( ) => void ) | undefined ;
11
11
@@ -37,9 +37,8 @@ const debouncedNotifyAndReset = debounce(async (action: ActionType) => {
37
37
38
38
await notify ( message , { type } ) ;
39
39
40
- // Reset the success flag and clear the set after the debounce period.
40
+ // Reset the success flag after the debounce period.
41
41
notifySuccess = false ;
42
- modifiedSelectors . clear ( ) ;
43
42
44
43
if ( batchUpdatePromiseResolve ) {
45
44
batchUpdatePromiseResolve ( ) ;
@@ -50,35 +49,34 @@ const debouncedNotifyAndReset = debounce(async (action: ActionType) => {
50
49
51
50
async function updateCustomSelectors (
52
51
action : ActionType ,
53
- pattern : string ,
54
- selectors ?: CustomSelectorsForPattern
52
+ url : string ,
53
+ selectors ?: CustomSelector [ ]
55
54
) {
56
55
const selectorsAffected = await withLockedStorageAccess (
57
56
"customSelectors" ,
58
57
async ( customSelectors ) => {
59
- const selectorsForPattern = customSelectors . get ( pattern ) ?? {
60
- include : [ ] ,
61
- exclude : [ ] ,
62
- } ;
63
-
64
58
if ( action === "store" ) {
65
59
if ( ! selectors ) throw new Error ( "No selectors provided to store" ) ;
60
+ customSelectors . push ( ...selectors ) ;
66
61
67
- selectorsForPattern . include = Array . from (
68
- new Set ( [ ...selectorsForPattern . include , ...selectors . include ] )
69
- ) ;
70
- selectorsForPattern . exclude = Array . from (
71
- new Set ( [ ...selectorsForPattern . exclude , ...selectors . exclude ] )
72
- ) ;
73
- customSelectors . set ( pattern , selectorsForPattern ) ;
74
- return [ ...selectors . include , ...selectors . exclude ] ;
62
+ return selectors ;
75
63
}
76
64
77
65
if ( action === "reset" ) {
78
- customSelectors . delete ( pattern ) ;
79
- return selectorsForPattern
80
- ? [ ...selectorsForPattern . include , ...selectorsForPattern . exclude ]
81
- : [ ] ;
66
+ const selectorsForPattern =
67
+ customSelectors . filter ( ( { pattern } ) => {
68
+ const patternRe = new RegExp ( pattern ) ;
69
+ return patternRe . test ( url ) ;
70
+ } ) ?? [ ] ;
71
+
72
+ // We need to filter the array in place because assigning would just
73
+ // modify the argument.
74
+ filterInPlace ( customSelectors , ( { pattern } ) => {
75
+ const patternRe = new RegExp ( pattern ) ;
76
+ return ! patternRe . test ( url ) ;
77
+ } ) ;
78
+
79
+ return selectorsForPattern ?? [ ] ;
82
80
}
83
81
84
82
return assertNever ( action ) ;
@@ -88,10 +86,6 @@ async function updateCustomSelectors(
88
86
// Update notifySuccess to true if any of the calls within the debounce period is successful.
89
87
if ( selectorsAffected . length > 0 ) notifySuccess = true ;
90
88
91
- for ( const selector of selectorsAffected ) {
92
- modifiedSelectors . add ( selector ) ;
93
- }
94
-
95
89
await debouncedNotifyAndReset ( action ) ;
96
90
97
91
if ( batchUpdatePromise ) {
@@ -105,21 +99,21 @@ async function updateCustomSelectors(
105
99
}
106
100
107
101
/**
108
- * Stores the custom selectors for the given URL pattern . It handles being
102
+ * Stores the custom selectors for the given URL. It handles being
109
103
* called multiple times to handle multiple frames wanting to change the custom
110
104
* selectors. It waits for a sequence of calls to finish before returning. Once
111
105
* calls have stopped it notifies if storing the custom selectors was
112
106
* successful, that is if any of the calls in the sequence resulted in custom
113
107
* selectors being added.
114
108
*
115
- * @param pattern The URL pattern where selectors apply
116
- * @param selectors An object with `include` and `exclude` CSS selectors for the given pattern
109
+ * @param url The URL where selectors apply
110
+ * @param selectors The selectors to store for the URL
117
111
*/
118
112
export async function storeCustomSelectors (
119
- pattern : string ,
120
- selectors : CustomSelectorsForPattern
113
+ url : string ,
114
+ selectors : CustomSelector [ ]
121
115
) {
122
- await updateCustomSelectors ( "store" , pattern , selectors ) ;
116
+ await updateCustomSelectors ( "store" , url , selectors ) ;
123
117
}
124
118
125
119
/**
@@ -130,8 +124,8 @@ export async function storeCustomSelectors(
130
124
* successful, that is if any of the calls in the sequence resulted in custom
131
125
* selectors being removed.
132
126
*
133
- * @param pattern The URL pattern where selectors apply
127
+ * @param url The URL pattern where selectors apply
134
128
*/
135
- export async function resetCustomSelectors ( pattern : string ) {
136
- await updateCustomSelectors ( "reset" , pattern ) ;
129
+ export async function resetCustomSelectors ( url : string ) {
130
+ await updateCustomSelectors ( "reset" , url ) ;
137
131
}
0 commit comments