pervert-monkey 1.0.15 → 1.0.17
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/dist/core/pervertmonkey.core.es.d.ts +9 -8
- package/dist/core/pervertmonkey.core.es.js +57 -46
- package/dist/core/pervertmonkey.core.es.js.map +1 -1
- package/dist/core/pervertmonkey.core.umd.js +57 -46
- package/dist/core/pervertmonkey.core.umd.js.map +1 -1
- package/dist/userscripts/3hentai.user.js +9 -3
- package/dist/userscripts/camgirlfinder.user.js +2 -2
- package/dist/userscripts/camwhores.user.js +2 -2
- package/dist/userscripts/e-hentai.user.js +7 -6
- package/dist/userscripts/ebalka.user.js +7 -7
- package/dist/userscripts/eporner.user.js +5 -2
- package/dist/userscripts/erome.user.js +7 -11
- package/dist/userscripts/eroprofile.user.js +2 -2
- package/dist/userscripts/javhdporn.user.js +2 -2
- package/dist/userscripts/missav.user.js +2 -2
- package/dist/userscripts/motherless.user.js +3 -3
- package/dist/userscripts/namethatporn.user.js +4 -4
- package/dist/userscripts/nhentai.user.js +2 -2
- package/dist/userscripts/obmenvsem.user.js +3 -2
- package/dist/userscripts/pornhub.user.js +2 -2
- package/dist/userscripts/spankbang.user.js +5 -5
- package/dist/userscripts/thisvid.user.js +5 -5
- package/dist/userscripts/xhamster.user.js +6 -6
- package/dist/userscripts/xvideos.user.js +8 -8
- package/package.json +1 -1
- package/src/core/data-handler/data-filter-fn-defaults.ts +8 -8
- package/src/core/data-handler/data-filter-fn.ts +10 -8
- package/src/core/data-handler/data-filter.ts +10 -8
- package/src/core/data-handler/data-manager.ts +29 -15
- package/src/core/parsers/thumb-data-parser.ts +11 -4
- package/src/userscripts/scripts/3hentai.ts +4 -2
- package/src/userscripts/scripts/camgirlfinder.ts +1 -1
- package/src/userscripts/scripts/camwhores.ts +1 -1
- package/src/userscripts/scripts/e-hentai.ts +9 -7
- package/src/userscripts/scripts/ebalka.ts +6 -6
- package/src/userscripts/scripts/eporner.ts +4 -1
- package/src/userscripts/scripts/erome.ts +6 -12
- package/src/userscripts/scripts/eroprofile.ts +1 -1
- package/src/userscripts/scripts/javhdporn.ts +1 -1
- package/src/userscripts/scripts/missav.ts +1 -1
- package/src/userscripts/scripts/motherless.ts +4 -3
- package/src/userscripts/scripts/namethatporn.ts +3 -3
- package/src/userscripts/scripts/nhentai.ts +1 -1
- package/src/userscripts/scripts/obmenvsem.ts +6 -2
- package/src/userscripts/scripts/pornhub.ts +1 -1
- package/src/userscripts/scripts/spankbang.ts +4 -4
- package/src/userscripts/scripts/thisvid.ts +3 -3
- package/src/userscripts/scripts/xhamster.ts +5 -5
- package/src/userscripts/scripts/xvideos.ts +7 -7
- package/src/utils/dom/dom-observers.ts +3 -3
- package/src/utils/dom/index.ts +1 -1
|
@@ -26,13 +26,13 @@ export declare type DataElement = {
|
|
|
26
26
|
export declare class DataFilter {
|
|
27
27
|
private rules;
|
|
28
28
|
filters: Map<string, () => DataFilterFnRendered>;
|
|
29
|
+
filterMapping: Record<string, string>;
|
|
29
30
|
constructor(rules: Rules);
|
|
30
|
-
static isFiltered(
|
|
31
|
-
|
|
31
|
+
static isFiltered(e: HTMLElement): boolean;
|
|
32
|
+
createCssFilters(wrapper?: (cssRule: string) => string): void;
|
|
32
33
|
customDataFilterFns: Record<string, DataFilterFnFrom<any>>;
|
|
33
34
|
registerFilters(customFilters: (Record<string, DataFilterFnFrom<any>> | string)[]): void;
|
|
34
35
|
registerFilter(customSelectorName: string): void;
|
|
35
|
-
filterMapping: Record<string, string>;
|
|
36
36
|
selectFilters(filters: {
|
|
37
37
|
[key: string]: boolean;
|
|
38
38
|
}): (() => DataFilterFnRendered)[];
|
|
@@ -43,7 +43,8 @@ declare class DataFilterFn<R> {
|
|
|
43
43
|
deps: string[];
|
|
44
44
|
name: string;
|
|
45
45
|
$preDefine?: ((state: StoreState) => R) | undefined;
|
|
46
|
-
|
|
46
|
+
static prefix: string;
|
|
47
|
+
static setPrefix(name: string): string;
|
|
47
48
|
constructor(handle: DataFilterFnHandle<R>, deps: string[] | undefined, name: string, $preDefine?: ((state: StoreState) => R) | undefined);
|
|
48
49
|
static from<R>(options: DataFilterFnFrom<R>, name: string): DataFilterFn<R>;
|
|
49
50
|
renderFn(state: StoreState): () => DataFilterFnRendered;
|
|
@@ -56,7 +57,7 @@ declare type DataFilterFnHandle<R> = (el: DataElement, state: StoreState, $preDe
|
|
|
56
57
|
declare type DataFilterFnRendered = (v: DataElement) => DataFilterFnRenderedResult;
|
|
57
58
|
|
|
58
59
|
declare type DataFilterFnRenderedResult = {
|
|
59
|
-
|
|
60
|
+
name: string;
|
|
60
61
|
condition: boolean;
|
|
61
62
|
};
|
|
62
63
|
|
|
@@ -68,6 +69,8 @@ export declare class DataManager {
|
|
|
68
69
|
dataFilter: DataFilter;
|
|
69
70
|
constructor(rules: Rules, containerHomogenity?: Parameters<typeof checkHomogenity>[2] | undefined);
|
|
70
71
|
applyFilters: (filters?: Record<string, boolean>, offset?: number) => Promise<void>;
|
|
72
|
+
layoutStylePaintEnabled: boolean;
|
|
73
|
+
private layoutStylePaint;
|
|
71
74
|
filterAll: (offset?: number) => Promise<void>;
|
|
72
75
|
parseData: (html: HTMLElement, container?: HTMLElement, removeDuplicates?: boolean, shouldLazify?: boolean) => void;
|
|
73
76
|
sortBy<K extends keyof DataElement>(key: K, direction?: boolean): void;
|
|
@@ -380,8 +383,6 @@ export declare function parseUrl(s: HTMLAnchorElement | Location | URL | string)
|
|
|
380
383
|
|
|
381
384
|
declare type Primitive = string | number | boolean;
|
|
382
385
|
|
|
383
|
-
declare type PrimitiveString = 'boolean' | 'string' | 'number' | 'float' | 'duration';
|
|
384
|
-
|
|
385
386
|
export declare function querySelectorLast<T extends Element = HTMLElement>(root: ParentNode | undefined, selector: string): T | undefined;
|
|
386
387
|
|
|
387
388
|
export declare function querySelectorLastNumber(selector: string, e?: ParentNode): number;
|
|
@@ -472,7 +473,7 @@ export declare class ThumbDataParser {
|
|
|
472
473
|
declare type ThumbDataSelector = {
|
|
473
474
|
name: string;
|
|
474
475
|
selector: string;
|
|
475
|
-
type:
|
|
476
|
+
type: 'boolean' | 'string' | 'number' | 'float' | 'duration';
|
|
476
477
|
};
|
|
477
478
|
|
|
478
479
|
declare type ThumbDataSelectorsRaw = Record<string, string | Pick<ThumbDataSelector, 'selector' | 'type'>>;
|
|
@@ -11,21 +11,23 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
|
|
|
11
11
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
12
|
var _i2, _n2, _t, _e2, _s2, _l2, _o2, _d, _p2, _g, _C_instances, r_fn, R_fn, b_fn, u_fn, m_fn, a_fn, P_fn, E_fn, S_fn, O_fn, k_fn, x_fn, h_fn, f_fn, T_fn, A_fn, y_fn, w_fn, c_fn, C_fn, _a, _i3, _n3, _t2, _e3, _s3, _l3, _b;
|
|
13
13
|
import { GM_addStyle } from "vite-plugin-monkey/dist/client";
|
|
14
|
-
class
|
|
14
|
+
const _DataFilterFn = class _DataFilterFn {
|
|
15
15
|
constructor(handle, deps = [], name, $preDefine) {
|
|
16
|
-
__publicField(this, "tag");
|
|
17
16
|
this.handle = handle;
|
|
18
17
|
this.deps = deps;
|
|
19
18
|
this.name = name;
|
|
20
19
|
this.$preDefine = $preDefine;
|
|
21
|
-
this.
|
|
20
|
+
this.name = _DataFilterFn.setPrefix(name);
|
|
21
|
+
}
|
|
22
|
+
static setPrefix(name) {
|
|
23
|
+
return `${_DataFilterFn.prefix}${name}`;
|
|
22
24
|
}
|
|
23
25
|
static from(options, name) {
|
|
24
26
|
if (typeof options === "function") {
|
|
25
27
|
const deps = [name];
|
|
26
|
-
return new
|
|
28
|
+
return new _DataFilterFn(options, deps, name);
|
|
27
29
|
}
|
|
28
|
-
return new
|
|
30
|
+
return new _DataFilterFn(
|
|
29
31
|
options.handle,
|
|
30
32
|
options.deps,
|
|
31
33
|
name,
|
|
@@ -33,20 +35,19 @@ class DataFilterFn {
|
|
|
33
35
|
);
|
|
34
36
|
}
|
|
35
37
|
renderFn(state) {
|
|
36
|
-
const
|
|
38
|
+
const name = this.name;
|
|
37
39
|
return () => {
|
|
38
40
|
var _a3;
|
|
39
41
|
const preDefined = (_a3 = this.$preDefine) == null ? void 0 : _a3.call(this, state);
|
|
40
42
|
return (a2) => {
|
|
41
43
|
const condition = this.handle(a2, state, preDefined);
|
|
42
|
-
return {
|
|
43
|
-
condition,
|
|
44
|
-
tag
|
|
45
|
-
};
|
|
44
|
+
return { condition, name };
|
|
46
45
|
};
|
|
47
46
|
};
|
|
48
47
|
}
|
|
49
|
-
}
|
|
48
|
+
};
|
|
49
|
+
__publicField(_DataFilterFn, "prefix", "filter-");
|
|
50
|
+
let DataFilterFn = _DataFilterFn;
|
|
50
51
|
function chunks(arr, size) {
|
|
51
52
|
return Array.from(
|
|
52
53
|
{ length: Math.ceil(arr.length / size) },
|
|
@@ -117,10 +118,10 @@ function sanitizeStr(s) {
|
|
|
117
118
|
}
|
|
118
119
|
function waitForElementToAppear(parent, selector, callback) {
|
|
119
120
|
const observer = new MutationObserver((_mutations) => {
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
121
|
+
const e = parent.querySelector(selector);
|
|
122
|
+
if (e) {
|
|
122
123
|
observer.disconnect();
|
|
123
|
-
callback(
|
|
124
|
+
callback(e);
|
|
124
125
|
}
|
|
125
126
|
});
|
|
126
127
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
@@ -219,7 +220,7 @@ function removeClassesAndDataAttributes(element, keyword) {
|
|
|
219
220
|
});
|
|
220
221
|
}
|
|
221
222
|
function getCommonParents(elements) {
|
|
222
|
-
const parents = Array.from(elements).map((
|
|
223
|
+
const parents = Array.from(elements).map((e) => e.parentElement).filter((parent) => parent !== null);
|
|
223
224
|
return [...new Set(parents)];
|
|
224
225
|
}
|
|
225
226
|
function findNextSibling(e) {
|
|
@@ -468,9 +469,9 @@ function parseCssUrl(s) {
|
|
|
468
469
|
function createTextFilter(filterName, dataPropName, positive) {
|
|
469
470
|
const filterNameValue = `${filterName}Words`;
|
|
470
471
|
return {
|
|
471
|
-
handle(
|
|
472
|
+
handle(e, state, searchFilter) {
|
|
472
473
|
if (!Object.hasOwn(state, filterName) || !state[filterName]) return false;
|
|
473
|
-
return !(searchFilter == null ? void 0 : searchFilter(
|
|
474
|
+
return !(searchFilter == null ? void 0 : searchFilter(e[dataPropName]));
|
|
474
475
|
},
|
|
475
476
|
$preDefine: (state) => {
|
|
476
477
|
const r = new RegexFilter(state[filterNameValue]);
|
|
@@ -481,9 +482,9 @@ function createTextFilter(filterName, dataPropName, positive) {
|
|
|
481
482
|
};
|
|
482
483
|
}
|
|
483
484
|
const filterDuration = {
|
|
484
|
-
handle(
|
|
485
|
+
handle(e, state, notInRange) {
|
|
485
486
|
if (!state.filterDuration) return false;
|
|
486
|
-
return !!(notInRange == null ? void 0 : notInRange(
|
|
487
|
+
return !!(notInRange == null ? void 0 : notInRange(e.duration));
|
|
487
488
|
},
|
|
488
489
|
$preDefine: (state) => {
|
|
489
490
|
const from = state.filterDurationFrom;
|
|
@@ -501,26 +502,27 @@ const defaultDataFilterFns = {
|
|
|
501
502
|
filterInclude: createTextFilter("filterInclude", "title", true),
|
|
502
503
|
filterUploaderExclude: createTextFilter("filterUploaderExclude", "uploader", false),
|
|
503
504
|
filterUploaderInclude: createTextFilter("filterUploaderInclude", "uploader", true),
|
|
504
|
-
filterHD: (
|
|
505
|
-
filterNonHD: (
|
|
506
|
-
filterPrivate: (
|
|
507
|
-
filterPublic: (
|
|
505
|
+
filterHD: (e, state) => state.filterHD && !e.hd,
|
|
506
|
+
filterNonHD: (e, state) => state.filterNonHD && e.hd,
|
|
507
|
+
filterPrivate: (e, state) => state.filterPrivate && e.private,
|
|
508
|
+
filterPublic: (e, state) => state.filterPublic && !e.private
|
|
508
509
|
};
|
|
509
510
|
class DataFilter {
|
|
510
511
|
constructor(rules) {
|
|
511
512
|
__publicField(this, "filters", /* @__PURE__ */ new Map());
|
|
512
|
-
__publicField(this, "customDataFilterFns", {});
|
|
513
513
|
__publicField(this, "filterMapping", {});
|
|
514
|
+
__publicField(this, "customDataFilterFns", {});
|
|
514
515
|
this.rules = rules;
|
|
515
516
|
this.registerFilters(rules.customDataFilterFns);
|
|
516
|
-
this.
|
|
517
|
+
this.createCssFilters();
|
|
517
518
|
}
|
|
518
|
-
static isFiltered(
|
|
519
|
-
return
|
|
519
|
+
static isFiltered(e) {
|
|
520
|
+
return e.className.includes(DataFilterFn.prefix);
|
|
520
521
|
}
|
|
521
|
-
|
|
522
|
+
createCssFilters(wrapper) {
|
|
522
523
|
this.filters.forEach((_2, name) => {
|
|
523
|
-
const
|
|
524
|
+
const className = DataFilterFn.setPrefix(name);
|
|
525
|
+
const cssRule = `.${className} { display: none !important; }`;
|
|
524
526
|
GM_addStyle(wrapper ? wrapper(cssRule) : cssRule);
|
|
525
527
|
});
|
|
526
528
|
}
|
|
@@ -533,12 +535,12 @@ class DataFilter {
|
|
|
533
535
|
});
|
|
534
536
|
}
|
|
535
537
|
registerFilter(customSelectorName) {
|
|
536
|
-
var _a3;
|
|
537
538
|
const dataFilterFn = DataFilterFn.from(
|
|
538
539
|
this.customDataFilterFns[customSelectorName],
|
|
539
540
|
customSelectorName
|
|
540
541
|
);
|
|
541
|
-
|
|
542
|
+
dataFilterFn.deps.push(customSelectorName);
|
|
543
|
+
dataFilterFn.deps.forEach((name) => {
|
|
542
544
|
Object.assign(this.filterMapping, { [name]: customSelectorName });
|
|
543
545
|
});
|
|
544
546
|
this.filters.set(customSelectorName, dataFilterFn.renderFn(this.rules.store.state));
|
|
@@ -568,8 +570,8 @@ class DataManager {
|
|
|
568
570
|
finished = !!done;
|
|
569
571
|
if (done) break;
|
|
570
572
|
for (const f of filtersToApply) {
|
|
571
|
-
const {
|
|
572
|
-
updates.push({ e: value.element,
|
|
573
|
+
const { name, condition } = f()(value);
|
|
574
|
+
updates.push({ e: value.element, name, condition });
|
|
573
575
|
}
|
|
574
576
|
}
|
|
575
577
|
if (!finished) {
|
|
@@ -580,13 +582,14 @@ class DataManager {
|
|
|
580
582
|
}
|
|
581
583
|
requestIdleCallback(runBatch);
|
|
582
584
|
});
|
|
583
|
-
const parents = new Set(updates.map((u) => u.e.parentElement))
|
|
585
|
+
const parents = [...new Set(updates.map((u) => u.e.parentElement))].filter(
|
|
586
|
+
(_2) => _2 !== null
|
|
587
|
+
);
|
|
584
588
|
requestAnimationFrame(() => {
|
|
585
|
-
const revertDisplayStyle =
|
|
586
|
-
const display = p
|
|
587
|
-
if (!display) return void 0;
|
|
589
|
+
const revertDisplayStyle = parents.map((p) => {
|
|
590
|
+
const display = p.style.display;
|
|
588
591
|
p.style.display = "none";
|
|
589
|
-
p
|
|
592
|
+
this.layoutStylePaint(p);
|
|
590
593
|
p.style.willChange = "contents";
|
|
591
594
|
return () => {
|
|
592
595
|
p.style.display = display;
|
|
@@ -596,13 +599,14 @@ class DataManager {
|
|
|
596
599
|
};
|
|
597
600
|
});
|
|
598
601
|
updates.forEach((u) => {
|
|
599
|
-
u.e.classList.toggle(u.
|
|
602
|
+
u.e.classList.toggle(u.name, u.condition);
|
|
600
603
|
});
|
|
601
604
|
revertDisplayStyle.forEach((f) => {
|
|
602
605
|
f == null ? void 0 : f();
|
|
603
606
|
});
|
|
604
607
|
});
|
|
605
608
|
});
|
|
609
|
+
__publicField(this, "layoutStylePaintEnabled", false);
|
|
606
610
|
__publicField(this, "filterAll", async (offset) => {
|
|
607
611
|
const keys = Array.from(this.dataFilter.filters.keys());
|
|
608
612
|
const filters = Object.fromEntries(
|
|
@@ -616,10 +620,6 @@ class DataManager {
|
|
|
616
620
|
const fragment = document.createDocumentFragment();
|
|
617
621
|
const parent = container || this.rules.container;
|
|
618
622
|
const homogenity = !!this.containerHomogenity;
|
|
619
|
-
if (parent) {
|
|
620
|
-
parent.style.contain = "layout style paint";
|
|
621
|
-
parent.style.willChange = "contents";
|
|
622
|
-
}
|
|
623
623
|
for (const thumbElement of thumbs) {
|
|
624
624
|
const url = this.rules.thumbDataParser.getUrl(thumbElement);
|
|
625
625
|
if (!url || this.data.has(url) || parent !== container && (parent == null ? void 0 : parent.contains(thumbElement)) || homogenity && !checkHomogenity(
|
|
@@ -639,8 +639,13 @@ class DataManager {
|
|
|
639
639
|
fragment.append(thumbElement);
|
|
640
640
|
}
|
|
641
641
|
this.filterAll(dataOffset).then(() => {
|
|
642
|
+
if (!parent) return;
|
|
643
|
+
parent.style.willChange = "contents";
|
|
642
644
|
requestAnimationFrame(() => {
|
|
643
645
|
parent == null ? void 0 : parent.appendChild(fragment);
|
|
646
|
+
requestAnimationFrame(() => {
|
|
647
|
+
parent.style.willChange = "auto";
|
|
648
|
+
});
|
|
644
649
|
});
|
|
645
650
|
});
|
|
646
651
|
});
|
|
@@ -648,12 +653,16 @@ class DataManager {
|
|
|
648
653
|
this.containerHomogenity = containerHomogenity;
|
|
649
654
|
this.dataFilter = new DataFilter(this.rules);
|
|
650
655
|
}
|
|
656
|
+
layoutStylePaint(e) {
|
|
657
|
+
if (!this.layoutStylePaintEnabled) return;
|
|
658
|
+
e.style.contain = "layout style paint";
|
|
659
|
+
}
|
|
651
660
|
sortBy(key, direction = true) {
|
|
652
661
|
if (this.data.size < 2) return;
|
|
653
662
|
const elements = this.data.values().toArray().filter((e) => e.element.parentElement !== null).map((e) => e);
|
|
654
663
|
const containers = new Set(elements.map((e) => e.element.parentElement));
|
|
655
664
|
containers.forEach((c) => {
|
|
656
|
-
c
|
|
665
|
+
this.layoutStylePaint(c);
|
|
657
666
|
c.style.willChange = "contents";
|
|
658
667
|
});
|
|
659
668
|
const elementsByContainers = /* @__PURE__ */ new Map();
|
|
@@ -3075,8 +3084,10 @@ class ThumbDataParser {
|
|
|
3075
3084
|
}
|
|
3076
3085
|
autoParseText(thumb) {
|
|
3077
3086
|
var _a3;
|
|
3078
|
-
|
|
3079
|
-
const
|
|
3087
|
+
let title = sanitizeStr(thumb.innerText);
|
|
3088
|
+
const durationStr = ((_a3 = title.match(/(\d+:\d+:?\d+?)|\d+m/)) == null ? void 0 : _a3[0]) || "";
|
|
3089
|
+
const duration = timeToSeconds(durationStr);
|
|
3090
|
+
title = title.replaceAll(durationStr, "");
|
|
3080
3091
|
return { title, duration };
|
|
3081
3092
|
}
|
|
3082
3093
|
getUrl(thumb) {
|