直接获取被masked的真实链接,无缝翻页
// ==UserScript==
// @name F95Zone
// @namespace -
// @version 1.0.0
// @license GPL-3.0
// @description 直接获取被masked的真实链接,无缝翻页
// @author stars-location
// @match https://f95zone.to/*
// @icon https://f95zone.to/assets/favicon-32x32.png
// @grant none
// @run-at document-end
// ==/UserScript==
(function () {
'use strict';
document.addEventListener('click', function (e) {
const link = e.target.closest('a');
if (!link || !link.href) return;
try {
const url = new URL(link.href, window.location.origin);
if (url.hostname !== 'f95zone.to' || !url.pathname.startsWith('/masked/')) {
return;
}
} catch (err) {
return;
}
e.preventDefault();
e.stopImmediatePropagation();
const maskedUrl = new URL(link.href, window.location.origin).href;
fetch(maskedUrl, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'xhr=1&download=1'
})
.then(r => r.json())
.then(data => {
if (data.status === 'ok') {
window.open(data.msg, '_blank');
} else {
window.open(maskedUrl, '_blank');
}
})
}, true);
})();
(function () {
'use strict';
if (!document.querySelector('.structItem--thread')) return;
let isLoading = false;
let hasMore = !!document.querySelector('a.pageNav-jump--next');
let preloadedDoc = null;
function preloadNextPage(){
if (isLoading || !hasMore || preloadedDoc) return;
isLoading = true;
const nextLink = document.querySelector('a.pageNav-jump--next');
if (!nextLink) {
hasMore = false;
return;
}
const nextPageUrl = nextLink.href;
fetch(nextPageUrl, { credentials: 'include' })
.then(res => {
if (!res.ok) throw new Error('HTTP error');
return res.text();
})
.then(html => {
const doc = new DOMParser().parseFromString(html, 'text/html');
const messages = doc.querySelector('.block-body')?.querySelectorAll('.message');
if (messages && messages.length > 0) {
preloadedDoc = doc;
} else {
throw 0;
}
})
.catch(() => {})
.finally(() => {
isLoading = false;
});
}
function loadNextPage() {
if (!preloadedDoc) return;
const newThreads = preloadedDoc.querySelector('.block-body').querySelectorAll('.message');
const container = document.querySelector('.block-body');
const nextPageUrl = document.querySelector('a.pageNav-jump--next').href;
if (container && newThreads.length > 0) {
newThreads.forEach(thread => container.appendChild(thread));
}
const newNext = preloadedDoc.querySelector('a.pageNav-jump--next');
const currentNext = document.querySelector('a.pageNav-jump--next');
if (newNext && currentNext) currentNext.href = newNext.href;
else {
currentNext.remove();
hasMore = false;
}
history.replaceState(null, '', nextPageUrl);
updatePageNum();
preloadedDoc = null;
}
function updatePageNum(){
const oldPageNavAll = document.querySelectorAll('.pageNav-main');
const oldPageNav = oldPageNavAll[0];
const newPageNav = preloadedDoc.querySelector('.pageNav-main');
const oldPageNum = oldPageNav.querySelector('.pageNav-page--current a').textContent.split('–')[0];
const newPageNum = newPageNav.querySelector('.pageNav-page--current a').textContent;
const pagesAfterCurrent1 = [];
const pagesAfterCurrent2 = [];
let foundCurrent = false;
for (const li of oldPageNav.querySelectorAll('.pageNav-page')) {
if (li.classList.contains('pageNav-page--current')) foundCurrent = true;
if (foundCurrent) pagesAfterCurrent1.push(li);
}
pagesAfterCurrent1.forEach(el => el.remove());
foundCurrent = false;
for (const li of newPageNav.querySelectorAll('.pageNav-page')) {
if (li.classList.contains('pageNav-page--current')) {
foundCurrent = true;
li.querySelector('a').textContent = oldPageNum + "–" + newPageNum;
}
if (foundCurrent) pagesAfterCurrent2.push(li);
}
if (pagesAfterCurrent2.length > 0) {
pagesAfterCurrent2.forEach(nav => oldPageNav.appendChild(nav));
}
oldPageNavAll[1].innerHTML = oldPageNavAll[0].innerHTML;
}
window.addEventListener('scroll', () => {
preloadNextPage();
});
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
if (preloadedDoc) loadNextPage();
else preloadNextPage();
}
}
}, { threshold: 0.1 });
observer.observe(document.querySelectorAll('.pageNav-main')[1]);
})();