Sleazy Fork is available in English.
Jump between JavDB, MissAV, SupJav, OneJav, and U9A9
// ==UserScript==
// @name Jav Multi-Site Jumper
// @namespace https://javdb.com/
// @version 1.1
// @description Jump between JavDB, MissAV, SupJav, OneJav, and U9A9
// @license MIT
// @author YourName
// @match https://javdb.com/*
// @match https://missav.ws/*
// @match https://missav.ai/*
// @match https://supjav.com/*
// @match *://onejav.com/*
// @match https://u9a9.com/*
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_notification
// @grant GM_setClipboard
// @grant GM_getResourceURL
// @grant GM_registerMenuCommand
// @grant GM_info
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @connect *
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
// ═══════════════════════════════════════════════════════════
// 全局樣式 (以 d.js 風格為主)
// ═══════════════════════════════════════════════════════════
const styles = `
#jav-jumper-container {
position: fixed;
left: 20px;
bottom: 20px;
z-index: 99999;
display: flex;
flex-direction: column;
gap: 10px;
font-family: Arial, sans-serif;
}
.jav-jumper-btn {
display: inline-block;
padding: 8px 12px;
color: white;
text-decoration: none;
border: none;
border-radius: 6px;
font-weight: bold;
font-size: 12px;
cursor: pointer;
transition: all 0.3s ease;
text-align: center;
min-width: 70px;
}
.jav-jumper-btn:hover {
transform: translateY(-2px);
}
.jj-missav {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.jj-missav:hover {
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}
.jj-supjav {
background: linear-gradient(135deg, #00bcd4 0%, #008ba3 100%);
box-shadow: 0 4px 15px rgba(0, 188, 212, 0.4);
}
.jj-supjav:hover {
box-shadow: 0 6px 20px rgba(0, 188, 212, 0.6);
}
.jj-javdb {
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
box-shadow: 0 4px 15px rgba(17, 153, 142, 0.4);
}
.jj-javdb:hover {
box-shadow: 0 6px 20px rgba(17, 153, 142, 0.6);
}
.jj-copy {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
box-shadow: 0 4px 15px rgba(240, 147, 251, 0.4);
}
.jj-copy:hover {
box-shadow: 0 6px 20px rgba(240, 147, 251, 0.6);
}
.jj-copied {
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%) !important;
}
/* OneJav 按鈕容器 */
.jj-onejav-container {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
`;
const styleSheet = document.createElement('style');
styleSheet.textContent = styles;
document.head.appendChild(styleSheet);
// ═══════════════════════════════════════════════════════════
// 番號格式化 (OneJav / U9A9 共用)
// ═══════════════════════════════════════════════════════════
function getAvCode(avid) {
if (!avid || typeof avid !== 'string') return 'Unknown';
// FC2PPV 格式統一處理
const fc2Match = avid.match(/^fc2ppv[-_]?(\d+)$/i);
if (fc2Match) return 'fc2-ppv-' + fc2Match[1];
// 保留特殊格式
if (/^fc2-ppv-\d+$/i.test(avid)) return avid.toLowerCase();
if (/^[-a-z0-9]+$/i.test(avid) && avid.includes('-')) return avid;
// OneJav 原有邏輯
if (avid.match(/-[^0]/g)) return avid;
if (avid.match(/^[0-9-_]+$/g)) return avid;
if (avid.match(/^(crazyasia|sm|video_|BrazzersExxtra)+/gi)) return avid;
if (avid.match(/^FC2PPV\d+$/i)) {
let numMatch = avid.match(/\d+$/);
let num = numMatch ? numMatch[0] : '000';
return "FC2-PPV-" + num;
}
// 移除 FC2 前綴並標準化
avid = avid.replace(/\b(FC2+)/gi, "");
const letter = (avid.match(/^[a-z]+/i)?.[0] || 'ID').toUpperCase();
const num = (avid.match(/-?(\d+)$/)?.[1] || '000').replace(/^0+/, '').padStart(3, '0');
return `${letter}-${num}`;
}
// ═══════════════════════════════════════════════════════════
// 取得番號 (javdb / missav / supjav)
// ═══════════════════════════════════════════════════════════
function getCode() {
if (window.location.href.includes('javdb.com')) {
var link = document.querySelector('.panel-block.first-block a.button.is-white.copy-to-clipboard');
return link ? link.getAttribute('data-clipboard-text') : '';
}
if (window.location.href.includes('missav.ws') || window.location.href.includes('missav.ai')) {
var el = document.querySelector('.text-secondary span.font-medium');
if (!el) return '';
return el.innerText.replace(/-UNCENSORED-LEAK|-CHINESE-SUBTITLE/g, '');
}
if (window.location.href.includes('supjav.com')) {
var m = window.location.search.match(/[?&]s=([^&]+)/);
return m ? decodeURIComponent(m[1]) : '';
}
return '';
}
// ═══════════════════════════════════════════════════════════
// U9A9 專用:從標題提取 AV code
// ═══════════════════════════════════════════════════════════
function extractU9a9Code() {
const panelTitle = document.querySelector('.panel-heading .panel-title')?.textContent.trim();
if (!panelTitle) return null;
// 優先匹配 FC2PPV- 格式
const fc2Match = panelTitle.match(/FC2PPV[-_]?\d+/i);
if (fc2Match) return fc2Match[0];
// 匹配數字前綴 AV code 格式:例如 390JAC-232 -> JAC-232
const prefixedAvCodeMatch = panelTitle.match(/\b\d+([A-Za-z]{3,5})[-_\s]?(\d{2,6})\b/);
if (prefixedAvCodeMatch) return `${prefixedAvCodeMatch[1]}-${prefixedAvCodeMatch[2]}`;
// 匹配 AV code 格式:3-5個字母 + - + 2-6位數字
const avCodeMatch = panelTitle.match(/\b([A-Za-z]{3,5})[-_]?(\d{2,6})\b/);
if (avCodeMatch) return avCodeMatch[0];
return null;
}
// ═══════════════════════════════════════════════════════════
// 通用:開新分頁
// ═══════════════════════════════════════════════════════════
function openInTab(url) {
var a = document.createElement('a');
a.href = url;
a.target = '_blank';
a.style.display = 'none';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
// ═══════════════════════════════════════════════════════════
// 通用:生成按鈕 (d.js 風格)
// ═══════════════════════════════════════════════════════════
function mkLinkBtn(text, href, cls) {
return Object.assign(document.createElement('a'), {
href: href,
target: '_blank',
textContent: text,
className: 'jav-jumper-btn ' + cls
});
}
function mkActionBtn(text, cls) {
return Object.assign(document.createElement('button'), {
textContent: text,
className: 'jav-jumper-btn ' + cls
});
}
// ═══════════════════════════════════════════════════════════
// 通用:創建浮動面板 (三個按鈕:複製 + 兩個跳轉)
// ═══════════════════════════════════════════════════════════
function createFloatingPanel(番號, btn1Target, btn2Target, btn1Label, btn2Label, btn1Class, btn2Class) {
var container = document.createElement('div');
container.id = 'jav-jumper-container';
// 複製按鈕
var copyBtn = mkActionBtn('複製', 'jj-copy');
copyBtn.onclick = async function() {
try {
await navigator.clipboard.writeText(番號);
var orig = copyBtn.textContent;
copyBtn.textContent = '已複製!';
copyBtn.classList.add('jj-copied');
setTimeout(function() {
copyBtn.textContent = orig;
copyBtn.classList.remove('jj-copied');
}, 1500);
} catch (e) {
copyBtn.textContent = '失敗';
setTimeout(function() { copyBtn.textContent = '複製'; }, 1500);
}
};
// 跳轉按鈕 1 (上方)
var btn1Url = btn1Target === 'missav'
? 'https://missav.ws/' + 番號.toLowerCase()
: btn1Target === 'supjav'
? 'https://supjav.com/?s=' + encodeURIComponent(番號)
: 'https://javdb.com/search?f=all&q=' + encodeURIComponent(番號);
var btn1 = mkLinkBtn(btn1Label, btn1Url, btn1Class);
// 跳轉按鈕 2 (下方)
var btn2Url = btn2Target === 'missav'
? 'https://missav.ws/' + 番號.toLowerCase()
: btn2Target === 'supjav'
? 'https://supjav.com/?s=' + encodeURIComponent(番號)
: 'https://javdb.com/search?f=all&q=' + encodeURIComponent(番號);
var btn2 = mkLinkBtn(btn2Label, btn2Url, btn2Class);
container.append(copyBtn, btn1, btn2);
document.body.appendChild(container);
}
// ═══════════════════════════════════════════════════════════
// 分站分流
// ═══════════════════════════════════════════════════════════
if (window.location.href.includes('onejav.com')) {
oneJavInit();
} else if (window.location.href.includes('u9a9.com')) {
u9a9Init();
} else {
floatingInit();
}
// ═══════════════════════════════════════════════════════════
// OneJav:在每個標題前插入按鈕
// ═══════════════════════════════════════════════════════════
function oneJavInit() {
function add() {
const titles = document.querySelectorAll('.title.is-4.is-spaced');
if (titles.length === 0) return;
titles.forEach(function(title) {
let avid = title.querySelector('a').textContent
? title.querySelector('a').textContent.replace(/[ ]/g, "").replace(/[\r\n]/g, "")
: 'Unknown';
if (!(/(-)/g).test(avid)) {
avid = getAvCode(avid);
}
const container = document.createElement('div');
container.className = 'jj-onejav-container';
const btnMiss = mkLinkBtn(avid,
'https://missav.ws/' + avid,
'jj-missav');
const btnSup = mkLinkBtn(avid,
'https://supjav.com/?s=' + encodeURIComponent(avid),
'jj-supjav');
const btnJav = mkLinkBtn(avid,
'https://javdb.com/search?q=' + encodeURIComponent(avid),
'jj-javdb');
container.appendChild(btnMiss);
container.appendChild(btnSup);
container.appendChild(btnJav);
title.parentNode.insertBefore(container, title);
});
}
window.addEventListener('load', add);
}
// ═══════════════════════════════════════════════════════════
// U9A9:浮動面板
// ═══════════════════════════════════════════════════════════
function u9a9Init() {
function tryCreate() {
if (document.getElementById('jav-jumper-container')) return;
var raw = extractU9a9Code();
if (!raw) return;
var processedCode = getAvCode(raw);
// 排列:複製 → SupJav → MissAV
createFloatingPanel(processedCode,
'supjav', 'missav',
processedCode, processedCode,
'jj-supjav', 'jj-missav');
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
var check = setInterval(function() {
if (document.querySelector('.panel-heading .panel-title')) {
clearInterval(check);
tryCreate();
}
}, 100);
setTimeout(function() { clearInterval(check); }, 5000);
});
} else {
var check = setInterval(function() {
if (document.querySelector('.panel-heading .panel-title')) {
clearInterval(check);
tryCreate();
}
}, 100);
setTimeout(function() { clearInterval(check); }, 5000);
}
new MutationObserver(function() {
if (!document.getElementById('jav-jumper-container')) tryCreate();
}).observe(document.body, { childList: true, subtree: true });
}
// ═══════════════════════════════════════════════════════════
// JavDB / MissAV / SupJav:浮動面板
// ═══════════════════════════════════════════════════════════
function floatingInit() {
var 番號 = getCode();
if (!番號) return;
if (window.location.href.includes('javdb.com')) {
// 複製 → SupJav → MissAV
createFloatingPanel(番號,
'supjav', 'missav',
番號, 番號,
'jj-supjav', 'jj-missav');
} else if (window.location.href.includes('missav.ws') || window.location.href.includes('missav.ai')) {
// 複製 → SupJav → JavDB
createFloatingPanel(番號,
'supjav', 'javdb',
番號, 番號,
'jj-supjav', 'jj-javdb');
} else if (window.location.href.includes('supjav.com')) {
// 複製 → MissAV → JavDB
createFloatingPanel(番號,
'missav', 'javdb',
番號, 番號,
'jj-missav', 'jj-javdb');
}
// ── JavDB 磁力連接下載按鈕修改 ──
updateDownloadButtons();
var observer = new MutationObserver(function() { updateDownloadButtons(); });
var magnetsContent = document.querySelector('#magnets-content');
if (magnetsContent) {
observer.observe(magnetsContent, { childList: true, subtree: true });
}
}
function updateDownloadButtons() {
if (!window.location.href.includes('javdb.com')) return;
var magnetItems = document.querySelectorAll('#magnets-content .item.columns');
magnetItems.forEach(function(item) {
var copyButton = item.querySelector('.copy-to-clipboard');
var downloadButton = item.querySelector('a.button.is-info.is-small[href^="https://keepshare.org"]');
if (copyButton && downloadButton) {
var magnetLink = copyButton.getAttribute('data-clipboard-text');
if (magnetLink) {
downloadButton.href = magnetLink;
downloadButton.removeAttribute('target');
}
}
});
}
})();