您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
レス末尾にサムネイル画像やツイート埋め込みなどを追加します。
// ==UserScript== // @name いろいろ自動読み込み [仮] // @description レス末尾にサムネイル画像やツイート埋め込みなどを追加します。 // @version 2.1.0 // @match *://*.2chan.net/* // @icon https://icons.duckduckgo.com/ip2/www.2chan.net.ico // @namespace https://gf.qytechs.cn/users/809755 // @grant GM_xmlhttpRequest // @run-at document-end // @license MIT // @connect item.rakuten.co.jp // @connect booth.pm // @connect steampowered.com // @connect shueisha.co.jp // @connect shonenjump.com // @connect shonenjumpplus.com // @connect tonarinoyj.jp // @connect shonenmagazine.com // @connect yanmaga.jp // @connect comic-days.com // @connect sunday-webry.com // @connect urasunday.com // @connect shogakukan.co.jp // @connect web-ace.jp // @connect comic-walker.com // @connect 7irocomics.jp // @connect 123hon.com // @connect chijin-plus.com // @connect comic-action.com // @connect comic-boost.com // @connect comic-brise.com // @connect comic-fuz.com // @connect comic-gardo.com // @connect comic-medu.com // @connect comic-meteor.jp // @connect comic-polaris.jp // @connect comic-ryu.jp // @connect comic-trail.com // @connect comic-valkyrie.com // @connect comic-zenon.com // @connect comicborder.com // @connect comicbunch.com // @connect comicbushi-web.com // @connect comicnettai.com // @connect comico.jp // @connect comicride.jp // @connect comip.jp // @connect cycomi.com // @connect digitalmargaret.jp // @connect feelweb.jp // @connect futabanet.jp // @connect ganganonline.com // @connect heros-web.com // @connect ichijinsha.co.jp // @connect inthelife.club // @connect j-nbooks.jp // @connect kuragebunch.com // @connect leedcafe.com // @connect mag-garden.co.jp // @connect magcomi.com // @connect manga-comisol.jp // @connect manga-park.com // @connect mangabox.me // @connect mangacross.jp // @connect mangafactory.jp // @connect novema.jp // @connect pixiv.net // @connect souffle.life // @connect sukima.me // @connect takeshobo.co.jp // @connect tameshiyo.me // @connect webnewtype.com // @connect yawaspi.com // @connect ext.nicovideo.jp // @connect tver.jp // ==/UserScript== /* jshint esversion: 8 */ (function () { 'use strict'; setTimeout(() => { setupTwitterWidget(); setInterval(main, 2000); }, 1000); function main() { const targetDomains = [ [/2chan\.net$/, futaba], [/amazon(?:\.co)?\.jp$/, amazon], [/(?:youtube\.com|youtu\.be)$/, youtube], [/twitter\.com$/, twitter], [/twimg\.com$/, twimg], [/(?:www\.nicovideo\.jp|nico\.ms)$/, niconico], [/www\.pixiv\.net$/, pixiv], ]; const DomainOGP = [ /****** ショップ系 ******/ 'item.rakuten.co.jp', 'booth.pm', 'steampowered.com', /****** 未分類 ******/ 'tver.jp', /****** Webマンガ? ******/ /*----- 集英社 -----*/ 'shueisha.co.jp', 'shonenjump.com', 'shonenjumpplus.com', 'tonarinoyj.jp', /*----- 講談社 -----*/ 'shonenmagazine.com', 'yanmaga.jp', 'comic-days.com', /*----- 小学館 -----*/ 'sunday-webry.com', 'urasunday.com', 'shogakukan.co.jp', /*----- KADOKAWA -----*/ 'web-ace.jp', 'comic-walker.com', /*----- その他 -----*/ '7irocomics.jp', '123hon.com', 'chijin-plus.com', 'comic-action.com', 'comic-boost.com', 'comic-brise.com', 'comic-fuz.com', 'comic-gardo.com', 'comic-medu.com', 'comic-meteor.jp', 'comic-polaris.jp', 'comic-ryu.jp', 'comic-trail.com', 'comic-valkyrie.com', 'comic-zenon.com', 'comicborder.com', 'comicbunch.com', 'comicbushi-web.com', 'comicnettai.com', 'comico.jp', 'comicride.jp', 'comip.jp', 'cycomi.com', 'digitalmargaret.jp', 'feelweb.jp', 'futabanet.jp', 'ganganonline.com', 'heros-web.com', 'ichijinsha.co.jp', 'inthelife.club', 'j-nbooks.jp', 'kuragebunch.com', 'leedcafe.com', 'mag-garden.co.jp', 'magcomi.com', 'manga-comisol.jp', 'manga-park.com', 'mangabox.me', 'mangacross.jp', 'mangafactory.jp', 'novema.jp', 'pixiv.net', 'souffle.life', 'sukima.me', 'takeshobo.co.jp', 'tameshiyo.me', 'webnewtype.com', 'yawaspi.com', //'comic-earthstar.jp', //'firecross.jp', //'ganma.jp', //'pash-up.jp', ]; const ignoreExt = /(?:bmp|jpe?g|png|gif|web[pm]|mp[34]|pdf|exe|zip)/; (async () => { for (let a of document.querySelectorAll("blockquote a:not(.checked):not(.imgAdded)")) { await (a => { return new Promise((resolve, reject) => { a.classList.add('checked'); for (const value of targetDomains) { if (value[0].test(a.host)) { return resolve(value[1](a)); } } if (a.parentNode.nodeName.toLowerCase() !== 'blockquote') { // 引用されてるときはOGPの処理をスキップ return resolve(); } const domainChk = (DomainOGP.some(d => escapeRegExp(d).test(a.host))); const extChk = !ignoreExt.test(a.pathname.split(/[#?]/)[0].split('/').pop().split('.').pop()); if (domainChk && extChk) { return resolve(addOGP(a)); } return resolve(); }); })(a); } })(); } function futaba(a) { const m = a.href.match(/dec\.2chan\.net\/up2?\/src\/(fu?\d+?)\.(.+)/i); if (m) { if (/bmp|jpe?g|png|gif|webp/i.test(m[2])) { const src = `https://${a.host.replace(/\./g, '-')}.cdn.ampproject.org/ii/w128/s/${a.host}${a.pathname}`; const a2 = createLinkThumbnails(a.href, src, '#FFE'); appendDetails(a, a2); } } } function amazon(a) { const m = a.href.match(/amazon[^/]+jp\/.*?(?:dp|gp\/(?:product|aw\/d)|ASIN)\/(\w+)/); if (m) { // const src = `https://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=JP&ASIN=${m[1]}&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL120_`; const href = `https://www.amazon.co.jp/dp/${m[1]}`; a.href = a.innerText = href; // const a2 = createLinkThumbnails(href, src, '#F90'); // appendDetails(a, a2); } } function youtube(a) { const m = a.href.match(/(?:youtu\.be\/|youtube\.com\/(?:watch.*?\Wv=|shorts\/))(.{11})/); if (m) { const src = `https://i.ytimg.com/vi/${m[1]}/default.jpg`; const a2 = createLinkThumbnails(a.href, src, '#FCC'); appendDetails(a, a2); } } function twitter(a) { const m = a.href.match(/twitter\.com\/(\w+?)\/\w+?\/(\d+)/); if (m) { a.href = `https://twitter.com/${m[1]}/status/${m[2]}`; const blockquote = document.createElement('blockquote'); blockquote.classList.add('twitter-tweet'); blockquote.innerHTML = `<a href="${a.href}" class='checked'></a>`; appendDetails(a, blockquote, 'tweetArea'); twttr.widgets.load(blockquote); } } function twimg(a) { const m = a.href.match(/pbs\.twimg\.com\/media\/([\w-]+).+?(png|jpg)/); if (m) { const urlThumb = `https://pbs.twimg.com/media/${m[1]}.${m[2]}?name=thumb`; const urlOrig = `https://pbs.twimg.com/media/${m[1]}.${m[2]}?name=orig`; a.href = urlOrig; const a2 = createLinkThumbnails(urlOrig, urlThumb, '#1DA1F2'); appendDetails(a, a2); } } async function niconico(a) { const m = a.href.match(/(?:nico\.ms|www\.nicovideo\.jp\/watch)\/(\w+)/); if (m) { const src = await (id => new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: `https://ext.nicovideo.jp/api/getthumbinfo/${id}`, anonymouse: true, onload: function (response) { const res = response.responseText; const reg1 = new RegExp(`<thumbnail_url>([^<]+?)<`, 'i'); const found = res.match(reg1); if (found) { return resolve(found[1]); } reject(response); }, onerror: function (error) { reject(error); } }); }))(m[1]); const a2 = createLinkThumbnails(a.href, src); appendDetails(a, a2); } } async function pixiv(a) { const m = a.href.match(/www\.pixiv\.net\/artworks\/(\d+)/); if (m) { const urlThumb = `https://embed.pixiv.net/decorate.php?illust_id=${m[1]}`; const result = await (url => new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "HEAD", url: url, anonymouse: true, onload: function (response) { if (response.status !== 404) { return resolve(true); } reject(`${url} 404`); }, onerror: function (error) { reject(error); } }); }))(urlThumb); if (result === true) { const a2 = createLinkThumbnails(a.href, urlThumb); appendDetails(a, a2); } } } async function addOGP(a) { const src = await getOGP(a.href); if (src) { const a2 = createLinkThumbnails(a.href, src); appendDetails(a, a2); } } function getOGP(url) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: url, anonymouse: true, onload: function (response) { const res = response.responseText; const regexp = [ new RegExp(`(?:og|twitter):image['"\\s]+content["'=\\s]+?([^'">]+?)["']`, 'i'), new RegExp(`meta\\s+?content["'=\\s]+?([^'">]+?)["'\\s]+?(?:property|name)["'=\\s]+?(?:twitter|og):image`, 'i'), new RegExp(`imageUrl['":\s]+([^"']+?)["']`, 'i'), ]; /* const meta = (new DOMParser()).parseFromString(res, 'text/html').querySelectorAll('meta[property*="image"]'); console.table(meta); */ let found; for (const reg of regexp) { found = res.match(reg); if (found) { const decodedString = (new DOMParser()).parseFromString(`<!doctype html><body>${found[1].replace(/\\+u0026/g, '&')}`, 'text/html').body.textContent; const newURL = (new URL(decodedString, response.finalUrl)).href; return resolve(newURL); } } reject(`${url} Not Found`); }, onerror: function (error) { reject(`${url} OGP Error`); } }); }); } function appendDetails(parent, element, targetArea = 'thumbsArea') { for (let i = 0; i < 3; i++) { parent = parent.parentNode; if (parent.nodeName.toLowerCase() === 'blockquote') { let details = parent.querySelector('.previewArea'); if (!details) { details = createDetails(); parent.appendChild(details); } let target = details.querySelector(`.${targetArea}`); target.appendChild(element); return; } } } function escapeRegExp(s) { return new RegExp(`${s.replace(/\./g, '\.')}$`); } function setupTwitterWidget() { // if ([...document.querySelectorAll('blockquote a')].some(a => /twitter\.com$/.test(a.host))) { const script = document.createElement('script'); script.setAttribute('async', true); script.setAttribute('charset', 'utf-8'); script.src = 'https://platform.twitter.com/widgets.js'; document.body.appendChild(script); // } } function createDetails() { const summary = document.createElement('summary'); summary.innerHTML = '<input type="button" value="開閉ボタン" onclick="(()=>{this.parentNode.click()})();">'; const div1 = document.createElement('div'); div1.classList.add('thumbsArea'); const div2 = document.createElement('div'); div2.classList.add('tweetArea'); const details = document.createElement('details'); details.classList.add('previewArea'); details.setAttribute('open', true); details.appendChild(summary); details.appendChild(div1); details.appendChild(div2); return details; } function createLinkThumbnails(linkUrl, imgSrc, solid = '#ccc') { const img = document.createElement('img'); img.src = imgSrc; img.setAttribute("loading", "lazy"); img.setAttribute('align', 'top'); img.setAttribute('style', `max-width: 160px; margin: 5px; border: 2px solid ${solid};`); const a = document.createElement('a'); a.setAttribute('target', '_blank'); a.classList.add('checked'); a.href = linkUrl; a.appendChild(img); return a; } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址