// ==UserScript==
// @name tianteng
// @namespace https://greasyfork.org/xmlspy
// @version 2.0.4
// @author xmlspy
// @description 各种开车网站的优化,javbus,javlib
// @license MIT
// @match *://*/*
// @require https://registry.npmmirror.com/jquery/3.7.1/files/dist/jquery.min.js#sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=
// @require https://cdn.jsdelivr.net/npm/ldloader@3.0.3/index.min.js
// @require https://cdn.jsdelivr.net/npm/tabbyjs@12.0.3/dist/js/tabby.min.js
// @resource ldbutton/index.min.css https://cdn.jsdelivr.net/npm/ldbutton@2.0.4/index.min.css
// @resource ldloader/index.min.css https://cdn.jsdelivr.net/npm/ldloader@3.0.3/index.min.css
// @resource tabbyjs/dist/css/tabby-ui.min.css https://cdn.jsdelivr.net/npm/tabbyjs@12.0.3/dist/css/tabby-ui.min.css
// @connect *://*/*
// @grant GM.setClipboard
// @grant GM.xmlHttpRequest
// @grant GM_addStyle
// @grant GM_deleteValue
// @grant GM_getResourceText
// @grant GM_getValue
// @grant GM_info
// @grant GM_openInTab
// @grant GM_setClipboard
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @run-at document-start
// ==/UserScript==
(function ($, Tabby, ldloader) {
'use strict';
var _GM = /* @__PURE__ */ (() => typeof GM != "undefined" ? GM : void 0)();
var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
var _GM_getResourceText = /* @__PURE__ */ (() => typeof GM_getResourceText != "undefined" ? GM_getResourceText : void 0)();
var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
var _GM_openInTab = /* @__PURE__ */ (() => typeof GM_openInTab != "undefined" ? GM_openInTab : void 0)();
var _GM_setClipboard = /* @__PURE__ */ (() => typeof GM_setClipboard != "undefined" ? GM_setClipboard : void 0)();
var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
function getUrlParam(url, name) {
const urlObj = new URL(url);
return urlObj.searchParams.get(name);
}
function drawImage(ImgObj, maxWidth, maxHeight) {
var image = new Image();
image.src = ImgObj.src;
var tempWidth;
var tempHeight;
if (image.width > 0 && image.height > 0) {
if (image.width / image.height >= maxWidth / maxHeight) {
if (image.width > maxWidth) {
tempWidth = maxWidth;
tempHeight = image.height * maxWidth / image.width;
} else {
tempWidth = image.width;
tempHeight = image.height;
}
} else {
if (image.height > maxHeight) {
tempHeight = maxHeight;
tempWidth = image.width * maxHeight / image.height;
} else {
tempWidth = image.width;
tempHeight = image.height;
}
}
ImgObj.height = tempHeight;
ImgObj.width = tempWidth;
ImgObj.alt = image.width + "×" + image.height;
}
}
function appendCopyButton(chePai, toAppendElement, callback) {
var copyButton = document.createElement("button");
copyButton.innerHTML = "复 制";
copyButton.setAttribute("id", "copyButton");
toAppendElement.appendChild(copyButton);
document.addEventListener("click", (e) => {
if (e.target.getAttribute("id") === "copyButton") {
_GM.setClipboard(chePai, "text");
}
});
callback && callback(copyButton, chePai, toAppendElement);
}
function addPasteAndSearchButton($searchButton, $searchInput, callback) {
const styleMap = { "margin-left": "5px" };
$searchButton[0] && $searchButton[0].computedStyleMap().forEach((value, key) => {
styleMap[key] = value;
});
let $pasteAndSearchButton = $(
`<input type="button" value="粘贴&搜索" id="pasteAndSearch"></input>`
);
$pasteAndSearchButton.css(styleMap);
$searchButton.after($pasteAndSearchButton);
$pasteAndSearchButton.click(() => {
navigator.clipboard.readText().then((clipText) => {
if (clipText != null && $.trim(clipText) != "") {
$searchInput.val($.trim(clipText));
$searchButton.click();
}
});
});
return $pasteAndSearchButton;
}
let seq = 0;
function debug(str, title) {
{
if (!str) {
str = "";
}
if (!Array.isArray(str)) {
str = [str];
}
seq++;
console.log(
`%c【tianteng ${_GM_info.script.version}】 ${title ? title : "debug"}:`,
"color: yellow;font-size: large;font-weight: bold;background-color: darkblue;",
seq,
...str
);
}
}
function pasteAndSearchEventHandler(searchButton, searchInput, pasteAndSearchButton) {
pasteAndSearchButton.on("click", () => {
navigator.clipboard.readText().then((clipText) => {
if (clipText != null && $.trim(clipText) != "") {
searchInput.val($.trim(clipText));
searchButton.trigger("click");
}
});
});
}
function observe(target, options, callback) {
return new MutationObserver(callback).observe(target, options);
}
function interceptEventListener(interceptorAdd, interceptorRemove) {
const ep = EventTarget.prototype;
if (!ep.addEventListenerOriginal) {
ep.addEventListenerOriginal = ep.addEventListener;
ep.addEventListener = function(type, callback, options) {
if (this) {
if (interceptorAdd) {
const result = interceptorAdd(this, type, callback, options);
if (result === true) {
return;
}
}
this.allListeners = this.allListeners || [];
this.allListeners.push({ type, callback, options });
this.addEventListenerOriginal.apply(this, arguments);
} else {
debug(
`[this] is bad. type: ${type} callback: ${callback} options: ${options}`,
"addEventListenerHook"
);
}
};
}
if (!ep.removeEventListenerOriginal) {
ep.removeEventListenerOriginal = ep.removeEventListener;
ep.removeEventListener = function(type, callback, options) {
if (this) {
{
debug(
`[this] is bad. type: ${type} callback: ${callback} options: ${options}`,
"removeEventListenerHook"
);
}
}
};
}
}
function makeRequestHeaders(headers) {
return $.extend(
{
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cache-Control": "max-age=0",
"Sec-Ch-Ua": '"Chromium";v="119", "Not?A_Brand";v="24"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "Windows",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36"
},
headers
);
}
class HandlerExecutor {
constructor(handler) {
this.handler = handler;
this.execute = this.execute.bind(this);
this.checkCondition = this.checkCondition.bind(this);
}
execute() {
if (!this.handler) {
throw new Error("handler is not defined");
}
const { name, condition, handle } = this.handler;
if (!name) {
throw new Error("handler name is not defined");
}
if (condition === null || condition === void 0) {
throw new Error("handler condition is not defined");
}
if (!handle) {
throw new Error("handler handle is not defined");
}
const result = this.checkCondition(condition);
if (result.success === true) {
handle(condition, result.keyOrIndex);
}
return result;
}
/**
*
* @param {RegExp|Function|boolean|string|jQuery|Array<any>} condition
* @returns {Result}
*/
checkCondition(condition) {
if ($.type(condition) === "regexp") {
return new Result(condition.test(window.location.href));
}
if ($.isFunction(condition)) {
return new Result(condition() === true);
}
if ($.type(condition) === "boolean") {
return new Result(condition === true);
}
if ($.type(condition) === "string") {
return new Result(document.querySelector(condition) != null);
}
if (condition instanceof $) {
return new Result(condition.length > 0);
}
if ($.isPlainObject(condition)) {
for (const key in condition) {
if (this.checkCondition(condition[key]).success) {
return new Result(true, key);
}
}
}
if ($.isArray(condition)) {
for (const [index, value] of condition) {
if (this.checkCondition(value).success) {
return new Result(true, index);
}
}
}
return new Result(false);
}
}
class Result {
constructor(success, keyOrIndex) {
this.success = success;
this.keyOrIndex = keyOrIndex;
}
}
class Handler {
constructor() {
if (this.constructor === Handler) {
throw new TypeError("Can not construct abstract class.");
}
this.handle = this.handle.bind(this);
}
get name() {
throw new Error("not implemented");
}
get condition() {
throw new Error("not implemented");
}
handle(condition, keyOrIndex) {
throw new Error("not implemented");
}
}
class BaiduHandler extends Handler {
get name() {
return "百度";
}
get condition() {
return /baidu\.com/;
}
handle(condition, keyOrIndex) {
debug("添加 粘贴并搜索 按钮", this.name);
const searchButton = $(`[type="submit"]`);
const searchInput = $(`#kw`);
if (searchButton.length === 0 || searchInput.length === 0) {
debug("找不到搜索按钮或搜索输入框", this.name);
debug("serachButton.length:{serachButton.length}", this.name);
debug("searchInput.length:{searchInput.length}", this.name);
return;
}
const pasteAndSearchButton = searchButton.clone();
pasteAndSearchButton.val("粘贴&搜索").removeAttr("id").attr("type", "button");
searchButton.parent().append(pasteAndSearchButton);
searchButton.parent().css("width", "auto");
_GM_addStyle(`
#head_wrapper .s_form {
width: auto;
height: 100%;
margin: 0 auto;
text-align: center;
}
#head_wrapper .s_btn_wr .wrapper_new{
width:auto;
}
`);
pasteAndSearchEventHandler(searchButton, searchInput, pasteAndSearchButton);
}
}
class OsChinaHandler extends Handler {
get name() {
return "开源中国";
}
get condition() {
return /oschina\.net/;
}
handle(condition, keyword) {
debug("修改首页某些链接无法中键点击问题.", "开源中国");
$(`[data-href]`).each(function() {
const $this = $(this);
const href = $this.attr("data-href");
const classCss = $this.attr("class");
const title = $this.attr("title");
const innerHtml = this.innerHTML;
const html = `<a target="_blank" title="${title}" href="${href}" class="${classCss}">${innerHtml}</a>`;
$this.replaceWith(html);
});
debug("删除url中的重定向.", "开源中国");
$('a[href*="/action/GoToLink?url"]').each(function() {
let href = $(this).attr("href");
if (href) {
let url = getUrlParam(href, "url");
$(this).attr("href", url);
}
});
}
}
class GiteeHandler extends Handler {
get name() {
return "gitee";
}
get condition() {
return /gitee\.com/;
}
handle(condition, keyword) {
debug("删除url中的重定向.", "gitee");
$('a[href*="/link?target"]').each(function(index) {
let href = $(this).attr("href");
if (href) {
let url = getUrlParam(href, "target");
$(this).attr("href", url);
}
});
}
}
class ZhihuHandler extends Handler {
get name() {
return "知乎";
}
get condition() {
return /zhihu\.com/;
}
handle(condition, keyOrIndex) {
debug("添加 粘贴并搜索 按钮", "知乎");
const searchButton = $(`button[class*="SearchBar-searchButton"]`);
const searchInput = $(`#Popover1-toggle`);
addPasteAndSearchButton(searchButton, searchInput);
}
}
class WnacgHandler extends Handler {
get name() {
return "绅士漫画";
}
get condition() {
return $('head>title:contains("紳士漫畫")');
}
handle(condition, keyword) {
if (location.href.includes("photos-index-aid")) {
debug("明细页面添加搜索框", "紳士漫畫");
const searchInput = `
<div class="search" style="float:right;">
<form id="album_search q-form" action="/search/" method="get" _lpchecked="1">
<div class="input-append" id="q-input">
<input type="text" class="search-query ui-autocomplete-input tips"
name="q" value="" title="搜索漫畫" autocomplete="off"
role="textbox" aria-autocomplete="list" aria-haspopup="true">
<input style="display:none" type="radio" name="f" value="_all" checked="">
<input style="display:none" name="s" value="create_time_DESC">
<input style="display:none" name="syn" value="yes">
<button type="" name=""></button>
</div>
</form>
</div>
`;
$("#bodywrap").prepend(searchInput);
}
if (location.href.includes("photos-slide-aid")) {
debug("下拉阅读页面,图片由一列改为两列", "紳士漫畫");
const nodeToObserve = document.querySelector("#img_list");
$(nodeToObserve).css({
width: "100%",
display: "flex",
"flex-wrap": "wrap",
"justify-content": "flex-start",
"overflow-x": "hidden"
});
const imgWidth = document.documentElement.clientWidth / 2 - 10;
const imgHeight = document.documentElement.clientHeight - 50;
new MutationObserver((mutations, observer) => {
$("#img_list>div").css({
flex: "1",
"background-color": "#cacaca",
margin: "0 5px 5px 0",
width: "calc((100% - 10px) / 2)",
"min-width": "calc((100% - 10px) / 2)",
"max-width": "calc((100% - 10px) / 2)"
});
$("#img_list>div>img").on("load", (e) => {
drawImage(e.target, imgWidth, imgHeight);
});
}).observe(nodeToObserve, { childList: true });
}
if ($("input.search-query").length > 0) {
debug("为搜索框后面添加 粘贴&搜索 按钮", "紳士漫畫");
const searchInput = $("[name=q]");
const searchButton = $("#q-input > button");
const pasteAndSearchButton = $(
`<button style="float:right;height:30px;">粘贴&搜索</button>`
);
$("#bodywrap").prepend(pasteAndSearchButton);
pasteAndSearchEventHandler(searchButton, searchInput, pasteAndSearchButton);
}
}
}
const domainConfig = {
javbus: { url: "https://www.fanbus.help" },
javlib: { url: "https://www.y78k.com" },
ciligege: { url: "https://www.ciligege2.com" },
// https://tellme.pw/btsow https://btsow.com
btsow: { url: "https://btsow.motorcycles" },
btsearch: { url: "https://www.btsearch.love" },
// 最新地址發布(請收藏):u9a9.link ,永久域名 u9a9.com,u9a9.net,u9a9.ru,u9a9.xyz,u9a9.org,u9a9.me
// Email: u9a9.com#protonmail.com
u9a9: { url: "https://y.u9a9y.xyz" },
skrbt: { url: "https://skrbtlz.top" }
};
domainConfig.javbus.searchUrl = `${domainConfig.javbus.url}/search?q=%s`;
domainConfig.javlib.searchUrl = `${domainConfig.javlib.url}/search?q=%s`;
domainConfig.ciligege.searchUrl = `${domainConfig.ciligege.url}/search/%s/1`;
domainConfig.btsow.searchUrl = `${domainConfig.btsow.url}/search/%s`;
domainConfig.btsearch.searchUrl = `${domainConfig.btsearch.url}/search?q=%s`;
domainConfig.u9a9.searchUrl = `${domainConfig.u9a9.url}/?type=2&search=%s`;
domainConfig.skrbt.searchUrl = `${domainConfig.skrbt.url}/search?keyword=%s`;
class FakeCookie extends Map {
constructor(fullCookieString) {
super();
this.fullCookieString = fullCookieString;
}
get fullCookieString() {
let result = "";
this.forEach((value, key, self) => {
result = result.concat(key).concat("=").concat(value).concat(";");
});
return result === "" ? result : result.substring(0, result.length - 1);
}
set fullCookieString(str) {
if (str) {
let items = str.split(";");
items.map((element, index) => element.trim()).filter((element, index, self) => self.indexOf(element) === index).forEach((element) => {
const pair = element.split("=");
this.set(pair[0], pair[1]);
});
}
}
/**
* 把newCookie合并到当前实例中.如果newCookie中的key与当前的实例重复,这使用newCookie中的覆盖.
* @param {String|FakeCookie} newCookie 要合并的新cookie,类型为String或者FakeCookie.
* 如果类型为String,表示包含全部cookie内容的字符串;
*/
merge(newCookie) {
if (!newCookie) {
return;
}
let newFakeCookie;
if (typeof newCookie === "string") {
newFakeCookie = new FakeCookie(newCookie);
} else if (newCookie instanceof FakeCookie) {
newFakeCookie = newCookie;
} else {
throw new TypeError("Invalid type.");
}
newFakeCookie.forEach((value, key, self) => this.set(key, value));
}
}
let fakeCookie = new FakeCookie();
function getSearchResultFromSkrbt(chepai, callback) {
const skrbtUrl = domainConfig.skrbt.url;
const searchUrl = domainConfig.skrbt.searchUrl.replace("%s", chepai);
function getResponseHeader(response, name) {
if (response && response.responseHeaders && name) {
var arr = response.responseHeaders.trim().split(/[\r\n]+/);
var headerMap = {};
arr.forEach(function(line) {
var parts = line.split(": ");
var header = parts.shift();
var value = parts.join(": ");
headerMap[header] = value;
});
return headerMap[name];
}
return null;
}
function onResponseHeaderRecieved(response) {
if (response.readyState === response.HEADERS_RECEIVED) {
console.log(response.responseHeaders);
const setCookie = getResponseHeader(response, "Set-Cookie");
fakeCookie.merge(setCookie);
}
}
const timeoutIds = [];
function clearTimeouts() {
timeoutIds.forEach((timeoutId) => clearTimeout(timeoutId));
}
function successHandler(response, callback2) {
clearTimeouts();
const $container = $(response.responseText).find(".col-md-6:eq(2)");
const data = $.map($container.find(".list-unstyled"), (item) => {
const title = $(item).find("a.rrt.common-link").html();
const detailHref = $(item).find("a.rrt.common-link").attr("href");
const fileSize = $(item).find("li.rrmi > span:nth-child(2)").text();
const fileCount = $(item).find("li.rrmi > span:nth-child(3)").text();
const timeIncluded = $(item).find("li.rrmi > span:nth-child(4)").text();
return {
name: title,
detailUrl: domainConfig.skrbt.url + detailHref,
//明细页面地址
size: fileSize,
// 文件总大小
fileCount,
// 文件总数
date: timeIncluded
// 收入时间
};
});
callback2({
result: 0,
data
// html: $container.html(),
});
}
_GM_xmlhttpRequest({
method: "get",
headers: makeRequestHeaders({ Referer: skrbtUrl }),
url: searchUrl,
onerror: function(e) {
console.log(e);
},
onload: function(response) {
console.log(response);
if (response.finalUrl.includes("/search?")) {
console.log("-----------OK");
successHandler(response, callback);
} else if (response.finalUrl.includes("/challenge")) {
waitRecaptcha();
} else {
console.log("错误");
clearTimeouts();
callback({ result: 1, message: "" });
}
},
onreadystatechange: onResponseHeaderRecieved
});
function waitRecaptcha() {
var remain = 10;
var startTime = (/* @__PURE__ */ new Date()).getTime();
timeoutIds.unshift(setTimeout(timeoutHandler, 1e3));
timeoutIds.unshift(setTimeout(doChallange, 1e3));
function timeoutHandler() {
console.log("timeoutHandler");
remain = remain - 1;
console.log(`remain: ${remain}`);
if (remain > 0) {
timeoutIds.unshift(setTimeout(timeoutHandler, 1e3));
} else {
doSubmit(randomString(100));
}
}
function doChallange() {
console.log("doChallange");
var aywcUid = genOrGetAywcUid();
var genApi = skrbtUrl + "/anti/recaptcha/v4/gen?aywcUid=" + aywcUid + "&_=" + (/* @__PURE__ */ new Date()).getTime();
_GM_xmlhttpRequest({
method: "get",
responseType: _GM_xmlhttpRequest.RESPONSE_TYPE_JSON,
headers: makeRequestHeaders({
Referer: `${skrbtUrl}/recaptcha/v4/challenge?url=${skrbtUrl}&s=1`
}),
url: genApi,
onerror: function(e) {
console.log(/* @__PURE__ */ new Date() + ": " + e);
timeoutIds.unshift(setTimeout(doChallange, 1e3));
console.log(e);
},
onload: function(response) {
const genResult = response.response;
if (genResult.errno == 0) {
doSubmit(genResult.token);
} else {
timeoutIds.unshift(setTimeout(doChallange, 1e3));
}
},
onreadystatechange: onResponseHeaderRecieved
});
}
function doSubmit(token) {
console.log("doSubmit");
var costtime = (/* @__PURE__ */ new Date()).getTime() - startTime;
_GM_xmlhttpRequest({
method: "get",
headers: makeRequestHeaders({
Referer: `${skrbtUrl}/recaptcha/v4/challenge?url=${skrbtUrl}&s=1`
}),
url: `${skrbtUrl}/anti/recaptcha/v4/verify?token=${token}&aywcUid=${genOrGetAywcUid()}&costtime=${costtime}`,
onerror: function(e) {
console.log(e);
clearTimeouts();
callback({ result: 2, message: "" });
},
onload: function(response) {
console.log("-----doSubmit OK");
console.log(response);
if (response.finalUrl.includes("search?")) {
successHandler(response, callback);
} else {
console.log("错误");
clearTimeouts();
callback({ result: 3, message: "" });
}
},
onreadystatechange: onResponseHeaderRecieved
});
}
function genOrGetAywcUid() {
const unifyidKey = "aywcUid";
let aywcUid = fakeCookie.get(unifyidKey);
if (isEmpty(aywcUid)) {
aywcUid = randomString(10) + "_" + formatDate("yyyyMMddhhmmss", /* @__PURE__ */ new Date());
fakeCookie.set(unifyidKey, aywcUid);
}
return aywcUid;
}
function isEmpty(x) {
if (x == null || x == void 0 || x == "") {
return true;
} else {
return false;
}
}
function randomString(len, charSet) {
charSet = charSet || "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var randomString2 = "";
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString2 += charSet.substring(randomPoz, randomPoz + 1);
}
return randomString2;
}
function formatDate(fmt, date) {
var o = {
"M+": date.getMonth() + 1,
"d+": date.getDate(),
"h+": date.getHours(),
"m+": date.getMinutes(),
"s+": date.getSeconds(),
"q+": Math.floor((date.getMonth() + 3) / 3),
S: date.getMilliseconds()
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
);
}
}
return fmt;
}
}
}
const magnetTabsConfig = {
id: "tianteng-magnet-tabs",
tabs: [
{
id: "tianteng-tab-skrbt",
title: "SKRBT",
url: domainConfig.skrbt.searchUrl,
default: true,
type: 1
},
{
id: "tianteng-tab-btsow",
title: "BTSOW",
url: domainConfig.btsow.searchUrl,
extractor: function(doc, itemCallback) {
const data = [];
$("div.data-list>.row[class=row]", doc).each(function(index, item) {
const detailUrl = "https:" + $("a", item).attr("href");
const name = $("a>div:first", item).html();
let magnet = $("a", item).attr("href").split("/magnet/detail/hash/")[1];
magnet = `magnet:?xt=urn:btih:${magnet}`;
const size = $(item).children("div").first().text().replace("文件大小:", "");
const date = $(item).children("div").last().text().replace("时间:", "");
const record = {
detailUrl,
name,
magnet,
size,
date
};
data.push(record);
itemCallback && itemCallback(record, index, item);
});
return data;
}
},
{
id: "tianteng-tab-ciligege",
title: "CiLiGeGe",
url: domainConfig.ciligege.searchUrl,
extractor: function(doc, itemCallback) {
const data = [];
$("div.bt-list>.bt-card", doc).each(function(index, item) {
const detailUrl = domainConfig.ciligege.url + $("a", item).attr("href");
const name = $("a", item).html();
let magnet = $("a", item).attr("href").replace("/search/", "");
magnet = `magnet:?xt=urn:btih:${magnet}`;
const size = $("div.bt-card-body>span", item).first().text().replace("文件大小:", "");
const date = $("div.bt-card-body>span", item).last().text().replace("时间:", "");
const record = {
detailUrl,
name,
magnet,
size,
date
};
data.push(record);
itemCallback && itemCallback(record, index, item);
});
return data;
}
},
{
id: "tianteng-tab-u9a9",
title: "U9A9",
url: domainConfig.u9a9.searchUrl,
extractor: function(doc, itemCallback) {
const data = [];
$("tbody>tr", doc).each(function(index, item) {
const a = $("td", item).eq(1).find("a");
const detailUrl = domainConfig.u9a9.url + a.attr("href");
const name = a.html();
let magnet = $("td", item).eq(2).find("a").eq(1).attr("href");
const size = $("td", item).eq(3).text();
const date = $("td", item).eq(4).text();
const record = {
detailUrl,
name,
magnet,
size,
date
};
data.push(record);
itemCallback && itemCallback(record, index, item);
});
return data;
}
}
]
};
class MagnetTab {
/**
*
* @param {string} chepai 车牌号
* @param {Function} onAttach 回调函数,function(tabContainer),
* 参数tabContainer是整个MagnetTab的根节点,可以在此函数中把tabContainer插入到页面中
* @param {object} tabsConfig 配置
*/
constructor(chepai, onAttach, tabsConfig) {
_GM_addStyle(_GM_getResourceText("tabbyjs/dist/css/tabby-ui.min.css"));
this.chepai = chepai;
if (tabsConfig) {
this.tabsConfig = tabsConfig;
} else {
this.tabsConfig = magnetTabsConfig;
}
this.onAttach = onAttach;
this.init();
}
getConfig(id) {
for (let i = 0; this.tabsConfig.tabs.length; i++) {
const config = this.tabsConfig.tabs[i];
if (id === config.id) {
return config;
}
}
return null;
}
/**
*
* <ul id="tianteng-magnet-tabs">
* <li><a data-tabby-default href="#tianteng-tab-skrbt">tab上的文字</a></li>
* <li><a href="#hermione">tab上的文字</a></li>
* <li><a href="#neville">tab上的文字</a></li>
* </ul>
*
* <div id="tianteng-tab-skrbt">tab内容,是个table</div>
* <div id="hermione">tab内容,是个table</div>
* <div id="neville">tab内容,是个table</div>
*/
init() {
this.handleButtonClick();
const fragment = document.createDocumentFragment();
const ul = document.createElement("ul");
ul.id = this.tabsConfig.id;
fragment.append(ul);
let defaultTabConfig;
let defaultTab;
let defaultTabContent;
this.tabsConfig.tabs.forEach((tab, index, array) => {
const li = document.createElement("li");
const a = document.createElement("a");
a.href = `#${tab.id}`;
a.text = tab.title;
li.append(a);
ul.append(li);
const div = document.createElement("div");
div.id = tab.id;
div.dataset["tiantengTabConfig"] = JSON.stringify(tab);
div.dataset["tiantengChepai"] = this.chepai;
div.tiantengTabConfig = tab;
fragment.append(div);
if (tab.default === true) {
a.dataset["tabbyDefault"] = "";
defaultTabConfig = tab;
defaultTab = a;
defaultTabContent = div;
}
});
const tabsContainer = document.createElement("div");
tabsContainer.id = "tianteng-tabs-container";
tabsContainer.append(fragment);
this.onAttach(tabsContainer);
$(tabsContainer).before(`
<style id='tianteng-tab-style'>
#tianteng-tabs-container {
background-color:white;
margin-top:10px;
margin-bottom:10px;
padding:12px;
}
#tianteng-tabs-container strong,
#tianteng-tabs-container em,
#tianteng-tabs-container .high-light,
#tianteng-tabs-container .highlight{
font-weight:normal;
color:#F00;
}
#tianteng-tabs-container tr:hover{
background-color:#d7e7f4;
}
#tianteng-tabs-container th,
#tianteng-tabs-container td{
text-align:center;
padding:10px,10px !important;
}
</style>`);
_GM_addStyle(_GM_getResourceText("ldloader/index.min.css"));
_GM_addStyle(_GM_getResourceText("ldbutton/index.min.css"));
this.tabby = new Tabby(`#${this.tabsConfig.id}`);
document.addEventListener(
"tabby",
(event) => {
const tab = event.detail.tab;
const content = event.detail.content;
this.currentTabConfig = content.tiantengTabConfig;
this.buildHtml(tab, content);
},
false
);
this.currentTabConfig = defaultTabConfig;
this.buildHtml(defaultTab, defaultTabContent);
}
buildHtml(tab, tabContent) {
if ($(tabContent).data("tiantengStatus") === "ok") {
return;
}
let tabConfig = tabContent.tiantengTabConfig;
let tableHtml = `
<table class="tianteng-magnet-table"
style="border-collapse: collapse;text-align:center;width:100%;">
<thead style="position:sticky;top:0;background-color:#f5f5f5;">
<tr>
<th style="border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: none; border-bottom: none; text-align:left;">
磁力名称</th>
<th style="border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: none; border-bottom: none;">
档案大小</th>
<th style="border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: none; border-bottom: none;">
分享日期</th>
</tr>
</thead>
<tbody class="tianteng-magnet-tbody">
{{tbody}}
</tbody>
</table>`;
const searchUrl = tabConfig.url.replace("%s", this.chepai);
if (tabConfig.type === 1 && tabConfig.id === "tianteng-tab-skrbt") {
getSearchResultFromSkrbt(this.chepai, function(data) {
if (data.result == 0) {
let tbodyHtml = "";
data.data.forEach(function(record, index, array) {
tbodyHtml += `
<tr>
<td style="border: 1px solid #ccc; text-align:left; width:70%;">
<a style="color:#333" target="_blank"
title="打开磁链明细页面"
href="${record.detailUrl}">
${record.name}
</a>
<button class="btn btn-danger tianteng-copy ld-ext-right"
type="button"
data-tianteng-magnet-url="${record.detailUrl}"
data-tianteng-magnet="${record.magnet}">
复制磁链
<div class="ld ldld bare"
style="width:1em;height:1em">
</div>
</button>
<button class="btn btn-danger tianteng-click ld-ext-right"
type="button"
data-tianteng-magnet-url="${record.detailUrl}"
data-tianteng-magnet="${record.magnet}">
打开磁链
<div class="ld ldld bare"
style="width:1em;height:1em">
</div>
</button>
</td>
<td style="border: 1px solid #ccc;">${record.size}</td>
<td style="border: 1px solid #ccc;">${record.date}</td>
</tr>
`;
});
tableHtml = tableHtml.replace("{{tbody}}", tbodyHtml);
$(tabContent).append(tableHtml);
$(tabContent).data("tiantengStatus", "ok");
}
});
} else {
_GM_xmlhttpRequest({
method: "GET",
url: searchUrl,
headers: makeRequestHeaders({ Referer: searchUrl }),
onerror: function() {
debug(arguments, "onerror");
},
ontimeout: function() {
debug(arguments, "ontimeout");
},
onreadystatechange: function() {
debug(arguments, "onreadystatechange");
},
onabort: function() {
debug(arguments, "onabort");
},
onloadstart: function() {
debug(arguments, "onloadstart");
},
onprogress: function() {
debug(arguments, "onprogress");
},
onload: function(response) {
debug(arguments, "onload");
const doc = $(response.responseText);
let tbodyHtml = "";
tabConfig.extractor(doc, (record, index, item) => {
tbodyHtml += `
<tr>
<td style="border: 1px solid #ccc; text-align:left; width:70%;">
<a style="color:#333" target="_blank"
title="打开磁链明细页面"
href="${record.detailUrl}">
${record.name}
</a>
<button class="btn btn-danger tianteng-copy"
type="button"
data-tianteng-magnet="${record.magnet}">复制磁链</button>
<button class="btn btn-danger tianteng-click"
type="button"
data-tianteng-magnet="${record.magnet}">打开磁链</button>
</td>
<td style="border: 1px solid #ccc;">${record.size}</td>
<td style="border: 1px solid #ccc;">${record.date}</td>
</tr>
`;
});
tableHtml = tableHtml.replace("{{tbody}}", tbodyHtml);
$(tabContent).append(tableHtml);
$(tabContent).data("tiantengStatus", "ok");
}
});
}
}
// end buildHtml
/**
* 复制磁链 和 打开磁链 按钮点击事件
*/
handleButtonClick() {
$(document).on("click", "button.tianteng-click, button.tianteng-copy", (e) => {
if (this.currentTabConfig.type === 1 && this.currentTabConfig.id === "tianteng-tab-skrbt") {
const button = e.target;
const magnet = button.dataset["tiantengMagnet"];
if (magnet !== "undefined") {
if ($(button).attr("class").includes("tianteng-copy")) {
_GM_setClipboard(magnet, "text");
} else {
_GM_openInTab(magnet);
}
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
return false;
} else {
const buttons = $(".tianteng-magnet-tbody .ld-ext-right");
const ldld = new ldloader({ root: buttons.toArray() });
buttons.attr("disabled", true);
ldld.toggle();
_GM_xmlhttpRequest({
method: "get",
headers: makeRequestHeaders({ Referer: `${domainConfig.skrbt.url}/search` }),
url: button.dataset["tiantengMagnetUrl"],
onerror: function(e2) {
console.log("获取磁链失败,等会儿再试一试! 若仍然有问题请刷新网页.");
buttons.attr("disabled", false);
ldld.off();
},
onload: function(response) {
buttons.attr("disabled", false);
ldld.off();
const magnet2 = $(response.responseText).find("#magnet").attr("href");
if (magnet2) {
button.dataset["tiantengMagnet"] = magnet2;
if ($(button).attr("class").includes("tianteng-copy")) {
button.nextElementSibling.dataset["tiantengMagnet"] = magnet2;
_GM_setClipboard(magnet2, "text");
} else {
button.previousElementSibling.dataset["tiantengMagnet"] = magnet2;
_GM_openInTab(magnet2);
}
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
} else {
console.log("获取磁链失败,等会儿再试一试! 若仍然有问题请刷新网页.");
console.log(response);
}
}
});
}
} else {
const button = e.target;
const magnet = button.dataset["tiantengMagnet"];
if ($(button).attr("class").includes("tianteng-copy")) {
_GM_setClipboard(magnet, "text");
} else {
_GM_openInTab(magnet);
}
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
return false;
}
});
}
}
class JavlibHandler extends Handler {
get name() {
return "javlib";
}
get condition() {
return $('head>title:contains("JAVLibrary")');
}
handle(condition, keyOrIndex) {
debug("所有页面", "Javlib");
debug("删除广告", "Javlib");
$(".socialmedia,#bottombanner13,#topbanner11,#sidebanner11").remove();
$("#leftmenu>div>ul:nth-child(2)>li:nth-child(2)").remove();
debug("调节UI", "Javlib");
$("#content").css("padding-top", "10px");
$("#toplogo").css("height", "50px");
$("#toplogo").find('img[src*="logo-top"]').attr("height", "40");
debug("添加 粘贴&搜索 按钮", "Javlib");
const styleMap = {};
$("#idsearchbutton")[0] && $("#idsearchbutton")[0].computedStyleMap().forEach((value, key) => {
styleMap[key] = value;
});
const $pasteAndSearchButton = $(
`<input type="button" value="粘贴&搜索" id="pasteAndSearch"></input>`
);
$pasteAndSearchButton.css(styleMap);
$pasteAndSearchButton.on("click", () => {
navigator.clipboard.readText().then((clipText) => {
if (clipText != null && $.trim(clipText) != "") {
$("#idsearchbox").val(clipText);
$("#idsearchbutton").trigger("click");
}
});
});
$("#idsearchbutton").parent().append($pasteAndSearchButton);
debug("添加 打开skrbt 连接", "Javlib");
$(".advsearch").append(
`
<a href="${domainConfig.skrbt.url}"
target="_blank"
class="tianteng-search-anchor"
title="打开后自动搜索剪贴板中的内容">打开skrbt</a>`
);
debug("删除url重定向", "Javlib");
$.each($("a[href^='redirect.php?url']"), function(index, a) {
var url = getUrlParam(a.href, "url");
a.href = url;
if (!a.href.startsWith("https")) {
a.href = a.href.replace("http", "https");
}
a.text = a.text + " " + a.href + " ";
if (a.href.includes("yimuhe")) {
$(a).parentsUntil("tr").closest(".t").css("background-color", "#6B6C83");
a.style = "font-size:20px;";
} else {
a.style = "font-size:20px;";
}
});
if (/.*\?v=.*/.test(location.href)) {
debug("详情页面", "Javlib");
debug("添加 复制车牌 按钮", "Javlib");
let chePai = document.querySelector("#video_id > table > tbody > tr > td.text").innerText;
let toAppendElement = document.querySelector("#video_id > table > tbody > tr > td.text");
appendCopyButton(chePai, toAppendElement);
debug("添加 javbus中查询 链接", "Javlib");
let trTag = document.querySelector("#video_id > table > tbody > tr");
let javdbQueryId = "javdbQueryId";
trTag.innerHTML = [
trTag.innerHTML,
'<td><a id="',
javdbQueryId,
'"href="',
domainConfig.javbus.url,
"/",
chePai,
'">javbus中查询</a></td>'
].join("");
debug("添加 用SkrBt搜索 链接", "Javlib");
$(trTag).append(`
<td>
<a
class="tianteng-search-anchor"
href="${domainConfig.skrbt.url}/search?keyword=${chePai}"
data-tianteng-keyword="${chePai}">
用SkrBt搜索
</a>
</td>
`);
$(".tianteng-search-anchor").on("click mouseup", function() {
const keyword = $(this).data("tiantengKeyword");
if (keyword) {
_GM_setValue("tiantengKeyword", keyword);
}
});
debug("删除名称中的链接", "Javlib");
const videoTitleNode = document.querySelector("#video_title > h3 > a");
if (videoTitleNode) {
const videoTitle = videoTitleNode.getInnerHTML();
videoTitleNode.parentNode.innerText = videoTitle;
}
debug("添加磁链tab", "Javlib");
new MagnetTab(chePai, (fragment) => {
$("#video_favorite_edit").after(fragment);
});
}
}
}
class JavbusHandler extends Handler {
get name() {
return "javbus";
}
get condition() {
return {
a1: $('head>title:contains("JavBus")'),
// /genre/hd , /genre/sub
a2: $("body > nav > div > div.navbar-header.mh50 > a > img[alt='JavBus']"),
// 论坛
luntan: "#toptb.jav-nav"
};
}
handle(condition, keyOrIndex) {
debug(`keyOrIndex:${keyOrIndex}`);
debug("添加 粘贴&搜索 按钮", "javbus");
const searchButton = $(`button[onclick="searchs('search-input')"]:first`);
const searchInput = $("#search-input:first");
addPasteAndSearchButton(searchButton, searchInput);
$(".nav>li>a").attr("style", "padding-left:8px;padding-right:8px;");
debug("添加 打开skrbt 链接", "javbus");
$(".nav-title.nav-inactive:last,ul.nav.navbar-nav:first").append(`
<li class="hidden-md hidden-sm">
<a href="${domainConfig.skrbt.url}" target="_blank">打开skrbt</a>
</li>
`);
debug("添加 打开今日新帖 按钮", "javbus");
let todayNewButton = $(
`<button id="tiantengNewButton"
class="jav-button btn btn-default ld-ext-right"
title="打开老司机福利讨论区的今日新帖,最多30个"
style="margin-top:7px;">
<span>打开今日新帖</span>
<div class="ld ldld bare"
style="width:1em;height:1em">
</div>
</button>`
);
_GM_addStyle(_GM_getResourceText("ldloader/index.min.css"));
_GM_addStyle(_GM_getResourceText("ldbutton/index.min.css"));
$(".nav-title.nav-inactive:last,ul.nav.navbar-nav:first").append(todayNewButton);
let loading = new ldloader({ root: "#tiantengNewButton" });
todayNewButton.on("click", function() {
if (loading.running) {
debug("正在加载数据,忽略点击...", "javbus");
return;
}
loading.toggle();
todayNewButton.attr("disabled", "true");
const origin = location.origin;
const talkUrl = `${origin}/forum/forum.php?mod=forumdisplay&fid=2&filter=author&orderby=dateline&dateline=86400`;
const now = /* @__PURE__ */ new Date();
const today = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
async function getPostData(url, date, pageNum) {
const r = await _GM.xmlHttpRequest({
url,
headers: {
Accept: `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7`,
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cache-Control": "max-age=0"
}
}).catch((e) => {
loading.off();
todayNewButton.attr("disabled", false);
console.error(e);
debug(e, "javbus");
alert("获取数据出现错误!!");
});
const data = $(r.responseXML);
const result = [];
$(".post_inforight", data).each(function() {
const date2 = $("span.dateline>span", $(this)).attr("title");
if (date2 === today) {
let postUrl = $("a.s", $(this)).attr("href");
result.push(`${origin}/forum/${postUrl}`);
}
});
return result;
}
getPostData(talkUrl).then(function(urlArray) {
if (urlArray.length === 0) {
debug("没有新的帖子", "javbus");
alert("没有新的帖子.");
}
$(urlArray).each(function() {
_GM_openInTab(this, true);
});
loading.off();
todayNewButton.attr("disabled", false);
});
});
let chePaiNode = document.querySelector(
"body > div.container > div.row.movie > div.col-md-3.info > p:nth-child(1) > span:nth-child(2)"
);
if (chePaiNode) {
debug("添加复制车牌号按钮", "javbus");
const chePai = chePaiNode.innerText.trim();
const toAppendElement = document.querySelector(
"body > div.container > div.row.movie > div.col-md-3.info > p:nth-child(1)"
);
appendCopyButton(
chePai,
toAppendElement,
(copyButton) => copyButton.className = "jav-button btn btn-default"
);
debug("删除磁力链接中的onclick事件", "javbus");
setInterval(() => $("#magnet-table td").removeAttr("onclick"), 1e3);
debug("添加 在javlibrary中打开", "javabus");
const javLibLink = `<a href="${domainConfig.javlib.url}/cn/vl_searchbyid.php?keyword=${chePai}">在javlib中打开</a>`;
$(toAppendElement).append(javLibLink);
new MagnetTab(chePai, (fragment) => {
$("div.row.movie").after(fragment);
});
}
if (location.href.includes("mod=viewthread")) {
let toAlienMagnet = function(magnet, alien) {
alien = alien ? alien : "-";
let part1 = magnet.slice(0, 21);
let part2 = magnet.slice(21);
return `${part1}${alien}${part2}`;
}, toNormalMagnet = function(magnet, alien) {
alien = alien ? alien : "-";
return magnet.replace(alien, "");
}, getMagnetRegExp = function(alien) {
if (alien) {
return new RegExp(
`(?:magnet:\\?xt=urn:btih:)?(?:(?:[0-9a-f]{1}${alien}[0-9a-f]{39})|(?:[2-7a-zA-Z]${alien}[2-7a-zA-Z]{31}))`,
"gim"
);
} else {
return /(?:magnet:\?xt=urn:btih:)?(?:[0-9a-fA-F]{40}|[2-7a-zA-Z]{32})/gim;
}
}, completeMagnet = function(magnet) {
if (!magnet) {
return magnet;
}
if (magnet.length === 32 || magnet.length === 40) {
return `magnet:?xt=urn:btih:${magnet}`;
}
return magnet;
};
debug("调整样式", "论坛明细页面");
_GM_addStyle(`
#p_btn {
padding:0;
}
.mtw {
margin-top: 0px !important;
}
.mbm {
margin-bottom: 10px !important;
}
.pi {
overflow: hidden;
margin-bottom: 0;
padding: 0;
height: 16px;
border-bottom: 1px dashed #CDCDCD;
}
.pct {
padding-bottom: 0;
}
.t_fsz {
min-height: auto;
}
.nthread_postinfo {
margin: 0 -16px;
border-top: 10px solid #f5f5f5;
padding: 10px 40px;
}
.pcb .cm .psth {
margin-bottom: 0px;
}
.pcb .psth {
width: 100%;
font-size: 17px !important;
line-height: 28px;
font-weight: normal;
color: #454545;
background: none;
border-bottom: 1px solid #CECECE;
padding: 0;
margin: 10px 0 0;
}
.pstl {
clear: left;
padding: 0em 0;
}
hin .pob {
padding-bottom: 0px !important;
}
.plc{padding-top:14px}
`);
debug("为磁链添加按钮", "论坛明细页面");
$(document).on("click", 'button[class*="tianteng-button"]', function(e) {
let button = $(e.target);
let buttonType = button.data("tiantengButton");
if (buttonType === "copy") {
let magnet = button.data("tiantengMagnet");
_GM.setClipboard(toNormalMagnet(magnet), "text");
return;
}
if (buttonType === "click") {
let magnet = button.data("tiantengMagnet");
setTimeout(() => window.open(toNormalMagnet(magnet)), 500);
return;
}
if (buttonType === "copyAll") {
let postId = button.data("tiantengPostId");
let magnets = "";
$(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(function() {
let magnet = $(this).data("tiantengMagnet");
magnets = magnets + toNormalMagnet(magnet) + "\n";
});
_GM.setClipboard(magnets, "text");
return;
}
if (buttonType === "clickAll") {
let postId = button.data("tiantengPostId");
$(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(function() {
let magnet = $(this).data("tiantengMagnet");
magnet = toNormalMagnet(magnet);
setTimeout(() => window.open(toNormalMagnet(magnet)), 500);
});
return;
}
if (buttonType === "copyAllNot") {
let postId = button.data("tiantengPostMessageId");
let magnets = "";
$(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(function() {
let magnet = $(this).data("tiantengMagnet");
magnets = magnets + toNormalMagnet(magnet) + "\n";
});
_GM.setClipboard(magnets, "text");
return;
}
if (buttonType === "clickAllNot") {
let postId = button.data("tiantengPostMessageId");
$(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(function() {
let magnet = $(this).data("tiantengMagnet");
magnet = toNormalMagnet(magnet);
setTimeout(() => window.open(toNormalMagnet(magnet)), 500);
});
return;
}
});
let magnetRegExp = getMagnetRegExp();
$(`div[id^="post_"] a[href^="magnet:?xt=urn:btih:"]`).each(function() {
let magnetAlien = completeMagnet($(this).attr("href"));
magnetAlien = toAlienMagnet(magnetAlien);
let html = this.outerHTML.replace(
magnetRegExp,
(match, offset, str) => toAlienMagnet(completeMagnet(match), "@")
);
html = html.replace("href", `data-tianteng-status="ok" href`);
html = `${html}
<button style="margin:0;padding:3px;"
class="jav-button tianteng-button"
data-tianteng-button="copy"
data-tianteng-magnet="${magnetAlien}"
type="button">复制磁链
</button>
<button style="margin:0;padding:3px;"
class="jav-button tianteng-button"
data-tianteng-button="click"
data-tianteng-magnet="${magnetAlien}"
type="button">打开磁链
</button>`;
this.outerHTML = html;
});
$('div[id^="post_"]').each(function() {
const treeWalker = document.createTreeWalker(this, NodeFilter.SHOW_TEXT);
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
if (node.nodeValue && magnetRegExp.test(node.nodeValue)) {
node.nodeValue = node.nodeValue.replace(
magnetRegExp,
(match, offset, str) => toAlienMagnet(completeMagnet(match), "tianteng")
);
}
}
});
$('div[id^="post_"]').each(function() {
let magnetAlienRegExp = getMagnetRegExp("tianteng");
let html = this.innerHTML;
html = html.replace(magnetAlienRegExp, function(match) {
match = toNormalMagnet(match, "tianteng");
let magnetAlien = toAlienMagnet(match);
return `
<a href="${match}" data-tianteng-status="ok">${match}</a>
<button style="margin:0;padding:3px;"
class="jav-button tianteng-button"
data-tianteng-button="copy"
data-tianteng-magnet="${magnetAlien}"
type="button">复制磁链
</button>
<button style="margin:0;padding:3px;"
class="jav-button tianteng-button"
data-tianteng-button="click"
data-tianteng-magnet="${magnetAlien}"
type="button">打开磁链
</button>`;
});
magnetAlienRegExp = getMagnetRegExp("@");
html = html.replace(magnetAlienRegExp, function(match) {
return toNormalMagnet(match, "@");
});
this.innerHTML = html;
const postId = $(this).attr("id");
const id = postId.replace("post_", "");
const postMessageId = `postmessage_${id}`;
if ($(`[data-tianteng-button="copy"]`, $(`#${postId}`)).length > 0) {
let allButtonHtml = `
<button style="margin:0;padding:5px;"
class="jav-button tianteng-button"
data-tianteng-button="copyAll"
data-tianteng-post-id="${postId}"
data-tianteng-post-message-id="${postMessageId}"
type="button">复制所有磁链
</button>
<button style="margin:0;padding:5px;"
class="jav-button tianteng-button"
data-tianteng-button="clickAll"
data-tianteng-post-id="${postId}"
data-tianteng-post-message-id="${postMessageId}"
type="button">打开所有磁链
</button>
<button style="margin:0;padding:5px;margin-left:10px;"
class="jav-button tianteng-button"
data-tianteng-button="copyAllNot"
data-tianteng-post-id="${postId}"
data-tianteng-post-message-id="${postMessageId}"
type="button">复制所有磁链(不含点评)
</button>
<button style="margin:0;padding:5px;"
class="jav-button tianteng-button"
data-tianteng-button="clickAllNot"
data-tianteng-post-id="${postId}"
data-tianteng-post-message-id="${postMessageId}"
type="button">打开所有磁链(不含点评)
</button>`;
$(`#${postMessageId}`).prepend(allButtonHtml + "<br><br>");
$(`#${postMessageId}`).append("<br><br>" + allButtonHtml);
}
});
}
}
}
class BtsowHandler extends Handler {
get name() {
return "BTSOW";
}
get condition() {
return $('head>title:contains("BTSOW")');
}
handle(condition, keyOrIndex) {
function allPages() {
const form = $("form.fullsearch-form");
form.each(function() {
const me = $(this);
if ($(".tianteng-paste-search", me).length === 0) {
const searchButton = $(`:submit`, me);
const pasteAndSearchButton = $(`
<button type="button" class="btn btn-default tianteng-paste-search">
粘贴&搜索
</button>`);
searchButton.after(pasteAndSearchButton);
}
});
}
function searchPage() {
if (location.pathname.startsWith("/search")) {
debug("添加 复制磁链,打开磁链 按钮", "btsow-搜索结果列表");
let buttonsHtml = `
<button class="btn btn-danger copy" type="button">复制磁链</button>
<button class="btn btn-danger click" type="button">打开磁链</button>`;
$("div.data-list>div.row>a>div.file").each((index, el) => {
if ($(el).find("button.copy").length === 0) {
$(el).append(buttonsHtml);
}
});
}
}
debug("添加 粘贴&搜索 按钮", "btsow-所有页面");
allPages();
$(document).on("click", "button.tianteng-paste-search", function(e) {
const me = $(this);
navigator.clipboard.readText().then((text) => {
if (text != null && $.trim(text) != "") {
me.parent().prev().val($.trim(text));
me.parentsUntil(".container")[2].submit();
}
});
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
return false;
});
searchPage();
if (location.pathname.startsWith("/search")) {
debug("添加 复制磁链,打开磁链 按钮", "btsow-搜索结果列表");
$(document).on("click", "button.copy, button.click", function(e) {
let magnet = $(this).parent().parent().attr("href").split("/")[6];
magnet = `magnet:?xt=urn:btih:${magnet}`;
if ($(this).attr("class").includes("copy")) {
_GM_setClipboard(magnet, "text");
} else if ($(this).attr("class").includes("click")) {
_GM_openInTab(magnet);
}
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
});
}
const nodeToObserve = document.querySelector("body");
new MutationObserver((mutationRecords, observer) => {
allPages();
searchPage();
}).observe(nodeToObserve, { childList: true });
}
}
class SkrbtHandler extends Handler {
get name() {
return "skrbt";
}
get condition() {
return $(`head>link[rel='shortcut icon'][href*='skrbt']`);
}
handle(condition, keyOrIndex) {
debug("添加 粘贴&搜索 按钮", "skrbt");
const $searchButton = $("button.search-btn");
const $searchInput = $(`input.search-input[name='keyword']`);
const $pasteAndSearchButton = addPasteAndSearchButton($searchButton, $searchInput);
$pasteAndSearchButton.removeAttr("style");
$pasteAndSearchButton.css("margin-left", "3px");
$pasteAndSearchButton.attr("class", $searchButton.attr("class"));
if (location.pathname === "/") {
const keyword = _GM_getValue("tiantengKeyword", null);
if (keyword) {
debug("搜索存储的内容", "skrbt-首页");
_GM_deleteValue("tiantengKeyword");
$searchInput.val(keyword);
$searchButton.click();
} else {
debug("搜索剪贴板中的内容", "skrbt-首页");
$pasteAndSearchButton.click();
}
}
debug("删除广告", "skrbt");
function removeAd() {
const $container = $(".col-md-6:eq(2)");
$container.remove(".label.label-primary");
$container.find('a.rrt.common-link[href^="http"]').parent().parent().remove();
}
removeAd();
if (location.href.includes("search")) {
debug("添加 复制磁链和打开磁链 按钮", "skrbt-搜索结果列表页面");
let buttonsHtml = `
<span class="rrmiv"><button class="btn btn-danger tianteng-button-copy" type="button">复制磁链</button></span>
<span class="rrmiv"><button class="btn btn-danger tianteng-button-click" type="button">打开磁链</button></span>`;
addButtonsForSkrbt(buttonsHtml, $(".col-md-6:eq(2)"), (el) => {
const classValue = $(el).attr("class");
if (classValue && classValue.includes("tianteng-button-copy")) {
return "copy";
}
if (classValue && classValue.includes("tianteng-button-click")) {
return "click";
}
return "other";
});
const nodeToObserve = document.querySelectorAll(".col-md-6")[2];
new MutationObserver((mutationRecords, observer) => {
$("a.rrt.common-link").each((index, el) => {
if ($(el).parent().find(".btn.btn-danger.tianteng-button-copy").length === 0) {
$(el).after(buttonsHtml);
}
});
removeAd();
}).observe(nodeToObserve, { childList: true });
}
}
}
function addButtonsForSkrbt(buttonsHtml, delegateElement, buttonTypeCallback) {
delegateElement.find("a.rrt.common-link").after(buttonsHtml);
delegateElement.on("click", '[class*="tianteng-button"]', (event) => {
const buttonType = buttonTypeCallback(event.target);
if ("copy" !== buttonType && "click" !== buttonType) {
return;
}
let liNode = $(event.target).parent().parent();
const exeButtonClick = (e) => {
if ("copy" === buttonType) {
navigator.clipboard.writeText(liNode.find(".magnet").attr("href"));
} else {
_GM_openInTab(liNode.find(".magnet").attr("href"));
}
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
return false;
};
if (liNode.find(".magnet").length != 0) {
return exeButtonClick(event);
}
let detailUrl = liNode.find("a.rrt.common-link").attr("href");
detailUrl = `${location.origin}${detailUrl}`;
$.get(detailUrl, function(data, textStatus, jqXHR) {
liNode.find("#errorTip").remove();
const magnet = $(data).find("#magnet").attr("href");
if (magnet) {
const aHtml = '<a class="magnet" href="' + magnet + '">' + magnet + "</a>";
liNode.append(aHtml);
return exeButtonClick(event);
} else {
liNode.append(
'<span id="errorTip">1.获取磁链失败,等会儿再试一试! 若仍然有问题请刷新网页.</span>'
);
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
return false;
}
}).fail(function(e) {
liNode.append(
'<span id="errorTip">2.获取磁链失败,等会儿再试一试! 若仍然有问题请刷新网页.</span>'
);
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
console.log(e);
return false;
});
});
}
class JinManTianTangHandler extends Handler {
get name() {
return "禁漫天堂";
}
get condition() {
return $(`head>title`)[0] && $(`head>title`)[0].text.endsWith("禁漫天堂");
}
handle(condition, keyOrIndex) {
observe(document, { childList: true, subtree: true }, () => {
debug(" 删除广告", "禁漫天堂");
$(".top-nav, .div-bf-pv").remove();
$("#Comic_Top_Nav").css("top", "-1px");
$("div.e8c78e-4_b").remove();
if (location.pathname === "/albums") {
const childNodes = document.querySelector("#wrapper > div.container").childNodes;
var forEach = Array.prototype.forEach;
forEach.call(childNodes, function(node) {
if (node.nodeName === "#text" && node.nodeValue.includes("中間廣告")) {
node.nodeValue = "";
}
});
}
});
}
}
debug(document.querySelector("title"));
if (location.href.includes("ahri8.top")) {
interceptEventListener((target, type, callback, options) => {
if (target.className && target.className.includes && target.className.includes("apo")) {
debug("禁止点击广告", "松鼠症倉庫");
return true;
}
});
}
$(() => {
const handlerList = [
BaiduHandler,
OsChinaHandler,
GiteeHandler,
ZhihuHandler,
WnacgHandler,
JavlibHandler,
JavbusHandler,
BtsowHandler,
SkrbtHandler,
JinManTianTangHandler
];
const executor = new HandlerExecutor();
for (const handler of handlerList) {
const instance = new handler();
const className = instance.constructor.name;
executor.handler = instance;
const result = executor.execute();
const resultJson = JSON.stringify(result);
debug(`执行 ${instance.name}(${className}), result: ${resultJson}`, "main");
}
});
})(jQuery, Tabby, ldloader);