// ==UserScript==
// @name 5chサムネイル表示他
// @description r(文字列未選択時):ホバー中のレスへのアンカーを記入(R:追記) r(文字列選択時):選択文字列を引用(R:追記) m:ホバー中のレスの10個前以降を表示 ,:ホバー中のレス以降を表示 .:ホバー中のレス以前を表示 d:書き込み欄にスクロール F:re.Find2chで検索 y:ホバー中の画像をyandexで画像検索 l:ホバー中のレスへのリンクをコピー
// @version 0.1.15
// @run-at document-idle
// @match *://*.5ch.net/test/read.cgi/*
// @match *://*.5ch.net/*/
// @match *://*.5ch.net/*/SETTING.TXT
// @grant GM_addStyle
// @grant GM.setClipboard
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @require https://code.jquery.com/jquery-3.4.1.min.js
// @require https://code.jquery.com/ui/1.12.1/jquery-ui.min.js
// @namespace http://greasyfork.icu/users/181558
// ==/UserScript==
(function() {
const enableHoverZoom = 1; // 1:画像サムネイルのホバーズームを有効
const DEFAULT_MAIL_ADDRESS = ""; // メールアドレス初期値 ""、"sage"、その他に変更可
const inlineImageThumbnailHeight = 65; // 画像サムネイルの縦サイズ(px)
const inlineImageThumbnailBokashi = 0; // 画像サムネイルのぼかしの強さ(0~10くらい)
const WAIT = performance.now() * 0.5; // ページ開始後のウエイト 不安定なときは大きくする
const WAIT_IMAGE_EMBED_INTERVAL = 500; // 画像埋め込みの頻度(ミリ秒)
const WAIT_VIDEO_EMBED_INTERVAL = 500; // 動画埋め込みの頻度(ミリ秒)
const NUMBER_IMAGE_EMBED_AT_ONCE = 3; // 画像埋め込みの速度(枚数)
const inlineImageThumbnailPreloadRadius = window.innerHeight * 1; // 画面外の上下何画面分までを「画面内」とするか
const DEBUG_TIMER = 0; // 1ならかかった時間を計測
const ALTERNATIVE_THUMBNAIL = 0; // 1:別方式のサムネイル
const CONFIRM_FOR_Y = 1; // 1:yキーでyandex検索をする時URLの確認を求める 0:求めない
const CONFIRM_FOR_MCP = 0; // 1:M,.キーでURLの確認を求める 0:求めない
const QUOTE_STYLE = "color:#008080;"; // 引用文のスタイル "";なら無効
var poppedUrl = "";
var yandexUrl = "";
if (location.href.match(/SETTING.TXT$/)) { // SETTING
var e = document.body.innerText.match(/BBS_LINE_NUMBER=(\d*)/);
if (e) { pref(getIta() + " : line_number", e[1]); }
var e = document.body.innerText.match(/BBS_MESSAGE_COUNT=(\d*)/);
if (e) { pref(getIta() + " : message_count", e[1]); }
// alert((getIta()+" "+e[1] ));
return;
}
function getIta() {
let name = location.href.match(/^https?:\/\/.+\.5ch\.net\/test\/read.cgi\/([^\/]+)/) || location.href.match(/^https?:\/\/.+\.5ch\.net\/([^\/]+)/);
if (name) name = name[1]
// alert(name)
return name;
}
var line_number = pref(getIta() + " : line_number") || null;
var message_count = pref(getIta() + " : message_count") || null;
// alert(line_number)
if (location.href.match(/^https?:\/\/.+\.5ch\.net\/[^/]+\/$/) && eleget0('//div[last()]/form[@method="POST"]/p/input[@value="新規スレッド作成"]')) { // 板トップ
elegeta('//div[@class="NEW_THREAD"]/form[@method="POST"]/p/textarea').forEach(mes => {
mes.setAttribute("stretchabletextarea", "1");
mes.setAttribute("wrap", "on");
mes.style.width = "90%";
mes.addEventListener("input", () => kakikomiStretch(mes));
mes.addEventListener("focus", () => kakikomiStretch(mes));
});
elegeta('//textarea[not(@stretchabletextarea)]').forEach(mes => {
mes.setAttribute("stretchabletextarea", "1");
mes.setAttribute("wrap", "on");
mes.style.width = "90%";
mes.addEventListener("input", () => kakikomiStretch(mes, "nearest"));
mes.addEventListener("focus", () => kakikomiStretch(mes, "nearest"));
});
return;
function kakikomiStretch(target, scrollBlock = "center") {
if (target.value == "") target.style.height = "100px";
let lineHeight = target.style.height.match("px") ? Number((target.style.height || "0px").replace("px", "")) : 0; //getAttribute("rows"));
let height = target.scrollHeight; //+12;
let clientHeight = Math.min(document.documentElement.clientHeight, window.innerHeight) - 165;
for (let i = 0; i < 200 && (height >= target.offsetHeight) && target.offsetHeight < clientHeight; i++) {
lineHeight += 10;
target.style.height = lineHeight + "px";
}
setTimeout(() => { target.scrollIntoView({ behavior: "smooth", block: scrollBlock, inline: "center" }); }, 17);
displayLineLimit(target);
}
}
if (/^https?:\/\/.+\.5ch\.net\/test\/read\.cgi\/.+/.test(location.href) == false) { return; }
// httpならhttpsに
if (location.href.indexOf("http://") != -1) {
location.href = location.href.replace(/^http:\/\//, "https://");
return;
}
if (location.href.indexOf("subback.html") != -1) { return; }
if (location.href.match(/\/\/.*\.5ch\.net\/\w*\/$/)) { return; }
$(".mascot").attr("style", "");
let serverColor = colorFromText(new URL(location.href).hostname, 50, 30);
$(document.body).append(`<span style="writing-mode: vertical-rl; top:2em; right:0.3em;position:fixed;z-index:-111; font-size:3em; opacity:0.5; color:${serverColor};">${document.title}</span>`);
$(eleget0('//ul/li[@class="menubottomnav"]/a[@class="menuitem" and text()="全部"]/../../..')).before(`<span style=" margin:0 0 0 0.2em;font-size:1.5em; opacity:0.9; color:${serverColor};">${document.title}</span>`);
function colorFromText(txt, s, l) {
return !txt ? "hsl(0,50%,50%)" : `hsl(${Array.from(txt).map(ch => ch.charCodeAt(0)).reduce((a, b) => a+b)**3%360}, ${s}%, ${l}%)`;
}
// レスにホバーしてキー入力
$(document).on("keypress", e => {
if (e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA' || e.target.getAttribute('contenteditable') == 'true') return;
var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
var selectedStr = window.getSelection().toString() ? ">" + window.getSelection().toString().replace(/^\r\n/, "").replace(/\r\n/g, "\r\n>").replace(/^\r\n|\r\n$/, "\r\n") : null;
let num = getNearest('//span[@class="number"]');
let current = location.href + ((location.href.match(/^https?:\/\/.+\.5ch\.net\/test\/read\.cgi\/\w+\/\d+$/)) ? "/" : ""); // /18246213874 で終わるとバグRう
if ($('form>p>textarea').length) {
if ((selectedStr && (key === "r" || key === "Shift+R"))) { // r::(文字列選択中)ホバー中のレスを引用(R::追記)
let res = getNearest('//div[@class="message"]');
if (num.innerText >= 2 || (num.innerText == 1 && $(window).scrollTop() < 500)) {
$(getNearest('//div[@class="message"]/..')).effect("highlight", 500);
floatKakikomi(">>" + num.innerText + "\r\n" +
// (selectedStr ? selectedStr : (res.innerText.replace(/^>.*$\n/gm, "").replace(/^(.+)$/gm, ">$1"))) + "\r\n",(e.key == "R"||e.key == "C") ); // 引用の引用をしない
(selectedStr ? selectedStr : (res.innerText.replace(/^(.+)$/gm, ">$1"))) + "\r\n", (e.key == "R" || e.key == "C"));
$('form>p>textarea').effect("highlight", 500);
}
return false;
}
if (key == "r" || key == "Shift+R") { // r::ホバー中のレスにアンカー R::レスにアンカー(追記)
if (num.innerText >= 2 || (num.innerText == 1 && $(window).scrollTop() < 500)) {
$(getNearest('//div[@class="message"]/..')).effect("highlight", 500);
floatKakikomi(">>" + num.innerText + "\n", e.key == "R");
$('form>p>textarea').effect("highlight", 500);
}
return false;
}
}
if (key === "m" || key === ",") { // ,::そのレス以降を表示 m::そのレスの10個前以降を表示
let num = getNearest('//span[@class="number"]');
if (num) {
let num2 = (num.innerText) - (e.key === "m" ? 10 : 0);
$(getNearest('//div[@class="message"]/..')).effect("highlight");
let last = current.replace(/\/l\d+$/, "/").replace(/^.*\/([0-9]{0,4})?-?([0-9n]{0,4}?$)/gm, "$2");
let url = current.replace(/\/l\d+$/, "/").replace(/\/[0-9\-]{0,4}-?[0-9n]{0,4}?$/gm, "/").replace(/(\d)$/, "$1/") + Math.max(1, num2) + "-" + last;
if (CONFIRM_FOR_MCP && !confirm(url)) return;
location.href = url;
}
return false;
}
if (key === ".") { // .::そのレス以前を表示
let num = getNearest('//span[@class="number"]');
if (num) {
let num2 = (num.innerText) - (e.key === "m" ? 10 : 0);
$(getNearest('//div[@class="message"]/..')).effect("highlight");
if (num2 > 1) {
let url = current.replace(/\/l\d+$/, "/").replace(/(\/[0-9]{0,4})-?[0-9n]{0,4}?$/gm, "$1") + "-" + Math.max(1, num2);
if (CONFIRM_FOR_MCP && !confirm(url)) return;
location.href = url;
}
}
return false;
}
if (key === "l") { // l::ホバー中のレスへのリンクをコピー
if (num) {
$(getNearest('//div[@class="message"]/..')).effect("highlight", 500);
GM.setClipboard(document.title + "\r\n" + location.href.replace(/\/l\d+$/, "").replace(/\/[0-9\-]{0,4}-?[0-9n]{0,4}?$/gm, "/").replace(/(\d)$/, "$1/") + num.innerText + "\r\n");
}
return false;
}
if (key === "Shift+F") { // F::re.Find2chで検索
let query = prompt("re.Find2chでキーワード検索します\n\nhttps://refind2ch.org/search?q=${キーワード}&sort=rate\n\n");
if (query) window.open(`https://refind2ch.org/search?q=${query}&sort=rate`);
return false;
}
if (key === "y" && yandexUrl) { // y::ホバー中の画像をyandex画像検索で検索
if (!CONFIRM_FOR_Y || window.confirm(yandexUrl + "\n\nを開きます。よろしいですか?")) window.open(yandexUrl);
return false;
}
});
$(document).on("keydown", e => {
if (e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA' || e.target.getAttribute('contenteditable') == 'true') return;
var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
if ($('form>p>textarea').length) {
if (key === "d") { // d::書き込み欄にスクロール
scrollKakikomi(false);
return false;
}
}
});
var mousex = 0;
var mousey = 0;
var lastEle = "";
document.addEventListener("mousemove", function(e) {
mousex = e.clientX;
mousey = e.clientY;
}, false);
if (enableHoverZoom) setInterval(onmove, 16.667);
function onmove() {
let ele = document.elementFromPoint(mousex, mousey);
if (lastEle !== ele) {
$('img.hzP').remove();
poppedUrl = "";
}
if (ele)
if (ele.tagName === "IMG" && lastEle !== ele) {
poppedUrl = pe(ele);
yandexUrl = poppedUrl.match(/\;base64\,/i) ? null : "https://yandex.com/images/search?rpt=imageview&url=" + poppedUrl;
}
lastEle = ele;
}
function pe(a) {
var panel = a.cloneNode(true);
if (!a) return;
if (a.parentNode.tagName == "A" && a.parentNode.href.match(/\.png|\.jpg|\.jpeg|\.gif|\.bmp/i)) { panel.src = a.parentNode.href.replace(/https?:\/\/jump\.5ch\.net\/\?/, ""); } else { if (a.parentNode.parentNode.tagName == "A" && a.parentNode.parentNode.href.match(/\.png|\.jpg|\.jpeg|\.gif|\.bmp/i)) panel.src = a.parentNode.parentNode.href.replace(/https?:\/\/jump\.5ch\.net\/\?/, ""); }
panel.className = "hzP";
setSize(a, panel);
document.body.appendChild(panel);
panel.addEventListener('load', a => {
setSize(a.target, a.target);
});
return panel.src;
}
function setSize(a, b) {
let imgAspect = a.naturalWidth / a.naturalHeight;
let clientAspect = window.innerWidth / 2 / window.innerHeight;
let boxPos = (mousey < (window.innerHeight / 2) ? "bottom:0px;" : "top:0px;") + ((mousex < window.innerWidth / 2) ? "right:0px; " : "left:0px;");
if (imgAspect > clientAspect) {
b.setAttribute("style", "all:initial; width:48%;" + boxPos + " z-index:2147483647; position:fixed; margin:5px; border-radius:3px; color:#ffffff; box-shadow:3px 3px 8px #0008; border:2px solid #fff; ");
} else {
b.setAttribute("style", "all:initial; height:98%;" + boxPos + " z-index:2147483647; position:fixed; margin:5px; border-radius:3px; color:#ffffff; box-shadow:3px 3px 8px #0008; border:2px solid #fff; ");
}
}
function getNearest(xpath) {
let ele = document.elementFromPoint(mousex, mousey);
return getEleFromParent(ele, xpath);
}
function getEleFromParent(ele, xpath) { // ele要素の親をさかのぼりxpathを持つ要素
for (let i = 0; i < 9; i++) {
var ele2 = elegeta(xpath, ele);
if (ele2.length) return ele2[0];
if (ele === document) return;
ele = ele.parentNode;
}
return;
}
var resFloat = false;
// 書き込み欄までスクロール
function scrollKakikomi(loop = true) {
if (resFloat) return;
var ele = eleget0('//div[@class="formbody"]/form/p/textarea');
if (ele) {
var $target = $('p>input.submitbtn'),
offset = $target.offset() || { top: 0, left: 0 },
outerHeight = $target.outerHeight();
$("html,body").animate({ scrollTop: (offset.top - window.innerHeight + outerHeight) });
} else if (loop) setTimeout(scrollKakikomi, 500);
}
// setTimeout(hNukiURLHokan, WAIT);
setTimeout(hNukiURLHokan, 0);
setTimeout(scrollKakikomi, 1);
setTimeout(scrollKakikomi, WAIT);
setTimeout(() => {
setInterval(videoUmekomi, WAIT_VIDEO_EMBED_INTERVAL);
setInterval(imageUmekomi, WAIT_IMAGE_EMBED_INTERVAL);
let ma = $(xa('//input[@placeholder="メールアドレス(省略可)"]'));
ma.dblclick(() => {
ma.val(ma.val() == "sage" ? "" : "sage");
floatKakikomi();
});
// 細かい調整
$("div.formbox").css("margin", "0");
$('input[placeholder="メールアドレス(省略可)"]').val(DEFAULT_MAIL_ADDRESS);
//$(eleget0('//p/input[@name="mail"]')).css("ime-mode", "inactive");
$("form>p>textarea").click(() => {
floatKakikomi();
});
}, WAIT);
//console.time("quote")
if (QUOTE_STYLE != "") elegeta('//div[@class="message"]').forEach(e => { e.outerHTML = e.outerHTML.replace(/<span class="escaped">\s?((〉|》|>|>)[^<]+)/, `<span class="escaped"> <span class="5tquote" style="${QUOTE_STYLE}">$1</span>`).replace(/<br> ((〉|》|>|>)[^<]+)/gmi, `<br><span class="5tquote" style="${QUOTE_STYLE}">$1</span>`) })
//console.timeEnd("quote")
return;
// h抜きのURLをリンクにする
function hNukiURLHokan() {
document.querySelectorAll("div.post").forEach(function(obj) {
var html = obj.innerHTML;
if (obj.innerText.match(/^ttps?:\/\//gm)) {
var newhtml = html.replace(/[^h](ttps?:\/\/\S+)/gm, "<a referrerpolicy='no-referrer' rel='nofollow external noopener noreferrer' href=\"h$1\">$1</a>");
obj.innerHTML = newhtml;
}
});
}
// 書き込み欄調整、クリックでフロート化
function floatKakikomi(str = "", addMode = 0) {
if (!resFloat) {
$(window).resize(() => {
$(eleget0('//p/textarea[@name="MESSAGE"]')).css({ "width": "70%", "min-width": Math.min(900, (window.innerWidth - 100)) + "px", "max-width": (window.innerWidth - 100) + "px" });
kakikomiStretch('//p/textarea[@name="MESSAGE"]', "resetHeight")
});
}
resFloat = true;
let curRes = $("form>p>textarea").val();
$(eleget0('//form/p/textarea[@name="MESSAGE"]')).css({ "z-index": "999", "position": "fixed", "right": "1em", "bottom": "3em" });
$(eleget0('//input[@class="submitbtn btn"]')).css({ "z-index": "9999999", "position": "fixed", "right": "1em", "bottom": "0em" });
str ? $("form>p>textarea").val((addMode ? curRes + ((curRes == "" || curRes.slice(-1) == "\n") ? "" : "\n") : "") + str) : 0;
$(eleget0('//p/textarea[@name="MESSAGE" and @wrap="off"]')).css({ "width": "70%", "min-width": Math.min(900, (window.innerWidth - 100)) + "px", "max-width": (window.innerWidth - 100) + "px" }).attr("wrap", "on").on("input", () => {
kakikomiStretch();
});
$(eleget0('//form/p/textarea[@name="MESSAGE"]')).focus().attr("stretchabletextarea", "1");
kakikomiStretch();
}
function kakikomiStretch(xp = '//p/textarea[@name="MESSAGE"]', command = "") {
let target = eleget0(xp);
if (target.value == "" || command === "resetHeight") target.rows = 3;
let lineHeight = Number(target.getAttribute("rows"));
let height = target.scrollHeight; //+12;
let clientHeight = Math.min(document.documentElement.clientHeight, window.innerHeight) - 165;
for (let i = 0; i < 90 && (height >= target.offsetHeight) && target.offsetHeight < clientHeight; i++) {
lineHeight++;
target.setAttribute("rows", lineHeight);
}
displayLineLimit(target);
return target;
}
function displayLineLimit(target) {
let line = target.value.split(/\r\n|\r|\n/).length;
if (line_number && message_count) {
// target.style.backgroundColor = line > line_number * 2 ? "#fff0f0" : encodeURIComponent(target.value).replace(/%../g,"x").length > message_count ? "#fffff0" : "#ffffff";
target.style.backgroundColor = line > line_number * 2 ? "#fff0f0" : (new Blob([target.value]).size) > message_count ? "#fffff0" : "#ffffff";
}
}
function sortDescendMiddle(array) {
return array.sort((a, b) => {
return Math.abs(a.getBoundingClientRect().top - document.documentElement.clientHeight / 2) > Math.abs(b.getBoundingClientRect().top - document.documentElement.clientHeight / 2) ? 1 : -1
});
}
// 画像と動画をインライン埋め込み
function imageUmekomi() {
// 画像埋め込み
var i = 0;
sw1("removeSysThumbs");
for (let a of sortDescendMiddle(elegeta('//a[@imge="af"]/div[@div="thumb5ch"]'))) { if (isinscreen(a)) setTimeout((function(a) { return function() { { a.remove(); } } })(a), WAIT_IMAGE_EMBED_INTERVAL * 10 / NUMBER_IMAGE_EMBED_AT_ONCE) }
sw2("removeSysThumbs");
sw1("umegazo")
for (let ele of sortDescendMiddle(elegeta('//a[not(@imge)]'))) {
let isImg = 0;
var url = ele.href || ($(ele).text());
url = url.replace(/^(ttps?:\/\/)/m, "h$1");
let urlImg = url.replace(/https?:\/\/jump\.5ch\.net\/\?/, "");
if ($(ele).text().match(/\.jpg|\.jpeg|\.png|\.gif|\.bmp/)) { isImg = 1; } else { isImg = 0; }
if (!isImg) ele.setAttribute("imge", "!i");
if ((!isinscreen(ele))) continue; // 画面内に無い
if (isImg) {
let next = ele.children ? ele.children[0] : null;
if (next && next.tagName === "DIV") {
if (ALTERNATIVE_THUMBNAIL) next.outerHTML = '<br><a referrerpolicy="no-referrer" rel="nofollow external noopener noreferrer" href=' + url + ' target="_blank"><img referrerpolicy="no-referrer" src=' + urlImg + ' height="' + inlineImageThumbnailHeight + '" ' + (inlineImageThumbnailBokashi ? 'style="filter: blur(' + inlineImageThumbnailBokashi + 'px);"' : '') + '/></a>';
ele.setAttribute("imge", "rp");
} else {
$(ele).after($('<br><a referrerpolicy="no-referrer" rel="nofollow external noopener noreferrer" href=' + url + ' target="_blank"><img referrerpolicy="no-referrer" src=' + urlImg + ' height="' + inlineImageThumbnailHeight + '" ' + (inlineImageThumbnailBokashi ? 'style="filter: blur(' + inlineImageThumbnailBokashi + 'px);"' : '') + '/></a>'));
ele.setAttribute("imge", "af");
}
if (++i >= NUMBER_IMAGE_EMBED_AT_ONCE) break; // 一度に設定枚数ずつしかやらない
}
}
sw2("umegazo")
};
function videoUmekomi() {
sw1("umedouga")
// ニコ動埋め込み(PrivacyBadger等は要Disable)
for (let ele of sortDescendMiddle(elegeta('//a[contains(@href,"nicovideo")][not(@nde)]'))) {
if ((!isinscreen(ele))) continue; // 画面内に無い
let url = ele.innerText.replace(/^ttp/i, "http");
ele.setAttribute("nde", "nde");
let nico = url.match(/h?ttps?:\/\/www.nicovideo.jp\/watch\/(.*)/i);
if (!nico) continue
$(ele).after('<br><iframe referrerpolicy="no-referrer" width="312" height="176" rel="nofollow external noopener noreferrer" src="https://ext.nicovideo.jp/thumb/' + nico[1] + '" scrolling="no" style="border:solid 1px #ccc;" frameborder="0"><a referrerpolicy="no-referrer" rel="nofollow external noopener noreferrer" href="' + url + '">ニコニコ動画</a></iframe>');
break; // 一度に1つずつしかやらない
}
sw2("umedouga")
sw1("umeYT")
// youtube埋め込み
for (let ele of sortDescendMiddle(elegeta('//a[contains(@href,"youtube.com")][not(@yte)]|//a[contains(@href,"youtu.be")][not(@yte)]'))) {
if ((!isinscreen(ele))) continue; // 画面内に無い
let url = ele.innerText;
ele.setAttribute("yte", "yte");
var sm = (url.match(/h?ttps?:\/\/youtu\.be\/([^&?]+.*)\?t=(\d*).*$/i) || url.match(/h?ttps?:\/\/w?w?w?m?\.youtube\.com\/watch\?v=([^&]+.*)&t=(\d*).*$/i)) || url.match(/h?ttps?:\/\/youtu\.be\/([^&?]+)/i) || url.match(/h?ttps?:\/\/w?w?w?m?\.youtube\.com\/watch\?v=([^&]+)/i);
if (!sm) continue
$(ele).after('<p style="margin:0 0 0px;"><iframe referrerpolicy="no-referrer" src="https://www.youtube.com/embed/' + sm[1] + (sm[2] ? "?start=" + sm[2] : "") + '" id="ytplayer" type="text/html" width=320 height=180 frameborder=0 allowfullscreen></p>');
break; // 一度に1つずつしかやらない
};
sw2("umeYT")
// video.twimg埋め込み
for (let ele of sortDescendMiddle(elegeta('//a[contains(@href,"ttps://video.twimg.com/ext_tw_video/")][not(@yte)]'))) {
if ((!isinscreen(ele))) continue; // 画面内に無い
let url = ele.innerText;
url = url.replace(/^ttp/i, "http");
ele.setAttribute("yte", "yte");
$(ele).after('<p><video preload="none" src="' + url + '" controls="" loop="" > <source src="' + url + '" type="video/mp4"> </video></p>')
break; // 一度に1つずつしかやらない
};
sw2("umeVideoTwimg")
}
// eleはスクロール画面内に入ってる?
function isinscreen(ele) {
if (!ele) return;
var eler = ele.getBoundingClientRect();
return (eler.top > 0 - inlineImageThumbnailPreloadRadius && eler.left > 0 && eler.left < document.documentElement.clientWidth && eler.top < Math.min(window.innerHeight, document.documentElement.clientHeight) + inlineImageThumbnailPreloadRadius);
}
function elegeta(xpath, node = document) {
if (!xpath) return [];
try {
var array = [];
var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
let l = ele.snapshotLength;
for (var i = 0; i < l; i++) array[i] = ele.snapshotItem(i);
return array;
} catch (e) { return []; }
}
function eleget0(xpath, node = document) {
if (!xpath) return null;
try {
var ele = document.evaluate(xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
return ele.snapshotLength > 0 ? ele.snapshotItem(0) : "";
} catch (e) { return null; }
}
function xa(xpath, node = document) {
if (!xpath) return [];
if (xpath.match(/^\/\//)) {
try {
var array = [];
var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
let l = ele.snapshotLength;
for (var i = 0; i < l; i++) array[i] = ele.snapshotItem(i);
return array;
} catch (e) { return []; }
} else {
return $(xpath);
}
}
function sw1(s) {
if (DEBUG_TIMER) console.time(s);
}
function sw2(s) {
if (DEBUG_TIMER) console.timeEnd(s);
}
function pref(name, store = null) { // prefs(name,data)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)、prefs(name)で読み出し
if (store === null) { // 読み出し
let data = GM_getValue(name) || GM_getValue(name);
if (data == undefined) return null; // 値がない
if (data.substring(0, 1) === "[" && data.substring(data.length - 1) === "]") { // 配列なのでJSONで返す
try { return JSON.parse(data || '[]'); } catch (e) {
alert("データベースがバグってるのでクリアします\n" + e);
pref(name, []);
return;
}
} else return data;
}
if (store === "" || store === []) { // 書き込み、削除
GM_deleteValue(name);
return;
} else if (typeof store === "string") { // 書き込み、文字列
GM_setValue(name, store);
return store;
} else { // 書き込み、配列
try { GM_setValue(name, JSON.stringify(store)); } catch (e) {
alert("データベースがバグってるのでクリアします\n" + e);
pref(name, "");
}
return store;
}
}
})();