おーぷん2ch無視設定変更スクリプト

    @@ -3,56 +3,321 @@ * @include http://*.open2ch.net/test/read.cgi/* * @license MIT License */ -//スレッド書き込み欄の下にボタンとテキストエリアが出てきます。 -//IDを好きに設定してください。完全一致のみです。 -//なお、ツイッターID「tw@~」を設定すると、@は消えますが使用であり問題なく設定できます。 -// -// ==UserScript== -// @name ローカルストレージ勉強 -// @namespace open -// @include http://*.open2ch.net/test/read.cgi/* -// @version 1 -// @grant none -// ==/UserScript== -function Manual_GetStorage() { - var mes = '' - try { - var ignArray = localStorage.getItem('ign:' + bbs).slice(1, - 1).split(',') - for (var i = 0; i < ignArray.length; i++) { - mes += ignArray[i].slice(0, ignArray[i].indexOf(':')).slice(1, - 1) + '\n' - } - } - catch (e) { - console.log('無視対象がありません') - } - return mes -} -var musiid = 'musi_upd_ta' -function Manual_SetStorage() { - var setMes = ''; - var at = '@' - //document.getElementById(musiid); - var setMesArray = Ta.value.split('\n'); - localStorage.setItem('ign:' + bbs, '') - for (var i = 0; i < setMesArray.length; i++) { - console.log('■' + setMesArray[i] + '■') - if (setMesArray[i] !== '' && setMesArray[i] !== '\n') { - setMes += '"' + setMesArray[i].replace(at, '') + '"' + ':1,' - } - } - setMes = '{' + setMes.slice(0, - 1) + '}' //var ignArray = - localStorage.setItem('ign:' + bbs, setMes) - window.location.reload(); -} -var Frm = document.getElementById('form1'); -var Botan = document.createElement('input'); -Botan.type = 'button'; -Botan.value = '無視設定配列更新ボタン'; -Botan.id = 'musi_upd_btn'; -Botan.onclick = Manual_SetStorage; -Frm.appendChild(Botan); -var Ta = document.createElement('textarea'); -Ta.value = Manual_GetStorage(); -Ta.id = musiid; -Ta.rows = 3 -Frm.appendChild(Ta); +//作った人 Awn +//Forked from && Inspired by http://let.hatelabo.jp/TimeFires/let/hJmesYHtkMte + +(function (d) { + //note:「Hatena::Let」の@includeが効かないようなので、 + // URLが「http://*.open2ch.net/test/read.cgi/*」を満たさ無い場合、スクリプト内部で弾く + let REGEXP_OPEN2CHREADCGI = new RegExp(/http:\/\/.*\.open2ch\.net\/test\/read\.cgi\/.*/); + if (!REGEXP_OPEN2CHREADCGI.test(location.href)) { + console.warn("available only under http://*.open2ch.net/test/read.cgi/*"); + return; + } + + //member + let appName = 'ignoreManager'; + let _ignores = ignores; + + + //initializer + _init(); + + + //function + function _init() { + _embedHTML(); + _assignEventListener(); + } + + function _embedHTML() { + _embedBackgroundElm(); + _embedMainElm(); + _setIgnores(); + } + + function _assignEventListener() { + AddBtnEventListener(); + DeleteAllBtnEventListener(); + DeleteWithoutTwitterBtnEventListener(); + DeleteSelectedBtnEventListener(); + CloseIgnoreManager(); + } + + function _embedBackgroundElm() { + let bg = d.createElement('div'); + bg.id = `${appName}_bg`; + bg.style = ` + background:black; + position:fixed; + top:0; + left:0; + width:100%; + height:100%; + opacity:0.5; + z-index:30; + `; + d.body.appendChild(bg); + } + + function _embedMainElm() { + let main = d.createElement('div'); + main.id = `${appName}_main`; + main.style = ` + background:#EFEFEF; + position:fixed; + top:30px; + left:30px; + width:calc(100% - 80px); + height:calc(100% - 80px); + z-index:31; + border:solid black 1px; + padding:10px; + `; + main.innerHTML = ` + <h1>無視id編集画面</h1> + <hr> + <form name="ign_form" style="width:500px" onsubmit="return false;"> + <fieldset> + <legend>一括削除</legend> + <input type="button" value="全て削除" id="b_deleteAll"> + <input type="button" value="TwitterID以外を削除" id="b_deleteWithoutTwitter"> + </fieldset> + <fieldset> + <legend>個別追加</legend> + <label> + 追加するid <input type="text" id="t_input"> + </label> + <input type="button" value="追加する" id="b_add"> + </fieldset> + </form> + <h2>無視id ↓</h2> + <hr> + <div id="ignoresView" style="height:200px;overflow:scroll;"> + </div> + <hr> + <input type="button" value="選択したidを削除する" id="b_deleteSelected"> + <span id="s_messageArea"></span> + `; + d.body.appendChild(main); + } + + function _setIgnores() { + let keys = Object.keys(_ignores); + let arr = []; + let id; + for (key of keys) { + [id, key] = _transformID(key); + arr.push(`<label style="display: block;"><input type="checkbox" value="${key}">${id}</label>`); + } + let div = d.querySelector('#ignoresView'); + div.innerHTML = arr.join(''); + } + + function _transformID(key) { + let id; + if (key.length > 3 && key.startsWith('tw@')) { + id = key; + key.replace(/^tw@/, 'tw'); + return [id, key]; + } + if (key.length > 3 && key.startsWith('tw')) { + id = key.replace(/^tw/, 'tw@'); + return [id, key]; + } + if (key.length > 3 && key.startsWith('@')) { + id = key.replace(/^@/, 'tw@'); + key = key.replace(/^@/, 'tw'); + return [id, key]; + } + id = key; + return [id, key]; + } + + function _addIgnore(key) { + let elm = d.createElement('label'); + elm.style = 'display:block'; + id = key; + id = id.length > 3 && id.startsWith('tw') ? id.replace(/^tw/, 'tw@') : id; + elm.innerHTML = `<input type="checkbox" value="${key}">${id}`; + let div = d.querySelector('#ignoresView'); + div.appendChild(elm); + } + + function _validateID(id) { + return new Promise((resolve, reject) => { + if (id.length < 3) { + reject(); + } + + //note: idで利用できない文字は弾く + if (/[^A-Za-z0-9@_]/.test(id)) { + reject(); + } + + //note: @が2つ以上現れるidは存在しないので弾く + if (id.includes('@') && id.match(/@/g).length > 1) { + reject(); + } + + if (id.length === 3) { + //note: 3文字の時はtwitterアカウント連携のidではないと「見做す」 + // 理論上(?)[1-3]文字のtwitterアカウントも存在しうるが、そんなレアな人が書き込む可能性は皆無であろう。 + if (id.includes('@') || id.includes('_')) { + reject(); + } + resolve(id); + } + + //note: 3文字より大きい場合 -> twitterIDと見做す + // idが[10,9,8,7,6,5,4]桁の過去スレは諦めよう + /* + # 正常ケース + tw@aidee_42 -> twaidee_42 + @aidee_42 -> twaidee_42 + aidee_42 -> twaidee_42 + # エラーケース + 正常ケース以外 + */ + if (id.length > 3) { + if (id.includes('@')) { + if (id.startsWith('tw@')) { + id = id.replace(/^tw@/, 'tw'); + resolve(id); + } else if (id.startsWith('@')) { + id = id.replace(/@/, 'tw'); + resolve(id); + } else { + reject(); + } + } else { + id = 'tw' + id; + resolve(id); + } + } + }); + } + + //deleter + function _deleteAll() { + delStorage(cachekey); + _ignores = new Object(); + ignores = _ignores; + return; + } + + function _deleteAllFromView() { + let div = d.querySelector('#ignoresView'); + while (div.firstChild) { + div.removeChild(div.firstChild); + } + } + + + function _deleteWithoutTwitter() { + let keys = Object.keys(_ignores); + for (let key of keys) { + if (key.length === 3) { + delete _ignores[key]; + } + } + setStorage(cachekey, JSON.stringify(_ignores)); + ignores = _ignores; + } + + function _deleteWithoutTwitterFromView() { + let div = d.querySelector('#ignoresView'); + let elms = div.querySelectorAll('input[type="checkbox"]'); + for (let elm of elms) { + if (elm.value.length === 3) { + div.removeChild(elm.parentElement); + } + } + } + + function _deleteSelected() { + let div = d.querySelector('#ignoresView'); + let elms = div.querySelectorAll('input[type="checkbox"]'); + let obj = {}; + for (let elm of elms) { + obj[elm.value] = 1; + } + _ignores = obj; + ignores = _ignores; + setStorage(cachekey, JSON.stringify(ignores)); + return; + } + + function _deleteSelectedFromView() { + let div = d.querySelector('#ignoresView'); + let elms = div.querySelectorAll('input[type="checkbox"]:checked'); + for (let elm of elms) { + div.removeChild(elm.parentElement); + } + return; + } + + //EventListener + function AddBtnEventListener() { + let elm = d.querySelector('#b_add'); + elm.addEventListener('click', function (ev) { + ev.preventDefault(); + let id = d.querySelector('#t_input').value; + id = id.trim(); + _validateID(id) + .then((key) => { + _ignores[key] = 1; + _addIgnore(key); + setStorage(cachekey, JSON.stringify(_ignores)); + console.dir(_ignores); + }, () => { alert(`${id}はidっぽくないみたい。。`); }); + }); + } + + function DeleteAllBtnEventListener() { + let elm = d.querySelector('#b_deleteAll'); + elm.addEventListener('click', function (ev) { + ev.preventDefault(); + if (confirm('消しますか?')) { + _deleteAll(); + _deleteAllFromView(); + } + }); + } + + function DeleteWithoutTwitterBtnEventListener() { + let elm = d.querySelector('#b_deleteWithoutTwitter'); + elm.addEventListener('click', function (ev) { + ev.preventDefault(); + if (confirm('消しますか?')) { + _deleteWithoutTwitter(); + _deleteWithoutTwitterFromView(); + } + }); + } + + function DeleteSelectedBtnEventListener() { + let elm = d.querySelector('#b_deleteSelected'); + elm.addEventListener('click', function (ev) { + ev.preventDefault(); + if (confirm('消しますか?')) { + _deleteSelectedFromView(); + _deleteSelected(); + } + }) + } + + function CloseIgnoreManager() { + let elm = document.querySelector('#ignoreManager_bg'); + elm.addEventListener('click', function (ev) { + if (confirm('閉じますか?')) { + let main = d.querySelector(`#${appName}_main`); + let bg = d.querySelector(`#${appName}_bg`); + d.body.removeChild(main); + d.body.removeChild(bg); + } + }); + } + + return; +})(document);
  • /*
     * @title おーぷん2ch無視設定変更スクリプト
     * @include http://*.open2ch.net/test/read.cgi/*
     * @license MIT License
     */
    //作った人 Awn
    //Forked from && Inspired by http://let.hatelabo.jp/TimeFires/let/hJmesYHtkMte
    
    (function (d) {
      //note:「Hatena::Let」の@includeが効かないようなので、
      //      URLが「http://*.open2ch.net/test/read.cgi/*」を満たさ無い場合、スクリプト内部で弾く
      let REGEXP_OPEN2CHREADCGI = new RegExp(/http:\/\/.*\.open2ch\.net\/test\/read\.cgi\/.*/);
      if (!REGEXP_OPEN2CHREADCGI.test(location.href)) {
        console.warn("available only under http://*.open2ch.net/test/read.cgi/*");
        return;
      }
    
      //member
      let appName = 'ignoreManager';
      let _ignores = ignores;
    
    
      //initializer
      _init();
    
    
      //function
      function _init() {
        _embedHTML();
        _assignEventListener();
      }
    
      function _embedHTML() {
        _embedBackgroundElm();
        _embedMainElm();
        _setIgnores();
      }
    
      function _assignEventListener() {
        AddBtnEventListener();
        DeleteAllBtnEventListener();
        DeleteWithoutTwitterBtnEventListener();
        DeleteSelectedBtnEventListener();
        CloseIgnoreManager();
      }
    
      function _embedBackgroundElm() {
        let bg = d.createElement('div');
        bg.id = `${appName}_bg`;
        bg.style = `
          background:black;
          position:fixed;
          top:0;
          left:0;
          width:100%;
          height:100%;
          opacity:0.5;
          z-index:30;
      `;
        d.body.appendChild(bg);
      }
    
      function _embedMainElm() {
        let main = d.createElement('div');
        main.id = `${appName}_main`;
        main.style = `
          background:#EFEFEF;
          position:fixed;
          top:30px;
          left:30px;
          width:calc(100% - 80px);
          height:calc(100% - 80px);
          z-index:31;
          border:solid black 1px;
          padding:10px;
        `;
        main.innerHTML = `
        <h1>無視id編集画面</h1>
        <hr>
        <form name="ign_form" style="width:500px" onsubmit="return false;">
          <fieldset>
            <legend>一括削除</legend>
            <input type="button" value="全て削除" id="b_deleteAll">
            <input type="button" value="TwitterID以外を削除" id="b_deleteWithoutTwitter">
          </fieldset>
          <fieldset>
            <legend>個別追加</legend>
            <label>
              追加するid <input type="text" id="t_input">
            </label>
            <input type="button" value="追加する" id="b_add">
          </fieldset>
        </form>
        <h2>無視id ↓</h2>
        <hr>
        <div id="ignoresView" style="height:200px;overflow:scroll;">
        </div>
        <hr>
        <input type="button" value="選択したidを削除する" id="b_deleteSelected">
        <span id="s_messageArea"></span>
        `;
        d.body.appendChild(main);
      }
    
      function _setIgnores() {
        let keys = Object.keys(_ignores);
        let arr = [];
        let id;
        for (key of keys) {
          [id, key] = _transformID(key);
          arr.push(`<label style="display: block;"><input type="checkbox" value="${key}">${id}</label>`);
        }
        let div = d.querySelector('#ignoresView');
        div.innerHTML = arr.join('');
      }
    
      function _transformID(key) {
        let id;
        if (key.length > 3 && key.startsWith('tw@')) {
          id = key;
          key.replace(/^tw@/, 'tw');
          return [id, key];
        }
        if (key.length > 3 && key.startsWith('tw')) {
          id = key.replace(/^tw/, 'tw@');
          return [id, key];
        }
        if (key.length > 3 && key.startsWith('@')) {
          id = key.replace(/^@/, 'tw@');
          key = key.replace(/^@/, 'tw');
          return [id, key];
        }
        id = key;
        return [id, key];
      }
    
      function _addIgnore(key) {
        let elm = d.createElement('label');
        elm.style = 'display:block';
        id = key;
        id = id.length > 3 && id.startsWith('tw') ? id.replace(/^tw/, 'tw@') : id;
        elm.innerHTML = `<input type="checkbox" value="${key}">${id}`;
        let div = d.querySelector('#ignoresView');
        div.appendChild(elm);
      }
    
      function _validateID(id) {
        return new Promise((resolve, reject) => {
          if (id.length < 3) {
            reject();
          }
    
          //note: idで利用できない文字は弾く
          if (/[^A-Za-z0-9@_]/.test(id)) {
            reject();
          }
    
          //note: @が2つ以上現れるidは存在しないので弾く
          if (id.includes('@') && id.match(/@/g).length > 1) {
            reject();
          }
    
          if (id.length === 3) {
            //note: 3文字の時はtwitterアカウント連携のidではないと「見做す」
            //     理論上(?)[1-3]文字のtwitterアカウントも存在しうるが、そんなレアな人が書き込む可能性は皆無であろう。
            if (id.includes('@') || id.includes('_')) {
              reject();
            }
            resolve(id);
          }
    
          //note: 3文字より大きい場合 -> twitterIDと見做す
          //     idが[10,9,8,7,6,5,4]桁の過去スレは諦めよう
          /*
            # 正常ケース
              tw@aidee_42 -> twaidee_42
              @aidee_42 -> twaidee_42
              aidee_42 -> twaidee_42
            # エラーケース
              正常ケース以外
          */
          if (id.length > 3) {
            if (id.includes('@')) {
              if (id.startsWith('tw@')) {
                id = id.replace(/^tw@/, 'tw');
                resolve(id);
              } else if (id.startsWith('@')) {
                id = id.replace(/@/, 'tw');
                resolve(id);
              } else {
                reject();
              }
            } else {
              id = 'tw' + id;
              resolve(id);
            }
          }
        });
      }
    
      //deleter
      function _deleteAll() {
        delStorage(cachekey);
        _ignores = new Object();
        ignores = _ignores;
        return;
      }
    
      function _deleteAllFromView() {
        let div = d.querySelector('#ignoresView');
        while (div.firstChild) {
          div.removeChild(div.firstChild);
        }
      }
    
    
      function _deleteWithoutTwitter() {
        let keys = Object.keys(_ignores);
        for (let key of keys) {
          if (key.length === 3) {
            delete _ignores[key];
          }
        }
        setStorage(cachekey, JSON.stringify(_ignores));
        ignores = _ignores;
      }
    
      function _deleteWithoutTwitterFromView() {
        let div = d.querySelector('#ignoresView');
        let elms = div.querySelectorAll('input[type="checkbox"]');
        for (let elm of elms) {
          if (elm.value.length === 3) {
            div.removeChild(elm.parentElement);
          }
        }
      }
    
      function _deleteSelected() {
        let div = d.querySelector('#ignoresView');
        let elms = div.querySelectorAll('input[type="checkbox"]');
        let obj = {};
        for (let elm of elms) {
          obj[elm.value] = 1;
        }
        _ignores = obj;
        ignores = _ignores;
        setStorage(cachekey, JSON.stringify(ignores));
        return;
      }
    
      function _deleteSelectedFromView() {
        let div = d.querySelector('#ignoresView');
        let elms = div.querySelectorAll('input[type="checkbox"]:checked');
        for (let elm of elms) {
          div.removeChild(elm.parentElement);
        }
        return;
      }
    
      //EventListener
      function AddBtnEventListener() {
        let elm = d.querySelector('#b_add');
        elm.addEventListener('click', function (ev) {
          ev.preventDefault();
          let id = d.querySelector('#t_input').value;
          id = id.trim();
          _validateID(id)
            .then((key) => {
              _ignores[key] = 1;
              _addIgnore(key);
              setStorage(cachekey, JSON.stringify(_ignores));
              console.dir(_ignores);
            }, () => { alert(`${id}はidっぽくないみたい。。`); });
        });
      }
    
      function DeleteAllBtnEventListener() {
        let elm = d.querySelector('#b_deleteAll');
        elm.addEventListener('click', function (ev) {
          ev.preventDefault();
          if (confirm('消しますか?')) {
            _deleteAll();
            _deleteAllFromView();
          }
        });
      }
    
      function DeleteWithoutTwitterBtnEventListener() {
        let elm = d.querySelector('#b_deleteWithoutTwitter');
        elm.addEventListener('click', function (ev) {
          ev.preventDefault();
          if (confirm('消しますか?')) {
            _deleteWithoutTwitter();
            _deleteWithoutTwitterFromView();
          }
        });
      }
    
      function DeleteSelectedBtnEventListener() {
        let elm = d.querySelector('#b_deleteSelected');
        elm.addEventListener('click', function (ev) {
          ev.preventDefault();
          if (confirm('消しますか?')) {
            _deleteSelectedFromView();
            _deleteSelected();
          }
        })
      }
    
      function CloseIgnoreManager() {
        let elm = document.querySelector('#ignoreManager_bg');
        elm.addEventListener('click', function (ev) {
          if (confirm('閉じますか?')) {
            let main = d.querySelector(`#${appName}_main`);
            let bg = d.querySelector(`#${appName}_bg`);
            d.body.removeChild(main);
            d.body.removeChild(bg);
          }
        });
      }
    
      return;
    })(document);
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2017/01/17 00:40:44 - 2017-01-17
  2. 2017/01/17 00:35:02 - 2017-01-17
  3. 2017/01/17 00:34:37 - 2017-01-17