billy-herrington-utils 1.5.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/billy-herrington-utils.es.js +5907 -327
- package/dist/billy-herrington-utils.es.js.map +1 -1
- package/dist/billy-herrington-utils.umd.js +5911 -331
- package/dist/billy-herrington-utils.umd.js.map +1 -1
- package/dist/index.d.ts +110 -103
- package/package.json +7 -5
- package/src/index.ts +18 -5
- package/src/types/globals.d.ts +0 -2
- package/src/userscripts/data-manager/data-filter.ts +110 -0
- package/src/userscripts/data-manager/index.ts +77 -174
- package/src/userscripts/infinite-scroll/index.ts +72 -71
- package/src/userscripts/pagination-parsing/index.ts +21 -29
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategy.ts +4 -12
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategyDataParams.ts +11 -2
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategyPathnameParams.ts +29 -2
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategySearchParams.ts +15 -7
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategyTrash.ts +9 -12
- package/src/userscripts/pagination-parsing/pagination-strategies/index.ts +1 -1
- package/src/userscripts/pagination-parsing/pagination-utils/index.ts +36 -7
- package/src/userscripts/router/router.ts +71 -0
- package/src/userscripts/rules/index.ts +227 -3
- package/src/userscripts/types/index.ts +19 -0
- package/src/utils/arrays/index.ts +3 -1
- package/src/utils/async/index.ts +22 -6
- package/src/utils/dom/index.ts +35 -68
- package/src/utils/dom/observers.ts +76 -0
- package/src/utils/events/index.ts +9 -2
- package/src/utils/fetch/index.ts +14 -7
- package/src/utils/objects/index.ts +25 -0
- package/src/utils/observers/index.ts +8 -2
- package/src/utils/parsers/index.ts +18 -11
- package/src/utils/strings/index.ts +5 -5
- package/src/utils/strings/regexes.ts +31 -0
- package/src/utils/userscript/index.ts +10 -0
- package/src/userscripts/jabroni-outfit-wrap/index.ts +0 -40
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { JabronioGUI } from 'jabroni-outfit';
|
|
2
|
+
import { JabronioStore } from 'jabroni-outfit';
|
|
3
|
+
import { JabroniTypes } from 'jabroni-outfit';
|
|
4
|
+
import { setupScheme } from 'jabroni-outfit';
|
|
5
|
+
import { StoreState } from 'jabroni-outfit';
|
|
6
|
+
|
|
1
7
|
export declare class AsyncPool {
|
|
2
8
|
private max;
|
|
3
9
|
private pool;
|
|
@@ -24,40 +30,29 @@ export declare function circularShift(n: number, c?: number, s?: number): number
|
|
|
24
30
|
|
|
25
31
|
export declare function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>): Promise<void[]>;
|
|
26
32
|
|
|
27
|
-
export declare function copyAttributes(target: HTMLElement
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
filterDuration: boolean;
|
|
36
|
-
filterDurationFrom: number;
|
|
37
|
-
filterDurationTo: number;
|
|
38
|
-
filterExclude: boolean;
|
|
39
|
-
filterExcludeWords: string;
|
|
40
|
-
filterInclude: boolean;
|
|
41
|
-
filterIncludeWords: string;
|
|
42
|
-
}
|
|
33
|
+
export declare function copyAttributes(target: HTMLElement, source: HTMLElement): void;
|
|
34
|
+
|
|
35
|
+
declare type CustomSelector<R> = {
|
|
36
|
+
handle: (el: DataElement, state: StoreState, $preDefineResult?: R) => boolean;
|
|
37
|
+
$preDefine?: (state: StoreState) => R;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
declare type DataElement = Record<string, string | number | boolean | HTMLElement>;
|
|
43
41
|
|
|
44
42
|
export declare class DataManager {
|
|
45
43
|
private rules;
|
|
46
44
|
private state;
|
|
47
45
|
private data;
|
|
48
46
|
private lazyImgLoader;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
constructor(rules: IRules, state: DataFilterState);
|
|
53
|
-
static filterDSLToRegex(str: string): RegExp[];
|
|
47
|
+
private dataFilter;
|
|
48
|
+
constructor(rules: RulesGlobal, state: StoreState);
|
|
54
49
|
isFiltered(el: HTMLElement): boolean;
|
|
55
|
-
applyFilters: (filters
|
|
50
|
+
applyFilters: (filters?: {
|
|
56
51
|
[key: string]: boolean;
|
|
57
52
|
}, offset?: number) => void;
|
|
58
53
|
filterAll: (offset?: number) => void;
|
|
59
54
|
parseData: (html: HTMLElement, container?: HTMLElement, removeDuplicates?: boolean, shouldLazify?: boolean) => void;
|
|
60
|
-
|
|
55
|
+
sortBy<K extends keyof DataElement>(key: K): void;
|
|
61
56
|
}
|
|
62
57
|
|
|
63
58
|
export declare function downloader(options?: {
|
|
@@ -73,117 +68,70 @@ export declare const fetchHtml: (url: string) => Promise<HTMLElement>;
|
|
|
73
68
|
|
|
74
69
|
export declare const fetchText: (url: string) => Promise<string>;
|
|
75
70
|
|
|
76
|
-
export declare function fetchWith(url: string, options?:
|
|
71
|
+
export declare function fetchWith(url: string, options?: {
|
|
72
|
+
html?: boolean;
|
|
73
|
+
mobile?: boolean;
|
|
74
|
+
}): Promise<string | HTMLElement>;
|
|
77
75
|
|
|
78
|
-
declare
|
|
76
|
+
export declare function findNextSibling(el: HTMLElement): Element | null;
|
|
79
77
|
|
|
80
|
-
declare type
|
|
81
|
-
|
|
82
|
-
declare interface FilterResult {
|
|
83
|
-
tag: string;
|
|
84
|
-
condition: boolean;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export declare function findNextSibling(el: HTMLElement | Element): Element | null;
|
|
88
|
-
|
|
89
|
-
declare interface GeneratorResult {
|
|
78
|
+
declare type GeneratorResult = {
|
|
90
79
|
url: string;
|
|
91
80
|
offset: number;
|
|
92
|
-
}
|
|
81
|
+
};
|
|
93
82
|
|
|
94
|
-
export declare function getAllUniqueParents(elements: HTMLCollection):
|
|
83
|
+
export declare function getAllUniqueParents(elements: HTMLCollection | HTMLElement[]): HTMLElement[];
|
|
95
84
|
|
|
96
|
-
export declare function getPaginationStrategy(options:
|
|
97
|
-
|
|
98
|
-
declare interface IInfiniteScroller {
|
|
99
|
-
delay?: number;
|
|
100
|
-
enabled?: boolean;
|
|
101
|
-
writeHistory?: boolean;
|
|
102
|
-
paginationOffset: number;
|
|
103
|
-
paginationLast: number;
|
|
104
|
-
paginationElement: HTMLElement;
|
|
105
|
-
paginationUrlGenerator: (offset: number) => string;
|
|
106
|
-
parseData: (document: HTMLElement) => void;
|
|
107
|
-
intersectionObservable?: HTMLElement;
|
|
108
|
-
alternativeGenerator?: () => OffsetGenerator;
|
|
109
|
-
}
|
|
85
|
+
export declare function getPaginationStrategy(options: Partial<PaginationStrategy>): PaginationStrategy;
|
|
110
86
|
|
|
111
87
|
export declare class InfiniteScroller {
|
|
112
|
-
paginationGenerator: OffsetGenerator;
|
|
113
88
|
enabled: boolean;
|
|
114
89
|
delay: number;
|
|
115
90
|
paginationOffset: number;
|
|
116
|
-
paginationLast: number;
|
|
117
91
|
writeHistory: boolean;
|
|
118
|
-
|
|
119
|
-
|
|
92
|
+
parseData?: (document: HTMLElement) => void;
|
|
93
|
+
rules: RulesGlobal;
|
|
94
|
+
private observer?;
|
|
95
|
+
private paginationGenerator;
|
|
96
|
+
constructor(options: InfiniteScrollerOptions);
|
|
97
|
+
dispose(): void;
|
|
98
|
+
setObserver(observable: HTMLElement): this;
|
|
120
99
|
private onScrollCBs;
|
|
121
100
|
onScroll(callback: (scroller: InfiniteScroller) => void, initCall?: boolean): this;
|
|
122
101
|
private _onScroll;
|
|
123
102
|
generatorConsumer: () => Promise<boolean>;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
declare interface IPaginationStrategy {
|
|
128
|
-
url?: URL | Location | string;
|
|
129
|
-
doc?: Document | HTMLElement;
|
|
130
|
-
paginationSelector?: string;
|
|
131
|
-
fixPaginationLast?: (n: number, offset?: number) => number;
|
|
132
|
-
pathnameSelector?: RegExp;
|
|
133
|
-
searchParamSelector?: string;
|
|
134
|
-
offsetMin?: number;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
declare interface IRules {
|
|
138
|
-
getThumbs: (html: HTMLElement) => HTMLElement[];
|
|
139
|
-
getThumbUrl: (thumbElement: HTMLElement) => string;
|
|
140
|
-
getThumbData: (thumbElement: HTMLElement) => {
|
|
141
|
-
title: string;
|
|
142
|
-
duration: number;
|
|
143
|
-
};
|
|
144
|
-
getThumbImgData: (thumbElement: HTMLElement) => {
|
|
145
|
-
img: HTMLElement;
|
|
146
|
-
imgSrc: string;
|
|
147
|
-
};
|
|
148
|
-
container: HTMLElement;
|
|
149
|
-
isPrivate: (element: HTMLElement) => boolean;
|
|
150
|
-
isHD: (element: HTMLElement) => boolean;
|
|
103
|
+
doScroll(url: string, offset: number): Promise<void>;
|
|
104
|
+
private createPaginationGenerator;
|
|
105
|
+
static create(store: JabronioStore, rules: RulesGlobal, parseData: (document: HTMLElement) => void): InfiniteScroller;
|
|
151
106
|
}
|
|
152
107
|
|
|
153
|
-
declare
|
|
154
|
-
paginationStrategy: PaginationStrategy;
|
|
155
|
-
delay?: number;
|
|
156
|
-
}
|
|
108
|
+
declare type InfiniteScrollerOptions = Pick<InfiniteScroller, 'rules'> & Partial<InfiniteScroller>;
|
|
157
109
|
|
|
158
110
|
export declare function isMob(): boolean;
|
|
159
111
|
|
|
160
|
-
declare interface JabroniStore {
|
|
161
|
-
state: Record<string, boolean | string | number>;
|
|
162
|
-
localState: Record<string, boolean | string | number>;
|
|
163
|
-
subscribe: (callback: () => void) => void;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
112
|
export declare class LazyImgLoader {
|
|
167
113
|
lazyImgObserver: Observer;
|
|
168
114
|
private attributeName;
|
|
169
115
|
constructor(shouldDelazify: (target: Element) => boolean);
|
|
170
|
-
lazify(_target: Element, img
|
|
116
|
+
lazify(_target: Element, img?: HTMLImageElement, imgSrc?: string): void;
|
|
171
117
|
delazify: (target: HTMLImageElement) => void;
|
|
172
118
|
}
|
|
173
119
|
|
|
174
|
-
export declare function listenEvents(dom: HTMLElement
|
|
120
|
+
export declare function listenEvents(dom: HTMLElement, events: Array<string>, callback: (e: Event) => void): void;
|
|
175
121
|
|
|
176
122
|
export declare const MOBILE_UA: string;
|
|
177
123
|
|
|
178
|
-
export declare function objectToFormData
|
|
124
|
+
export declare function objectToFormData<T extends {}>(obj: T): FormData;
|
|
179
125
|
|
|
180
126
|
export declare class Observer {
|
|
181
127
|
private callback;
|
|
182
128
|
observer: IntersectionObserver;
|
|
129
|
+
private timeout;
|
|
183
130
|
constructor(callback: (entry: Element) => void);
|
|
184
131
|
observe(target: Element): void;
|
|
185
132
|
throttle(target: Element, throttleTime: number): void;
|
|
186
133
|
handleIntersection(entries: Iterable<IntersectionObserverEntry>): void;
|
|
134
|
+
dispose(): void;
|
|
187
135
|
static observeWhile(target: Element, callback: () => Promise<boolean> | boolean, throttleTime: number): Observer;
|
|
188
136
|
}
|
|
189
137
|
|
|
@@ -194,11 +142,13 @@ export declare class PaginationStrategy {
|
|
|
194
142
|
url: URL;
|
|
195
143
|
paginationSelector: string;
|
|
196
144
|
searchParamSelector: string;
|
|
145
|
+
static _pathnameSelector: RegExp;
|
|
197
146
|
pathnameSelector: RegExp;
|
|
147
|
+
dataparamSelector: string;
|
|
198
148
|
fixPaginationLast?: (n: number, offset?: number) => number;
|
|
199
149
|
offsetMin: number;
|
|
200
|
-
constructor(options?:
|
|
201
|
-
getPaginationElement():
|
|
150
|
+
constructor(options?: Partial<PaginationStrategy>);
|
|
151
|
+
getPaginationElement(): HTMLElement | null;
|
|
202
152
|
get hasPagination(): boolean;
|
|
203
153
|
getPaginationOffset(): number;
|
|
204
154
|
getPaginationLast(): number;
|
|
@@ -209,10 +159,13 @@ export declare class PaginationStrategyDataParams extends PaginationStrategy {
|
|
|
209
159
|
getPaginationLast(): number;
|
|
210
160
|
getPaginationOffset(): number;
|
|
211
161
|
getPaginationUrlGenerator(): (n: number) => string;
|
|
162
|
+
static testLinks(doc?: HTMLElement | Document): boolean;
|
|
212
163
|
}
|
|
213
164
|
|
|
214
165
|
export declare class PaginationStrategyPathnameParams extends PaginationStrategy {
|
|
215
166
|
extractPage: (a: HTMLAnchorElement | Location | string) => number;
|
|
167
|
+
static checkLink(link: URL, pathnameSelector?: RegExp): boolean;
|
|
168
|
+
static testLinks(links: URL[], options: Partial<PaginationStrategy>): boolean;
|
|
216
169
|
getPaginationLast(): number;
|
|
217
170
|
getPaginationOffset(): number;
|
|
218
171
|
getPaginationUrlGenerator(url_?: URL): (offset: number) => string;
|
|
@@ -220,10 +173,11 @@ export declare class PaginationStrategyPathnameParams extends PaginationStrategy
|
|
|
220
173
|
|
|
221
174
|
export declare class PaginationStrategySearchParams extends PaginationStrategy {
|
|
222
175
|
extractPage: (a: HTMLAnchorElement | Location | URL | string) => number;
|
|
223
|
-
static checkLink(link: URL, searchParamSelector?: string): boolean;
|
|
224
176
|
getPaginationLast(): number;
|
|
225
177
|
getPaginationOffset(): number;
|
|
226
178
|
getPaginationUrlGenerator(): (offset: number) => string;
|
|
179
|
+
static checkLink(link: URL, searchParamSelector?: string): boolean;
|
|
180
|
+
static testLinks(links: URL[], searchParamSelector?: string): boolean;
|
|
227
181
|
}
|
|
228
182
|
|
|
229
183
|
export declare function parseCSSUrl(s: string): string;
|
|
@@ -234,13 +188,64 @@ export declare function parseDom(html: string): HTMLElement;
|
|
|
234
188
|
|
|
235
189
|
export declare function parseIntegerOr(n: string | number, or: number): number;
|
|
236
190
|
|
|
191
|
+
export declare function querySelectorText(el: HTMLElement, selector?: string): string;
|
|
192
|
+
|
|
237
193
|
export declare function range(size: number, startAt?: number, step?: number): number[];
|
|
238
194
|
|
|
239
|
-
export declare function replaceElementTag(e: HTMLElement
|
|
195
|
+
export declare function replaceElementTag(e: HTMLElement, tagName: string): HTMLElement;
|
|
196
|
+
|
|
197
|
+
export declare class RulesGlobal {
|
|
198
|
+
delay?: number;
|
|
199
|
+
alternativeGenerator?: () => OffsetGenerator;
|
|
200
|
+
getThumbUrl(thumb: HTMLElement | HTMLAnchorElement): string;
|
|
201
|
+
titleSelector: undefined | string;
|
|
202
|
+
uploaderSelector: undefined | string;
|
|
203
|
+
durationSelector: undefined | string;
|
|
204
|
+
getThumbDataStrategy: 'default' | 'auto-select' | 'auto-text';
|
|
205
|
+
getThumbDataCallback?: (thumb: HTMLElement, thumbData: ThumbData) => void;
|
|
206
|
+
getThumbData(thumb: HTMLElement): ThumbData;
|
|
207
|
+
getThumbImgDataAttrSelector: string | undefined;
|
|
208
|
+
getThumbImgDataStrategy: 'default' | 'auto';
|
|
209
|
+
getThumbImgData(thumb: HTMLElement): {
|
|
210
|
+
img?: HTMLImageElement;
|
|
211
|
+
imgSrc?: string;
|
|
212
|
+
};
|
|
213
|
+
containerSelector: string | (() => HTMLElement);
|
|
214
|
+
intersectionObservable?: HTMLElement;
|
|
215
|
+
get container(): HTMLElement;
|
|
216
|
+
thumbsSelector: string;
|
|
217
|
+
getThumbsStrategy: 'default' | 'auto';
|
|
218
|
+
getThumbs(html: HTMLElement): HTMLElement[];
|
|
219
|
+
paginationStrategy: PaginationStrategy;
|
|
220
|
+
get observable(): HTMLElement;
|
|
221
|
+
mutationObservers: MutationObserver[];
|
|
222
|
+
reset(): void;
|
|
223
|
+
resetOnPaginationOrContainerDeath: boolean;
|
|
224
|
+
resetOn(): void;
|
|
225
|
+
customSelectors: Record<string, CustomSelector<any>>;
|
|
226
|
+
animatePreview?: (doc?: HTMLElement) => void;
|
|
227
|
+
storeOptions?: JabroniTypes.StoreStateOptions;
|
|
228
|
+
customScheme?: JabroniTypes.SchemeInput;
|
|
229
|
+
defaultSchemeOptions: Parameters<typeof setupScheme>[0];
|
|
230
|
+
store: JabronioStore;
|
|
231
|
+
scheme: JabroniTypes.SchemeInput;
|
|
232
|
+
gui: JabronioGUI;
|
|
233
|
+
dataManager: DataManager;
|
|
234
|
+
infiniteScroller: InfiniteScroller;
|
|
235
|
+
private resetInfiniteScroller;
|
|
236
|
+
initialGrope: 'all-in-one' | 'all-in-all' | undefined;
|
|
237
|
+
gropeInit(): void;
|
|
238
|
+
constructor();
|
|
239
|
+
}
|
|
240
240
|
|
|
241
241
|
export declare function sanitizeStr(s: string): string;
|
|
242
242
|
|
|
243
|
-
export declare function
|
|
243
|
+
export declare function splitWith(s: string, c?: string): Array<string>;
|
|
244
|
+
|
|
245
|
+
declare type ThumbData = {
|
|
246
|
+
title: string;
|
|
247
|
+
duration?: number;
|
|
248
|
+
};
|
|
244
249
|
|
|
245
250
|
export declare class Tick {
|
|
246
251
|
private delay;
|
|
@@ -256,10 +261,12 @@ export declare function timeToSeconds(t: string): number;
|
|
|
256
261
|
|
|
257
262
|
export declare function wait(milliseconds: number): Promise<unknown>;
|
|
258
263
|
|
|
259
|
-
export declare function
|
|
264
|
+
export declare function waitForElementToAppear(parent: HTMLElement, selector: string, callback: (el: Element) => void): MutationObserver;
|
|
265
|
+
|
|
266
|
+
export declare function waitForElementToDisappear(observable: HTMLElement, callback: () => void): MutationObserver;
|
|
260
267
|
|
|
261
|
-
export declare function watchDomChangesWithThrottle(element: HTMLElement
|
|
268
|
+
export declare function watchDomChangesWithThrottle(element: HTMLElement, callback: () => void, throttle?: number, times?: number, options?: MutationObserverInit): MutationObserver;
|
|
262
269
|
|
|
263
|
-
export declare function watchElementChildrenCount(element: HTMLElement
|
|
270
|
+
export declare function watchElementChildrenCount(element: HTMLElement, callback: (observer: MutationObserver, count: number) => void): MutationObserver;
|
|
264
271
|
|
|
265
272
|
export { }
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "billy-herrington-utils",
|
|
3
3
|
"description": "daddy told us not to be ashamed of our utils",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"utils",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"unpkg": "dist/billy-herrington-utils.es.js",
|
|
27
27
|
"exports": {
|
|
28
28
|
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
29
30
|
"import": "./dist/billy-herrington-utils.es.js",
|
|
30
|
-
"require": "./dist/billy-herrington-utils.umd.js"
|
|
31
|
-
"types": "./dist/index.d.ts"
|
|
31
|
+
"require": "./dist/billy-herrington-utils.umd.js"
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
@@ -41,8 +41,10 @@
|
|
|
41
41
|
"preview": "vite preview"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
+
"@types/tampermonkey": "^5.0.5",
|
|
45
|
+
"jabroni-outfit": "^2.0.92",
|
|
44
46
|
"typescript": "^5.5.3",
|
|
45
|
-
"vite": "^
|
|
47
|
+
"vite": "^6.4.1",
|
|
46
48
|
"vite-plugin-dts": "^4.0.3"
|
|
47
49
|
}
|
|
48
|
-
}
|
|
50
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { DataManager } from './userscripts/data-manager';
|
|
2
2
|
export { InfiniteScroller } from './userscripts/infinite-scroll';
|
|
3
|
-
export { createInfiniteScroller } from './userscripts/jabroni-outfit-wrap';
|
|
4
3
|
export { getPaginationStrategy } from './userscripts/pagination-parsing';
|
|
5
4
|
export {
|
|
6
5
|
PaginationStrategy,
|
|
@@ -8,6 +7,7 @@ export {
|
|
|
8
7
|
PaginationStrategyPathnameParams,
|
|
9
8
|
PaginationStrategySearchParams,
|
|
10
9
|
} from './userscripts/pagination-parsing/pagination-strategies';
|
|
10
|
+
export { RulesGlobal } from './userscripts/rules';
|
|
11
11
|
export { chunks, range } from './utils/arrays';
|
|
12
12
|
export { AsyncPool, computeAsyncOneAtTime, wait } from './utils/async';
|
|
13
13
|
export { isMob } from './utils/device';
|
|
@@ -18,14 +18,27 @@ export {
|
|
|
18
18
|
findNextSibling,
|
|
19
19
|
getAllUniqueParents,
|
|
20
20
|
parseDom,
|
|
21
|
+
querySelectorText,
|
|
21
22
|
replaceElementTag,
|
|
22
|
-
|
|
23
|
+
waitForElementToAppear,
|
|
24
|
+
waitForElementToDisappear,
|
|
23
25
|
watchDomChangesWithThrottle,
|
|
24
26
|
watchElementChildrenCount,
|
|
25
27
|
} from './utils/dom';
|
|
26
28
|
export { listenEvents, Tick } from './utils/events';
|
|
27
|
-
export {
|
|
29
|
+
export {
|
|
30
|
+
fetchHtml,
|
|
31
|
+
fetchText,
|
|
32
|
+
fetchWith,
|
|
33
|
+
MOBILE_UA,
|
|
34
|
+
objectToFormData,
|
|
35
|
+
} from './utils/fetch';
|
|
28
36
|
export { circularShift } from './utils/math';
|
|
29
37
|
export { LazyImgLoader, Observer } from './utils/observers';
|
|
30
|
-
export {
|
|
31
|
-
|
|
38
|
+
export {
|
|
39
|
+
parseCSSUrl,
|
|
40
|
+
parseDataParams,
|
|
41
|
+
parseIntegerOr,
|
|
42
|
+
timeToSeconds,
|
|
43
|
+
} from './utils/parsers';
|
|
44
|
+
export { sanitizeStr, splitWith } from './utils/strings';
|
package/src/types/globals.d.ts
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { StoreState } from 'jabroni-outfit';
|
|
2
|
+
import { RegexFilter } from '../../utils/strings/regexes';
|
|
3
|
+
import type { RulesGlobal } from '../rules';
|
|
4
|
+
import type { DataElement } from '.';
|
|
5
|
+
|
|
6
|
+
export type CustomSelector<R> = {
|
|
7
|
+
handle: (el: DataElement, state: StoreState, $preDefineResult?: R) => boolean;
|
|
8
|
+
$preDefine?: (state: StoreState) => R;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
interface FilterResult {
|
|
12
|
+
tag: string;
|
|
13
|
+
condition: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type FilterFunction = (v: DataElement) => FilterResult;
|
|
17
|
+
|
|
18
|
+
export class DataFilter {
|
|
19
|
+
public filters = new Map<string, () => FilterFunction>();
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private rules: RulesGlobal,
|
|
23
|
+
private state: StoreState,
|
|
24
|
+
) {
|
|
25
|
+
this.registerFilters(DataFilter.customFiltersDefault);
|
|
26
|
+
this.registerFilters(rules.customSelectors);
|
|
27
|
+
this.applyCSSFilters();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public applyCSSFilters() {
|
|
31
|
+
Object.keys(this.filters).forEach((name) => {
|
|
32
|
+
const className = `.filter-${name.toLowerCase().slice(6)}`;
|
|
33
|
+
GM_addStyle(`${className} { display: none !important; content-visibility: auto; }`);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public registerFilters(customFilters: Record<string, CustomSelector<any>>) {
|
|
38
|
+
Object.entries(customFilters).forEach(([k, v]) => {
|
|
39
|
+
if (!Object.hasOwn(this.rules.customSelectors, k)) {
|
|
40
|
+
this.rules.customSelectors[k] = v;
|
|
41
|
+
}
|
|
42
|
+
this.registerFilter(k);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public registerFilter(CustomSelectorName: string) {
|
|
47
|
+
const handler = this.rules.customSelectors[CustomSelectorName];
|
|
48
|
+
|
|
49
|
+
const fn = (): FilterFunction => {
|
|
50
|
+
const preDefined = handler.$preDefine?.(this.state);
|
|
51
|
+
|
|
52
|
+
return (v: DataElement) => {
|
|
53
|
+
const result = handler.handle(v, this.state, preDefined);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
condition: result,
|
|
57
|
+
tag: `filter-${CustomSelectorName}`,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
this.filters.set(CustomSelectorName, fn);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static customFiltersDefault: Record<string, CustomSelector<any>> = {
|
|
66
|
+
isPrivate: {
|
|
67
|
+
handle(el, state) {
|
|
68
|
+
const isPrivate = !!(el.element as HTMLElement).querySelector('.private');
|
|
69
|
+
return (state.filterPrivate as boolean) && isPrivate;
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
isPublic: {
|
|
73
|
+
handle(el, state) {
|
|
74
|
+
const isPublic = !!(el.element as HTMLElement).querySelector('.public');
|
|
75
|
+
return (state.filterPublic as boolean) && isPublic;
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
filterDuration: {
|
|
79
|
+
handle(el, state, preDefined) {
|
|
80
|
+
const d = el.duration as number;
|
|
81
|
+
const notInRange = d < (preDefined.from as number) || d > (preDefined.to as number);
|
|
82
|
+
return (state.filterDuration as boolean) && notInRange;
|
|
83
|
+
},
|
|
84
|
+
$preDefine: (state) => {
|
|
85
|
+
const f = (x: number) => (state.filterDurationMinutes ? x * 60 : x);
|
|
86
|
+
const from = f(state.filterDurationFrom as number);
|
|
87
|
+
const to = f(state.filterDurationTo as number);
|
|
88
|
+
return { from, to };
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
filterExclude: {
|
|
92
|
+
handle(el, state, searchFilter) {
|
|
93
|
+
return (
|
|
94
|
+
(state.filterExclude as boolean) &&
|
|
95
|
+
(searchFilter as RegexFilter).hasNone(el.title as string)
|
|
96
|
+
);
|
|
97
|
+
},
|
|
98
|
+
$preDefine: (state) => new RegexFilter(state.filterExcludeWords as string),
|
|
99
|
+
},
|
|
100
|
+
filterInclude: {
|
|
101
|
+
handle(el, state, searchFilter) {
|
|
102
|
+
return (
|
|
103
|
+
(state.filterInclude as boolean) &&
|
|
104
|
+
(searchFilter as RegexFilter).hasEvery(el.title as string)
|
|
105
|
+
);
|
|
106
|
+
},
|
|
107
|
+
$preDefine: (state) => new RegexFilter(state.filterIncludeWords as string),
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|