pervert-monkey 1.0.13 → 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 +90 -36
- package/dist/core/pervertmonkey.core.es.js +258 -129
- package/dist/core/pervertmonkey.core.es.js.map +1 -1
- package/dist/core/pervertmonkey.core.umd.js +258 -129
- package/dist/core/pervertmonkey.core.umd.js.map +1 -1
- package/dist/userscripts/3hentai.user.js +4 -5
- package/dist/userscripts/camgirlfinder.user.js +2 -2
- package/dist/userscripts/camwhores.user.js +7 -16
- package/dist/userscripts/e-hentai.user.js +8 -8
- package/dist/userscripts/ebalka.user.js +18 -10
- package/dist/userscripts/eporner.user.js +24 -41
- package/dist/userscripts/erome.user.js +13 -16
- package/dist/userscripts/eroprofile.user.js +5 -14
- package/dist/userscripts/javhdporn.user.js +6 -5
- package/dist/userscripts/missav.user.js +10 -4
- package/dist/userscripts/motherless.user.js +13 -6
- package/dist/userscripts/namethatporn.user.js +10 -16
- package/dist/userscripts/nhentai.user.js +5 -13
- package/dist/userscripts/obmenvsem.user.js +11 -4
- package/dist/userscripts/pornhub.user.js +14 -6
- package/dist/userscripts/spankbang.user.js +28 -7
- package/dist/userscripts/thisvid.user.js +15 -33
- package/dist/userscripts/xhamster.user.js +13 -18
- package/dist/userscripts/xvideos.user.js +33 -5
- package/package.json +1 -1
- package/src/core/data-handler/data-filter-fn-defaults.ts +52 -0
- package/src/core/data-handler/data-filter-fn.ts +62 -0
- package/src/core/data-handler/data-filter.ts +31 -103
- package/src/core/data-handler/data-manager.ts +91 -28
- package/src/core/jabroni-config/default-scheme.ts +54 -5
- package/src/core/jabroni-config/index.ts +1 -0
- package/src/core/jabroni-config/jabroni-gui-controller.ts +1 -1
- package/src/core/jabroni-config/scheme-selectors-mapping.ts +12 -0
- package/src/core/parsers/thumb-data-parser.ts +15 -19
- package/src/core/rules/index.ts +15 -9
- package/src/userscripts/index.ts +1 -1
- package/src/userscripts/scripts/3hentai.ts +3 -4
- package/src/userscripts/scripts/camgirlfinder.ts +1 -1
- package/src/userscripts/scripts/camwhores.ts +5 -14
- package/src/userscripts/scripts/e-hentai.ts +12 -12
- package/src/userscripts/scripts/ebalka.ts +16 -8
- package/src/userscripts/scripts/eporner.ts +23 -39
- package/src/userscripts/scripts/erome.ts +13 -17
- package/src/userscripts/scripts/eroprofile.ts +4 -12
- package/src/userscripts/scripts/javhdporn.ts +7 -8
- package/src/userscripts/scripts/missav.ts +10 -4
- package/src/userscripts/scripts/motherless.ts +13 -7
- package/src/userscripts/scripts/namethatporn.ts +10 -17
- package/src/userscripts/scripts/nhentai.ts +6 -13
- package/src/userscripts/scripts/obmenvsem.ts +14 -4
- package/src/userscripts/scripts/pornhub.ts +13 -4
- package/src/userscripts/scripts/spankbang.ts +29 -5
- package/src/userscripts/scripts/thisvid.ts +16 -31
- package/src/userscripts/scripts/xhamster.ts +13 -18
- package/src/userscripts/scripts/xvideos.ts +32 -3
- package/src/utils/dom/dom-observers.ts +3 -3
- package/src/utils/dom/index.ts +1 -1
- package/src/utils/parsers/index.ts +5 -2
|
@@ -17,9 +17,9 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export const meta: MonkeyUserScript = {
|
|
19
19
|
name: 'CamWhores PervertMonkey',
|
|
20
|
-
version: '3.0.
|
|
20
|
+
version: '3.0.10',
|
|
21
21
|
description:
|
|
22
|
-
'Infinite scroll [optional]. Filter by Title, Duration and Private/Public. Mass friend request button. Download button',
|
|
22
|
+
'Infinite scroll [optional]. Filter by Title, Duration and Private/Public. Sort by Duration and Views. Mass friend request button. Download button',
|
|
23
23
|
match: ['https://*.camwhores.tv', 'https://*.camwhores.*/*'],
|
|
24
24
|
exclude: 'https://*.camwhores.tv/*mode=async*',
|
|
25
25
|
};
|
|
@@ -54,27 +54,18 @@ const rules = new Rules({
|
|
|
54
54
|
strategy: 'auto-select',
|
|
55
55
|
selectors: {
|
|
56
56
|
private: { type: 'boolean', selector: '[class*=private]' },
|
|
57
|
+
views: { selector: '.views', type: 'float' },
|
|
57
58
|
},
|
|
58
59
|
},
|
|
59
60
|
thumbImg: {
|
|
60
61
|
selector: 'data-original',
|
|
61
62
|
},
|
|
62
63
|
gropeStrategy: 'all-in-all',
|
|
63
|
-
customDataSelectorFns: [
|
|
64
|
-
'filterInclude',
|
|
65
|
-
'filterExclude',
|
|
66
|
-
'filterDuration',
|
|
67
|
-
{
|
|
68
|
-
filterPrivate: (e, state) => (state.filterPrivate && e.private) as boolean,
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
filterPublic: (e, state) => (state.filterPublic && !e.private) as boolean,
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
64
|
schemeOptions: [
|
|
75
|
-
'
|
|
65
|
+
'Title Filter',
|
|
76
66
|
'Duration Filter',
|
|
77
67
|
'Privacy Filter',
|
|
68
|
+
'Sort By',
|
|
78
69
|
'Badge',
|
|
79
70
|
{
|
|
80
71
|
title: 'Advanced',
|
|
@@ -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.7',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: ['https://*.e-hentai.org/*'],
|
|
10
10
|
};
|
|
@@ -13,33 +13,31 @@ const rules = new Rules({
|
|
|
13
13
|
thumbs: { selector: '.gl1t' },
|
|
14
14
|
thumb: {
|
|
15
15
|
selectors: {
|
|
16
|
-
title: '.glname'
|
|
17
|
-
}
|
|
16
|
+
title: '.glname',
|
|
17
|
+
},
|
|
18
18
|
},
|
|
19
19
|
thumbImg: {
|
|
20
20
|
selector: 'data-lazy-load',
|
|
21
21
|
},
|
|
22
22
|
containerSelectorLast: '.itg.gld',
|
|
23
23
|
paginationStrategyOptions: createPaginationStrategyOptions(),
|
|
24
|
-
|
|
25
|
-
schemeOptions: ['Text Filter', 'Badge', 'Advanced'],
|
|
24
|
+
schemeOptions: ['Title Filter', 'Badge', 'Advanced'],
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
function createPaginationStrategyOptions(): Rules['paginationStrategyOptions'] {
|
|
29
28
|
let nextLink: string;
|
|
30
29
|
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
30
|
+
function getNextLink(doc: Document | HTMLElement = document) {
|
|
31
|
+
return [...doc.querySelectorAll<HTMLAnchorElement>('a#dnext[href]')].pop()
|
|
32
|
+
?.href as string;
|
|
33
|
+
}
|
|
36
34
|
|
|
35
|
+
function getPaginationUrlGenerator() {
|
|
37
36
|
const paginationUrlGenerator = async (_: number) => {
|
|
38
37
|
if (!nextLink) {
|
|
39
38
|
nextLink = getNextLink();
|
|
40
39
|
return nextLink;
|
|
41
40
|
}
|
|
42
|
-
// need cache or reuse infinite scroller request
|
|
43
41
|
const doc = await fetchHtml(nextLink);
|
|
44
42
|
nextLink = getNextLink(doc);
|
|
45
43
|
return nextLink;
|
|
@@ -48,9 +46,11 @@ function createPaginationStrategyOptions(): Rules['paginationStrategyOptions'] {
|
|
|
48
46
|
return paginationUrlGenerator;
|
|
49
47
|
}
|
|
50
48
|
|
|
49
|
+
const totalTitles = Number.parseInt(getNextLink()?.match(/\d+$/)?.[0] || '0');
|
|
50
|
+
|
|
51
51
|
return {
|
|
52
52
|
paginationSelector: '.searchnav + div + .searchnav',
|
|
53
|
-
overwritePaginationLast: () =>
|
|
53
|
+
overwritePaginationLast: () => totalTitles,
|
|
54
54
|
getPaginationUrlGenerator,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
@@ -4,8 +4,8 @@ import { exterminateVideo, OnHover, parseHtml } from '../../utils';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'Ebalka PervertMonkey',
|
|
7
|
-
version: '3.0.
|
|
8
|
-
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
7
|
+
version: '3.0.7',
|
|
8
|
+
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
9
9
|
match: [
|
|
10
10
|
'https://b.ebalka.zip/*',
|
|
11
11
|
'https://a.ebalka.love/*',
|
|
@@ -27,25 +27,33 @@ const rules = new Rules({
|
|
|
27
27
|
selectors: {
|
|
28
28
|
title: '.card__title',
|
|
29
29
|
duration: '.card__spot > span:last-child',
|
|
30
|
+
hd: { selector: '.card__icons > .card__icon', type: 'boolean' },
|
|
30
31
|
},
|
|
31
32
|
},
|
|
32
33
|
animatePreview,
|
|
33
|
-
schemeOptions: [
|
|
34
|
+
schemeOptions: [
|
|
35
|
+
'Title Filter',
|
|
36
|
+
'Duration Filter',
|
|
37
|
+
'HD Filter',
|
|
38
|
+
'Sort By Duration',
|
|
39
|
+
'Badge',
|
|
40
|
+
'Advanced',
|
|
41
|
+
],
|
|
34
42
|
});
|
|
35
43
|
|
|
36
44
|
function animatePreview(container: HTMLElement) {
|
|
37
45
|
function animateThumb(thumb: HTMLElement) {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
const src =
|
|
46
|
+
const e = thumb.querySelector('.card__thumb_video') as HTMLElement;
|
|
47
|
+
e.classList.toggle('video-on');
|
|
48
|
+
const src = e.querySelector('.card__image')?.getAttribute('data-preview') as string;
|
|
41
49
|
|
|
42
50
|
const videoElem =
|
|
43
51
|
parseHtml(`<video style="position: absolute; left: 0px; top: 0px; visibility: visible; margin-top: -1px;"
|
|
44
52
|
autoplay="" loop="" playsinline="true" webkit-playsinline="true" src="${src}"></video>`) as HTMLVideoElement;
|
|
45
|
-
|
|
53
|
+
e.appendChild(videoElem);
|
|
46
54
|
|
|
47
55
|
return () => {
|
|
48
|
-
|
|
56
|
+
e.classList.toggle('video-on');
|
|
49
57
|
exterminateVideo(videoElem);
|
|
50
58
|
};
|
|
51
59
|
}
|
|
@@ -5,8 +5,9 @@ import { OnHover } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Eporner PervertMonkey',
|
|
8
|
-
version: '2.0.
|
|
9
|
-
description:
|
|
8
|
+
version: '2.0.9',
|
|
9
|
+
description:
|
|
10
|
+
'Infinite scroll [optional], Filter by Title, Uploader, Duration and HD, Sort by Views and Duration',
|
|
10
11
|
match: ['https://*.eporner.com/*', 'https://*.eporner.*/*'],
|
|
11
12
|
};
|
|
12
13
|
|
|
@@ -19,10 +20,11 @@ const rules = new Rules({
|
|
|
19
20
|
thumbs: { selector: 'div[id^=vf][data-id]' },
|
|
20
21
|
thumb: {
|
|
21
22
|
selectors: {
|
|
22
|
-
quality: { type: 'number', selector: '[title="Quality"]' },
|
|
23
23
|
title: 'a',
|
|
24
24
|
uploader: '[title="Uploader"]',
|
|
25
25
|
duration: '[title="Duration"]',
|
|
26
|
+
views: { selector: '[title="Views"]', type: 'float' },
|
|
27
|
+
quality: { selector: '[title="Quality"]', type: 'number' },
|
|
26
28
|
},
|
|
27
29
|
},
|
|
28
30
|
thumbImg: {
|
|
@@ -30,52 +32,34 @@ const rules = new Rules({
|
|
|
30
32
|
remove: 'auto',
|
|
31
33
|
},
|
|
32
34
|
containerSelectorLast: '#vidresults',
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
quality480: (el, state) => !!state.quality480 && el.quality !== 480,
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
quality720: (el, state) => !!state.quality720 && el.quality !== 720,
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
quality1080: (el, state) => !!state.quality1080 && el.quality !== 1080,
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
quality4k: (el, state) => !!state.quality4k && el.quality !== 4,
|
|
51
|
-
},
|
|
35
|
+
customDataFilterFns: [
|
|
36
|
+
{ quality360: (el, state) => !!state.quality360 && el.quality !== 360 },
|
|
37
|
+
{ quality480: (el, state) => !!state.quality480 && el.quality !== 480 },
|
|
38
|
+
{ quality720: (el, state) => !!state.quality720 && el.quality !== 720 },
|
|
39
|
+
{ quality1080: (el, state) => !!state.quality1080 && el.quality !== 1080 },
|
|
40
|
+
{ quality2k: (el, state) => !!state.quality2k && el.quality !== 2 },
|
|
41
|
+
{ quality4k: (el, state) => !!state.quality4k && el.quality !== 4 },
|
|
52
42
|
],
|
|
53
43
|
schemeOptions: [
|
|
54
|
-
'
|
|
55
|
-
'
|
|
44
|
+
'Title Filter',
|
|
45
|
+
'Uploader Filter',
|
|
56
46
|
'Duration Filter',
|
|
57
47
|
{
|
|
58
48
|
title: 'Quality Filter ',
|
|
59
49
|
content: [
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
quality720: false,
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
quality1080: false,
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
quality4k: false,
|
|
74
|
-
},
|
|
50
|
+
{ quality360: false },
|
|
51
|
+
{ quality480: false },
|
|
52
|
+
{ quality720: false },
|
|
53
|
+
{ quality1080: false },
|
|
54
|
+
{ quality2k: false },
|
|
55
|
+
{ quality4k: false },
|
|
75
56
|
],
|
|
76
57
|
},
|
|
58
|
+
'Sort By',
|
|
59
|
+
'Badge',
|
|
77
60
|
'Advanced',
|
|
78
61
|
],
|
|
62
|
+
gropeStrategy: 'all-in-all',
|
|
79
63
|
animatePreview,
|
|
80
64
|
});
|
|
81
65
|
|
|
@@ -4,8 +4,9 @@ import { Rules } from '../../core';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'Erome PervertMonkey',
|
|
7
|
-
version: '5.0.
|
|
8
|
-
description:
|
|
7
|
+
version: '5.0.8',
|
|
8
|
+
description:
|
|
9
|
+
'Infinite scroll [optional], Filter by Title, Uploader and Video/Photo albums, Sort by Views. Show/Hide Photos in album. Remove disclaimer.',
|
|
9
10
|
match: ['*://*.erome.com/*'],
|
|
10
11
|
};
|
|
11
12
|
|
|
@@ -22,37 +23,32 @@ const rules = new Rules({
|
|
|
22
23
|
selectors: {
|
|
23
24
|
title: '.album-title',
|
|
24
25
|
uploader: '.album-user',
|
|
25
|
-
videoAlbum: {
|
|
26
|
+
videoAlbum: { selector: '.album-videos', type: 'boolean' },
|
|
27
|
+
views: { selector: '.album-bottom-views', type: 'float' },
|
|
26
28
|
},
|
|
27
29
|
},
|
|
28
30
|
storeOptions: { showPhotos: true },
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
filterPhotoAlbums: (el, state) =>
|
|
34
|
-
(state.filterPhotoAlbums && !el.videoAlbum) as boolean,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
filterVideoAlbums: (el, state) =>
|
|
38
|
-
(state.filterVideoAlbums && el.videoAlbum) as boolean,
|
|
39
|
-
},
|
|
31
|
+
customDataFilterFns: [
|
|
32
|
+
{ filterPhotoAlbums: (el, state) => !!state.filterPhotoAlbums && !el.videoAlbum },
|
|
33
|
+
{ filterVideoAlbums: (el, state) => !!state.filterVideoAlbums && !!el.videoAlbum },
|
|
40
34
|
],
|
|
41
35
|
schemeOptions: [
|
|
42
|
-
'
|
|
36
|
+
'Title Filter',
|
|
37
|
+
'Uploader Filter',
|
|
43
38
|
{
|
|
44
39
|
title: 'Filter Albums',
|
|
45
40
|
content: [
|
|
46
41
|
{
|
|
47
42
|
filterVideoAlbums: false,
|
|
48
|
-
label: '
|
|
43
|
+
label: 'photo',
|
|
49
44
|
},
|
|
50
45
|
{
|
|
51
46
|
filterPhotoAlbums: false,
|
|
52
|
-
label: '
|
|
47
|
+
label: 'video',
|
|
53
48
|
},
|
|
54
49
|
],
|
|
55
50
|
},
|
|
51
|
+
'Sort By Views',
|
|
56
52
|
'Badge',
|
|
57
53
|
'Advanced',
|
|
58
54
|
],
|
|
@@ -3,8 +3,8 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Eroprofile PervertMonkey',
|
|
6
|
-
version: '2.0.
|
|
7
|
-
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
6
|
+
version: '2.0.7',
|
|
7
|
+
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
8
8
|
match: ['https://*.eroprofile.com/*'],
|
|
9
9
|
};
|
|
10
10
|
|
|
@@ -23,18 +23,10 @@ const rules = new Rules({
|
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
containerSelector: '.videoGrid',
|
|
26
|
-
customDataSelectorFns: ['filterInclude', 'filterExclude', 'filterDuration'],
|
|
27
26
|
schemeOptions: [
|
|
28
|
-
'
|
|
27
|
+
'Title Filter',
|
|
29
28
|
'Duration Filter',
|
|
30
|
-
|
|
31
|
-
title: 'Sort By ',
|
|
32
|
-
content: [
|
|
33
|
-
{
|
|
34
|
-
'sort by duration': () => {},
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
},
|
|
29
|
+
'Sort By Duration',
|
|
38
30
|
'Badge',
|
|
39
31
|
'Advanced',
|
|
40
32
|
],
|
|
@@ -3,12 +3,10 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Javhdporn PervertMonkey',
|
|
6
|
-
version: '3.0.
|
|
7
|
-
description:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"https://*.javhdporn.*/*"
|
|
11
|
-
],
|
|
6
|
+
version: '3.0.7',
|
|
7
|
+
description:
|
|
8
|
+
'Infinite scroll [optional], Filter by Title and Duration, Sort By Duration and Views',
|
|
9
|
+
match: ['https://*.javhdporn.net/*', 'https://*.javhdporn.*/*'],
|
|
12
10
|
};
|
|
13
11
|
|
|
14
12
|
const rules = new Rules({
|
|
@@ -18,10 +16,11 @@ const rules = new Rules({
|
|
|
18
16
|
selectors: {
|
|
19
17
|
title: 'header.entry-header',
|
|
20
18
|
duration: '.duration',
|
|
21
|
-
|
|
19
|
+
views: { selector: '.views', type: 'float' },
|
|
20
|
+
},
|
|
22
21
|
},
|
|
23
22
|
paginationStrategyOptions: {
|
|
24
23
|
pathnameSelector: /\/page\/(\d+)\/?$/,
|
|
25
24
|
},
|
|
26
|
-
schemeOptions: ['
|
|
25
|
+
schemeOptions: ['Title Filter', 'Duration Filter', 'Sort By', 'Badge', 'Advanced'],
|
|
27
26
|
});
|
|
@@ -3,8 +3,8 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Missav PervertMonkey',
|
|
6
|
-
version: '3.0.
|
|
7
|
-
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
6
|
+
version: '3.0.7',
|
|
7
|
+
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
8
8
|
match: [
|
|
9
9
|
'https://*.missav123.com/*',
|
|
10
10
|
'https://*.missav.*/*',
|
|
@@ -24,8 +24,14 @@ const rules = new Rules({
|
|
|
24
24
|
selectors: {
|
|
25
25
|
title: 'div > div > a.text-secondary',
|
|
26
26
|
duration: 'div > a > span.text-xs',
|
|
27
|
-
}
|
|
27
|
+
},
|
|
28
28
|
},
|
|
29
29
|
thumbImg: { strategy: 'auto' },
|
|
30
|
-
schemeOptions: [
|
|
30
|
+
schemeOptions: [
|
|
31
|
+
'Title Filter',
|
|
32
|
+
'Duration Filter',
|
|
33
|
+
'Sort By Duration',
|
|
34
|
+
'Badge',
|
|
35
|
+
'Advanced',
|
|
36
|
+
],
|
|
31
37
|
});
|
|
@@ -5,8 +5,9 @@ import { fetchWith, OnHover, replaceElementTag, Tick } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Motherless PervertMonkey',
|
|
8
|
-
version: '5.0.
|
|
9
|
-
description:
|
|
8
|
+
version: '5.0.8',
|
|
9
|
+
description:
|
|
10
|
+
'Infinite scroll [optional], Filter by Title, Uploader and Duration, Sort by Duration and Views',
|
|
10
11
|
match: ['https://motherless.com/*'],
|
|
11
12
|
grant: ['GM_addElement', 'GM_addStyle', 'unsafeWindow'],
|
|
12
13
|
};
|
|
@@ -31,7 +32,14 @@ const rules = new Rules({
|
|
|
31
32
|
},
|
|
32
33
|
animatePreview,
|
|
33
34
|
gropeStrategy: 'all-in-all',
|
|
34
|
-
schemeOptions: [
|
|
35
|
+
schemeOptions: [
|
|
36
|
+
'Title Filter',
|
|
37
|
+
'Uploader Filter',
|
|
38
|
+
'Duration Filter',
|
|
39
|
+
'Sort By',
|
|
40
|
+
'Badge',
|
|
41
|
+
'Advanced',
|
|
42
|
+
],
|
|
35
43
|
});
|
|
36
44
|
|
|
37
45
|
function animatePreview(_: HTMLElement) {
|
|
@@ -152,7 +160,7 @@ async function desktopAddMobGalleries() {
|
|
|
152
160
|
const overwrite1 = (x: string) => `@media only screen and (max-width: 1280px) {
|
|
153
161
|
#categories-page.inner ${x} }`;
|
|
154
162
|
|
|
155
|
-
rules.dataManager.dataFilter.
|
|
163
|
+
rules.dataManager.dataFilter.createCssFilters(overwrite1);
|
|
156
164
|
|
|
157
165
|
GM_addStyle(`
|
|
158
166
|
.img-container, .desktop-thumb { min-height: 150px; max-height: 150px; }
|
|
@@ -174,9 +182,7 @@ function applySearchFilters() {
|
|
|
174
182
|
let pathname = window.location.pathname;
|
|
175
183
|
|
|
176
184
|
const wordsToFilter =
|
|
177
|
-
(rules.store.state.filterExcludeWords as string)
|
|
178
|
-
.replace(/f:/g, '')
|
|
179
|
-
.match(/(?<!user:)\b\w+\b(?!\s*:)/g) || [];
|
|
185
|
+
(rules.store.state.filterExcludeWords as string).match(/\w+/g) || [];
|
|
180
186
|
|
|
181
187
|
wordsToFilter
|
|
182
188
|
.filter((w) => !pathname.includes(w))
|
|
@@ -4,8 +4,8 @@ import { Rules } from '../../core';
|
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'NameThatPorn PervertMonkey',
|
|
7
|
-
version: '3.0.
|
|
8
|
-
description: 'Infinite scroll [optional], Filter by Title and
|
|
7
|
+
version: '3.0.7',
|
|
8
|
+
description: 'Infinite scroll [optional], Filter by Title, Uploader and Solved/Unsolved',
|
|
9
9
|
match: ['https://namethatporn.com/*'],
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -16,35 +16,28 @@ const rules = new Rules({
|
|
|
16
16
|
selectors: {
|
|
17
17
|
title: '.item_title, .nsw_r_tit',
|
|
18
18
|
uploader: '.item_answer b, .nsw_r_desc',
|
|
19
|
-
solved: {
|
|
20
|
-
type: 'boolean',
|
|
21
|
-
selector: '.item_solved, .nsw_r_slvd',
|
|
22
|
-
},
|
|
19
|
+
solved: { selector: '.item_solved, .nsw_r_slvd', type: 'boolean' },
|
|
23
20
|
},
|
|
24
21
|
},
|
|
25
22
|
thumbImg: {
|
|
26
|
-
selector: (img: HTMLImageElement) =>
|
|
27
|
-
|
|
28
|
-
img.getAttribute('data-dyn')?.concat('.webp') || (img.getAttribute('src') as string)
|
|
29
|
-
);
|
|
30
|
-
},
|
|
23
|
+
selector: (img: HTMLImageElement) =>
|
|
24
|
+
img.getAttribute('data-dyn')?.concat('.webp') || (img.getAttribute('src') as string),
|
|
31
25
|
},
|
|
32
26
|
paginationStrategyOptions: {
|
|
33
27
|
paginationSelector: '#smi_wrp, #nsw_p',
|
|
34
28
|
},
|
|
35
29
|
gropeStrategy: 'all-in-all',
|
|
36
|
-
|
|
37
|
-
'filterInclude',
|
|
38
|
-
'filterExclude',
|
|
30
|
+
customDataFilterFns: [
|
|
39
31
|
{
|
|
40
|
-
filterSolved: (
|
|
32
|
+
filterSolved: (e, state) => (state.filterSolved && e.solved) as boolean,
|
|
41
33
|
},
|
|
42
34
|
{
|
|
43
|
-
filterUnsolved: (
|
|
35
|
+
filterUnsolved: (e, state) => (state.filterUnsolved && !e.solved) as boolean,
|
|
44
36
|
},
|
|
45
37
|
],
|
|
46
38
|
schemeOptions: [
|
|
47
|
-
'
|
|
39
|
+
'Title Filter',
|
|
40
|
+
'Uploader Filter',
|
|
48
41
|
{
|
|
49
42
|
title: 'Filter Status',
|
|
50
43
|
content: [
|
|
@@ -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.7',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: ['https://*.nhentai.net/*', 'https://*.nhentai.*/*'],
|
|
10
10
|
};
|
|
@@ -14,18 +14,10 @@ const IS_SEARCH_PAGE = /^\/search\//.test(location.pathname);
|
|
|
14
14
|
|
|
15
15
|
const nhentaiRules = new Rules({
|
|
16
16
|
thumbs: { selector: '.gallery' },
|
|
17
|
-
thumb: {
|
|
18
|
-
|
|
19
|
-
title: '.caption'
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
thumbImg: {
|
|
23
|
-
strategy: 'auto',
|
|
24
|
-
remove: 'auto'
|
|
25
|
-
},
|
|
17
|
+
thumb: { selectors: { title: '.caption' } },
|
|
18
|
+
thumbImg: { strategy: 'auto', remove: 'auto' },
|
|
26
19
|
containerSelectorLast: '.index-container, .container',
|
|
27
|
-
|
|
28
|
-
schemeOptions: ['Text Filter', 'Badge', 'Advanced'],
|
|
20
|
+
schemeOptions: ['Title Filter', 'Badge', 'Advanced'],
|
|
29
21
|
gropeStrategy: 'all-in-all',
|
|
30
22
|
});
|
|
31
23
|
|
|
@@ -57,7 +49,8 @@ function filtersUI() {
|
|
|
57
49
|
const btns = parseHtml(`<div class="sort-type"></div>`);
|
|
58
50
|
groupOfButtons.forEach((k) => {
|
|
59
51
|
const btn = parseHtml(
|
|
60
|
-
`<a href="#" ${
|
|
52
|
+
`<a href="#" ${
|
|
53
|
+
state.custom[k] ? 'style="background: rgba(59, 49, 70, 1)"' : ''
|
|
61
54
|
}>${filterDescriptors[k as keyof typeof filterDescriptors].name}</a>`,
|
|
62
55
|
);
|
|
63
56
|
btn.addEventListener('click', (e) => {
|
|
@@ -5,9 +5,13 @@ import { fetchHtml, parseUrl } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Obmensvem PervertMonkey',
|
|
8
|
-
version: '1.0.
|
|
9
|
-
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
10
|
-
match: [
|
|
8
|
+
version: '1.0.8',
|
|
9
|
+
description: 'Infinite scroll [optional], Filter by Title and Duration, Sort by Duration',
|
|
10
|
+
match: [
|
|
11
|
+
'https://*.obmenvsem.com/*',
|
|
12
|
+
'https://*.obmenvsem.*/*',
|
|
13
|
+
'https://*.obmenvsems.*/*',
|
|
14
|
+
],
|
|
11
15
|
grant: ['GM_addStyle', 'GM_addElement', 'unsafeWindow'],
|
|
12
16
|
};
|
|
13
17
|
|
|
@@ -67,5 +71,11 @@ const rules = new Rules({
|
|
|
67
71
|
return img.src;
|
|
68
72
|
},
|
|
69
73
|
},
|
|
70
|
-
schemeOptions: [
|
|
74
|
+
schemeOptions: [
|
|
75
|
+
'Title Filter',
|
|
76
|
+
'Duration Filter',
|
|
77
|
+
'Sort By Duration',
|
|
78
|
+
'Badge',
|
|
79
|
+
'Advanced',
|
|
80
|
+
],
|
|
71
81
|
});
|
|
@@ -3,8 +3,9 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'PornHub PervertMonkey',
|
|
6
|
-
version: '4.0.
|
|
7
|
-
description:
|
|
6
|
+
version: '4.0.7',
|
|
7
|
+
description:
|
|
8
|
+
'Infinite scroll [optional]. Filter by Title, Uploader and Duration. Sort by Duration and Views',
|
|
8
9
|
match: ['https://*.pornhub.com/*'],
|
|
9
10
|
exclude: 'https://*.pornhub.com/embed/*',
|
|
10
11
|
};
|
|
@@ -19,20 +20,28 @@ const rules = new Rules({
|
|
|
19
20
|
.filter((e) => e.children.length > 0 && e.checkVisibility())
|
|
20
21
|
.pop() as HTMLElement,
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
containerHomogenity: { id: true, className: true },
|
|
23
24
|
thumbs: { selector: 'li[data-video-vkey]' },
|
|
24
25
|
thumb: {
|
|
25
26
|
selectors: {
|
|
26
27
|
title: 'span.title',
|
|
27
28
|
uploader: '.usernameWrap',
|
|
28
29
|
duration: '.duration',
|
|
30
|
+
views: { selector: '.views', type: 'float' },
|
|
29
31
|
},
|
|
30
32
|
},
|
|
31
33
|
thumbImg: {
|
|
32
34
|
selector: ['data-mediumthumb', 'data-image'],
|
|
33
35
|
},
|
|
34
36
|
gropeStrategy: 'all-in-all',
|
|
35
|
-
schemeOptions: [
|
|
37
|
+
schemeOptions: [
|
|
38
|
+
'Title Filter',
|
|
39
|
+
'Uploader Filter',
|
|
40
|
+
'Duration Filter',
|
|
41
|
+
'Sort By',
|
|
42
|
+
'Badge',
|
|
43
|
+
'Advanced',
|
|
44
|
+
],
|
|
36
45
|
});
|
|
37
46
|
|
|
38
47
|
function bypassAgeVerification() {
|
|
@@ -3,8 +3,9 @@ import { Rules } from '../../core';
|
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'SpankBang.com PervertMonkey',
|
|
6
|
-
version: '4.0.
|
|
7
|
-
description:
|
|
6
|
+
version: '4.0.7',
|
|
7
|
+
description:
|
|
8
|
+
'Infinite scroll [optional]. Filter by Title and Duration. Sort by Duration and Views',
|
|
8
9
|
match: ['https://*.spankbang.com/*', 'https://*.spankbang.*/*'],
|
|
9
10
|
};
|
|
10
11
|
|
|
@@ -17,11 +18,34 @@ const rules = new Rules({
|
|
|
17
18
|
thumb: {
|
|
18
19
|
selectors: {
|
|
19
20
|
title: '[title]',
|
|
20
|
-
tags: { selector: '[data-testid="title"]', type: 'string' },
|
|
21
21
|
duration: '[data-testid="video-item-length"]',
|
|
22
|
-
|
|
22
|
+
// tags: { selector: '[data-testid="title"]', type: 'string' },
|
|
23
|
+
views: { selector: '[data-testid="views"]', type: 'float' },
|
|
24
|
+
quality: { selector: '[data-testid="video-item-resolution"]', type: 'string' },
|
|
25
|
+
},
|
|
23
26
|
},
|
|
24
27
|
thumbImg: { strategy: 'auto' },
|
|
25
28
|
gropeStrategy: 'all-in-all',
|
|
26
|
-
|
|
29
|
+
customDataFilterFns: [
|
|
30
|
+
{ qualityLow: (e, state) => !!state.qualityLow && e.quality !== '' },
|
|
31
|
+
{ qualityHD: (e, state) => !!state.qualityHD && e.quality !== 'HD' },
|
|
32
|
+
{ quality4k: (e, state) => !!state.quality4k && e.quality !== '4K' },
|
|
33
|
+
],
|
|
34
|
+
schemeOptions: [
|
|
35
|
+
'Title Filter',
|
|
36
|
+
'Duration Filter',
|
|
37
|
+
{
|
|
38
|
+
title: 'Quality Filter',
|
|
39
|
+
content: [
|
|
40
|
+
{ qualityLow: false, label: 'Low' },
|
|
41
|
+
{ qualityHD: false, label: 'HD' },
|
|
42
|
+
{ quality4k: false, label: '4K' },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
'Sort By',
|
|
46
|
+
'Badge',
|
|
47
|
+
'Advanced',
|
|
48
|
+
],
|
|
27
49
|
});
|
|
50
|
+
|
|
51
|
+
console.log(rules.dataManager.data.values().toArray());
|