// ==UserScript== // @name 学園祭カレンダー絞り込み // @description s:絞り込み (とどラン)a:相関が弱いものを消す // @version 0.3.6 // @run-at document-idle // @match *://*.5ch.net/* // @match *://auctions.yahoo.co.jp/category/list/* // @match *://auctions.yahoo.co.jp/search/search* // @match *://auctions.yahoo.co.jp/seller/* // @match *://auctions.yahoo.co.jp/jp/show/* // @match *://choku-buy.com/* // @match *://fmfm.jp/* // @match *://labo.tv/2chnews/* // @match *://omocoro.jp/* // @match *://oowata.com/* // @match *://owata-net.com/* // @match *://store.workman.co.jp/* // @match *://todo-ran.com/t/soukan/* // @match *://todo-ran.com/t/kiji/* // @match *://www.gakkou.net/daigaku/gakuensai/* // @match *://www.nicochart.jp/user/* // @match *://www.nicochart.jp/search/* // @match *://www.nicochart.jp/name/* // @match *://www.nicochart.jp/tag/* // @match *://www.nicovideo.jp/ranking // @match *://www.nicovideo.jp/search/* // @match *://www.nicovideo.jp/tag/* // @match *://www.nicovideo.jp/user/* // @match *://www.nicovideo.jp/series/* // @match *://www.suruga-ya.jp/pcmypage/action_favorite_list/detail/* // @match *://www.youtube.com/* // @match *://www.youtube.com/channel/* // @match *://www.youtube.com/user/* // @match *://www.youtube.com/playlist?list=* // @match *://gigazine.net/* // @match *://gigazine.net/news/C* // @match *://www.ebay.com/sch/* // @match *://www.lifehacker.jp/* // @match *://www.gizmodo.jp/* // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM.setClipboard // @require https://code.jquery.com/jquery-3.4.1.min.js // @namespace https://greasyfork.org/users/181558 // @downloadURL none // ==/UserScript== // @match *://*/* (function() { const LogMatch = 0; const historyLen = 50; const SITEINFO = [{ // 上が優先 url: "//www.gakkou.net/daigaku/gakuensai/", filterPlace: "H2.GESTitle", mapPlace: "h3.ListTtlN", filterItem: "ol[class^='articleListN']>li", filterSampleWord: "東京", }, { url: "//todo-ran.com/t/soukan/|//todo-ran.com/t/kiji/", filterPlace: "div.kiji_ktext", filterItem: '//table[@id="t_soukan_r"]/tbody/tr/td[1]/a/../..|//table[@class="kenbetsuranking" and @id="t_soukan"]/tbody/tr/td/a/../..', filterSampleWord: "消費", }, { url: "//fmfm.jp/", filterPlace: '#calendarTitleDate', filterItem: 'div.eventListbox', filterSampleWord: "東京", }, { url: "//www.nicovideo.jp/ranking", filterPlace: "div.BaseLayout-block ul", filterItem: '//div[@class="Card-title"]/..', filterSampleWord: "!ゆっくり 解説|講座", }, { url: "//www.youtube.com/results", filterPlace: '//div[@id="filter-menu"]', filterItem: '//div[@id="dismissable"]|//ytd-playlist-renderer|//ytd-channel-renderer|//ytd-movie-renderer|//ytd-horizontal-card-list-renderer', }, { url: "//www.youtube.com/channel/.*/search|//www.youtube.com/user/.*/search", filterPlace: '//input[@class="style-scope paper-input"]', filterItem: '//*[@class="style-scope ytd-section-list-renderer"]', }, { url: "//www.youtube.com/channel/|//www.youtube.com/user/", filterPlace: "div#primary-items", filterItem: "div.style-scope ytd-grid-video-renderer,ytd-grid-playlist-renderer", }, { url: "//www.youtube.com/playlist\?", filterPlace: '//div[@id="items"]/ytd-playlist-sidebar-secondary-info-renderer', filterItem: '//*[@class="style-scope ytd-playlist-video-list-renderer"]', }, { url: "//www.youtube.com/$", filterPlace: '//span[@id="title" and text()="あなたへのおすすめ"]', //'span#title:contains("あなたへのおすすめ"):visible', filterItem: '//div[@id="dismissable"]', }, { url: "//omocoro.jp/", filterPlace: '//div[@class="tag-inner"]/h2[@class="waku-text"]|//div[@class="category-inner"]/h2[@class="waku-text"]|//div[@class="new-entries"]/div/h2[@class="title waku-text"]|//div[@class="writer-inner"]/h2[@class="waku-text"]', filterItem: "div.box", }, { url: "//store.workman.co.jp/", filterPlace: "div.control_bar:has(dd.kosuu)", filterItem: "div.item_box", filterSampleWord: "ストレッチ|STRETCH" }, { url: "//www.nicovideo.jp/user/", filterPlace: "div.outer.VideoListHeadMenuContainer", filterItem: '//div[@class="outer VideoItem"]', }, { url: '//www.nicovideo.jp/tag/', filterPlace: '//div[@class="column main"]/div[2]/div[@class="toolbar"]', filterItem: 'li.item.nrn-thumb-info-done', }, { url: '//www.nicovideo.jp/search/', filterPlace: '//div[@id="nrn-config-bar"]', filterItem: '//li[@data-nicoad-video=""]', }, { url: '//choku-buy.com/', mapPlace: '//p[@class="address"]' }, { url: '//auctions.yahoo.co.jp/search/search', filterPlace: '//div[@class="Options"]', filterItem: '//li[@class="Product"]', filterSampleWord: '入札0|\\d時間', }, { url: '//auctions.yahoo.co.jp/seller/', filterPlace: '//div[@class="bd"]/..', filterItem: '//td[@class="i"]/..', filterSampleWord: '入札0|\\d時間', }, { url: '//auctions.yahoo.co.jp/category/list/', filterPlace: '//div[@class="Options"]', filterItem: '//li[@class="Product"]', filterSampleWord: '入札0|\\d時間', }, { url: '//.*\.5ch\.net/', filterPlace: '//h1[@class="title"]', filterItem: '//div[@class="post"]', important: true, filterFunc: function() { $('div.post:hidden').next("br").css("display", "none"); $('div.post:visible').next("br:hidden").css("display", "block"); } //余計な改行を詰める }, { url: '//www.nicochart.jp/user/|//www.nicochart.jp/search/|//www.nicochart.jp/name/|//www.nicochart.jp/tag/', filterPlace: '//div[@id="result"]/ul[1]', filterItem: 'ul[@class="video-list"]/li/ul/..', }, { url: '//labo.tv/2chnews/', filterPlace: '//html/body/center/table/tbody/tr/td[@align="left"]/h2', filterItem: '//html/body/center/table/tbody/tr/td[@valign="top"]/div/ul/li', }, { url: '//owata-net.com', filterPlace: '//div/div[@class="clearfix"]', filterItem: '//div[@class="feed clearfix"]|//div[@class="feed-list"]/div', }, { url: '//oowata.com', filterPlace: '//div[4]/ul[@id="globalNavi"]', filterItem: '//td[contains(@class,"t")]/..|//ul/li[@class="t"]', }, { url: '//www.suruga-ya.jp/pcmypage/action_favorite_list/detail/', filterPlace: '//form[contains(@class,"favorite-form") and @method="post"]', filterItem: '//td[@class="gnavBox"]', filterSampleWord: '税込', }, { url: '//auctions.yahoo.co.jp/jp/show/rating', filterPlace: '//b[text()="評価コメントの一覧"]', filterItem: '//tr[2]/td[@colspan="3"]/small/a/../../../../..', }, { url: 'gigazine.net/|gigazine.net/news/C', filterPlace: '//header[@id="header"]', filterItem: '//div[@class="content"]/section|//div[@id="search_results"]/section', filterSampleWord: '!試食|ヘッドライン|取材', }, { url: '//www.ebay.com/sch/', filterPlace: '//div/div/div[@class="clearfix srp-controls__row-2"]', filterItem: '//li[@class="s-item "]/div/..', }, { url: '//www.lifehacker.jp/', filterPlace: 'h2.lh-block-title:contains("記事"):visible,div>div>h2:contains("の検索結果"):visible', filterPlace: '//h2[@class="lh-block-title" and contains(text(),"記事")]|//div/div[1]/h2[contains(text(),"の検索結果")]', filterItem: '//div[@class="lh-summary"]|//div/a[@class="lh-summary"]', filterSampleWord: '方法', }, { url: '//www.nicovideo.jp/series/', filterPlace: '//div[@class="SeriesDetailContainer-media"]', filterItem: '//div[@class="SeriesVideoListContainer"]/div', }, { url: '//www.gizmodo.jp/', filterPlace: '//div[@class="h-body-header"]/div', filterItem: '//article[@class="p-timeline-cardPost"]|//ul[@class="p-slider1-cardList swiper-wrapper"]/li|//div/div[@class="p-cardHead"]/article|//section[@class="s-Ranking_ListItemPost"]|//article[@class="s-body-cardList3CardPost"]|//article[@class="p-post-reviewList-CardPost"]|//article[@class="p-archive-cardPost"]', filterSampleWord: '', }, { url: '', filterPlace: '', filterItem: '', filterSampleWord: '', mapPlace: '', important: false, filterFunc: null, }, { url: '', filterPlace: '', filterItem: '', filterSampleWord: '', mapPlace: '', important: false, filterFunc: null, }, { url: '', //対応URLにmatchする正規表現 filterPlace: '', //絞り込みフォームを設置する場所 XPathかjQueryセレクタ(省略可) filterItem: '', //絞り込みフォームで絞り込む要素 XPathかjQueryセレクタ(省略可) filterSampleWord: '', //絞り込みフォームの検索ワード例(省略可) mapPlace: '', //地図検索を設置したい住所の書いてある要素 XPathかjQueryセレクタ(省略可) important: false, //!importantを付けないと非表示にできないサイトでtrueを指定(省略可) filterFunc: null, //絞り込み実行時に行わせたい追加処理(省略可) }]; var shiboDNIevent; var shiboTimer = null; // match文を生成 if (LogMatch) { let matchlist = "" for (let s of SITEINFO.slice().sort(function(a, b) { return a.url > b.url ? 1 : -1 })) { if (s.url != "") for (let s2 of s.url.split("|")) { matchlist += "// @match *:" + s2.replace(/\.\*/gm, "*").replace(/^\./, "//*.") + "*\n"; } } alert(matchlist); } //URL遷移を監視 var href = location.href; var observer = new MutationObserver(function(mutations) { if (href !== location.href) { href = location.href; $(document).off('keydown.shibo'); $(".shibo").remove(); if (shiboDNIevent && location.href.match(/www\.youtube\.com/)) setTimeout(() => { run("url"); }, 1500) for (let i = 0; i < (location.href.match(/www\.youtube\.com/) ? 3 : 1 + 0); i++) setTimeout(run, 1000 + i * 1000); } }); observer.observe(document, { childList: true, subtree: true }); run(); return; function run(mode) { $(".shibo").remove(); $(document).off('keydown.shibo'); if (shiboDNIevent || mode === "url") { document.body.removeEventListener('DOMNodeInserted', shiboDNIevent); shiboDNIevent = null; shibo(""); } // thissiteを決定 var thissite = null; for (var i = 0; i < SITEINFO.length; i++) { if (SITEINFO[i].url == "") continue; if (location.href.match(SITEINFO[i].url)) { thissite = i; break; } } if (thissite === null) return; if (LogMatch) console.log(SITEINFO[thissite]); const tips = "Tips:\n「ABCやDEFを含まず、GHIかJKLを含み、かつMNOとPQRも含む」\n!ABC|DEF GHI|JKL MNO PQR\n"; var filterSampleWord = SITEINFO[thissite].filterSampleWord || ""; //県民性専用機能 if (location.href.match(/:\/\/todo-ran\.com\/t\/kiji\//)) { $("div.kiji>div:eq(2)").after($("a:contains('全相関記事を見る'):first").clone().css("float", "right")); } // ? if (location.href.match(/:\/\/todo-ran\.com\/t\/soukan\//)) $("table#t_soukan_r tbody tr td a,table#t_soukan tbody tr td a").each(function() { $(this).append("全相関記事を見る") }); // a: 相関係数が0に近いものを消す if (location.href.match(/:\/\/todo-ran\.com\/t\/soukan\//)) { $("A:相関が弱いものを消す").appendTo(document.body).click(function() { soukan(); }); $(document).off('keydown.soukan').on('keydown.soukan', function(e) { if (/input|textarea/i.test(e.target.tagName) == false) { var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key; if (key == "a" && $(xa(SITEINFO[thissite].filterItem)).length > 0) { soukan(); return false; } } }); function soukan() { var key = proInput("残す個数", 35, 0); if (key > 1) { $('tr:hidden').remove(); var min = $(xa('//table[@id="t_soukan_r"]/tbody/tr/td[last()]|//table[@class="kenbetsuranking" and @id="t_soukan"]/tbody/tr/td[2]')).sort(function(a, b) { return Math.abs($(a).text()) > Math.abs($(b).text()) ? 1 : -1; }); for (var i = 0; i < $(min).length; i++) { if (i < ($(min).length - key)) $(min[i]).parent().hide(); else $(min[i]).parent().show(); } } } } //チョクバイ!住所一覧ボタン $('住所一覧をクリップボードにコピー').appendTo(xa('//div[@class="result-main"]/div/table/tbody/tr/td/h3')).on('click', function(e) { if ($(xa(SITEINFO[thissite].mapPlace))) { var maplist = []; $(xa(SITEINFO[thissite].mapPlace)).each(function() { maplist.push($(this).text().trim().replace(/\s|地図|付近/gmi, "")); }) maplist = Array.from(new Set(maplist)).sort(); alert(Array.from(new Set(maplist)).sort().join("\r\n")); GM.setClipboard(Array.from(new Set(maplist)).sort().join("\r\n")); } }) //地図検索機能 if ($(xa(SITEINFO[thissite].mapPlace))) $(xa(SITEINFO[thissite].mapPlace)).each(function() { $(this).append("地図"); }); //検索窓設置場所と対象項目が1つでもあれば if ($(xa(SITEINFO[thissite].filterPlace)).length && $(xa(SITEINFO[thissite].filterItem)).length) { var shiboPrompt = function() { var key = prompt("絞り込みキーワード(正規表現)\n\n例:\n" + filterSampleWord + /*"\n\n現在値:\n" + (pref("defWord") || "") +*/ "\n\n履歴:\n" + (pref("defWordLog") || []).slice(0, historyLen).join("\n") + "\n\n" + tips + "\n\n", pref("defWord") || ""); if (key !== null) { shibo(prefl("defWord", key)); } else { shibo(""); } } // 絞り込みフォームを付ける $('絞り込み(s)').insertAfter($(xa(SITEINFO[thissite].filterPlace))); // autofocus="on" $("#shiboButton").click(shiboPrompt); $("#sear").change(() => { shibo(prefl("defWord", $("#sear").val(), 3)) }); // 絞り込みショートカットキーイベントを設定 $(document).off('keydown.shibo').on('keydown.shibo', function(e) { if (/input|textarea/i.test(e.target.tagName) == false && ($(xa(SITEINFO[thissite].filterPlace)).length && $(xa(SITEINFO[thissite].filterItem)).length)) { var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key; if (key == "s" && $(xa(SITEINFO[thissite].filterItem)).length > 0) { shiboPrompt(); return false; } } }); } return; //絞り込む function shibo(sear = "") { if (sear === "") { if (shiboDNIevent) { document.body.removeEventListener('DOMNodeInserted', shiboDNIevent); shiboDNIevent = null; } shibo3(""); } else { shibo3(sear); if (shiboDNIevent) document.body.removeEventListener('DOMNodeInserted', shiboDNIevent); shiboDNIevent = { handleEvent: shibo2, arg1: sear }; document.body.addEventListener('DOMNodeInserted', shiboDNIevent, false); } } function shibo2() { shibo3(this.arg1); } function shibo3(sear = "") { var node = document; if (shiboTimer) return; shiboTimer = setTimeout(function() { if (!($(xa(SITEINFO[thissite].filterPlace)) && $(xa(SITEINFO[thissite].filterItem)).length)) return; $("#sear").val(sear); var searRE = sear.replace(/|/gm, "|").replace(/^[\!|!](\S*)/, "^(?!.*($1)).*").replace(/(\S*)[  ](\S*)/gm, "^(?=.*($1))(?=.*\($2\))").replace(/\s| /gm, ".*"); //alert(searRE); try { $(xa(SITEINFO[thissite].filterItem, node)).each((function(len, sear) { return function() { var ele = $(this); if (ele.css("opacity") == 0 || !(ele.text().replace(/\r|\n|\s/gm, " ").match(new RegExp(searRE, "gmi")))) { SITEINFO[thissite].important ? ele.attr("style", "display:none !important;") : len < 50 ? ele.hide(200) : len > 200 ? ele.hide() : ele.fadeOut(200); } else { // SITEINFO[thissite].important ? ele.attr("style", "display:block !important;") : len < 50 ? ele.show(200) : len > 200 ? ele.show() : ele.fadeIn(200); } } })($(xa(SITEINFO[thissite].filterItem)).length, sear)) } catch { alert("おそらく正規表現の構文エラーです\n" + searRE); } shiboTimer = 0; if (typeof SITEINFO[thissite].filterFunc === "function") SITEINFO[thissite].filterFunc(); // サイトごとの特殊処理があれば }, 200); } function prefl(name, store = undefined, logLen = 100) { // prefl(name,data,len)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)・"name+Log"にlen個の履歴保存、pref(name)で読み出し if (store === undefined) { // 読み出し return pref(name); } else { // 書き込み、削除 if (store) { var a = pref(name + "Log") || []; a.unshift(store); a = Array.from(new Set(a)); pref(name + "Log", a.slice(0, logLen)); } return pref(name, store); } } function pref(name, store = undefined) { // pref(name,data)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)、pref(name)で読み出し var domain = (location.href.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1] || location.href); if (store === undefined) { // 読み出し let data = GM_getValue(domain + " ::: " + name) if (data == undefined) return store; // 値がないなら終わり if (data.substr(0, 1) === "[") { // 配列なのでJSONで返す try { return JSON.parse(data || '[]'); } catch (e) { console.log("(読み出し)データベースがバグってるのでクリアします\n" + e); pref(name, null); return null; } } else return data; } if (store === "" || store === [] || store === null) { // 書き込み、削除 GM_deleteValue(domain + " ::: " + name); return store; } else if (typeof store === "string") { // 書き込み、文字列b GM_setValue(domain + " ::: " + name, store); return store; } else { // 書き込み、配列 try { GM_setValue(domain + " ::: " + name, JSON.stringify(store)); } catch (e) { console.log("(書き込み)データベースがバグってるのでクリアします\n" + e); pref(name, ""); return null; } return store; } return store; } } 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); for (var i = 0; i < ele.snapshotLength; i++) array[i] = ele.snapshotItem(i); return array; } catch (e) { return []; } } else { return $(xpath); } } function proInput(prom, defaultval, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) { return Math.min(Math.max( Number(window.prompt(prom, defaultval).replace(/[A-Za-z0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248); }).replace(/[^-^0-9^\.]/g, "")), min), max); } })()