您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Redirects PTT URLs to other sites
当前为
// ==UserScript== // @name PTT Sites Redirection // @namespace Userscript // @version 0.1.0 // @license MIT // @author CY Fung // @run-at document-start // @grant GM_registerMenuCommand // // @match https://www.ptt.cc/bbs/* // @match https://www.pttweb.cc/* // @match https://disp.cc/ptt/* // @match https://hotptt.com/* // @match https://moptt.tw/p/* // @match https://ptthito.com/* // @match https://webptt.com/* // @match https://pttweb.tw/* // @match http://www.ucptt.com/* // @match https://www.ucptt.com/* // // @match https://pttent.com/* // @match https://pttgame.com/* // @match https://pttdigit.com/* // @match https://pttlocal.com/* // // @description Redirects PTT URLs to other sites // // ==/UserScript== (() => { /** * To obtain the full list of boards. https://webptt.com/Hot.html window.m33t = 'td:first-child a[href*="bbs/"]'; window.ss3 = new Set(); window.n33g = (a)=>a.map(e=>e.textContent).filter(x=>/^[\x20-\xFF]+$/.test(x)).filter(x=>!/[\s\,\|]/.test(x)) setInterval(()=>{ for(const t of window.n33g([...document.querySelectorAll(window.m33t)])) window.ss3.add(t); },1); [...ss3.keys()] [...ss3.keys()].join(',').replace(/(\b.{100,120}\b,)/g,'$1\n') * * */ const NO_BUTTON_FOR_CACHER = true; const lowerCaseMatcher = (() => { const fullBoards = ` ALLPOST,AC_Sale,Accounting,Actuary,ai-photo,AllTogether,AnimalGoods,Anti-ramp,AntiVirus,Aquarium,aqua-shop,Aromatherapy, Ask,Babymother,bag,Bank_Service,barterbooks,Baseball,beauty,BeautyBody,BeautyMarket,BeautySalon,bicycle,biker,BikerShop, Boy-Girl,Brand,Browsers,BuyTogether,C_Chat,Cad_Cae,car,cat,CATCH,Chat82gether,chatskill,China-Drama,Clothes,CMWang, ComicHouse,CompBook,cookclub,creditcard,consumer,CVS,DC,dog,DPP,drama-ticket,DSLR,DV,EatToDie,Education,egg-exchange, equal_change,e-shopping,Examination,EZsoft,facelift,FamilyCircle,fastfood,feminine_sex,Finance,first-wife,Fitness,Food, forsale,Free_box,Fund,Gamesale,gardener,gay,GEPT,Getmarry,give,GoodShop,Gossiping,graduate,guitar,hairdo,handmade, HardwareSale,hate,HelpBuy,HK-drama,homemaker,home-sale,hypermall,IELTS,Insurance,Japan_Travel,japanavgirls,Japandrama, jeans,joke,joyinDIY,Key_Mou_Pad,Kids,KMT,KoreaDrama,KR_Entertain,L_BeautyCare,License,LicenseShop,Lifeismoney,LightNovel, Little-Games,LivingGoods,LoL,Lomo,Lottery,MacShop,MakeUp,Mancare,marriage,marvel,memento,MenTalk,Mind,Mix_Match,MJ, MobileComm,mobilesales,model,movie,multi-lovers,MuscleBeach,NailSalon,NBA,NBA_Film,nb-shopping,nightlife,TOEFL_iBT, Office,Old-Games,Option,P2PSoftWare,Palmar_Drama,pay_home,PC_Shopping,perfume,Perfume_Shop,pet,photo-buy,PhotoCritic, PhotoLink,Plant,PttEarnMoney,pttlifelaw,PuzzleDragon,Q_ary,rabbit,Railway,rent-exp,RIPE_gender,sex,share,Loan,sp_teacher, SportLottery,SportsShop,Stock,Storage_Zone,studyteacher,StupidClown,Rent_apart,Rent_tao,Rent_ya,TaiwanDrama,talk,tax, Teacher,teaching,Tech_Job,teeth_salon,Test,textbook,third-person,TOEIC,ToS,underwear,Wanted,WomenTalk,WoodworkDIY, jawawa `.replace(/\s/g, '').split(','); let lowerCaseMatcher = new Map(); for (const board of fullBoards) lowerCaseMatcher.set(board.toLowerCase(), board); return lowerCaseMatcher; })(); const cacheKey = 'nJ0wg'; // let m = sessionStorage.setItem(cacheKey function onReady() { // Extract the current hostname let currentHostname = window.location.hostname; // Function to handle menu command redirection function redirectToPTT(url) { sessionStorage.setItem(cacheKey, new URL(url).hostname); window.location.href = url; } function extraction(uObject) { // Extract parameters /* * supported: https://www.pttweb.cc/bbs/C_Chat/M.1684501378.A.9F2 https://moptt.tw/p/C_Chat.M.1684501378.A.9F2 https://www.ptt.cc/bbs/C_Chat/M.1684501378.A.9F2.html https://disp.cc/ptt/C_Chat/1acPSKqZ https://ptthito.com/c_chat/m-1684501378-a-9f2/ https://webptt.com/m.aspx?n=bbs/C_Chat/M.1684501378.A.9F2.html https://pttweb.tw/C_Chat/M.1684501378.A.9F2 http://www.ucptt.com/article/C_Chat/1684501378/9F2 https://hotptt.com/j3pu5u01ag supported (no menu option): https://pttent.com/movie/M.1548573736.A.DD4.html https://pttgame.com/lol/M.1476373373.A.239.html https://pttdigit.com/macshop/M.1551692551.A.8EA.html https://pttlocal.com/tainan/M.1551683492.A.63D.html not supported: https://ptt.reviews/HatePolitics/E.w1rS970orKqI https://www.ptt666.com/M.1551680529.A.759.html */ const f = (board) => { // lowerCased-board if (!board) return board; if (board !== board.toLowerCase()) return board; return lowerCaseMatcher.get(board) || board.replace(/_/g, '-').replace(/\b([a-z])([a-z0-9]*)\b/g, (_, a, b) => a.toUpperCase() + (b || '')).replace(/-/g, '_'); } const { pathname, hostname } = uObject if (pathname.startsWith('/bbs/')) { let s = pathname.split('/'); return { board: s[2], article: s[3].replace('.html', '') } } else if (pathname.startsWith('/p/')) { let d = pathname.substring(3); let i = d.indexOf('.'); if (i > 0) { return { board: d.substring(0, i), article: d.substring(i + 1) } } } else if (hostname === 'ptthito.com') { // just in case let s = pathname.split('/'); return { board: f(s[1]), article: s[2].replace(/-/g, '.').toUpperCase() } } else if (hostname === 'webptt.com') { let s = location.search.split('/'); return { board: s[1], article: s[2].replace('.html', '') } } else if (hostname === 'pttweb.tw') { let s = pathname.split('/'); return { board: s[1], article: s[2].replace('.html', '') } } else if (hostname === 'www.ucptt.com') { let s = pathname.split('/'); if (s[1] === 'article' && s.length === 5) { return { board: s[2], article: `M.${s[3]}.A.${s[4]}` } } } else if (hostname === 'pttent.com' || hostname === 'pttgame.com' || hostname === 'pttdigit.com') { let s = pathname.split('/'); return { board: f(s[1]), article: s[2].replace('.html', '') } } return null; } let objectVariables = null; // Handle disp.cc URL conversion if (currentHostname === "disp.cc" /*|| currentHostname === "ptthito.com"*/ || currentHostname === 'hotptt.com') { let pttLink = document.evaluate("//span[contains(text(),'※ 文章網址: ')]/a", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if (pttLink && !pttLink.href.startsWith("https://www.ptt.cc/bbs/")) pttLink = null; if (!pttLink) { pttLink = document.querySelector('a[href^="https://www.ptt.cc/bbs/"]'); } if (pttLink) { let pttURL = pttLink.href; if (pttURL && pttURL.startsWith("https://www.ptt.cc/bbs/")) { objectVariables = extraction(new URL(pttURL)); } } } else { objectVariables = extraction(window.location) } console.log(objectVariables) if (!objectVariables || !objectVariables.board || !objectVariables.article) return; lowerCaseMatcher.set(objectVariables.board.toLowerCase(), objectVariables.board); if (currentHostname !== "www.ptt.cc") { GM_registerMenuCommand("Redirect to www.ptt.cc", function () { redirectToPTT("https://www.ptt.cc/bbs/" + (objectVariables.board + "/" + objectVariables.article) + ".html"); }); } if (currentHostname !== "www.pttweb.cc") { GM_registerMenuCommand("Redirect to www.pttweb.cc", function () { redirectToPTT("https://www.pttweb.cc/bbs/" + objectVariables.board + "/" + objectVariables.article); }); } /* if (currentHostname !== "disp.cc") { GM_registerMenuCommand("Redirect to disp.cc", function () { redirectToPTT("https://disp.cc/ptt/" + (objectVariables.board + "/" + objectVariables.article)); }); } */ if (currentHostname !== "moptt.tw") { GM_registerMenuCommand("Redirect to moptt.tw", function () { redirectToPTT("https://moptt.tw/p/" + objectVariables.board + "." + objectVariables.article); }); } if (currentHostname !== "ptthito.com") { GM_registerMenuCommand("Redirect to ptthito.tw", function () { redirectToPTT("https://ptthito.com/" + (objectVariables.board + "/" + objectVariables.article.replace(/\./g, '-') + "/").toLowerCase()); }); } if (currentHostname !== "webptt.com") { GM_registerMenuCommand("Redirect to webptt.com", function () { redirectToPTT(`https://webptt.com/m.aspx?n=bbs/${objectVariables.board}/${objectVariables.article}.html`); }); } if (currentHostname !== "pttweb.tw") { GM_registerMenuCommand("Redirect to pttweb.tw", function () { redirectToPTT(`https://pttweb.tw/${objectVariables.board}/${objectVariables.article}`); }); } if (currentHostname !== 'www.ucptt.com') { GM_registerMenuCommand("Redirect to www.ucptt.com", function () { let p = /M\.([^\s.,|\/\\]+)\.A\.([^\s.,|\/\\]+)/.exec(objectVariables.article); if (p) { redirectToPTT(`http://www.ucptt.com/article/${objectVariables.board}/${p[1]}/${p[2]}`); } }); } if (currentHostname !== 'pttent.com' && !NO_BUTTON_FOR_CACHER) { // not all posts can read // https://www.ptt.cc/bbs/Lifeismoney/M.1687762841.A.5E8.html GM_registerMenuCommand("Redirect to pttent.com", function () { redirectToPTT(`https://pttent.com/${objectVariables.board.toLowerCase()}/${objectVariables.article}.html`); }); } if (currentHostname !== 'pttgame.com' && !NO_BUTTON_FOR_CACHER) { // not all posts can read // https://www.ptt.cc/bbs/Lifeismoney/M.1687762841.A.5E8.html GM_registerMenuCommand("Redirect to pttgame.com", function () { redirectToPTT(`https://pttgame.com/${objectVariables.board.toLowerCase()}/${objectVariables.article}.html`); }); } if (currentHostname !== 'pttdigit.com' && !NO_BUTTON_FOR_CACHER) { // not all posts can read // https://www.ptt.cc/bbs/Lifeismoney/M.1687762841.A.5E8.html GM_registerMenuCommand("Redirect to pttdigit.com", function () { redirectToPTT(`https://pttdigit.com/${objectVariables.board.toLowerCase()}/${objectVariables.article}.html`); }); } if (currentHostname !== 'pttlocal.com' && !NO_BUTTON_FOR_CACHER) { // not all posts can read // https://www.ptt.cc/bbs/Lifeismoney/M.1687762841.A.5E8.html GM_registerMenuCommand("Redirect to pttlocal.com", function () { redirectToPTT(`https://pttlocal.com/${objectVariables.board.toLowerCase()}/${objectVariables.article}.html`); }); } } if (document.readyState != 'loading') { onReady(); } else { window.addEventListener("DOMContentLoaded", onReady, false); } })();