pervert-monkey 1.0.10 → 1.0.12
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 +22 -11
- package/dist/core/pervertmonkey.core.es.d.ts +31 -19
- package/dist/core/pervertmonkey.core.es.js +752 -120
- package/dist/core/pervertmonkey.core.es.js.map +1 -1
- package/dist/core/pervertmonkey.core.umd.js +752 -120
- package/dist/core/pervertmonkey.core.umd.js.map +1 -1
- package/dist/userscripts/3hentai.user.js +19 -26
- package/dist/userscripts/camgirlfinder.user.js +2 -2
- package/dist/userscripts/camwhores.user.js +12 -16
- package/dist/userscripts/e-hentai.user.js +3 -4
- package/dist/userscripts/ebalka.user.js +6 -11
- package/dist/userscripts/eporner.user.js +11 -16
- package/dist/userscripts/erome.user.js +2 -2
- 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 +19 -40
- package/dist/userscripts/namethatporn.user.js +5 -4
- package/dist/userscripts/nhentai.user.js +3 -3
- package/dist/userscripts/obmenvsem.user.js +18 -4
- package/dist/userscripts/pornhub.user.js +9 -12
- package/dist/userscripts/spankbang.user.js +6 -38
- package/dist/userscripts/thisvid.user.js +20 -22
- package/dist/userscripts/xhamster.user.js +20 -16
- package/dist/userscripts/xvideos.user.js +7 -12
- package/package.json +2 -1
- package/src/core/data-handler/data-manager.ts +4 -4
- package/src/core/infinite-scroll/index.ts +9 -9
- package/src/core/jabroni-config/index.ts +3 -2
- package/src/core/jabroni-config/jabroni-gui-controller.ts +60 -0
- package/src/core/parsers/thumb-data-parser.ts +36 -13
- package/src/core/parsers/thumb-img-parser.ts +49 -46
- package/src/core/rules/index.ts +12 -39
- package/src/userscripts/index.ts +1 -1
- package/src/userscripts/scripts/3hentai.ts +21 -25
- package/src/userscripts/scripts/camgirlfinder.ts +1 -1
- package/src/userscripts/scripts/camwhores.ts +10 -18
- package/src/userscripts/scripts/e-hentai.ts +1 -2
- package/src/userscripts/scripts/ebalka.ts +7 -12
- package/src/userscripts/scripts/eporner.ts +10 -16
- package/src/userscripts/scripts/erome.ts +1 -1
- 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 +19 -49
- package/src/userscripts/scripts/namethatporn.ts +7 -6
- package/src/userscripts/scripts/nhentai.ts +2 -2
- package/src/userscripts/scripts/obmenvsem.ts +19 -4
- package/src/userscripts/scripts/pornhub.ts +10 -14
- package/src/userscripts/scripts/spankbang.ts +2 -38
- package/src/userscripts/scripts/thisvid.ts +26 -26
- package/src/userscripts/scripts/xhamster.ts +20 -23
- package/src/userscripts/scripts/xvideos.ts +8 -13
- package/src/utils/dom/index.ts +10 -0
- package/src/utils/events/on-hover.ts +17 -25
- package/src/utils/events/tick.ts +1 -3
- package/src/utils/observers/index.ts +8 -4
- package/src/utils/parsers/time-parser.ts +2 -2
package/src/core/rules/index.ts
CHANGED
|
@@ -6,20 +6,21 @@ import {
|
|
|
6
6
|
} from '../../utils';
|
|
7
7
|
import { DataManager, type DataSelectorFn } from '../data-handler';
|
|
8
8
|
import { InfiniteScroller, type OffsetGenerator } from '../infinite-scroll';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DefaultScheme,
|
|
11
|
+
JabronioGuiController,
|
|
12
|
+
type SchemeOptions,
|
|
13
|
+
StoreStateDefault,
|
|
14
|
+
} from '../jabroni-config';
|
|
10
15
|
import {
|
|
11
16
|
getPaginationStrategy,
|
|
12
17
|
type PaginationStrategy,
|
|
13
18
|
ThumbDataParser,
|
|
14
19
|
ThumbImgParser,
|
|
15
|
-
ThumbsParser
|
|
20
|
+
ThumbsParser,
|
|
16
21
|
} from '../parsers';
|
|
17
22
|
|
|
18
23
|
export class Rules {
|
|
19
|
-
public getThumbUrl(thumb: HTMLElement | HTMLAnchorElement) {
|
|
20
|
-
return ((thumb.querySelector('a[href]') || thumb) as HTMLAnchorElement).href;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
24
|
public thumb: Parameters<typeof ThumbDataParser.create>[0] = {};
|
|
24
25
|
public thumbDataParser: ThumbDataParser;
|
|
25
26
|
|
|
@@ -73,6 +74,7 @@ export class Rules {
|
|
|
73
74
|
public schemeOptions: SchemeOptions = [];
|
|
74
75
|
public store: JabronioStore;
|
|
75
76
|
public gui: JabronioGUI;
|
|
77
|
+
public inputController: JabronioGuiController;
|
|
76
78
|
|
|
77
79
|
private createStore() {
|
|
78
80
|
const config = { ...StoreStateDefault, ...this.storeOptions };
|
|
@@ -117,35 +119,6 @@ export class Rules {
|
|
|
117
119
|
return window.self !== window.top;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
private setupStoreListeners() {
|
|
121
|
-
const eventsMap = {
|
|
122
|
-
'sort by duration': {
|
|
123
|
-
action: (direction: boolean) => this.dataManager.sortBy('duration', direction),
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
let lastEvent: undefined | string;
|
|
128
|
-
let direction = true;
|
|
129
|
-
|
|
130
|
-
this.store.eventSubject.subscribe((event) => {
|
|
131
|
-
if (event === lastEvent) {
|
|
132
|
-
direction = !direction;
|
|
133
|
-
} else {
|
|
134
|
-
lastEvent = event;
|
|
135
|
-
direction = true;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (event in eventsMap) {
|
|
139
|
-
const ev = eventsMap[event as keyof typeof eventsMap];
|
|
140
|
-
ev?.action(direction);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
this.store.stateSubject.subscribe((a) => {
|
|
145
|
-
this.dataManager.applyFilters(a as { [key: string]: boolean });
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
122
|
private mutationObservers: MutationObserver[] = [];
|
|
150
123
|
|
|
151
124
|
public resetOnPaginationOrContainerDeath = true;
|
|
@@ -171,8 +144,6 @@ export class Rules {
|
|
|
171
144
|
public onResetCallback?: () => void;
|
|
172
145
|
|
|
173
146
|
private reset() {
|
|
174
|
-
// console.log('\nRESET\n');
|
|
175
|
-
|
|
176
147
|
this.mutationObservers.forEach((o) => {
|
|
177
148
|
o.disconnect();
|
|
178
149
|
});
|
|
@@ -181,7 +152,9 @@ export class Rules {
|
|
|
181
152
|
this.paginationStrategy = getPaginationStrategy(this.paginationStrategyOptions);
|
|
182
153
|
|
|
183
154
|
this.dataManager = new DataManager(this, this.dataHomogenity);
|
|
184
|
-
|
|
155
|
+
|
|
156
|
+
this.inputController.dispose();
|
|
157
|
+
this.inputController = new JabronioGuiController(this.store, this.dataManager);
|
|
185
158
|
|
|
186
159
|
this.resetInfiniteScroller();
|
|
187
160
|
|
|
@@ -209,8 +182,8 @@ export class Rules {
|
|
|
209
182
|
this.gui = this.createGui();
|
|
210
183
|
|
|
211
184
|
this.dataManager = new DataManager(this, this.dataHomogenity);
|
|
185
|
+
this.inputController = new JabronioGuiController(this.store, this.dataManager);
|
|
212
186
|
|
|
213
187
|
this.reset();
|
|
214
|
-
// console.log('data', this.dataManager.data.values().toArray());
|
|
215
188
|
}
|
|
216
189
|
}
|
package/src/userscripts/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import './scripts/
|
|
1
|
+
import './scripts/eporner'
|
|
@@ -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.4',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: 'https://*.3hentai.net/*',
|
|
10
10
|
};
|
|
@@ -12,12 +12,12 @@ export const meta: MonkeyUserScript = {
|
|
|
12
12
|
const rules = new Rules({
|
|
13
13
|
containerSelectorLast: '.listing-container',
|
|
14
14
|
thumbs: {
|
|
15
|
-
selector: '.doujin-col'
|
|
15
|
+
selector: '.doujin-col',
|
|
16
16
|
},
|
|
17
17
|
thumb: {
|
|
18
18
|
selectors: {
|
|
19
19
|
title: '.title',
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
21
|
},
|
|
22
22
|
thumbImg: {
|
|
23
23
|
strategy: 'auto',
|
|
@@ -30,30 +30,26 @@ const rules = new Rules({
|
|
|
30
30
|
|
|
31
31
|
function animatePreview() {
|
|
32
32
|
const tick = new Tick(500, false);
|
|
33
|
-
const end =
|
|
33
|
+
const end = 9999;
|
|
34
34
|
|
|
35
35
|
function rotate(src: string) {
|
|
36
|
-
return src.replace(/(\d+)(?=t\.jpg$)/,
|
|
37
|
-
(_, n) => `${circularShift(parseInt(n), end)}`);
|
|
36
|
+
return src.replace(/(\d+)(?=t\.jpg$)/, (_, n) => `${circularShift(parseInt(n), end)}`);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
OnHover.create(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
57
|
-
(_) => tick.stop()
|
|
58
|
-
);
|
|
39
|
+
OnHover.create(document.body, '.doujin-col', (e) => {
|
|
40
|
+
const img = e.querySelector('img') as HTMLImageElement;
|
|
41
|
+
const origin = img.src;
|
|
42
|
+
img.src = img.src.replace(/\w+\.\w+$/, '1t.jpg');
|
|
43
|
+
img.onerror = (_) => tick.stop();
|
|
44
|
+
tick.start(
|
|
45
|
+
() => {
|
|
46
|
+
img.src = rotate(img.src);
|
|
47
|
+
},
|
|
48
|
+
() => {
|
|
49
|
+
img.src = origin;
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return () => tick.stop();
|
|
54
|
+
});
|
|
59
55
|
}
|
|
@@ -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.2',
|
|
6
6
|
description:
|
|
7
7
|
'Adds model links for CamWhores, webcamrecordings, recu.me, camvideos, privat-zapisi',
|
|
8
8
|
match: ['https://camgirlfinder.net/*'],
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export const meta: MonkeyUserScript = {
|
|
19
19
|
name: 'CamWhores PervertMonkey',
|
|
20
|
-
version: '3.0.
|
|
20
|
+
version: '3.0.6',
|
|
21
21
|
description:
|
|
22
22
|
'Infinite scroll [optional]. Filter by Title, Duration and Private/Public. Mass friend request button. Download button',
|
|
23
23
|
match: ['https://*.camwhores.tv', 'https://*.camwhores.*/*'],
|
|
@@ -48,7 +48,7 @@ const rules = new Rules({
|
|
|
48
48
|
},
|
|
49
49
|
thumbs: {
|
|
50
50
|
selector:
|
|
51
|
-
'.list-videos .item, .playlist .item, .list-playlists > div > .item, .item:has(.title)'
|
|
51
|
+
'.list-videos .item, .playlist .item, .list-playlists > div > .item, .item:has(.title)',
|
|
52
52
|
},
|
|
53
53
|
thumb: {
|
|
54
54
|
strategy: 'auto-select',
|
|
@@ -58,7 +58,6 @@ const rules = new Rules({
|
|
|
58
58
|
},
|
|
59
59
|
thumbImg: {
|
|
60
60
|
selector: 'data-original',
|
|
61
|
-
strategy: 'auto',
|
|
62
61
|
},
|
|
63
62
|
gropeStrategy: 'all-in-all',
|
|
64
63
|
customDataSelectorFns: [
|
|
@@ -109,28 +108,21 @@ function animatePreview(container: HTMLElement) {
|
|
|
109
108
|
|
|
110
109
|
OnHover.create(
|
|
111
110
|
container,
|
|
112
|
-
(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
(_target) => {
|
|
118
|
-
const target = _target as HTMLImageElement;
|
|
119
|
-
const origin = target.src;
|
|
120
|
-
const count = parseInt(target.getAttribute('data-cnt') as string) || 5;
|
|
111
|
+
'.list-videos .item, .playlist .item, .list-playlists > div > .item, .item:has(.title)',
|
|
112
|
+
(e) => {
|
|
113
|
+
const img = e.querySelector('img') as HTMLImageElement;
|
|
114
|
+
const origin = img.src;
|
|
115
|
+
const count = parseInt(img.getAttribute('data-cnt') as string) || 5;
|
|
121
116
|
tick.start(
|
|
122
117
|
() => {
|
|
123
|
-
|
|
118
|
+
img.src = rotateImg(img.src, count);
|
|
124
119
|
},
|
|
125
120
|
() => {
|
|
126
|
-
|
|
121
|
+
img.src = origin;
|
|
127
122
|
},
|
|
128
123
|
);
|
|
129
|
-
return
|
|
130
|
-
leaveTarget: target.closest('.item') as HTMLElement,
|
|
131
|
-
};
|
|
124
|
+
return () => tick.stop();
|
|
132
125
|
},
|
|
133
|
-
() => tick.stop(),
|
|
134
126
|
);
|
|
135
127
|
}
|
|
136
128
|
|
|
@@ -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.2',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: ['https://*.e-hentai.org/*'],
|
|
10
10
|
};
|
|
@@ -18,7 +18,6 @@ const rules = new Rules({
|
|
|
18
18
|
},
|
|
19
19
|
thumbImg: {
|
|
20
20
|
selector: 'data-lazy-load',
|
|
21
|
-
strategy: 'auto',
|
|
22
21
|
},
|
|
23
22
|
containerSelectorLast: '.itg.gld',
|
|
24
23
|
paginationStrategyOptions: createPaginationStrategyOptions(),
|
|
@@ -4,7 +4,7 @@ import { 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.3',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
9
9
|
match: [
|
|
10
10
|
'https://b.ebalka.zip/*',
|
|
@@ -21,13 +21,13 @@ const rules = new Rules({
|
|
|
21
21
|
paginationSelector: '.pagination:not([id *= member])',
|
|
22
22
|
},
|
|
23
23
|
thumbs: {
|
|
24
|
-
selector: '.card_video'
|
|
24
|
+
selector: '.card_video',
|
|
25
25
|
},
|
|
26
26
|
thumb: {
|
|
27
27
|
selectors: {
|
|
28
28
|
title: '.card__title',
|
|
29
29
|
duration: '.card__spot > span:last-child',
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
31
|
},
|
|
32
32
|
animatePreview,
|
|
33
33
|
schemeOptions: ['Text Filter', 'Badge', 'Duration Filter', 'Advanced'],
|
|
@@ -50,13 +50,8 @@ function animatePreview(container: HTMLElement) {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
OnHover.create(
|
|
54
|
-
|
|
55
|
-
(
|
|
56
|
-
|
|
57
|
-
const thumb = target.closest('.card') as HTMLElement;
|
|
58
|
-
const onOverCallback = animateThumb(thumb);
|
|
59
|
-
return { leaveTarget: thumb, onOverCallback };
|
|
60
|
-
},
|
|
61
|
-
);
|
|
53
|
+
OnHover.create(container, '.card_video', (target) => {
|
|
54
|
+
const thumb = target.closest('.card') as HTMLElement;
|
|
55
|
+
return animateThumb(thumb);
|
|
56
|
+
});
|
|
62
57
|
}
|
|
@@ -5,7 +5,7 @@ import { OnHover } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Eporner PervertMonkey',
|
|
8
|
-
version: '2.0.
|
|
8
|
+
version: '2.0.4',
|
|
9
9
|
description: 'Infinite scroll [optional], Filter by Title, Duration and HD',
|
|
10
10
|
match: ['https://*.eporner.com/*', 'https://*.eporner.*/*'],
|
|
11
11
|
};
|
|
@@ -16,6 +16,7 @@ const rules = new Rules({
|
|
|
16
16
|
paginationStrategyOptions: {
|
|
17
17
|
paginationSelector: '.numlist2',
|
|
18
18
|
},
|
|
19
|
+
thumbs: { selector: 'div[id^=vf][data-id]' },
|
|
19
20
|
thumb: {
|
|
20
21
|
selectors: {
|
|
21
22
|
quality: { type: 'number', selector: '[title="Quality"]' },
|
|
@@ -25,11 +26,8 @@ const rules = new Rules({
|
|
|
25
26
|
},
|
|
26
27
|
},
|
|
27
28
|
thumbImg: {
|
|
28
|
-
strategy: 'auto'
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
thumbs: {
|
|
32
|
-
selector: 'div[id^=vf][data-id]',
|
|
29
|
+
strategy: 'auto',
|
|
30
|
+
remove: 'auto',
|
|
33
31
|
},
|
|
34
32
|
containerSelectorLast: '#vidresults',
|
|
35
33
|
customDataSelectorFns: [
|
|
@@ -82,14 +80,10 @@ const rules = new Rules({
|
|
|
82
80
|
});
|
|
83
81
|
|
|
84
82
|
function animatePreview(doc: HTMLElement) {
|
|
85
|
-
OnHover.create(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const id = thumb?.getAttribute('data-id');
|
|
92
|
-
show_video_prev(id);
|
|
93
|
-
},
|
|
94
|
-
);
|
|
83
|
+
OnHover.create(doc, 'div[id^=vf][data-id]', (e) => {
|
|
84
|
+
const target = e as HTMLImageElement;
|
|
85
|
+
const thumb = target.closest('[data-id]');
|
|
86
|
+
const id = thumb?.getAttribute('data-id');
|
|
87
|
+
show_video_prev(id);
|
|
88
|
+
});
|
|
95
89
|
}
|
|
@@ -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.3',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title and Video/Photo albums',
|
|
9
9
|
match: ['*://*.erome.com/*'],
|
|
10
10
|
};
|
|
@@ -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.3',
|
|
7
7
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
8
8
|
match: ['https://*.eroprofile.com/*'],
|
|
9
9
|
};
|
|
@@ -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.3',
|
|
7
7
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
8
8
|
match: [
|
|
9
9
|
"https://*.javhdporn.net/*",
|
|
@@ -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.3',
|
|
7
7
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
8
8
|
match: [
|
|
9
9
|
'https://*.missav123.com/*',
|
|
@@ -5,10 +5,10 @@ import { fetchWith, OnHover, replaceElementTag, Tick } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Motherless PervertMonkey',
|
|
8
|
-
version: '5.0.
|
|
8
|
+
version: '5.0.4',
|
|
9
9
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
10
10
|
match: ['https://motherless.com/*'],
|
|
11
|
-
grant: ['GM_addElement', 'GM_addStyle', 'unsafeWindow']
|
|
11
|
+
grant: ['GM_addElement', 'GM_addStyle', 'unsafeWindow'],
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
(unsafeWindow as any).__is_premium = true;
|
|
@@ -22,7 +22,7 @@ const rules = new Rules({
|
|
|
22
22
|
uploader: '.uploader',
|
|
23
23
|
title: '.title',
|
|
24
24
|
duration: '.size',
|
|
25
|
-
}
|
|
25
|
+
},
|
|
26
26
|
},
|
|
27
27
|
thumbImg: { strategy: 'auto' },
|
|
28
28
|
paginationStrategyOptions: {
|
|
@@ -34,28 +34,15 @@ const rules = new Rules({
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
function animatePreview(_: HTMLElement) {
|
|
37
|
-
const
|
|
38
|
-
const tick = new Tick(ANIMATION_INTERVAL);
|
|
39
|
-
let currentOverlay: HTMLElement | null = null;
|
|
40
|
-
|
|
41
|
-
function onLeave(target: HTMLElement) {
|
|
42
|
-
tick.stop();
|
|
43
|
-
|
|
44
|
-
const img = target.querySelector('img.static') as HTMLElement;
|
|
45
|
-
img.classList.remove('animating');
|
|
46
|
-
|
|
47
|
-
if (currentOverlay) {
|
|
48
|
-
currentOverlay.style.display = 'none';
|
|
49
|
-
}
|
|
50
|
-
}
|
|
37
|
+
const tick = new Tick(500);
|
|
51
38
|
|
|
52
39
|
function onOver(target: HTMLElement) {
|
|
53
40
|
$('.video').off();
|
|
54
|
-
const container = target.
|
|
41
|
+
const container = target.querySelector('.desktop-thumb.video') as HTMLElement;
|
|
55
42
|
const img = container.querySelector('img.static') as HTMLImageElement;
|
|
56
43
|
const stripSrc = img.getAttribute('data-strip-src');
|
|
57
44
|
|
|
58
|
-
|
|
45
|
+
container.classList.toggle('animating');
|
|
59
46
|
|
|
60
47
|
let overlay = img.nextElementSibling as HTMLElement;
|
|
61
48
|
if (!overlay || overlay.tagName !== 'DIV') {
|
|
@@ -64,54 +51,37 @@ function animatePreview(_: HTMLElement) {
|
|
|
64
51
|
'style',
|
|
65
52
|
'z-index: 8; position: absolute; top: 0; left: 0; pointer-events: none;',
|
|
66
53
|
);
|
|
67
|
-
img.
|
|
54
|
+
img.after(overlay);
|
|
68
55
|
}
|
|
69
56
|
|
|
70
|
-
currentOverlay = overlay;
|
|
71
57
|
overlay.style.display = 'block';
|
|
72
58
|
|
|
73
59
|
let j = 0;
|
|
74
|
-
const containerHeight = container.offsetHeight;
|
|
60
|
+
const containerHeight = container.offsetHeight + 20;
|
|
61
|
+
const w = img.offsetWidth;
|
|
62
|
+
const h = img.offsetHeight;
|
|
63
|
+
const widthRatio = Math.floor((1000.303 * w) / 100);
|
|
64
|
+
const heightRatio = Math.floor((228.6666 * h) / 100);
|
|
65
|
+
const verticalOffset = (containerHeight - h) / 2;
|
|
75
66
|
|
|
76
67
|
tick.start(() => {
|
|
77
|
-
const w = img.offsetWidth;
|
|
78
|
-
const h = img.offsetHeight;
|
|
79
|
-
|
|
80
|
-
const widthRatio = Math.floor((1000.303 * w) / 100);
|
|
81
|
-
const heightRatio = Math.floor((228.6666 * h) / 100);
|
|
82
|
-
|
|
83
|
-
const verticalOffset = (containerHeight - h) / 2;
|
|
84
|
-
|
|
85
68
|
Object.assign(overlay.style, {
|
|
86
69
|
width: `${w}px`,
|
|
87
70
|
height: `${containerHeight}px`,
|
|
88
71
|
backgroundImage: `url('${stripSrc}')`,
|
|
89
72
|
backgroundSize: `${widthRatio}px ${heightRatio}px`,
|
|
90
73
|
backgroundPosition: `-${(j++ * w) % widthRatio}px ${verticalOffset}px`,
|
|
91
|
-
backgroundRepeat: 'no-repeat',
|
|
92
74
|
});
|
|
93
75
|
});
|
|
94
76
|
|
|
95
|
-
|
|
96
|
-
|
|
77
|
+
return () => {
|
|
78
|
+
tick.stop();
|
|
79
|
+
container.classList.toggle('animating');
|
|
80
|
+
overlay.style.display = 'none';
|
|
81
|
+
};
|
|
97
82
|
}
|
|
98
83
|
|
|
99
|
-
OnHover.create(
|
|
100
|
-
document.body,
|
|
101
|
-
(e) => {
|
|
102
|
-
const container = e.closest('.desktop-thumb.video') as HTMLElement;
|
|
103
|
-
if (!container) return false;
|
|
104
|
-
|
|
105
|
-
const img = container.querySelector('img.static') as HTMLImageElement;
|
|
106
|
-
if (!img) return false;
|
|
107
|
-
|
|
108
|
-
const stripSrc = img.getAttribute('data-strip-src');
|
|
109
|
-
if (!stripSrc || img.classList.contains('animating')) return false;
|
|
110
|
-
|
|
111
|
-
return true;
|
|
112
|
-
},
|
|
113
|
-
onOver,
|
|
114
|
-
);
|
|
84
|
+
OnHover.create(document.body, '.thumb-container, .mobile-thumb', onOver);
|
|
115
85
|
}
|
|
116
86
|
|
|
117
87
|
//====================================================================================================
|
|
@@ -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.3',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title and Un/Solved',
|
|
9
9
|
match: ['https://namethatporn.com/*'],
|
|
10
10
|
};
|
|
@@ -20,12 +20,14 @@ const rules = new Rules({
|
|
|
20
20
|
type: 'boolean',
|
|
21
21
|
selector: '.item_solved, .nsw_r_slvd',
|
|
22
22
|
},
|
|
23
|
-
}
|
|
23
|
+
},
|
|
24
24
|
},
|
|
25
25
|
thumbImg: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
selector: (img: HTMLImageElement) => {
|
|
27
|
+
return (
|
|
28
|
+
img.getAttribute('data-dyn')?.concat('.webp') || (img.getAttribute('src') as string)
|
|
29
|
+
);
|
|
30
|
+
},
|
|
29
31
|
},
|
|
30
32
|
paginationStrategyOptions: {
|
|
31
33
|
paginationSelector: '#smi_wrp, #nsw_p',
|
|
@@ -55,7 +57,6 @@ const rules = new Rules({
|
|
|
55
57
|
],
|
|
56
58
|
});
|
|
57
59
|
|
|
58
|
-
// some monkeypatching here...
|
|
59
60
|
unsafeWindow.confirm = () => true;
|
|
60
61
|
|
|
61
62
|
function handleKeys(event: KeyboardEvent) {
|
|
@@ -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.3',
|
|
8
8
|
description: 'Infinite scroll [optional], Filter by Title',
|
|
9
9
|
match: ['https://*.nhentai.net/*', 'https://*.nhentai.*/*'],
|
|
10
10
|
};
|
|
@@ -21,7 +21,7 @@ const nhentaiRules = new Rules({
|
|
|
21
21
|
},
|
|
22
22
|
thumbImg: {
|
|
23
23
|
strategy: 'auto',
|
|
24
|
-
|
|
24
|
+
remove: 'auto'
|
|
25
25
|
},
|
|
26
26
|
containerSelectorLast: '.index-container, .container',
|
|
27
27
|
customDataSelectorFns: ['filterInclude', 'filterExclude'],
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import type { MonkeyUserScript } from 'vite-plugin-monkey';
|
|
2
|
-
import { GM_addStyle } from '$';
|
|
2
|
+
import { GM_addElement, GM_addStyle } from '$';
|
|
3
3
|
import { Rules } from '../../core';
|
|
4
4
|
import { fetchHtml, parseUrl } from '../../utils';
|
|
5
5
|
|
|
6
6
|
export const meta: MonkeyUserScript = {
|
|
7
7
|
name: 'Obmensvem PervertMonkey',
|
|
8
|
-
version: '1.0.
|
|
8
|
+
version: '1.0.3',
|
|
9
9
|
description: 'Infinite scroll [optional], Filter by Title and Duration',
|
|
10
10
|
match: ['https://*.obmenvsem.com/*', 'https://*.obmenvsem.*/*'],
|
|
11
|
+
grant: ['GM_addStyle', 'GM_addElement', 'unsafeWindow'],
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
const IS_USER_FILES = location.pathname.startsWith('/user_files');
|
|
15
|
+
const IS_VIDEO_PAGE = /info.php\?id=\d+$/.test(location.href);
|
|
14
16
|
const SEARCH_PARAM = IS_USER_FILES ? 'start' : 'page';
|
|
15
17
|
|
|
16
18
|
function setup() {
|
|
@@ -20,7 +22,21 @@ function setup() {
|
|
|
20
22
|
...document.querySelectorAll('.item:has(> a.block[href *= info] > img)'),
|
|
21
23
|
);
|
|
22
24
|
document.querySelector('.c2')?.after(container);
|
|
23
|
-
|
|
25
|
+
|
|
26
|
+
if (!IS_VIDEO_PAGE) {
|
|
27
|
+
GM_addStyle('a.block[href *= info] > img:first-child { height: 240px; }');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (IS_VIDEO_PAGE) {
|
|
31
|
+
const vidh = document.querySelector('a[href*=mp4]') as HTMLAnchorElement;
|
|
32
|
+
vidh?.after(
|
|
33
|
+
GM_addElement('video', {
|
|
34
|
+
src: vidh.href,
|
|
35
|
+
controls: true,
|
|
36
|
+
width: vidh.parentElement?.offsetWidth,
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
24
40
|
}
|
|
25
41
|
|
|
26
42
|
setup();
|
|
@@ -43,7 +59,6 @@ const rules = new Rules({
|
|
|
43
59
|
thumbs: { selector: '.item:has(> a.block[href *= info] > img)' },
|
|
44
60
|
thumb: { strategy: 'auto-text' },
|
|
45
61
|
thumbImg: {
|
|
46
|
-
strategy: 'auto',
|
|
47
62
|
selector: (img) => {
|
|
48
63
|
const url = (img.closest('a') as HTMLAnchorElement).href;
|
|
49
64
|
fetchHtml(url).then((dom) => {
|