Greasy Fork is available in English.

学園祭カレンダー絞り込み

s:絞り込み (とどラン)a:相関が弱いものを消す

Version au 01/04/2020. Voir la dernière version.

// ==UserScript==
// @name 学園祭カレンダー絞り込み
// @description s:絞り込み (とどラン)a:相関が弱いものを消す
// @version      0.3.5
// @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 *://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
// ==/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/|//www.youtube.com/user/",
    filterPlace: "div#primary-items",
    filterItem: "div.style-scope ytd-grid-video-renderer,ytd-grid-playlist-renderer",
  }, {
    url: "//www.youtube.com",
    filterPlace: '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 style='float:right;-moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;' rel=\"noopener noreferrer nofollow\" href='" + $(this).attr("href").replace("kiji", "soukan") + "'>全相関記事を見る</a>") });
    // a: 相関係数が0に近いものを消す
    if (location.href.match(/:\/\/todo-ran\.com\/t\/soukan\//)) {
      $("<span class='phov' style='cursor:pointer; color:#505050; font-size:90%; background:#ffffffc0; padding:3px; border-radius:9px;border:#505050 1px solid; position:fixed; bottom:3em; right: 1em;'>A:相関が弱いものを消す</span>").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();
          }
        }
      }
    }

    //チョクバイ!住所一覧ボタン
    $('<span style="cursor:pointer; text-align:center; background-color:#ffffff; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; font-size:14px; font-weight:normal; color:#606060; margin:0px 2px;  text-decoration:none; text-align:center; padding:0px 7px 1px; border:outset #909090 1px; border-radius:5px; background: linear-gradient(#fefefe, #f4f4f4);" >住所一覧をクリップボードにコピー</span>').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("<a class='shibo' style='text-align:center; background-color:#ffffff; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; font-size:14px; font-weight:normal; color:#606060; margin:0px 2px;  text-decoration:none; text-align:center; padding:0px 7px 1px; border:outset #909090 1px; border-radius:5px; background: linear-gradient(#fefefe, #f4f4f4); float:right;' rel=\"noopener noreferrer nofollow\" href='https://www.google.co.jp/maps/search/" + $(this).text().replace(/\s+/gmi, "") + "'>地図</a>"); });


    //検索窓設置場所と対象項目が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("");
        }
      }

      // 絞り込みフォームを付ける
      $('<span ID="shiboButton" class="shibo" title="S or Shift+Alt+S" style="cursor:pointer; background-color:#999999; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; font-size:13px; font-weight:500; color:#ffffff; margin:0px 2px;  text-decoration:none; text-align:center; padding:1px 5px 1px; border:outset #909090 0px; border-radius:5px; ">絞り込み(s)</span><input class="shibo" style="width:80%" type="text" id="sear" accesskey="s" title="' + tips + '" Placeholder="例)' + filterSampleWord + '">').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);
  }

})()