pervert-monkey 1.0.9 → 1.0.10
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 +121 -59
- package/dist/core/pervertmonkey.core.es.js +1001 -315
- package/dist/core/pervertmonkey.core.es.js.map +1 -1
- package/dist/core/pervertmonkey.core.umd.js +1001 -315
- package/dist/core/pervertmonkey.core.umd.js.map +1 -1
- package/dist/userscripts/3hentai.user.js +14 -8
- package/dist/userscripts/camgirlfinder.user.js +1 -1
- package/dist/userscripts/camwhores.user.js +15 -9
- package/dist/userscripts/e-hentai.user.js +12 -6
- package/dist/userscripts/ebalka.user.js +11 -5
- package/dist/userscripts/eporner.user.js +15 -10
- package/dist/userscripts/erome.user.js +11 -10
- package/dist/userscripts/eroprofile.user.js +9 -5
- package/dist/userscripts/javhdporn.user.js +9 -5
- package/dist/userscripts/missav.user.js +10 -6
- package/dist/userscripts/motherless.user.js +11 -7
- package/dist/userscripts/namethatporn.user.js +17 -13
- package/dist/userscripts/nhentai.user.js +12 -6
- package/dist/userscripts/obmenvsem.user.js +14 -18
- package/dist/userscripts/pornhub.user.js +14 -10
- package/dist/userscripts/spankbang.user.js +10 -6
- package/dist/userscripts/thisvid.user.js +27 -21
- package/dist/userscripts/xhamster.user.js +26 -26
- package/dist/userscripts/xvideos.user.js +19 -17
- package/package.json +5 -3
- package/src/core/{data-control → data-handler}/data-filter.ts +3 -8
- package/src/core/{data-control → data-handler}/data-manager.ts +8 -7
- package/src/core/data-handler/index.ts +2 -0
- package/src/core/index.ts +4 -4
- package/src/core/infinite-scroll/index.ts +20 -29
- package/src/core/parsers/index.ts +4 -0
- package/src/core/{pagination-parsing → parsers/pagination-parser}/index.ts +3 -0
- package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategy.ts +1 -1
- package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategyDataParams.ts +1 -1
- package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategyPathnameParams.ts +2 -1
- package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-utils/index.ts +1 -4
- package/src/core/parsers/thumb-data-parser.ts +96 -0
- package/src/core/parsers/thumb-img-parser.ts +62 -0
- package/src/core/parsers/thumbs-parser.ts +29 -0
- package/src/core/rules/index.ts +39 -207
- package/src/userscripts/index.ts +1 -1
- package/src/userscripts/scripts/3hentai.ts +14 -6
- package/src/userscripts/scripts/camwhores.ts +19 -13
- package/src/userscripts/scripts/e-hentai.ts +13 -7
- package/src/userscripts/scripts/ebalka.ts +11 -5
- package/src/userscripts/scripts/eporner.ts +16 -10
- package/src/userscripts/scripts/erome.ts +11 -10
- package/src/userscripts/scripts/eroprofile.ts +10 -6
- package/src/userscripts/scripts/javhdporn.ts +9 -5
- package/src/userscripts/scripts/missav.ts +10 -6
- package/src/userscripts/scripts/motherless.ts +11 -7
- package/src/userscripts/scripts/namethatporn.ts +18 -14
- package/src/userscripts/scripts/nhentai.ts +13 -8
- package/src/userscripts/scripts/obmenvsem.ts +14 -13
- package/src/userscripts/scripts/pornhub.ts +14 -10
- package/src/userscripts/scripts/spankbang.ts +10 -6
- package/src/userscripts/scripts/thisvid.ts +32 -27
- package/src/userscripts/scripts/xhamster.ts +37 -38
- package/src/userscripts/scripts/xvideos.ts +18 -16
- package/src/utils/index.ts +7 -19
- package/src/utils/parsers/index.ts +4 -0
- package/src/utils/strings/index.ts +2 -0
- package/src/core/data-control/index.ts +0 -2
- /package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/PaginationStrategySearchParams.ts +0 -0
- /package/src/core/{pagination-parsing → parsers/pagination-parser}/pagination-strategies/index.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
2
|
import { GM_addStyle, unsafeWindow } from '$';
|
|
3
|
-
import {
|
|
3
|
+
import { Rules } from '../../core';
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'Erome PervertMonkey',
|
|
@@ -12,16 +12,17 @@ export const meta: MonkeyUserScript = {
|
|
|
12
12
|
const $ = (unsafeWindow as any).$;
|
|
13
13
|
declare var LazyLoad: ObjectConstructor;
|
|
14
14
|
|
|
15
|
-
const rules = new
|
|
15
|
+
const rules = new Rules({
|
|
16
16
|
containerSelector: '#albums',
|
|
17
|
-
thumbsSelector: 'div[id^=album-]',
|
|
18
|
-
titleSelector: '.album-title',
|
|
19
|
-
uploaderSelector: '.album-user',
|
|
20
17
|
gropeStrategy: 'all-in-one',
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
thumbs: {
|
|
19
|
+
selector: 'div[id^=album-]',
|
|
20
|
+
},
|
|
21
|
+
thumb: {
|
|
22
|
+
selectors: {
|
|
23
|
+
title: '.album-title',
|
|
24
|
+
uploader: '.album-user',
|
|
25
|
+
videoAlbum: { type: 'boolean', selector: '.album-videos' },
|
|
25
26
|
},
|
|
26
27
|
},
|
|
27
28
|
storeOptions: { showPhotos: true },
|
|
@@ -57,7 +58,7 @@ const rules = new RulesGlobal({
|
|
|
57
58
|
],
|
|
58
59
|
});
|
|
59
60
|
|
|
60
|
-
rules.infiniteScroller?.
|
|
61
|
+
rules.infiniteScroller?.subject.subscribe(() => {
|
|
61
62
|
setTimeout(() => new LazyLoad(), 100);
|
|
62
63
|
});
|
|
63
64
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import {
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Eroprofile PervertMonkey',
|
|
@@ -10,15 +10,19 @@ export const meta: MonkeyUserScript = {
|
|
|
10
10
|
|
|
11
11
|
document.querySelector('.videoGrid')?.after(document.querySelector('.clB') as HTMLElement);
|
|
12
12
|
|
|
13
|
-
const rules = new
|
|
13
|
+
const rules = new Rules({
|
|
14
14
|
paginationStrategyOptions: {
|
|
15
15
|
paginationSelector: '.boxNav2',
|
|
16
16
|
searchParamSelector: 'pnum',
|
|
17
17
|
},
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
thumbs: { selector: '.video' },
|
|
19
|
+
thumb: {
|
|
20
|
+
selectors: {
|
|
21
|
+
title: '[title]',
|
|
22
|
+
duration: '.videoDur',
|
|
23
|
+
}
|
|
24
|
+
},
|
|
20
25
|
containerSelector: '.videoGrid',
|
|
21
|
-
thumbsSelector: '.video',
|
|
22
26
|
customDataSelectorFns: ['filterInclude', 'filterExclude', 'filterDuration'],
|
|
23
27
|
schemeOptions: [
|
|
24
28
|
'Text Filter',
|
|
@@ -27,7 +31,7 @@ const rules = new RulesGlobal({
|
|
|
27
31
|
title: 'Sort By ',
|
|
28
32
|
content: [
|
|
29
33
|
{
|
|
30
|
-
'sort by duration': () => {},
|
|
34
|
+
'sort by duration': () => { },
|
|
31
35
|
},
|
|
32
36
|
],
|
|
33
37
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import {
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Javhdporn PervertMonkey',
|
|
@@ -11,11 +11,15 @@ export const meta: MonkeyUserScript = {
|
|
|
11
11
|
],
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
const rules = new
|
|
14
|
+
const rules = new Rules({
|
|
15
15
|
containerSelector: 'div:has(> article)',
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
thumbs: { selector: 'article.thumb-block' },
|
|
17
|
+
thumb: {
|
|
18
|
+
selectors: {
|
|
19
|
+
title: 'header.entry-header',
|
|
20
|
+
duration: '.duration',
|
|
21
|
+
}
|
|
22
|
+
},
|
|
19
23
|
paginationStrategyOptions: {
|
|
20
24
|
pathnameSelector: /\/page\/(\d+)\/?$/,
|
|
21
25
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import {
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'Missav PervertMonkey',
|
|
@@ -14,14 +14,18 @@ export const meta: MonkeyUserScript = {
|
|
|
14
14
|
],
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const rules = new
|
|
17
|
+
const rules = new Rules({
|
|
18
18
|
paginationStrategyOptions: {
|
|
19
19
|
paginationSelector: 'nav[x-data]',
|
|
20
20
|
},
|
|
21
21
|
containerSelector: '.grid[x-data]',
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
thumbs: { selector: 'div:has(> .thumbnail.group)' },
|
|
23
|
+
thumb: {
|
|
24
|
+
selectors: {
|
|
25
|
+
title: 'div > div > a.text-secondary',
|
|
26
|
+
duration: 'div > a > span.text-xs',
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
thumbImg: { strategy: 'auto' },
|
|
26
30
|
schemeOptions: ['Text Filter', 'Duration Filter', 'Badge', 'Advanced'],
|
|
27
31
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
2
|
import { GM_addElement, GM_addStyle, unsafeWindow } from '$';
|
|
3
|
-
import {
|
|
3
|
+
import { Rules } from '../../core';
|
|
4
4
|
import { fetchWith, OnHover, replaceElementTag, Tick } from '../../utils';
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
@@ -14,13 +14,17 @@ export const meta: MonkeyUserScript = {
|
|
|
14
14
|
(unsafeWindow as any).__is_premium = true;
|
|
15
15
|
const $ = (unsafeWindow as any).$;
|
|
16
16
|
|
|
17
|
-
const rules = new
|
|
17
|
+
const rules = new Rules({
|
|
18
18
|
containerSelectorLast: '.content-inner',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
thumbs: { selector: '.thumb-container, .mobile-thumb' },
|
|
20
|
+
thumb: {
|
|
21
|
+
selectors: {
|
|
22
|
+
uploader: '.uploader',
|
|
23
|
+
title: '.title',
|
|
24
|
+
duration: '.size',
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
thumbImg: { strategy: 'auto' },
|
|
24
28
|
paginationStrategyOptions: {
|
|
25
29
|
paginationSelector: '.pagination_link, .ml-pagination',
|
|
26
30
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
2
|
import { unsafeWindow } from '$';
|
|
3
|
-
import {
|
|
3
|
+
import { Rules } from '../../core';
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
6
6
|
name: 'NameThatPorn PervertMonkey',
|
|
@@ -9,24 +9,28 @@ export const meta: MonkeyUserScript = {
|
|
|
9
9
|
match: ['https://namethatporn.com/*'],
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const rules = new
|
|
13
|
-
|
|
12
|
+
const rules = new Rules({
|
|
13
|
+
thumbs: { selector: '.item, .nsw_r_w' },
|
|
14
14
|
containerSelector: '#items_wrapper, #nsw_r',
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
thumb: {
|
|
16
|
+
selectors: {
|
|
17
|
+
title: '.item_title, .nsw_r_tit',
|
|
18
|
+
uploader: '.item_answer b, .nsw_r_desc',
|
|
19
|
+
solved: {
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
selector: '.item_solved, .nsw_r_slvd',
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
thumbImg: {
|
|
26
|
+
strategy: 'auto',
|
|
27
|
+
selector: (img: HTMLImageElement) =>
|
|
28
|
+
img.getAttribute('data-dyn')?.concat('.webp') || (img.getAttribute('src') as string),
|
|
29
|
+
},
|
|
17
30
|
paginationStrategyOptions: {
|
|
18
31
|
paginationSelector: '#smi_wrp, #nsw_p',
|
|
19
32
|
},
|
|
20
|
-
customThumbDataSelectors: {
|
|
21
|
-
solved: {
|
|
22
|
-
type: 'boolean',
|
|
23
|
-
selector: '.item_solved, .nsw_r_slvd',
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
33
|
gropeStrategy: 'all-in-all',
|
|
27
|
-
getThumbImgDataStrategy: 'auto',
|
|
28
|
-
getThumbImgDataAttrSelector: (img: HTMLImageElement) =>
|
|
29
|
-
img.getAttribute('data-dyn')?.concat('.webp') || (img.getAttribute('src') as string),
|
|
30
34
|
customDataSelectorFns: [
|
|
31
35
|
'filterInclude',
|
|
32
36
|
'filterExclude',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import {
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
3
|
import { parseHtml } from '../../utils';
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
@@ -12,12 +12,18 @@ export const meta: MonkeyUserScript = {
|
|
|
12
12
|
const IS_TITLE_PAGE = /^\/g\/\d+/.test(location.pathname);
|
|
13
13
|
const IS_SEARCH_PAGE = /^\/search\//.test(location.pathname);
|
|
14
14
|
|
|
15
|
-
const nhentaiRules = new
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const nhentaiRules = new Rules({
|
|
16
|
+
thumbs: { selector: '.gallery' },
|
|
17
|
+
thumb: {
|
|
18
|
+
selectors: {
|
|
19
|
+
title: '.caption'
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
thumbImg: {
|
|
23
|
+
strategy: 'auto',
|
|
24
|
+
shouldDelete: 'auto'
|
|
25
|
+
},
|
|
19
26
|
containerSelectorLast: '.index-container, .container',
|
|
20
|
-
titleSelector: '.caption',
|
|
21
27
|
customDataSelectorFns: ['filterInclude', 'filterExclude'],
|
|
22
28
|
schemeOptions: ['Text Filter', 'Badge', 'Advanced'],
|
|
23
29
|
gropeStrategy: 'all-in-all',
|
|
@@ -51,8 +57,7 @@ function filtersUI() {
|
|
|
51
57
|
const btns = parseHtml(`<div class="sort-type"></div>`);
|
|
52
58
|
groupOfButtons.forEach((k) => {
|
|
53
59
|
const btn = parseHtml(
|
|
54
|
-
`<a href="#" ${
|
|
55
|
-
state.custom[k] ? 'style="background: rgba(59, 49, 70, 1)"' : ''
|
|
60
|
+
`<a href="#" ${state.custom[k] ? 'style="background: rgba(59, 49, 70, 1)"' : ''
|
|
56
61
|
}>${filterDescriptors[k as keyof typeof filterDescriptors].name}</a>`,
|
|
57
62
|
);
|
|
58
63
|
btn.addEventListener('click', (e) => {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
2
|
import { GM_addStyle } from '$';
|
|
3
|
-
import {
|
|
4
|
-
import { parseUrl } from '../../
|
|
5
|
-
import { fetchHtml } from '../../utils';
|
|
3
|
+
import { Rules } from '../../core';
|
|
4
|
+
import { fetchHtml, parseUrl } from '../../utils';
|
|
6
5
|
|
|
7
6
|
export const meta: MonkeyUserScript = {
|
|
8
7
|
name: 'Obmensvem PervertMonkey',
|
|
@@ -26,7 +25,7 @@ function setup() {
|
|
|
26
25
|
|
|
27
26
|
setup();
|
|
28
27
|
|
|
29
|
-
const rules = new
|
|
28
|
+
const rules = new Rules({
|
|
30
29
|
paginationStrategyOptions: {
|
|
31
30
|
getPaginationUrlGenerator() {
|
|
32
31
|
const url = parseUrl(location.href);
|
|
@@ -41,15 +40,17 @@ const rules = new RulesGlobal({
|
|
|
41
40
|
paginationSelector: '.item.pages, .pagination',
|
|
42
41
|
},
|
|
43
42
|
containerSelectorLast: '.container',
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
thumbs: { selector: '.item:has(> a.block[href *= info] > img)' },
|
|
44
|
+
thumb: { strategy: 'auto-text' },
|
|
45
|
+
thumbImg: {
|
|
46
|
+
strategy: 'auto',
|
|
47
|
+
selector: (img) => {
|
|
48
|
+
const url = (img.closest('a') as HTMLAnchorElement).href;
|
|
49
|
+
fetchHtml(url).then((dom) => {
|
|
50
|
+
img.src = dom.querySelector<HTMLImageElement>('img[src*=attach]')?.src || img.src;
|
|
51
|
+
});
|
|
52
|
+
return img.src;
|
|
53
|
+
},
|
|
51
54
|
},
|
|
52
|
-
getThumbImgDataStrategy: 'auto',
|
|
53
|
-
getThumbDataStrategy: 'auto-text',
|
|
54
55
|
schemeOptions: ['Text Filter', 'Duration Filter', 'Badge', 'Advanced'],
|
|
55
56
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import {
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
3
|
|
|
4
4
|
export const meta: MonkeyUserScript = {
|
|
5
5
|
name: 'PornHub PervertMonkey',
|
|
@@ -10,7 +10,7 @@ export const meta: MonkeyUserScript = {
|
|
|
10
10
|
exclude: 'https://*.pornhub.com/embed/*',
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const rules = new
|
|
13
|
+
const rules = new Rules({
|
|
14
14
|
paginationStrategyOptions: {
|
|
15
15
|
paginationSelector: '.paginationGated',
|
|
16
16
|
overwritePaginationLast: (n: number) => (n === 9 ? 999 : n),
|
|
@@ -20,15 +20,19 @@ const rules = new RulesGlobal({
|
|
|
20
20
|
.filter((e) => e.children.length > 0 && e.checkVisibility())
|
|
21
21
|
.pop() as HTMLElement,
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
dataHomogenity: { id: true, className: true },
|
|
24
|
+
thumbs: { selector: 'li[data-video-vkey]' },
|
|
25
|
+
thumb: {
|
|
26
|
+
selectors: {
|
|
27
|
+
title: 'span.title',
|
|
28
|
+
uploader: '.usernameWrap',
|
|
29
|
+
duration: '.duration',
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
thumbImg: {
|
|
33
|
+
strategy: 'auto', // WHAT?
|
|
34
|
+
selector: ['data-mediumthumb', 'data-image'],
|
|
25
35
|
},
|
|
26
|
-
thumbsSelector: 'li[data-video-vkey]',
|
|
27
|
-
getThumbImgDataStrategy: 'auto',
|
|
28
|
-
getThumbImgDataAttrSelector: ['data-mediumthumb', 'data-image'],
|
|
29
|
-
uploaderSelector: '.usernameWrap',
|
|
30
|
-
titleSelector: 'span.title',
|
|
31
|
-
durationSelector: '.duration',
|
|
32
36
|
gropeStrategy: 'all-in-all',
|
|
33
37
|
schemeOptions: ['Text Filter', 'Duration Filter', 'Badge', 'Advanced'],
|
|
34
38
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import {
|
|
2
|
+
import { Rules } from '../../core';
|
|
3
3
|
import { exterminateVideo, OnHover, parseHtml } from '../../utils';
|
|
4
4
|
|
|
5
5
|
export const meta: MonkeyUserScript = {
|
|
@@ -9,15 +9,19 @@ export const meta: MonkeyUserScript = {
|
|
|
9
9
|
match: ['https://*.spankbang.com/*', 'https://*.spankbang.*/*'],
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const rules = new
|
|
12
|
+
const rules = new Rules({
|
|
13
13
|
containerSelector: '.main-container .js-media-list, .main_content_container .video-list',
|
|
14
14
|
paginationStrategyOptions: {
|
|
15
15
|
paginationSelector: '.paginate-bar, .pagination',
|
|
16
16
|
},
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
thumbs: { selector: '.video-item:not(.clear-fix), .js-video-item' },
|
|
18
|
+
thumb: {
|
|
19
|
+
selectors: {
|
|
20
|
+
title: '[title]',
|
|
21
|
+
duration: '[data-testid="video-item-length"]',
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
thumbImg: { strategy: 'auto' },
|
|
21
25
|
gropeStrategy: 'all-in-all',
|
|
22
26
|
schemeOptions: ['Text Filter', 'Duration Filter', 'Badge', 'Advanced'],
|
|
23
27
|
animatePreview,
|
|
@@ -3,14 +3,14 @@ import { concatMap, flatMap, map, takeWhile } from 'ix/asynciterable/operators';
|
|
|
3
3
|
import { LSKDB } from 'lskdb';
|
|
4
4
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
5
5
|
import { GM_addStyle, unsafeWindow } from '$';
|
|
6
|
-
import { getPaginationStrategy, InfiniteScroller,
|
|
6
|
+
import { getPaginationStrategy, InfiniteScroller, Rules } from '../../core';
|
|
7
7
|
import {
|
|
8
8
|
circularShift,
|
|
9
9
|
downloader,
|
|
10
10
|
fetchHtml,
|
|
11
11
|
getCommonParents,
|
|
12
|
-
objectToFormData,
|
|
13
12
|
OnHover,
|
|
13
|
+
objectToFormData,
|
|
14
14
|
parseCssUrl,
|
|
15
15
|
parseHtml,
|
|
16
16
|
querySelectorLastNumber,
|
|
@@ -29,7 +29,7 @@ export const meta: MonkeyUserScript = {
|
|
|
29
29
|
|
|
30
30
|
const $ = (unsafeWindow as any).$;
|
|
31
31
|
|
|
32
|
-
type RulesConfig = ConstructorParameters<typeof
|
|
32
|
+
type RulesConfig = ConstructorParameters<typeof Rules>[0];
|
|
33
33
|
|
|
34
34
|
const lskdb = new LSKDB();
|
|
35
35
|
|
|
@@ -56,33 +56,38 @@ function fixPlaylistThumbUrl(src: string) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const defaultRulesConfig: RulesConfig = {
|
|
59
|
-
|
|
60
|
-
'div:has(> .tumbpu[title]):not(.thumbs-photo) > .tumbpu[title], .thumb-holder'
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
thumbs: {
|
|
60
|
+
selector: 'div:has(> .tumbpu[title]):not(.thumbs-photo) > .tumbpu[title], .thumb-holder'
|
|
61
|
+
},
|
|
62
|
+
thumb: {
|
|
63
|
+
selectors: {
|
|
64
|
+
titleSelector: '.title',
|
|
65
|
+
durationSelector: '.duration',
|
|
66
|
+
private: { selector: '.private', type: 'boolean' },
|
|
67
|
+
hd: { selector: '.quality', type: 'boolean' },
|
|
68
|
+
views: { selector: '.view', type: 'number' },
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
thumbImg: {
|
|
72
|
+
getImgData(thumb: HTMLElement) {
|
|
73
|
+
const img = thumb.querySelector('img') as HTMLImageElement;
|
|
74
|
+
const privateThumb = thumb.querySelector('.private') as HTMLElement;
|
|
64
75
|
|
|
65
|
-
|
|
76
|
+
let imgSrc = img?.getAttribute('data-original') as string;
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
if (privateThumb) {
|
|
79
|
+
imgSrc = parseCssUrl(privateThumb.style.background);
|
|
80
|
+
privateThumb.removeAttribute('style');
|
|
81
|
+
}
|
|
71
82
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
img.removeAttribute('data-original');
|
|
84
|
+
img.removeAttribute('data-cnt');
|
|
85
|
+
img.classList.remove('lazy-load');
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
return { img, imgSrc };
|
|
88
|
+
}
|
|
77
89
|
},
|
|
78
90
|
containerSelectorLast: '.thumbs-items',
|
|
79
|
-
titleSelector: '.title',
|
|
80
|
-
durationSelector: '.duration',
|
|
81
|
-
customThumbDataSelectors: {
|
|
82
|
-
private: { selector: '.private', type: 'boolean' },
|
|
83
|
-
hd: { selector: '.quality', type: 'boolean' },
|
|
84
|
-
views: { selector: '.view', type: 'number' },
|
|
85
|
-
},
|
|
86
91
|
animatePreview,
|
|
87
92
|
customDataSelectorFns: [
|
|
88
93
|
'filterInclude',
|
|
@@ -131,7 +136,7 @@ const defaultRulesConfig: RulesConfig = {
|
|
|
131
136
|
const config: RulesConfig =
|
|
132
137
|
IS_MY_MEMBER_PAGE || IS_MY_WALL ? await createPrivateFeed() : defaultRulesConfig;
|
|
133
138
|
|
|
134
|
-
const rules = new
|
|
139
|
+
const rules = new Rules(config);
|
|
135
140
|
|
|
136
141
|
GM_addStyle(`
|
|
137
142
|
.haveNoAccess { background: linear-gradient(to bottom, #b50000 0%, #2c2c2c 100%) red !important; }
|
|
@@ -215,7 +220,7 @@ async function friendMemberFriends(orientationFilter?: string) {
|
|
|
215
220
|
}
|
|
216
221
|
}, 60),
|
|
217
222
|
)
|
|
218
|
-
.forEach(() => {});
|
|
223
|
+
.forEach(() => { });
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
function initFriendship() {
|
|
@@ -498,7 +503,7 @@ async function createPrivateFeed() {
|
|
|
498
503
|
) => void,
|
|
499
504
|
private type = 'private',
|
|
500
505
|
private by: Parameters<typeof getMemberFriends>[1] = undefined,
|
|
501
|
-
) {}
|
|
506
|
+
) { }
|
|
502
507
|
|
|
503
508
|
public async *consume() {
|
|
504
509
|
const membersIds = await getMemberFriends(this.id, this.by);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
2
|
import { unsafeWindow } from '$';
|
|
3
|
-
import {
|
|
3
|
+
import { Rules } from '../../core';
|
|
4
4
|
import {
|
|
5
5
|
exterminateVideo,
|
|
6
6
|
fetchJson,
|
|
7
|
-
getCommonParents,
|
|
8
7
|
instantiateTemplate,
|
|
9
8
|
Observer,
|
|
10
9
|
OnHover,
|
|
@@ -15,10 +14,11 @@ import {
|
|
|
15
14
|
|
|
16
15
|
export const meta: MonkeyUserScript = {
|
|
17
16
|
name: 'Xhamster Improved',
|
|
18
|
-
version: '5.0.
|
|
17
|
+
version: '5.0.2',
|
|
19
18
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
20
19
|
match: ['https://*.xhamster.com/*', 'https://*.xhamster.*/*'],
|
|
21
20
|
exclude: 'https://*.xhamster.com/embed*',
|
|
21
|
+
grant: ['GM_addElement', 'GM_addStyle', 'unsafeWindow']
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const IS_VIDEO_PAGE = /^\/videos|moments\//.test(location.pathname);
|
|
@@ -45,15 +45,15 @@ function createThumb(data: Record<string, string>): string {
|
|
|
45
45
|
return instantiateTemplate('.video-thumb', attrsToReplace, text);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const getPaginationData:
|
|
48
|
+
const getPaginationData: Rules['getPaginationData'] = !IS_PLAYLIST
|
|
49
49
|
? undefined
|
|
50
50
|
: async (url: string): Promise<HTMLElement> => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
const data = await fetchJson(url);
|
|
52
|
+
const thumbsHtml = (data as any).list
|
|
53
|
+
.map((e: Record<string, string>) => createThumb(e))
|
|
54
|
+
.join('\n');
|
|
55
|
+
return parseHtml(`<div>${thumbsHtml}</div>`);
|
|
56
|
+
};
|
|
57
57
|
|
|
58
58
|
function createPlaylistPaginationStrategy() {
|
|
59
59
|
const collectionId = location.pathname
|
|
@@ -63,7 +63,7 @@ function createPlaylistPaginationStrategy() {
|
|
|
63
63
|
const paginationLast = data.favoritesVideoPaging.maxPages;
|
|
64
64
|
const paginationOffset = data.favoritesVideoPaging.active;
|
|
65
65
|
|
|
66
|
-
const playlistPaginationStrategy:
|
|
66
|
+
const playlistPaginationStrategy: Rules['paginationStrategyOptions'] = {
|
|
67
67
|
paginationSelector: 'nav[class *= "pagination"]',
|
|
68
68
|
getPaginationLast: () => paginationLast,
|
|
69
69
|
getPaginationOffset: () => paginationOffset,
|
|
@@ -75,7 +75,7 @@ function createPlaylistPaginationStrategy() {
|
|
|
75
75
|
return playlistPaginationStrategy;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
const paginationStrategyOptionsDefault:
|
|
78
|
+
const paginationStrategyOptionsDefault: Rules['paginationStrategyOptions'] = {
|
|
79
79
|
paginationSelector: '.prev-next-list, .test-pager',
|
|
80
80
|
};
|
|
81
81
|
|
|
@@ -83,22 +83,26 @@ const paginationStrategyOptions = IS_PLAYLIST
|
|
|
83
83
|
? createPlaylistPaginationStrategy()
|
|
84
84
|
: paginationStrategyOptionsDefault;
|
|
85
85
|
|
|
86
|
-
const rules = new
|
|
86
|
+
const rules = new Rules({
|
|
87
87
|
paginationStrategyOptions,
|
|
88
88
|
getPaginationData,
|
|
89
89
|
containerSelectorLast: '.thumb-list',
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
thumbs: { selector: 'video-thumb' }, // [class *= video-thumb]:has(img)(and :has(~ neighbour))
|
|
91
|
+
thumb: {
|
|
92
|
+
selectors: {
|
|
93
|
+
title: '.video-thumb-info__name,.video-thumb-info>a',
|
|
94
|
+
duration: '.thumb-image-container__duration',
|
|
95
|
+
watched: {
|
|
96
|
+
type: 'boolean',
|
|
97
|
+
selector: '[data-role="video-watched',
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
thumbImg: {
|
|
102
|
+
strategy: 'auto',
|
|
103
|
+
shouldDelete: '[loading]',
|
|
101
104
|
},
|
|
105
|
+
gropeStrategy: 'all-in-all',
|
|
102
106
|
customDataSelectorFns: [
|
|
103
107
|
'filterInclude',
|
|
104
108
|
'filterExclude',
|
|
@@ -128,12 +132,14 @@ const rules = new RulesGlobal({
|
|
|
128
132
|
|
|
129
133
|
function animatePreview() {
|
|
130
134
|
function createPreviewVideoElement(src: string, mount: HTMLElement) {
|
|
131
|
-
const video =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
const video = GM_addElement('video', {
|
|
136
|
+
playsInline: true,
|
|
137
|
+
autoplay: true,
|
|
138
|
+
loop: true,
|
|
139
|
+
class: 'thumb-image-container__video',
|
|
140
|
+
src
|
|
141
|
+
});
|
|
142
|
+
|
|
137
143
|
video.addEventListener(
|
|
138
144
|
'loadeddata',
|
|
139
145
|
() => {
|
|
@@ -157,7 +163,7 @@ function animatePreview() {
|
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
function expandMoreVideoPage() {
|
|
160
|
-
watchElementChildrenCount(rules.container, () => setTimeout(
|
|
166
|
+
watchElementChildrenCount(rules.container, () => setTimeout(rules.gropeInit, 1800));
|
|
161
167
|
waitForElementToAppear(document.body, 'button[data-role="show-more-next"]', (el) => {
|
|
162
168
|
const observer = new Observer((target) => {
|
|
163
169
|
(target as HTMLButtonElement).click();
|
|
@@ -166,13 +172,6 @@ function expandMoreVideoPage() {
|
|
|
166
172
|
});
|
|
167
173
|
}
|
|
168
174
|
|
|
169
|
-
function parseThumbs() {
|
|
170
|
-
const containers = getCommonParents(rules.getThumbs(document.body));
|
|
171
|
-
containers.forEach((c) => {
|
|
172
|
-
rules.dataManager.parseData(c, c);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
175
|
if (IS_VIDEO_PAGE) {
|
|
177
176
|
expandMoreVideoPage();
|
|
178
177
|
}
|