// ==UserScript==
// @name YouTubeとニコニコ動画にRSSリンクを追加
// @description YouTube:ユーザー、マイリスト、チャンネル ニコニコ動画:ユーザー、マイリスト、タグ reddit:キーワード検索結果、サブレディット、スレッド、ユーザー twitter:キーワード検索、ユーザー Pinterest:ユーザー、ボード
// @version 0.5.27
// @run-at document-idle
// @match *://www.youtube.com
// @match *://www.youtube.com/*
// @match *://www.nicovideo.jp/user/*
// @match *://www.nicovideo.jp/mylist/*
// @match *://www.nicovideo.jp/tag/*
// @match *://www.nicovideo.jp/related_tag/*
// @match *://www.nicovideo.jp/search/*
// @match *://www.nicovideo.jp/watch/*
// @match *://www.nicovideo.jp/mylist_search/*
// @match *://www.reddit.com/*
// @match *://twitter.com/*
// @match *://mobile.twitter.com/*
// @match *://www.pinterest.jp/*
// @match https://github.com/zedeus/nitter/wiki/Instances
// @grant none
// @require https://code.jquery.com/jquery-3.3.1.min.js
// @namespace https://greasyfork.org/users/181558
// @downloadURL none
// ==/UserScript==
(function() {
// 使うnitterのインスタンス(https://github.com/zedeus/nitter/wiki/Instances
const NITTER_INSTANCES = ["nitter.net", "nitter.lacontrevoie.fr", "nitter.pussthecat.org", "nitter.kavin.rocks", "nitter.unixfox.eu", "nitter.namazso.eu", "nitter.hu", "nitter.moomoo.me", "nitter.it", "twitter.censors.us", "nitter.grimneko.de", "nitter.ca", "nitter.fly.dev", "notabird.site", "nitter.weiler.rocks", "nitter.sethforprivacy.com", "nttr.stream", "nitter.cutelab.space", "nitter.nl", "nitter.mint.lgbt", "nitter.bus-hit.me", "nitter.esmailelbob.xyz", "tw.artemislena.eu", "nitter.winscloud.net", "nitter.tiekoetter.com", "nitter.spaceint.fr", "twtr.bch.bar", "nitter.privacy.com.de", "nitter.poast.org", "nitter.bird.froth.zone", "nitter.dcs0.hu", "twitter.dr460nf1r3.org", "nitter.garudalinux.org", "twitter.beparanoid.de", "n.ramle.be", "nitter.cz", "nitter.privacydev.net", "nitter.evil.site", "tweet.lambda.dance", "nitter.kylrth.com", "nitter.foss.wtf", "nitter.priv.pw", "nitter.tokhmi.xyz", "nitter.catalyst.sx", "unofficialbird.com", "nitter.projectsegfau.lt", "singapore.unofficialbird.com", "twt.funami.tech", "nitter.fprivacy.com", "canada.unofficialbird.com", "india.unofficialbird.com", "nederland.unofficialbird.com", "uk.unofficialbird.com", "n.l5.ca", "nitter.slipfox.xyz", "nitter.soopy.moe", "nitter.qwik.space", "read.whatever.social", "nitter.rawbit.ninja", "nt.vern.cc", "ntr.odyssey346.dev", "nitter.ir", "nitter.privacytools.io", "nitter.sneed.network", "n.sneed.network", "nitter.manasiwibi.com", "nitter.smnz.de", "nitter.twei.space", "nitter.inpt.fr", "nitter.d420.de", "nitter.caioalonso.com", "nitter.at", "nitter.drivet.xyz", "nitter.pw", "nitter.nicfab.eu"]
const NITTER_INSTANCE = NITTER_INSTANCES[Math.floor(Math.random() * (NITTER_INSTANCES.length))]; // alert(NITTER_INSTANCE);
const INSURE = 0;
var PERNOW = Math.max(2500, performance.now());
const TWITTER_USERHOME_USERNAME_XPATH = '//div[2]/div/div/div[last()]/div/div[@class="css-1dbjc4n"]/div/span|/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[2]/MAIN[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/SPAN[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[2]/MAIN[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/SECTION[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/ARTICLE[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/A[1]/DIV[1]/DIV[1]/SPAN[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[2]/MAIN[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/SECTION[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/ARTICLE[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/A[1]/DIV[1]/DIV[1]/SPAN[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[2]/MAIN[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/SECTION[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/ARTICLE[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/A[1]/DIV[1]/SPAN[1]';
if (location.href == "https://github.com/zedeus/nitter/wiki/Instances") {
let a = elegeta('//td[1]/a[text()="nitter.net"][contains(@href,"https://")]|//div[contains(@class,"markdown-body")]/table[2]/tbody/tr/td[1]/a[contains(@href,"https://")]').filter(e => !eleget0('//g-emoji[@alias="x"]|.//g-emoji[@alias="question"]', e.closest('tr'))).filter(e => !e?.href?.match(/\.jp|\.cn|\.kr|\.kp/));
a.forEach(e => e.style.outline = "0.3em dotted #0f0")
a = a.map(e => e?.href?.replace(/^https?:\/\/|\/$/g, ""))
if (a)($(`
YouTubeとニコニコ動画にRSSリンクを追加:
コピペ用 [Online ✅ ] \& [Updated ✅ ] \& [https ✅ ] なインスタンス
${`["` + a.join(`", "`) + `"]`}
`).on("dblclick", e => $("#okserver").remove()).insertAfter($(elegeta('//table[2]')[0])).hide().show(999)) //[0]?.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" })
return
}
if (location.href.match(/\/\/twitter\.com\/|\/\/mobile\.twitter\.com\//)) twitterRSS();
else if (location.href.match(/\/\/www\.youtube\.com|\/\/www\.nicovideo\.jp\/|\/\/www\.reddit\.com\/|\/\/www\.pinterest\./)) youtubeNicoRedditRSS();
return;
// ---------------------------------------------------------------------------------------------------------------------
function youtubeNicoRedditRSS() {
(function() {
var rssICON = '
';
addLinks();
setTimeout(addLinks, 200);
setTimeout(addLinks, 1000);
setTimeout(addLinks, 2500);
setTimeout(addLinks, PERNOW);
//ページ継ぎ足しアドオンに対応
if (location.href.match(/related_tag|mylist_search/)) document.addEventListener("AutoPagerize_DOMNodeInserted", addLinks);
//AutoPagerize系アドオンでuserやタグページを継ぎ足した時に2ページ目以降のリンクがおかしくなるのを修正
//userページ
if (location.href.match(/www.nicovideo.jp\/user/)) document.addEventListener("AutoPagerize_DOMNodeInserted", function() {
for (let ele of elegeta("//div[@class='section']/h5/a[contains(@href,'https://www.nicovideo.jp/user/')]"))
ele.href = "https://www.nicovideo.jp/watch/" + ele.href.replace(/https?:\/\/www.nicovideo.jp\/user\/\d*\/watch\//, "");
});
//related_tagページ
if (location.href.match(/www.nicovideo.jp\/related_tag/)) document.addEventListener("AutoPagerize_DOMNodeInserted", function() {
for (let ele of elegeta("//a[contains(@href,'https://www.nicovideo.jp/related_tag/tag/')]"))
ele.href = "https://www.nicovideo.jp/tag/" + ele.href.replace(/https?:\/\/www.nicovideo.jp\/related_tag\/tag\//, "");
});
// URL変化したら再実行
// if (location.href.indexOf("nicovideo") === -1 && !observer) {
var href = location.href;
var observer = new MutationObserver(function(mutations) {
if (href !== location.href) {
href = location.href;
removeAllRSS();
for (let i = 0; i < (location.href.match(/reddit|youtube|pinterest/) ? 4 : 1 + INSURE); i++) setTimeout(addLinks, PERNOW * i);
}
});
observer.observe(document, { childList: true, subtree: true });
// }
function removeAllRSS() { // 前回つけたRSSを剥がす
$('link.multirss,span.multirss,a.multirss').remove();
}
function redditYoutubeInitAndAddRSS() {
removeAllRSS();
if (location.href.match(/^https?:\/\/www\.reddit\.com\/search\/?\?q=/gmi) && eleget0('//input[@id="header-search-bar"]')) { // reddit search
var url = "https://www.reddit.com/search.rss?q=***&sort=new".replace("***", eleget0('//div[1]/div/h3/span').innerText);
addICONandRAD(eleget0('//div[1]/div/h3/span'), url, eleget0('//div[1]/div/h3/span').value);
} else
if (location.href.match(/^https?:\/\/www\.reddit\.com\/user\/[^\/]+\/posts\/$/gmi)) { // reddit user posts
var url = location.href.replace(/\/posts\//, "/submitted/") + ".rss";
addICONandRAD(eleget0('//div[@style="margin-left:24px;margin-top:0"]/div/div[1]/div/a/..|/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[4]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/A[1]/..'), url);
} else
if (location.href.match(/^https?:\/\/www\.reddit\.com\/user\/[^\/]+\/comments\/$/gmi)) { // reddit user comments
var url = location.href + ".rss";
addICONandRAD(eleget0('//div[@style="margin-left:24px;margin-top:0"]/div/div[1]/div/a/..|/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[4]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/A[1]/..'), url);
} else
if (location.href.match(/^https?:\/\/www\.reddit\.com\/user\/[^\/]+\/$/gmi)) { // reddit user overview
var url = location.href + (location.href.match(/\/$/) ? ".rss" : "/.rss");
addICONandRAD(eleget0('//div[@style="max-width:100%"]/div[last()]/div/div[1]/div/span|//div[2]/div/div[1]/div/h1|/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[4]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/SPAN[1]'), url);
} else
if (location.href.match(/^https?:\/\/www\.reddit\.com\/r\//gmi) && location.href.match(/\/search\/|comments/) == null) { // reddit subreddit
var url = location.href + (location.href.match(/\/$/) ? ".rss" : "/.rss");
addICONandRAD(eleget0('/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/H2[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/H2[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/H2[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/H2[1]'), url);
} else
if (location.href.match(/^https?:\/\/www\.reddit\.com\/.+/gmi) && location.href.match(/\/comments\//)) { // reddit thread
var url = location.href.replace(/\/\?.*/, "") + (location.href.match(/\/$/) ? ".rss" : "/.rss");
addICONandRAD(eleget0('//div/div[3]/div[1]/div/h1|//div[2]/div/div[2]/div/div/h1'), url);
}
addRSSICONandRADlink("://www.youtube.com/playlist?list=", '//yt-formatted-string[@class="style-scope ytd-playlist-sidebar-primary-info-renderer"]/a|//h1[@class="style-scope ytd-playlist-sidebar-primary-info-renderer"]/yt-formatted-string', '*RSS Feed*', "list=");
addRSSICONandRADlink("://www.youtube.com/channel/", '//div[@id="meta"]/ytd-channel-name[@id="channel-name"]|//span[@id="channel-title"]', '*RSS Feed*', "channel/");
addRSSICONandRADlink("://www.youtube.com/user/", '//div[@id="meta"]/ytd-channel-name|//span[@id="channel-title"]', '*RSS Feed*', "user/");
let chId = eleget0('//link[@rel="canonical"]');
if (chId && chId.href) {
addRSSICONandRADlink("://www.youtube.com/c/", '//div[@id="meta"]/ytd-channel-name[@id="channel-name"]|//span[@id="channel-title"]', '*RSS Feed*', "");
}
// Pinterest ボード
if (location.href.match(/\/\/www\.pinterest\.jp\/[^/]*\/[^/]*\//) && !(location.href.match(/\/\/www\.pinterest\.jp\/pin\/|\/\/www.pinterest.jp\/today\//))) {
var url = location.href.match(/https:\/\/www\.pinterest\.jp\/[^/]*\/[^/]*/) + ".rss";
var place = eleget0('//DIV[1]/DIV[1]/H1[1]|//div[last()]/div/div/div/div[1]/h4'); //TBD
addICONandRAD(place, url, place.value);
}
// Pinterest ユーザー
if (location.href.match(/\/\/www\.pinterest\.jp\/[^/]*\/$/) && !(location.href.match(/\/\/www\.pinterest\.jp\/pin\/|\/\/www.pinterest.jp\/today\//))) {
setTimeout(() => {
removeAllRSS();
var url = location.href.match(/https:\/\/www\.pinterest\.jp\/[^/]*\/$/) + "feed.rss";
var place = eleget0('/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/H1[1]'); //TBD o?
addICONandRAD(place, url, place.value);
}, 2200);
}
}
return;
function addICONandRAD(place, url, title = "") {
if (!place) return;
// removeAllRSS();
var link = document.body.parentNode.insertBefore(document.createElement("link"), document.body);
link.title = title || place.innerText;
link.rel = "alternate";
link.type = "application/rss+xml";
link.className = "multirss";
link.href = url;
if (!link.title) return;
var url = link.href;
var ele = place.appendChild(document.createElement('span'));
ele.setAttribute("style", "font-weight:normal;");
ele.className = "multirss";
let rssICON = '
';
ele.innerHTML = " " + rssICON + "";
}
//実際にリンクを付ける
function addLinks() {
//「新しいタブで開く」指定を外す
//for (let ele of elegeta('//a[@target="_blank"]')) ele.removeAttribute("target");
removeAllRSS();
redditYoutubeInitAndAddRSS();
var nicodeleteOpt = /[\?&]f_range=.|[\?&]l_range=.|[\?&]opt_md=.*|[\?&]start=.*|[\?&]end=.*|[\?&]ref=[^&]*|[\?&]sort=.|[\?&]order=.|[\?&]page=\d*|[\?&]track=[^&]*|#+.*/g;
addRSSICONandRADlink("www.nicovideo.jp/user/", '//h3[@class="UserDetailsHeader-nickname"]', '*RSS Feed*', "/user/", "", nicodeleteOpt);
addRSSICONandRADlink(/www.nicovideo.jp\/user\/.*?\/mylist\//, '//h1[@class="MylistHeader-name"]', '*RSS Feed*', /user\/.*?\//, "?rss=2.0&lang=ja-jp&special_chars_decode=1", nicodeleteOpt); // 2020年07月29日新
addRSSICONandRADlink3(/www.nicovideo.jp\/user\/.*?\/mylist\//, '//ul[@class="SubMenuLinkList MylistPageSubMenu-menu"]/li/a/span[2]/..', '*RSS Feed*', /https?\:\/\/www.nicovideo.jp\/user\/.*?\/mylist\//, "", nicodeleteOpt); // 2020年09月20日新
addRSSICONandRADlink("www.nicovideo.jp/tag/", '//header[@class="contentHeader"]/h1/span', '*RSS Feed*', "", "?sort=f&rss=2.0&lang=ja-jp", nicodeleteOpt);
addRSSICONandRADlink2("www.nicovideo.jp/related_tag/", '//table[@class="font12"]/tbody/tr/td/a', '*RSS Feed*', "", "", nicodeleteOpt);
addRSSICONandRADlink2("www.nicovideo.jp/search", "//ul[@class='tags']//a", '*RSS Feed*', "", "", nicodeleteOpt);
addRSSICONandRADlink2("www.nicovideo.jp/tag", "//ul[@class='tags']//a", '*RSS Feed*', "", "", nicodeleteOpt);
addRSSICONandRADlink2("www.nicovideo.jp/watch/", '//a[@class="Link TagItem-name"]', '*RSS Feed*', "", "", nicodeleteOpt);
if (/www.nicovideo.jp\/mylist_search\//.exec(location.href))
for (let ele of elegeta('//div[@id="PAGEBODY"]/div[2]/div/div/p/a')) addRSSICONandRAD(ele, ele.href + "?rss=2.0&lang=ja-jp&special_chars_decode=1", ele.innerText);
return;
}
function eleget0(xpath) {
var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
return ele.snapshotLength > 0 ? ele.snapshotItem(0) : "";
}
function elegeta(xpath) {
var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var array = [];
for (var i = 0; i < ele.snapshotLength; i++) array[i] = ele.snapshotItem(i);
return array;
}
function addRAD(inurl, xpath, newurl, part, after, urlGarbage = /$^/) { // RSS auto-discoveryを付ける
if (location.href.indexOf(inurl) == -1) return;
var place = eleget0(xpath);
var link = eleget0('//head').appendChild(document.createElement("link"));
var url2 = after ? ('*RSS Feed*') : newurl.replace("***", location.href.split(part)[1].match(/[^\?&\/]*/g)[0]);;
link.rel = "alternate"
link.type = "application/rss+xml"
link.title = document.title;
link.href = url2;
link.setAttribute("class", "multirss");
}
function addRSSICONandRAD(place, url, title) {
// removeAllRSS();
var link = place.parentNode.insertBefore(document.createElement("a"), place);
link.href = url;
link.setAttribute("title", title + "のRSSを購読");
link.setAttribute("class", "multirss");
link.innerHTML = rssICON;
var rac = document.createElement("link");
rac.rel = "alternate"
rac.type = "application/rss+xml"
rac.title = title;
rac.href = url
rac.setAttribute("class", "multirss");
eleget0('//head').appendChild(rac);
}
function addRSSICONandRADlink(inurl, xpath, newurl, part, after, urlGarbage = /$^/) {
if (typeof inurl == "string" && location.href.indexOf(inurl) == -1) return;
if (typeof inurl == "object" && !(location.href.match(inurl))) return
var ele = eleget0(xpath);
if (!ele) return;
// removeAllRSS();
var text = newurl + location.href.split(part)[1];
var url = location.href.replace(urlGarbage, "");
var link = document.createElement("span");
// var url2 = after ? ('*RSS Feed*') : newurl.replace("***", location.href.split(part)[1].match(/[^\?&\/]*/g)[0]);
if (typeof part == "string") {
var url2 = after ? ('*RSS Feed*') : newurl.replace("***", location.href.split(part)[1].match(/[^\?&\/]*/g)[0]);
} else {
var url2 = after ? ('*RSS Feed*') : newurl.replace("***", location.href.replace(part, "").match(/[^\?&\/]*/g)[0]); // 現在ニコ動mylist専用
}
var bgcol = "background-color:#c9e9ff;";
link.setAttribute("title", ele.innerText + "のRSSを購読");
link.setAttribute("class", "multirss");
link.innerHTML = url2.replace("*RSS Feed*", rssICON)
ele.parentNode.appendChild(link);
addRAD1(ele, url2);
return;
}
function addRSSICONandRADlink2(inurl, xpath, newurl, part, after, urlGarbage = /$^/) {
if (location.href.indexOf(inurl) == -1) return
// removeAllRSS();
for (let ele of elegeta(xpath)) {
var url = location.href.replace(urlGarbage, "");
var link = document.createElement("span");
var url2 = newurl.replace("***", encodeURIComponent(ele.innerText));
var bgcol = "background-color:#c9e9ff;";
link.setAttribute("title", ele.innerText + "のRSSを購読");
link.setAttribute("class", "multirss");
link.innerHTML = url2.replace("*RSS Feed*", rssICON)
ele.parentNode.insertBefore(link, ele);
addRAD1(ele, url2)
}
return;
}
function addRSSICONandRADlink3(inurl, xpath, newurl, part, after, urlGarbage = /$^/) {
if (location.href.match(inurl) == false) return
// removeAllRSS();
for (let ele of elegeta(xpath)) {
var url = location.href.replace(urlGarbage, "");
var link = document.createElement("span");
var url2 = newurl.replace("***", ele.href.replace(part, ""));
var bgcol = "background-color:#c9e9ff;";
link.setAttribute("title", ele.innerText + "のRSSを購読");
link.setAttribute("class", "multirss");
link.innerHTML = url2.replace("*RSS Feed*", rssICON)
link.style = "position:relative;top:2em;left:-1.5em;";
ele.parentNode.insertBefore(link, ele);
addRAD1(ele, url2)
}
return;
}
function addRAD1(ele, url2) {
// removeAllRSS();
for (let rad of elegeta("//link[@type='application/rss+xml']")) { if (rad.href == url2.match(/\"(.*)\"/)[1]) return; } // 重複登録を避ける
var rac = document.createElement("link");
rac.rel = "alternate"
rac.type = "application/rss+xml"
rac.title = ele.innerText;
rac.href = url2.match(/\"(.*)\"/)[1];
rac.setAttribute("class", "multirss");
eleget0('//head').appendChild(rac);
}
})();
}
// ---------------------------------------------------------------------------------------------------------------------
function twitterRSS() {
(function() {
addAutoDiscovery();
setTimeout(addAutoDiscovery, PERNOW); //addAutoDiscovery();
// URLが変化したら再実行
var href = location.href;
var observer = new MutationObserver(function(mutations) {
if (href !== location.href) {
href = location.href;
setTimeout(addAutoDiscovery, PERNOW);
}
});
observer.observe(document, { childList: true, subtree: true });
return;
function addAutoDiscovery() { // Twitter検索へのRSSリンクとRSS Autodiscoveryを埋め込む
for (let ele of elegeta('//*[@class="multirss"]')) ele.remove();
//新2ペイン
if (location.href.indexOf("/search?") != -1) { // 文字列検索
embedAutoDiscovery('//input[@placeholder="キーワード検索"]', /(.)/, "$1", "*** | Nitter Twitterキーワード", "https://" + NITTER_INSTANCE + "/search/rss?f=tweets&q=***")
embedAutoDiscovery('//input[@placeholder="キーワード検索"]', /(.)/, "$1", "*** | Nitter Twitterキーワード 画像か動画", "https://" + NITTER_INSTANCE + "/search/rss?f=tweets&q=***+(filter:images OR filter:videos)")
embedAutoDiscovery('//input[@placeholder="キーワード検索"]', /(.)/, "$1", "*** | Nitter Twitterキーワード 日本語ツイートのみ", "https://" + NITTER_INSTANCE + "/search/rss?f=tweets&q=***+lang:ja")
embedAutoDiscovery('//input[@placeholder="キーワード検索"]', /(.)/, "$1", "*** | Nitter Twitterキーワード 日本語ツイートのみ 画像か動画", "https://" + NITTER_INSTANCE + "/search/rss?f=tweets&q=***+lang:ja+(filter:images OR filter:videos)")
} else { // ユーザー
embedAutoDiscovery(TWITTER_USERHOME_USERNAME_XPATH, /(^@)/, "", "from:*** | Nitter Twitterユーザー", "https://" + NITTER_INSTANCE + "/***/rss")
embedAutoDiscovery(TWITTER_USERHOME_USERNAME_XPATH, /(^@)/, "", "from:*** | Nitter Twitterユーザー 画像か動画", "https://" + NITTER_INSTANCE + "/***/media/rss")
// embedAutoDiscovery(TWITTER_USERHOME_USERNAME_XPATH, /(^@)/, "from:@", "from:*** (filter:videos) | Queryfeed Twitterユーザー 動画", "https://Queryfeed.net/tw?q=***%20(filter:videos)")
// twicomiへのリンク
let ele = eleget0(TWITTER_USERHOME_USERNAME_XPATH);
if (ele && !eleget0('//a[@id="twicomi"]')) {
$(ele).after('')
$(ele).after('')
$(``).on("click", () => { var input = prompt(`${ele.innerText.trim()}さんのツイートを文字列で検索\n|、|は OR に置き換えます\n\nhttps://twitter.com/search?q=from:${ele.innerText.trim()}%20《文字列》&src=typd&f=live&vertical=default\n\n`); if (input !==null) { window.open(`https://twitter.com/search?q=from:${ele.innerText.trim()}%20${input.replace(/\|||/gmi," OR ")}&src=typd&f=live&vertical=default`) || "" }; }).insertAfter($(ele));
$(``).on("click", () => { var input = prompt(`${ele.innerText.trim()}さんのツイートを文字列で検索(画像か動画付き)\n|、|は OR に置き換えます\n\n空欄のままEnterを押すと単に画像か動画付きツイートのみを表示します\n\nhttps://twitter.com/search?q=from:${ele.innerText.trim()}%20《文字列》%20%28filter%3Aimages%20OR%20filter%3Avideos%29&src=typd&f=live&vertical=default\n\n`); if (input == "" || input > "") { window.open(`https://twitter.com/search?q=from:${ele.innerText.trim()}%20${input.replace(/\|||/gmi," OR ")}%20%28filter%3Aimages%20OR%20filter%3Avideos%29&src=typd&f=live&vertical=default`) || "" }; }).insertAfter($(ele));
}
}
return;
}
function embedAutoDiscovery(wordXP, wordtermRE, replaceStr, itemName, url) {
// if (location.href.indexOf("google") == -1) return
var ele = eleget0(wordXP);
if (!ele) return;
var word = ele.innerText || ele.value;
if (!word) return;
if (itemName.match("日本語ツイートのみ") && !(word.match(/^[\x20-\x7e]*$/))) return;
word = word.replace(/(\(filter\:videos\)|\(filter\:images OR filter\:videos\))/gmi, "").trim();
// if (itemName.match(/\(En\)/) && !(word.match(/^[\x20-\x7e]*$/))) return; // google news en なら半角英数以外を含んだらやらない
var link = eleget0('//head').appendChild(document.createElement("link"));
link.title = itemName.replace("***", word);
link.rel = "alternate"
link.type = "application/rss+xml"
link.className = "multirss";
link.href = url.replace("***", encodeURIComponent(word.replace(wordtermRE, replaceStr)));
//旧3ペイン
//var place = eleget0('//div/h2/a/span[@class="username u-dir"]|//h1[@class="SearchNavigation-titleText"]');
//新2ペイン
//var place = eleget0('//div/h2/a/span[@class="username u-dir"]|//h1[@class="SearchNavigation-titleText"]|//div[@aria-haspopup="false"]/div/div[1]/div/span/span|//div/div/div/div[1]/div/h2[@aria-level="2" and @role="heading"]/span|/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[2]/MAIN[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/SPAN[1]|/HTML/BODY/DIV[1]/DIV[1]/DIV[1]/DIV[2]/MAIN[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]/DIV[2]/DIV[2]/DIV[1]/DIV[1]/DIV[2]/DIV[1]/SPAN[1]|//input[@placeholder="キーワード検索"]/../..');
var place = eleget0('//div/h2/a/span[@class="username u-dir"]|//h1[@class="SearchNavigation-titleText"]|//div[@aria-haspopup="false"]/div/div[1]/div/span/span|//div/div/div/div[1]/div/h2[@aria-level="2" and @role="heading"]/span|' + TWITTER_USERHOME_USERNAME_XPATH + '|//input[@placeholder="キーワード検索"]/../../..');
if (!place) return;
var url = link.href;
var ele = place.appendChild(document.createElement('span'));
ele.className = "multirss";
ele.setAttribute("style", "font-weight:normal;display:inline;");
let rssICON = '
';
ele.innerHTML = " " + rssICON + "";
return;
}
function addLink(site, placexpath, terms, beforetitle, title, append, deleteoption, option) {
if (location.href.indexOf(site) == -1) return;
var place = eleget0(placexpath);
if (!place) return;
var url = window.location.href;
if (terms !== "") url = url.replace(/&tbm=.*/, "");
if (terms !== "none") url = url + terms;
url = url.replace(deleteoption, '') + option;
var ele = document.createElement('span');
ele.className = "multirss";
ele.setAttribute("style", "font-weight:normal;");
ele.innerHTML = beforetitle + "" + title + "" + append;
place.appendChild(ele);
return;
}
})();
}
function elegeta(xpath, node = document) {
if (!xpath || !node) return [];
let flag
if (!/^\.?\//.test(xpath)) return /:visible$/.test(xpath) ? [...node.querySelectorAll(xpath.replace(/:visible$/, ""))].filter(e => e.offsetHeight) : [...node.querySelectorAll(xpath)]
try {
var array = [];
var ele = document.evaluate("." + xpath.replace(/:visible$/, ""), 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 /:visible$/.test(xpath) ? array.filter(e => e.offsetHeight) : array;
} catch (e) { popup3(e + "\n" + xpath + "\n" + JSON.stringify(node), 1); return []; }
}
function eleget0(xpath, node = document) {
if (!xpath || !node) return null;
if (!/^\.?\//.test(xpath)) return /:visible$/.test(xpath) ? [...node.querySelectorAll(xpath.replace(/:visible$/, ""))].filter(e => e.offsetHeight)[0] ?? null : node.querySelector(xpath.replace(/:visible$/, ""));
try {
var ele = document.evaluate("." + xpath.replace(/:visible$/, ""), node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
return ele.snapshotLength > 0 ? ele.snapshotItem(0) : null;
} catch (e) { alert(e + "\n" + xpath + "\n" + JSON.stringify(node)); return null; }
}
function lh(re) { let tmp = location.href.match(re); if (!tmp) { return null } else if (tmp.length > 1) { return tmp[1] } else return tmp[0] } // gフラグ不可
})();