おーぷん2ch無視設定変更スクリプト
-
/*
* @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));
updateIgnore();
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 です。