Skip to content

Commit 887b87b

Browse files
committed
Update
1 parent d39cdc7 commit 887b87b

File tree

1 file changed

+135
-72
lines changed

1 file changed

+135
-72
lines changed

improve-adult-experience.js

Lines changed: 135 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// ==UserScript==
22
// @name Improve Adult Experience
3-
// @description Skip intros, set best quality and duration filters by default, make unrelated video previews transparent
4-
// @version 0.7
3+
// @description Skip intros, set best quality and duration filters by default, make unwanted video previews transparent
4+
// @version 0.8
55
// @downloadURL https://userscripts.codonaft.com/improve-adult-experience.js
66
// @exclude-match https://spankbang.com/*/video/*
77
// @match https://spankbang.com/*
@@ -18,7 +18,9 @@
1818
(_ => {
1919
'use strict';
2020

21-
const MIN_DURATION_MIN = 20;
21+
// TODO: improve resistance to exceptions
22+
23+
const MIN_DURATION_MINS = 20;
2224
const MIN_VIDEO_HEIGHT = 1080;
2325

2426
if (performance.getEntriesByType('navigation')[0]?.responseStatus !== 200) return;
@@ -37,6 +39,7 @@
3739

3840
const simulateClick = (document, node) => {
3941
console.log('simulateClick');
42+
if (!node) return;
4043
const rect = node.getBoundingClientRect();
4144
const clientX = rect.x + rect.width / 2;
4245
const clientY = rect.y + rect.height / 2;
@@ -52,9 +55,6 @@
5255
};
5356

5457
const pornhub = _ => {
55-
// TODO: never redirect, just update the URLs
56-
// TODO: improve resistance to exceptions
57-
5858
const UNWANTED = '__unwanted';
5959
const loadUnwanted = () => JSON.parse(localStorage.getItem(UNWANTED)) || {};
6060
const setUnwanted = (url, ttl) => {
@@ -72,47 +72,60 @@
7272

7373
const processEmbedded = (document, similarVideos) => {
7474
const main = document.querySelector('div#main-container') || document.body;
75-
const css = `
76-
div.mgp_topBar { display: none !important; }
77-
div.mgp_thumbnailsGrid { display: none !important; }
78-
img.mgp_pornhub { display: none !important; }
79-
`;
80-
const styleApplied = !![...main.querySelectorAll('style')].find(i => i.innerHTML === css);
81-
if (styleApplied) {
82-
console.log('embedded video is already initialized');
83-
return;
75+
76+
try {
77+
const css = `
78+
div.mgp_topBar { display: none !important; }
79+
div.mgp_thumbnailsGrid { display: none !important; }
80+
img.mgp_pornhub { display: none !important; }
81+
`;
82+
const styleApplied = !![...main.querySelectorAll('style')].find(i => i.innerHTML === css);
83+
if (styleApplied) {
84+
console.log('embedded video is already initialized');
85+
return;
86+
}
87+
console.log('applying style');
88+
const style = document.createElement('style');
89+
style.innerHTML = css;
90+
main.appendChild(style);
91+
} catch (e) {
92+
console.error(e);
8493
}
85-
console.log('applying style');
86-
const style = document.createElement('style');
87-
style.innerHTML = css;
88-
main.appendChild(style);
8994

90-
const requiresRefresh = main.querySelector('div.mgp_errorIcon') && main.querySelector('p')?.textContent.includes('Please refresh the page');
91-
if (requiresRefresh) {
92-
console.log('refreshing after error');
93-
window.location.href = window.location.toString();
95+
try {
96+
const requiresRefresh = main.querySelector('div.mgp_errorIcon') && main.querySelector('p')?.textContent.includes('Please refresh the page');
97+
if (requiresRefresh) {
98+
console.log('refreshing after error');
99+
window.location.href = window.location.toString();
100+
}
101+
} catch (e) {
102+
console.error(e);
94103
}
95104

96105
const video = main.querySelector('video');
97-
if (!video) {
98-
console.log('embedding this video is probably not allowed');
99-
window.stop();
100-
101-
if (!isUnwanted(url)) {
102-
console.log('making single refresh attempt');
103-
setUnwanted(url, currentTime() + 5 * 60);
104-
window.location = url.toString();
105-
return;
106-
}
106+
try {
107+
if (!video) {
108+
console.log('embedding this video is probably not allowed');
109+
window.stop();
107110

108-
if (similarVideos.length > 0) {
109-
console.log('redirecting to random non-unwanted similar video');
110-
const newSimilarVideos = similarVideos.filter(i => !watchedVideos.has(i));
111-
window.location.href = newSimilarVideos.length > 0 ? pickRandom(newSimilarVideos) : pickRandom(similarVideos);
112-
} else {
113-
console.log('giving up');
111+
if (!isUnwanted(url)) {
112+
console.log('making single refresh attempt');
113+
setUnwanted(url, currentTime() + 60 * 60);
114+
window.location = url.toString();
115+
return;
116+
}
117+
118+
if (similarVideos.length > 0) {
119+
console.log('redirecting to a random non-unwanted similar video');
120+
const newSimilarVideos = similarVideos.filter(i => !watchedVideos.has(i));
121+
window.location.href = newSimilarVideos.length > 0 ? pickRandom(newSimilarVideos) : pickRandom(similarVideos);
122+
} else {
123+
console.log('giving up');
124+
}
125+
return;
114126
}
115-
return;
127+
} catch (e) {
128+
console.error(e);
116129
}
117130

118131
video.addEventListener('loadstart', _ => simulateClick(document, main.querySelector('div.mgp_playIcon')));
@@ -139,26 +152,31 @@
139152
video.load();
140153
};
141154

142-
const processPreview = i => {
143-
const link = i.closest('a');
144-
if (link) {
145-
const duration = timeToSeconds(i.textContent);
146-
const t = random(duration / 4, duration / 3);
155+
const premiumRedirect = node => node.href.startsWith('javascript:');
156+
157+
const processPreview = node => {
158+
try {
159+
const link = node.closest('a');
160+
if (!link) return;
147161

148-
const premiumRedirect = !link.href.startsWith('https://');
149-
if (!premiumRedirect) {
162+
const duration = timeToSeconds(node.textContent);
163+
const premium = premiumRedirect(link);
164+
if (!premium) {
165+
const t = random(duration / 4, duration / 3);
150166
link.href += `&t=${t}`;
151167
}
152168

153-
const node = link.closest('div.phimage')?.parentNode || link.closest('li');
154-
if (premiumRedirect || duration < MIN_DURATION_MIN * 60 || isUnwanted(new URL(link.href))) {
155-
node?.classList.add(UNWANTED);
169+
const container = link.closest('div.phimage')?.parentNode || link.closest('li');
170+
if (premium || duration < MIN_DURATION_MINS * 60 || isUnwanted(new URL(link.href))) {
171+
container?.classList.add(UNWANTED);
156172
} else {
157173
if (link.querySelector('div.watchedVideoText')) {
158174
watchedVideos.add(link.href);
159175
}
160176
return link.href;
161177
}
178+
} catch (e) {
179+
console.log(e);
162180
}
163181
};
164182

@@ -176,12 +194,57 @@
176194
const main = document.querySelector('div#main-container') || document.body;
177195
subscribeOnChanges(main, processPlaylistItem);
178196

179-
const style = document.createElement('style');
180-
style.innerHTML = `
181-
div.${UNWANTED}, li.${UNWANTED} { opacity: 10%; }
182-
div.${UNWANTED}:hover, li.${UNWANTED}:hover { opacity: 40%; }
183-
`;
184-
main.appendChild(style);
197+
try {
198+
const style = document.createElement('style');
199+
style.innerHTML = `
200+
div.${UNWANTED}, li.${UNWANTED} { opacity: 10%; }
201+
div.${UNWANTED}:hover, li.${UNWANTED}:hover { opacity: 40%; }
202+
`;
203+
main.appendChild(style);
204+
} catch (e) {
205+
console.error(e);
206+
}
207+
208+
const filterParams = Object.entries({
209+
'min_duration': MIN_DURATION_MINS,
210+
'hd': 1,
211+
'o': 'tr',
212+
't': 'm',
213+
});
214+
215+
const processLink = node => {
216+
if (node.nodeType !== 1) return;
217+
if (node.tagName === 'A') {
218+
try {
219+
if (premiumRedirect(node)) return;
220+
const url = new URL(node.href.startsWith('https:') ? node.href : `${window.location.origin}${node.href}`);
221+
const params = url.searchParams;
222+
const p = url.pathname;
223+
if (p === '/video' || p === '/video/search' || p.startsWith('/categories/')) {
224+
filterParams.forEach(([key, value]) => params.set(key, value));
225+
node.href = url.toString();
226+
}
227+
} catch (e) {
228+
console.error(node.href, e);
229+
}
230+
return;
231+
}
232+
node.childNodes.forEach(processLink);
233+
};
234+
235+
subscribeOnChanges(main, processLink);
236+
237+
// TODO
238+
/*const searchForm = main.querySelector('form#search_form') || main.querySelector('form');
239+
if (searchForm) {
240+
filterParams.forEach(([key, value]) => {
241+
const input = document.createElement('input');
242+
input.type = 'hidden';
243+
input.name = key;
244+
input.value = value;
245+
searchForm.appendChild(input);
246+
});
247+
}*/
185248

186249
const similarVideos = [...main.querySelectorAll('var.duration')]
187250
.map(i => processPreview(i))
@@ -231,10 +294,6 @@
231294
window.location.href = embedUrl;
232295
}
233296
}
234-
} else if (params.get('hd') !== '1' && !params.has('min_duration') && (p.startsWith('/categories/') || p === '/video' || p === '/video/search')) {
235-
params.set('min_duration', MIN_DURATION_MIN);
236-
params.set('hd', 1);
237-
newUrl = url.toString();
238297
}
239298
};
240299

@@ -243,13 +302,13 @@
243302

244303
if (p === '/' && params.has('k') && !params.has('quality')) {
245304
params.set('sort', 'rating');
246-
params.set('durf', `${MIN_DURATION_MIN}min_more`);
305+
params.set('durf', `${MIN_DURATION_MINS}min_more`);
247306
params.set('quality', `${MIN_VIDEO_HEIGHT}P`);
248307
newUrl = url.toString();
249308
} else if (p.startsWith('/c/') && !p.includes(`q:${MIN_VIDEO_HEIGHT}P`)) {
250309
const ps = p.split('/');
251310
if (ps.length >= 3) {
252-
url.pathname = `${ps[1]}/s:rating/d:${MIN_DURATION_MIN}min_more/q:${MIN_VIDEO_HEIGHT}P/${ps[2]}`;
311+
url.pathname = `${ps[1]}/s:rating/d:${MIN_DURATION_MINS}min_more/q:${MIN_VIDEO_HEIGHT}P/${ps[2]}`;
253312
newUrl = url.toString();
254313
}
255314
}
@@ -263,7 +322,7 @@
263322
url.pathname = '/trending_videos/'
264323
}
265324
params.set('q', 'fhd');
266-
params.set('d', MIN_DURATION_MIN);
325+
params.set('d', MIN_DURATION_MINS);
267326
newUrl = url.toString();
268327
}
269328
};
@@ -274,17 +333,21 @@
274333
[...document.body.querySelectorAll('a')]
275334
.filter(i => !!['categories', 'channels', 'models', 'top-rated'].find(page => expectedPage(page, i.href)))
276335
.forEach(i => {
277-
const url = new URL(i.href);
278-
const ps = url.pathname.split('/').filter(i => i.length > 0);
279-
for (const i of ['hd', 'top-rated', 'thirty-all-min']) {
280-
if (!ps.includes(i)) {
281-
ps.push(i);
336+
try {
337+
const url = new URL(i.href);
338+
const ps = url.pathname.split('/').filter(i => i.length > 0);
339+
for (const i of ['hd', 'top-rated', 'thirty-all-min']) {
340+
if (!ps.includes(i)) {
341+
ps.push(i);
342+
}
282343
}
344+
ps.push('');
345+
ps.unshift('');
346+
url.pathname = ps.join('/');
347+
i.href = url.toString();
348+
} catch (e) {
349+
console.error(i.href, e);
283350
}
284-
ps.push('');
285-
ps.unshift('');
286-
url.pathname = ps.join('/');
287-
i.href = url.toString();
288351
});
289352
};
290353

0 commit comments

Comments
 (0)