pervert-monkey 1.0.24 → 1.0.26
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 +5 -2
- package/dist/core/pervertmonkey.core.es.d.ts +2 -540
- package/dist/core/pervertmonkey.core.es.js +8001 -9280
- package/dist/core/pervertmonkey.core.es.js.map +1 -1
- package/dist/core/pervertmonkey.core.umd.js +8829 -10050
- package/dist/core/pervertmonkey.core.umd.js.map +1 -1
- package/dist/userscripts/3hentai.user.js +40 -46
- package/dist/userscripts/camgirlfinder.user.js +56 -49
- package/dist/userscripts/camwhores.user.js +286 -343
- package/dist/userscripts/e-hentai.user.js +54 -57
- package/dist/userscripts/ebalka.user.js +52 -55
- package/dist/userscripts/eporner.user.js +76 -68
- package/dist/userscripts/erome.user.js +79 -84
- package/dist/userscripts/eroprofile.user.js +28 -29
- package/dist/userscripts/javhdporn.user.js +28 -22
- package/dist/userscripts/missav.user.js +22 -23
- package/dist/userscripts/motherless.user.js +141 -147
- package/dist/userscripts/namethatporn.user.js +49 -58
- package/dist/userscripts/nhentai.user.js +104 -99
- package/dist/userscripts/obmenvsem.user.js +61 -69
- package/dist/userscripts/pornhub.user.js +50 -47
- package/dist/userscripts/simpcity.user.js +44 -0
- package/dist/userscripts/socialmediagirls.user.js +26 -22
- package/dist/userscripts/spankbang.user.js +62 -44
- package/dist/userscripts/thisvid.user.js +1269 -1366
- package/dist/userscripts/xhamster.user.js +119 -132
- package/dist/userscripts/xvideos.user.js +115 -91
- package/package.json +10 -6
- package/src/core/data-handler/data-filter.ts +4 -3
- package/src/core/parsers/pagination-parser/index.ts +0 -6
- package/src/core/parsers/pagination-parser/pagination-strategies/PaginationStrategyPathnameParams.ts +36 -1
- package/src/core/parsers/thumb-data-parser.ts +7 -3
- package/src/userscripts/index.ts +1 -1
- package/src/userscripts/meta.json +1 -1
- package/src/userscripts/scripts/3hentai.ts +1 -1
- package/src/userscripts/scripts/camgirlfinder.ts +1 -1
- package/src/userscripts/scripts/camwhores.ts +2 -2
- package/src/userscripts/scripts/e-hentai.ts +1 -1
- package/src/userscripts/scripts/ebalka.ts +1 -1
- package/src/userscripts/scripts/eporner.ts +41 -15
- package/src/userscripts/scripts/erome.ts +1 -1
- package/src/userscripts/scripts/eroprofile.ts +6 -6
- package/src/userscripts/scripts/javhdporn.ts +1 -1
- package/src/userscripts/scripts/missav.ts +1 -1
- package/src/userscripts/scripts/motherless.ts +42 -37
- package/src/userscripts/scripts/namethatporn.ts +1 -1
- package/src/userscripts/scripts/nhentai.ts +1 -1
- package/src/userscripts/scripts/obmenvsem.ts +1 -1
- package/src/userscripts/scripts/pornhub.ts +1 -1
- package/src/userscripts/scripts/simpcity.ts +27 -0
- package/src/userscripts/scripts/socialmediagirls.ts +4 -3
- package/src/userscripts/scripts/spankbang.ts +20 -4
- package/src/userscripts/scripts/thisvid.ts +8 -21
- package/src/userscripts/scripts/xhamster.ts +11 -3
- package/src/userscripts/scripts/xvideos.ts +26 -7
- package/src/utils/fetch/index.ts +2 -0
- package/src/utils/objects/memoize.ts +1 -9
- package/dist/test/test.user.js +0 -10301
package/src/core/parsers/pagination-parser/pagination-strategies/PaginationStrategyPathnameParams.ts
CHANGED
|
@@ -7,7 +7,8 @@ export class PaginationStrategyPathnameParams extends PaginationStrategy {
|
|
|
7
7
|
const href = typeof a === 'string' ? a : a.href;
|
|
8
8
|
const { pathname } = new URL(href, this.doc.baseURI || this.url.origin);
|
|
9
9
|
return parseInt(
|
|
10
|
-
pathname.match(this.pathnameSelector)?.pop() ||
|
|
10
|
+
pathname.match(this.pathnameSelector)?.filter(Boolean)?.pop() ||
|
|
11
|
+
this.offsetMin.toString(),
|
|
11
12
|
);
|
|
12
13
|
};
|
|
13
14
|
|
|
@@ -55,19 +56,53 @@ export class PaginationStrategyPathnameParams extends PaginationStrategy {
|
|
|
55
56
|
getPaginationUrlGenerator(url_: URL = this.url) {
|
|
56
57
|
const url = new URL(url_.href);
|
|
57
58
|
|
|
59
|
+
// console.log('this.pathnameSelector', this.pathnameSelector);
|
|
60
|
+
|
|
58
61
|
const pathnameSelectorPlaceholder = this.pathnameSelector
|
|
59
62
|
.toString()
|
|
60
63
|
.replace(/\\{1,}/g, '')
|
|
61
64
|
.replace(/[$?()]+/g, '')
|
|
62
65
|
.replace(/\/{1,}/g, '/');
|
|
63
66
|
|
|
67
|
+
// console.log({ pathnameSelectorPlaceholder, 'url.pathname': url.pathname });
|
|
68
|
+
|
|
64
69
|
if (!this.pathnameSelector.test(url.pathname)) {
|
|
65
70
|
url.pathname = url.pathname
|
|
66
71
|
.concat(pathnameSelectorPlaceholder.replace(/d\+/, this.offsetMin.toString()))
|
|
67
72
|
.replace(/\/{1,}/g, '/');
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
// console.log({ pathnameSelectorPlaceholder, 'url.pathname': url.pathname });
|
|
76
|
+
|
|
70
77
|
const paginationUrlGenerator = (offset: number) => {
|
|
78
|
+
// console.log({
|
|
79
|
+
// pathname: url.pathname,
|
|
80
|
+
// replace: '',
|
|
81
|
+
// pathnameSelector: this.pathnameSelector,
|
|
82
|
+
// pathnameSelectorPlaceholder: pathnameSelectorPlaceholder.replace(
|
|
83
|
+
// /d\+/,
|
|
84
|
+
// offset.toString(),
|
|
85
|
+
// ),
|
|
86
|
+
// });
|
|
87
|
+
|
|
88
|
+
// pathnameSelectorPlaceholder.replace()
|
|
89
|
+
// need to create tests
|
|
90
|
+
|
|
91
|
+
// url.pathname = url.pathname.replace(
|
|
92
|
+
// this.pathnameSelector,
|
|
93
|
+
// (a, b, c, d) => {
|
|
94
|
+
// console.log({ a, b, c, d, pathnameSelectorPlaceholder });
|
|
95
|
+
// if (a.length + 1 < pathnameSelectorPlaceholder.length) {
|
|
96
|
+
// return a.replace(/\d+/, offset.toString());
|
|
97
|
+
// }
|
|
98
|
+
// // return a;
|
|
99
|
+
// return pathnameSelectorPlaceholder.replace(/d\+/, offset.toString());
|
|
100
|
+
// },
|
|
101
|
+
// // pathnameSelectorPlaceholder.replace(/d\+/, offset.toString()),
|
|
102
|
+
// );
|
|
103
|
+
// return url.href;
|
|
104
|
+
// };
|
|
105
|
+
|
|
71
106
|
url.pathname = url.pathname.replace(
|
|
72
107
|
this.pathnameSelector,
|
|
73
108
|
pathnameSelectorPlaceholder.replace(/d\+/, offset.toString()),
|
|
@@ -35,7 +35,7 @@ export class ThumbDataParser {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
public getUrl(thumb: HTMLElement | HTMLAnchorElement) {
|
|
38
|
-
return (querySelectorOrSelf(thumb,
|
|
38
|
+
return (querySelectorOrSelf(thumb, this.getUrlSelector) as HTMLAnchorElement).href;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
private preprocessCustomThumbDataSelectors() {
|
|
@@ -56,6 +56,7 @@ export class ThumbDataParser {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
private thumbDataSelectors: ThumbDataSelector[] = [];
|
|
59
|
+
|
|
59
60
|
private readonly defaultThumbDataSelectors: ThumbDataSelector[] = [
|
|
60
61
|
{ name: 'title', type: 'string', selector: '[class *= title],[title]' },
|
|
61
62
|
{
|
|
@@ -91,14 +92,17 @@ export class ThumbDataParser {
|
|
|
91
92
|
public strategy: 'manual' | 'auto-select' | 'auto-text' = 'manual',
|
|
92
93
|
public selectors: ThumbDataSelectorsRaw = {},
|
|
93
94
|
public callback?: (thumb: HTMLElement, thumbData: ThumbData) => void,
|
|
95
|
+
public getUrlSelector = 'a[href]',
|
|
94
96
|
) {
|
|
95
97
|
this.preprocessCustomThumbDataSelectors();
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
public static create(
|
|
99
|
-
o: Partial<
|
|
101
|
+
o: Partial<
|
|
102
|
+
Pick<ThumbDataParser, 'strategy' | 'selectors' | 'callback' | 'getUrlSelector'>
|
|
103
|
+
> = {},
|
|
100
104
|
) {
|
|
101
|
-
return new ThumbDataParser(o.strategy, o.selectors, o.callback);
|
|
105
|
+
return new ThumbDataParser(o.strategy, o.selectors, o.callback, o.getUrlSelector);
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
public getThumbData(thumb: HTMLElement): ThumbData {
|
package/src/userscripts/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import './scripts/
|
|
1
|
+
import './scripts/eporner';
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
"grant": ["unsafeWindow", "GM_addStyle"],
|
|
7
7
|
"homepageURL": "https://sleazyfork.org/en/users/1253342-smartacephale",
|
|
8
8
|
"supportURL": "https://github.com/smartacephale/sleazy-fork/issues",
|
|
9
|
-
"source": "https://github.com/smartacephale"
|
|
9
|
+
"source": "https://github.com/smartacephale/sleazy-fork"
|
|
10
10
|
}
|
|
@@ -4,7 +4,7 @@ import { circularShift, OnHover, Tick } from '../../utils';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: '3Hentai PervertMonkey',
|
|
7
|
-
version: '1.0.
|
|
7
|
+
version: '1.0.20',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title, thumb preview',
|
|
9
9
|
match: 'https://*.3hentai.net/*',
|
|
10
10
|
};
|
|
@@ -2,7 +2,7 @@ import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
|
2
2
|
|
|
3
3
|
export const meta: MonkeyUserScript = {
|
|
4
4
|
name: 'CamGirlFinder PervertMonkey',
|
|
5
|
-
version: '1.6.
|
|
5
|
+
version: '1.6.19',
|
|
6
6
|
description:
|
|
7
7
|
'Adds model links for CamWhores, webcamrecordings, recu.me, camvideos, privat-zapisi',
|
|
8
8
|
match: ['https://camgirlfinder.net/*'],
|
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export const meta: MonkeyUserScript = {
|
|
19
19
|
name: 'CamWhores PervertMonkey',
|
|
20
|
-
version: '3.0.
|
|
20
|
+
version: '3.0.24',
|
|
21
21
|
description:
|
|
22
22
|
'Infinite scroll [optional]. Filter by Title, Duration and Private/Public. Sort by Duration and Views. Mass friend request button. Download button',
|
|
23
|
-
match: ['https://*.camwhores.tv', 'https://*.camwhores.*/*'],
|
|
23
|
+
match: ['https://*.camwhores.tv/*', 'https://*.camwhores.*/*'],
|
|
24
24
|
exclude: 'https://*.camwhores.tv/*mode=async*',
|
|
25
25
|
};
|
|
26
26
|
|
|
@@ -4,7 +4,7 @@ import { fetchHtml } from '../../utils';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'E-Hentai PervertMonkey',
|
|
7
|
-
version: '1.0.
|
|
7
|
+
version: '1.0.20',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: ['https://*.e-hentai.org/*'],
|
|
10
10
|
};
|
|
@@ -4,7 +4,7 @@ import { downloader, exterminateVideo, OnHover, parseHtml } from '../../utils';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'Ebalka PervertMonkey',
|
|
7
|
-
version: '3.0.
|
|
7
|
+
version: '3.0.21',
|
|
8
8
|
description:
|
|
9
9
|
'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration, Download button.',
|
|
10
10
|
match: [
|
|
@@ -5,22 +5,24 @@ import { OnHover } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Eporner PervertMonkey',
|
|
8
|
-
version: '2.
|
|
8
|
+
version: '2.1.3',
|
|
9
9
|
description:
|
|
10
10
|
'Infinite scroll [optional], Filter by Title, Uploader, Duration and HD, Sort by Views and Duration',
|
|
11
11
|
match: ['https://*.eporner.com/*', 'https://*.eporner.*/*'],
|
|
12
|
+
supportURL: 'https://sleazyfork.org/en/scripts/552559-eporner-pervertmonkey/feedback',
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
const show_video_prev = (unsafeWindow as any).show_video_prev;
|
|
15
|
-
|
|
16
15
|
const rules = new Rules({
|
|
17
16
|
paginationStrategyOptions: {
|
|
18
17
|
paginationSelector: '.numlist2',
|
|
18
|
+
// pathnameSelector: /\/(\d+)\/?$/,
|
|
19
|
+
// pathnameSelector: /\/(\d+)\/([\w-]+\/)?$/
|
|
20
|
+
overwritePaginationLast: (n, _) => (n === 9 ? 9999 : n),
|
|
19
21
|
},
|
|
20
22
|
thumbs: { selector: 'div[id^=vf][data-id]' },
|
|
21
23
|
thumb: {
|
|
22
24
|
selectors: {
|
|
23
|
-
title: 'a',
|
|
25
|
+
title: 'a[href*=video-]',
|
|
24
26
|
uploader: '[title="Uploader"]',
|
|
25
27
|
duration: '[title="Duration"]',
|
|
26
28
|
views: { selector: '[title="Views"]', type: 'float' },
|
|
@@ -33,12 +35,38 @@ const rules = new Rules({
|
|
|
33
35
|
},
|
|
34
36
|
containerSelectorLast: '#vidresults',
|
|
35
37
|
customDataFilterFns: [
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
{
|
|
39
|
+
qualityFilter: {
|
|
40
|
+
handle(el, state) {
|
|
41
|
+
const hasAnyQualitySelected =
|
|
42
|
+
state.quality360 ||
|
|
43
|
+
state.quality480 ||
|
|
44
|
+
state.quality720 ||
|
|
45
|
+
state.quality1080 ||
|
|
46
|
+
state.quality2k ||
|
|
47
|
+
state.quality4k;
|
|
48
|
+
|
|
49
|
+
if (!hasAnyQualitySelected) return false;
|
|
50
|
+
|
|
51
|
+
return !(
|
|
52
|
+
(state.quality360 && el.quality === 360) ||
|
|
53
|
+
(state.quality480 && el.quality === 480) ||
|
|
54
|
+
(state.quality720 && el.quality === 720) ||
|
|
55
|
+
(state.quality1080 && el.quality === 1080) ||
|
|
56
|
+
(state.quality2k && el.quality === 2) ||
|
|
57
|
+
(state.quality4k && el.quality === 4)
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
deps: [
|
|
61
|
+
'quality360',
|
|
62
|
+
'quality480',
|
|
63
|
+
'quality720',
|
|
64
|
+
'quality1080',
|
|
65
|
+
'quality2k',
|
|
66
|
+
'quality4k',
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
42
70
|
],
|
|
43
71
|
schemeOptions: [
|
|
44
72
|
'Title Filter',
|
|
@@ -59,15 +87,13 @@ const rules = new Rules({
|
|
|
59
87
|
'Badge',
|
|
60
88
|
'Advanced',
|
|
61
89
|
],
|
|
62
|
-
gropeStrategy: 'all-in-
|
|
90
|
+
gropeStrategy: 'all-in-one',
|
|
63
91
|
animatePreview,
|
|
64
92
|
});
|
|
65
93
|
|
|
66
94
|
function animatePreview(doc: HTMLElement) {
|
|
67
95
|
OnHover.create(doc, 'div[id^=vf][data-id]', (e) => {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
const id = thumb?.getAttribute('data-id');
|
|
71
|
-
show_video_prev(id);
|
|
96
|
+
const thumb = e.closest('[data-id]');
|
|
97
|
+
(unsafeWindow as any).EP.thumbs.preview.start(thumb);
|
|
72
98
|
});
|
|
73
99
|
}
|
|
@@ -4,7 +4,7 @@ import { Rules } from '../../core';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'Erome PervertMonkey',
|
|
7
|
-
version: '5.0.
|
|
7
|
+
version: '5.0.21',
|
|
8
8
|
description:
|
|
9
9
|
'Infinite scroll [optional], Filter by Title, Uploader and Video/Photo albums, Sort by Views. Show/Hide Photos in album. Remove disclaimer. Restore Search Bar',
|
|
10
10
|
match: ['*://*.erome.com/*'],
|
|
@@ -3,7 +3,7 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Eroprofile PervertMonkey',
|
|
6
|
-
version: '2.0.
|
|
6
|
+
version: '2.0.21',
|
|
7
7
|
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
8
8
|
match: ['https://*.eroprofile.com/*'],
|
|
9
9
|
};
|
|
@@ -12,17 +12,17 @@ document.querySelector('.videoGrid')?.after(document.querySelector('.clB') as HT
|
|
|
12
12
|
|
|
13
13
|
const rules = new Rules({
|
|
14
14
|
paginationStrategyOptions: {
|
|
15
|
-
paginationSelector: '.
|
|
15
|
+
paginationSelector: '.page-nav',
|
|
16
16
|
searchParamSelector: 'pnum',
|
|
17
17
|
},
|
|
18
|
-
thumbs: { selector: '.video' },
|
|
18
|
+
thumbs: { selector: '.grid-tile-video' },
|
|
19
19
|
thumb: {
|
|
20
20
|
selectors: {
|
|
21
|
-
title: '
|
|
22
|
-
duration: '.
|
|
21
|
+
title: '.title',
|
|
22
|
+
duration: '.duration',
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
|
-
containerSelector: '
|
|
25
|
+
containerSelector: 'div:has(>.grid-tile-video)',
|
|
26
26
|
schemeOptions: [
|
|
27
27
|
'Title Filter',
|
|
28
28
|
'Duration Filter',
|
|
@@ -3,7 +3,7 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Javhdporn PervertMonkey',
|
|
6
|
-
version: '3.0.
|
|
6
|
+
version: '3.0.20',
|
|
7
7
|
description:
|
|
8
8
|
'Infinite scroll [optional], Filter by Title and Duration, Sort By Duration and Views',
|
|
9
9
|
match: ['https://*.javhdporn.net/*', 'https://*.javhdporn.*/*'],
|
|
@@ -3,7 +3,7 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Missav PervertMonkey',
|
|
6
|
-
version: '3.0.
|
|
6
|
+
version: '3.0.19',
|
|
7
7
|
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
8
8
|
match: [
|
|
9
9
|
'https://*.missav123.com/*',
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
2
|
import { GM_addElement, GM_addStyle, unsafeWindow } from '$';
|
|
3
3
|
import { Rules } from '../../core';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
fetchWith,
|
|
6
|
+
OnHover,
|
|
7
|
+
replaceElementTag,
|
|
8
|
+
Tick,
|
|
9
|
+
waitForElementToAppear,
|
|
10
|
+
} from '../../utils';
|
|
5
11
|
|
|
6
12
|
export const meta: MonkeyUserScript = {
|
|
7
13
|
name: 'Motherless PervertMonkey',
|
|
8
|
-
version: '5.0.
|
|
14
|
+
version: '5.0.25',
|
|
9
15
|
description:
|
|
10
16
|
'Infinite scroll [optional], Filter by Title, Uploader and Duration, Sort by Duration and Views',
|
|
11
|
-
match: ['https://motherless.
|
|
17
|
+
match: ['https://motherless.xxx/*'],
|
|
12
18
|
grant: ['GM_addElement', 'GM_addStyle', 'unsafeWindow'],
|
|
13
19
|
};
|
|
14
20
|
|
|
@@ -16,7 +22,7 @@ export const meta: MonkeyUserScript = {
|
|
|
16
22
|
const $ = (unsafeWindow as any).$;
|
|
17
23
|
|
|
18
24
|
const rules = new Rules({
|
|
19
|
-
|
|
25
|
+
containerSelector: '.content-inner',
|
|
20
26
|
thumbs: { selector: '.thumb-container, .mobile-thumb' },
|
|
21
27
|
thumb: {
|
|
22
28
|
selectors: {
|
|
@@ -38,7 +44,12 @@ const rules = new Rules({
|
|
|
38
44
|
'Duration Filter',
|
|
39
45
|
'Sort By',
|
|
40
46
|
'Badge',
|
|
41
|
-
|
|
47
|
+
{
|
|
48
|
+
title: 'Advanced',
|
|
49
|
+
content: [
|
|
50
|
+
{ applyTitleFiltersToSearch: false, label: 'apply title filters to search' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
42
53
|
],
|
|
43
54
|
});
|
|
44
55
|
|
|
@@ -47,7 +58,8 @@ function animatePreview(_: HTMLElement) {
|
|
|
47
58
|
|
|
48
59
|
function onOver(target: HTMLElement) {
|
|
49
60
|
$('.video').off();
|
|
50
|
-
const container = target.querySelector('.
|
|
61
|
+
const container = target.querySelector('.video') as HTMLElement;
|
|
62
|
+
if (!container) return;
|
|
51
63
|
const img = container.querySelector('img.static') as HTMLImageElement;
|
|
52
64
|
const stripSrc = img.getAttribute('data-strip-src');
|
|
53
65
|
|
|
@@ -93,8 +105,6 @@ function animatePreview(_: HTMLElement) {
|
|
|
93
105
|
OnHover.create(document.body, '.thumb-container, .mobile-thumb', onOver);
|
|
94
106
|
}
|
|
95
107
|
|
|
96
|
-
//====================================================================================================
|
|
97
|
-
|
|
98
108
|
function fixURLs() {
|
|
99
109
|
document.querySelectorAll<HTMLElement>('.gallery-container').forEach((g) => {
|
|
100
110
|
const x = (g.innerText as string).match(/([\d|.]+)k? videos/gi)?.[0];
|
|
@@ -108,12 +118,11 @@ function fixURLs() {
|
|
|
108
118
|
});
|
|
109
119
|
|
|
110
120
|
document
|
|
111
|
-
.querySelectorAll<HTMLAnchorElement>(
|
|
121
|
+
.querySelectorAll<HTMLAnchorElement>(
|
|
122
|
+
'a[href^="/term/"]:not([href^="/term/videos/"]):not(.pop):not([rel])',
|
|
123
|
+
)
|
|
112
124
|
.forEach((a) => {
|
|
113
|
-
a.href = a.href.replace(
|
|
114
|
-
/[\w|+]+$/,
|
|
115
|
-
(v) => `videos/${v}?term=${v}&range=0&size=0&sort=date`,
|
|
116
|
-
);
|
|
125
|
+
a.href = a.href.replace(/[\w|+]+$/, (v) => `videos/${v}?term=${v}`);
|
|
117
126
|
});
|
|
118
127
|
|
|
119
128
|
document
|
|
@@ -123,8 +132,6 @@ function fixURLs() {
|
|
|
123
132
|
});
|
|
124
133
|
}
|
|
125
134
|
|
|
126
|
-
//====================================================================================================
|
|
127
|
-
|
|
128
135
|
function mobileGalleryToDesktop(e: HTMLElement) {
|
|
129
136
|
e.querySelector('.clear-left')?.remove();
|
|
130
137
|
const container = e.firstElementChild as HTMLElement;
|
|
@@ -141,26 +148,27 @@ async function desktopAddMobGalleries() {
|
|
|
141
148
|
const galleries = document.querySelector('.media-related-galleries');
|
|
142
149
|
if (!galleries) return;
|
|
143
150
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const mobGalleries = (mobDom as HTMLElement).querySelectorAll<HTMLElement>(
|
|
148
|
-
'.ml-gallery-thumb',
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
for (const [i, x] of mobGalleries.entries()) {
|
|
152
|
-
if (i > galleriesCount - 1) {
|
|
153
|
-
galleriesContainer.append(mobileGalleryToDesktop(x));
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
151
|
+
await new Promise((resolve) => {
|
|
152
|
+
waitForElementToAppear(document, '.thumb-container.gallery-container', resolve);
|
|
153
|
+
});
|
|
157
154
|
|
|
158
|
-
|
|
155
|
+
const mobDom = await fetchWith<HTMLElement>(window.location.href, {
|
|
156
|
+
type: 'html',
|
|
157
|
+
mobile: true,
|
|
158
|
+
});
|
|
159
|
+
const mobGalleries = mobDom.querySelectorAll<HTMLElement>('.ml-gallery-thumb');
|
|
159
160
|
|
|
160
|
-
const
|
|
161
|
-
#categories-page.inner ${x} }`;
|
|
161
|
+
const galleriesContainer = galleries.querySelector('.content-inner') as HTMLElement;
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
for (const x of mobGalleries.values()) {
|
|
164
|
+
const mobGallery = mobileGalleryToDesktop(x);
|
|
165
|
+
const mobGalleryId = (mobGallery.querySelector('a') as HTMLAnchorElement).href
|
|
166
|
+
.split('/')
|
|
167
|
+
.at(-1);
|
|
168
|
+
if (galleriesContainer.querySelector(`a[href*=${mobGalleryId}]`)) continue;
|
|
169
|
+
galleriesContainer.append(mobGallery);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
164
172
|
|
|
165
173
|
GM_addStyle(`
|
|
166
174
|
.img-container, .desktop-thumb { min-height: 150px; max-height: 150px; }
|
|
@@ -176,8 +184,6 @@ document
|
|
|
176
184
|
.querySelector('.ml-pagination')
|
|
177
185
|
?.before(GM_addElement('div', { class: 'clear-left' }));
|
|
178
186
|
|
|
179
|
-
//====================================================================================================
|
|
180
|
-
|
|
181
187
|
function applySearchFilters() {
|
|
182
188
|
let pathname = window.location.pathname;
|
|
183
189
|
|
|
@@ -195,11 +201,10 @@ function applySearchFilters() {
|
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
//====================================================================================================
|
|
199
|
-
|
|
200
204
|
desktopAddMobGalleries().then(() => fixURLs());
|
|
201
205
|
|
|
202
206
|
const IS_SEARCH = /^\/term\//.test(location.pathname);
|
|
203
|
-
|
|
207
|
+
|
|
208
|
+
if (IS_SEARCH && rules.store.state.applyTitleFiltersToSearch) {
|
|
204
209
|
applySearchFilters();
|
|
205
210
|
}
|
|
@@ -4,7 +4,7 @@ import { Rules } from '../../core';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'NameThatPorn PervertMonkey',
|
|
7
|
-
version: '3.0.
|
|
7
|
+
version: '3.0.20',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title, Uploader and Solved/Unsolved',
|
|
9
9
|
match: ['https://namethatporn.com/*'],
|
|
10
10
|
};
|
|
@@ -4,7 +4,7 @@ import { parseHtml } from '../../utils';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'NHentai PervertMonkey',
|
|
7
|
-
version: '4.0.
|
|
7
|
+
version: '4.0.20',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: ['https://*.nhentai.net/*', 'https://*.nhentai.*/*'],
|
|
10
10
|
};
|
|
@@ -5,7 +5,7 @@ import { fetchHtml, parseUrl } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Obmenvsem PervertMonkey',
|
|
8
|
-
version: '1.0.
|
|
8
|
+
version: '1.0.22',
|
|
9
9
|
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
10
10
|
match: [
|
|
11
11
|
'https://*.obmenvsem.com/*',
|
|
@@ -3,7 +3,7 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'PornHub PervertMonkey',
|
|
6
|
-
version: '4.0.
|
|
6
|
+
version: '4.0.20',
|
|
7
7
|
description:
|
|
8
8
|
'Infinite scroll [optional]. Filter by Title, Uploader and Duration. Sort by Duration and Views',
|
|
9
9
|
match: ['https://*.pornhub.com/*'],
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
|
+
|
|
4
|
+
export const meta: MonkeyUserScript = {
|
|
5
|
+
name: 'Simpcity PervertMonkey',
|
|
6
|
+
version: '1.0.2',
|
|
7
|
+
description: 'Infinite scroll [optional], Filter by Title',
|
|
8
|
+
match: 'https://simpcity.cr/threads/*',
|
|
9
|
+
'run-at': 'document-end',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const rules = new Rules({
|
|
13
|
+
containerSelector: '.js-replyNewMessageContainer',
|
|
14
|
+
paginationStrategyOptions: {
|
|
15
|
+
paginationSelector: '.block-container + * .pageNav',
|
|
16
|
+
pathnameSelector: /\/page-(\d+)\/?$/,
|
|
17
|
+
},
|
|
18
|
+
thumbs: {
|
|
19
|
+
selector: 'article.message',
|
|
20
|
+
},
|
|
21
|
+
thumb: {
|
|
22
|
+
strategy: 'auto-text',
|
|
23
|
+
getUrlSelector: 'a[href*=threads]',
|
|
24
|
+
},
|
|
25
|
+
gropeStrategy: 'all-in-all',
|
|
26
|
+
schemeOptions: ['Title Filter', 'Badge', 'Advanced'],
|
|
27
|
+
});
|
|
@@ -3,7 +3,7 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Socialmediagirls PervertMonkey',
|
|
6
|
-
version: '1.0.
|
|
6
|
+
version: '1.0.5',
|
|
7
7
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
8
8
|
match: 'https://forums.socialmediagirls.com/threads/*',
|
|
9
9
|
'run-at': 'document-end',
|
|
@@ -12,14 +12,15 @@ export const meta: MonkeyUserScript = {
|
|
|
12
12
|
const rules = new Rules({
|
|
13
13
|
containerSelector: '.js-replyNewMessageContainer',
|
|
14
14
|
paginationStrategyOptions: {
|
|
15
|
-
paginationSelector: '.
|
|
16
|
-
pathnameSelector:
|
|
15
|
+
paginationSelector: '.block-container + * .pageNav',
|
|
16
|
+
pathnameSelector: /\/page-(\d+)\/?$/,
|
|
17
17
|
},
|
|
18
18
|
thumbs: {
|
|
19
19
|
selector: 'article.message',
|
|
20
20
|
},
|
|
21
21
|
thumb: {
|
|
22
22
|
strategy: 'auto-text',
|
|
23
|
+
getUrlSelector: 'a[href*=threads]',
|
|
23
24
|
},
|
|
24
25
|
gropeStrategy: 'all-in-all',
|
|
25
26
|
schemeOptions: ['Title Filter', 'Badge', 'Advanced'],
|
|
@@ -3,7 +3,7 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'SpankBang.com PervertMonkey',
|
|
6
|
-
version: '4.0
|
|
6
|
+
version: '4.1.0',
|
|
7
7
|
description:
|
|
8
8
|
'Infinite scroll [optional]. Filter by Title and Duration. Sort by Duration and Views',
|
|
9
9
|
match: ['https://*.spankbang.com/*', 'https://*.spankbang.*/*'],
|
|
@@ -27,9 +27,25 @@ const rules = new Rules({
|
|
|
27
27
|
thumbImg: { strategy: 'auto' },
|
|
28
28
|
gropeStrategy: 'all-in-all',
|
|
29
29
|
customDataFilterFns: [
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
{
|
|
31
|
+
qualityFilter: {
|
|
32
|
+
handle(el, state) {
|
|
33
|
+
const hasAnyQualitySelected =
|
|
34
|
+
state.qualityLow ||
|
|
35
|
+
state.qualityHD ||
|
|
36
|
+
state.quality4k;
|
|
37
|
+
|
|
38
|
+
if (!hasAnyQualitySelected) return false;
|
|
39
|
+
|
|
40
|
+
return !(
|
|
41
|
+
(state.qualityLow && el.quality === '') ||
|
|
42
|
+
(state.qualityHD && el.quality === 'HD') ||
|
|
43
|
+
(state.quality4k && el.quality === '4K')
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
deps: ['qualityLow', 'qualityHD', 'quality4k'],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
33
49
|
],
|
|
34
50
|
schemeOptions: [
|
|
35
51
|
'Title Filter',
|