// ツリーをvanishするスクリプト
var isIE = document.all ? true : false;
function contains(array, elm) {
for (var j = 0; j < array.length; j++) {
if (array[j] == value) return true;
}
return false;
}
function equals(lhs, rhs) {
if (lhs == rhs) return true;
return false;
}
var stopIteration = new Object();
function foreach(array, fun) {
for (var i = 0; i < array.length; i++) {
if (fun(array[i]) == stopIteration) break;
}
}
function foreachTag(tag, fun) {
var nodes = document.getElementsByTagName(tag);
foreach(nodes, fun);
// for (var i = 0; i < nodes.length; i++) {
// if (fun(nodes[i]) == stopIteration) break;
// }
}
function foreachTagWithClass(tag, cls, fun) {
var pred = cls instanceof Array ? contains : equals;
foreachTag(tag, function(node) {
if (pred(cls, node.className)) {
return fun(node);
}
});
}
var thumbnailer = {
update:function(size1, size2, ngThumbnail) {
this.thumbnailSize = size1;
this.popImageSize = size2;
this.ngThumbnail = ngThumbnail;
this.init();
foreachTag('img', function(node) {
if (node.className == 'ZANGZANGThumbnail') {
if (size1 < 1) {
node.parentNode.style.display = 'none';
} else {
node.parentNode.style.display = '';
}
thumbnailer.setImageSize(node, size1);
} else if (node.className == 'ZANGZANGPopImage') {
thumbnailer.setImageSize(node, size2);
}
});
},
setImageSize:function(node, size) {
if (isIE) {
node.style.width = size;
node.style.height = "auto";
} else {
node.style.maxWidth = size;
}
},
init:function() {
if (!this.isInitialized && this.thumbnailSize > 0) {
this.apply();
this.isInitialized = true;
}
},
apply:function() {
var regex = /^https?:\/\/(.*)\.(jpg|jpeg|gif|png)$/i;
var ngThumb = this.ngThumbnail;
var ngRegex = new RegExp(ngThumb, 'i');
// 最初のマッチは飛ばす、かつ、新しく追加したものも飛ばすためのフラグ
var skip = false;
foreachTag('a', function(node) {
if (node.href.match(regex)) {
if (skip) {
skip = false;
return;
}
if (ngThumb && ngThumb != '' && node.href.search(ngRegex) != -1) return;
var thumb = node.cloneNode(false);
//thumb.className = 'thumbnail';
var img1 = document.createElement('img');
//img1.style.maxWidth = thumbnailer.thumbnailSize;
thumbnailer.setImageSize(img1, thumbnailer.popImageSize);
img1.src = node.href;
img1.className = 'ZANGZANGThumbnail';
thumb.appendChild(img1);
if (!thumbnailer.popImageSize || thumbnailer.popImageSize != 0) (function() {
var thumb_ = thumb;
var initialized = false;
var pop = null;
thumb.onmouseover = function() {
if (initialized) {
pop.style.display = '';
return;
}
else initialized = true;
pop = document.createElement('a');
var img2 = document.createElement('img');
img2.src = thumb_.childNodes[0].src;
thumbnailer.setImageSize(img2, thumbnailer.popImageSize);
//img2.style.maxWidth = thumbnailer.popImageSize;
img2.className = 'ZANGZANGPopImage';
pop.appendChild(img2);
pop.appendChild(document.createElement('br'));
pop.appendChild(document.createTextNode(thumb_.childNodes[0].src));
pop.href = thumb_.childNodes[0].src;
pop.target = thumb_.childNodes[0].target;
pop.style.backgroundColor = '#054';
pop.style.border = '1px dashed #099';
pop.style.padding = '2px';
pop.style.fontSize = '80%';
pop.style.position = 'absolute';
pop.style.top = thumb_.offsetTop;
pop.style.left = thumb_.offsetLeft;
pop.onmouseout = function() {
pop.style.display = 'none';
};
pop.onmouseover = function() {
pop.style.display = '';
}
document.body.appendChild(pop);
}
thumb.onmouseout = function() {
pop.style.display = 'none';
}
})();
var holder = document.createElement('span');
holder.appendChild(thumb);
holder.appendChild(document.createElement('br'));
node.parentNode.insertBefore(holder, node);
skip = true;
}
});
},
isInitialized:false,
thumbnailSize:60,
popImageSize:600
}
var cookie = {
get:function(n,m){return (m=('; '+document.cookie+';').match('; '+n+'=(.*?);'))?decodeURIComponent(m[1]):''},
set:function(n,v){document.cookie=n+'='+encodeURIComponent(v)+'; expires=Mon, 31-Dec-2029 23:59:59 GMT'}
}
var vanisher = {
save:function(id) {
var vanishIdArray = cookie.get('vanishIdList').split(':');
vanishIdArray.push(id);
if (vanishIdArray.length > 50) vanishIdArray.shift();
cookie.set('vanishIdList', vanishIdArray.join(':'));
},
contain:function(array, value) {
for (var j = 0; j < array.length; j++) {
if (array[j] == value) return true;
}
return false;
},
iterateTree:function(func) {
var regex = /s=(\d+)&/;
foreachTagWithClass('div', 'ZANGZANGTreearticle', function(node) {
var match = regex.exec(node.childNodes[1].href);
if (match.length >= 2) {
if (!func(node, match[1])) return stopIteration;
}
});
},
display:function(idArray, disp) {
var hitCount = 0;
this.iterateTree(function(tree, id){
if (vanisher.contain(idArray, id)) {
tree.style.display = disp;
if (++hitCount >= idArray.length) return false;
}
return true;
});
},
vanish:function(id) {
this.display([id], 'none');
this.save(id);
this.count++;
this.updateResetLink();
},
resetVanish:function() {
this.display(cookie.get('vanishIdList').split(':'), '');
cookie.set('vanishIdList', '');
this.count = 0;
this.updateResetLink();
},
updateResetLink:function() {
this.resetLink.innerHTML = this.count > 0 ? ' 出(' + this.count + '件消去)' : '';
},
init:function() {
var forms = document.getElementsByTagName('form');
if (forms.length > 0) {
// vanish tree
this.initVanishTree(forms[0]);
// ng word
this.initNgWord(forms[0]);
// setting
this.initSettings(forms[0]);
}
},
initVanishTree:function(place) {
if (!this.isTreeMode()) return;
var vanishIdArray = cookie.get('vanishIdList').split(':');
this.iterateTree(function(tree, id){
if (vanisher.contain(vanishIdArray, id)) {
tree.style.display = 'none';
vanisher.count++;
}
var v = document.createElement("span");
v.innerHTML = ' 消';
tree.insertBefore(v, tree.childNodes[4]);
return true;
});
this.resetLink = document.createElement("span");
this.updateResetLink();
place.appendChild(this.resetLink);
place.appendChild(document.createTextNode(' '));
},
initNgWord:function(place) {
var ngWord = cookie.get('ngWord');
this.vanishNgWord(ngWord);
this.ngWordLink = document.createElement("a");
this.ngWordLink.href = '#';
var ngWordDisp = false;
this.ngWordLink.onclick = function(e) {
vanisher.ngWordBox.style.display = ngWordDisp ? 'none' : '';
ngWordDisp = ngWordDisp ? false : true;
return false;
}
this.ngWordLink.appendChild(document.createTextNode('NG Word('+ this.ngWordCount +'件hit)'));
place.appendChild(this.ngWordLink);
place.appendChild(document.createTextNode(' '));
var ngWordText = document.createElement("input");
ngWordText.size = 64;
ngWordText.name = 'ngword';
ngWordText.value = ngWord;
ngWordText.type = 'text';
this.ngWordBox = document.createElement("span");
this.ngWordBox.appendChild(ngWordText);
this.ngWordBox.appendChild(document.createTextNode(' '));
this.ngWordBox.style.display = 'none';
ngWordUpdate = document.createElement("a");
ngWordUpdate.href = '#';
ngWordUpdate.onclick = function(e) {
ngWordDisp = false;
vanisher.resetSkipReadMessage();
vanisher.ngWordBox.style.display = 'none';
vanisher.ngWordCount = 0;
// getElementsByNameはieですべてのタグに使えない
//var nodes = document.getElementsByName('ZANGZANGNgWordReDisp');
foreachTagWithClass('a', 'ZANGZANGNgWordReDisp', function(node) {
node.parentNode.removeChild(node);
});
vanisher.vanishNgWord(ngWordText.value);
cookie.set('ngWord', ngWordText.value);
vanisher.updateNgWordLink();
vanisher.skipReadMessage();
return false;
}
ngWordUpdate.appendChild(document.createTextNode('更新'));
this.ngWordBox.appendChild(ngWordUpdate);
place.appendChild(this.ngWordBox);
place.appendChild(document.createTextNode(' '));
},
initSettings:function(place) {
var settingBoxView = false;
this.settingLink = document.createElement("a");
this.settingLink.href = '#';
this.settingLink.onclick = function(e) {
if (settingBoxView) vanisher.settingBox.style.display = 'none';
else vanisher.settingBox.style.display = '';
settingBoxView = !settingBoxView;
return false;
};
place.appendChild(this.settingLink);
this.settingLink.appendChild(document.createTextNode('設定'));
this.settingBox = document.createElement('div');
this.settingBox.style.display = 'none';
this.settingBox.style.margin = '1em';
this.settingBox.style.marginLeft = '2em';
// NG Word Silent Mode
this.initNgWordSilent(this.settingBox);
this.settingBox.appendChild(document.createTextNode(' '))
// 既読skip
this.initSkipRead(this.settingBox);
// thumbnail
this.initThumbnail(this.settingBox);
place.appendChild(this.settingBox);
},
initNgWordSilent:function(place) {
var ngWordSilent = cookie.get('ngWordSilent');
var ngWordSilentCheck = document.createElement('input');
ngWordSilentCheck.type = 'checkbox';
ngWordSilentCheck.id = 'ngWordSilentCheck';
ngWordSilentCheck.name = 'ngWordSilentCheck';
var ngWordSilentFun = function(e) {
vanisher.resetSkipReadMessage();
var disp = ''; var val = '';
if (ngWordSilentCheck.checked) {
disp = 'none'; val = 'checked';
}
foreach(vanisher.ngWordSilentList, function(elem) {
elem.style.display = disp;
});
cookie.set('ngWordSilent', val);
vanisher.skipReadMessage();
};
// IEでonchangeは正常に動かない
if (isIE) { ngWordSilentCheck.onclick = ngWordSilentFun; } else { ngWordSilentCheck.onchange = ngWordSilentFun; }
place.appendChild(ngWordSilentCheck);
ngWordSilentCheck.checked = ngWordSilent != '' ? true : false;
var ngWordSilentCheckLabel = document.createElement('label');
ngWordSilentCheckLabel.appendChild(document.createTextNode('\'出\'を表示しない'));
ngWordSilentCheckLabel.htmlFor = 'ngWordSilentCheck';
place.appendChild(ngWordSilentCheckLabel);
},
initSkipRead:function(place) {
if (!this.isTreeMode()) return;
var skipRead = cookie.get('skipRead');
skipCheck = document.createElement("input");
skipCheck.id = 'skipReadCheck';
skipCheck.type = 'checkbox';
var fun = function(e) {
if (skipCheck.checked) {
cookie.set('skipRead', 'checked');
vanisher.skipReadMessage();
} else {
cookie.set('skipRead', '');
vanisher.resetSkipReadMessage(true);
}
};
// IEでonchangeは正常に動かない
if (isIE) { skipCheck.onclick = fun; } else { skipCheck.onchange = fun; }
place.appendChild(document.createTextNode(' '));
place.appendChild(skipCheck);
// IEではskipCheck.checkedを追加後に操作しないと状態が勝手に変わる
skipCheck.checked = skipRead != '' ? true : false;
var label = document.createElement("label");
label.htmlFor = 'skipReadCheck';
label.appendChild(document.createTextNode('既読skip'));
place.appendChild(label);
if (skipCheck.checked) this.skipReadMessage();
},
initThumbnail:function(place) {
var thumbnailSize = cookie.get('thumbnailSize');
var thumbnailSizeText = document.createElement("input");
thumbnailSizeText.size = 10;
thumbnailSizeText.name = 'thumbnailsize';
thumbnailSizeText.value = thumbnailSize;
thumbnailSizeText.type = 'text';
var popImageSize = cookie.get('popImageSize');
var popImageSizeText = document.createElement("input");
popImageSizeText.size = 10;
popImageSizeText.name = 'popimagesize';
popImageSizeText.value = popImageSize;
popImageSizeText.type = 'text';
var ngThumbnail = cookie.get('ngThumbnail');
var ngThumbnailText = document.createElement("input");
ngThumbnailText.size = 30;
ngThumbnailText.name = 'ngthumbnail';
ngThumbnailText.value = ngThumbnail;
ngThumbnailText.type = 'text';
var updateLink = document.createElement('a');
updateLink.href = '#';
updateLink.onclick = function() {
thumbnailer.update(thumbnailSizeText.value, popImageSizeText.value, ngThumbnailText.value);
cookie.set('thumbnailSize', thumbnailSizeText.value);
cookie.set('popImageSize', popImageSizeText.value);
cookie.set('ngThumbnail', ngThumbnailText.value);
return false;
}
updateLink.appendChild(document.createTextNode('更新'));
var thumbnailBox = document.createElement('div');
//thumbnailBox.style.border = '1px dashed #099';
//thumbnailBox.style.padding = '5px';
thumbnailBox.appendChild(document.createTextNode('サムネイルサイズ(0だと非表示)'));
thumbnailBox.appendChild(thumbnailSizeText);
thumbnailBox.appendChild(document.createTextNode(' '));
thumbnailBox.appendChild(document.createTextNode('ポップアップ画像サイズ'));
thumbnailBox.appendChild(popImageSizeText);
thumbnailBox.appendChild(document.createElement('br'));
thumbnailBox.appendChild(document.createTextNode('NGサムネイル(URLにhitするとサムネイル化されません)'));
thumbnailBox.appendChild(ngThumbnailText);
thumbnailBox.appendChild(document.createTextNode(' '));
thumbnailBox.appendChild(updateLink);
place.appendChild(document.createElement('br'));
place.appendChild(document.createElement('br'));
place.appendChild(thumbnailBox);
thumbnailer.update(thumbnailSizeText.value, popImageSizeText.value, ngThumbnailText.value);
},
updateNgWordLink:function() {
this.ngWordLink.innerHTML = 'NG Word('+ this.ngWordCount +'件hit)';
},
vanishNgWord:function(ngWord) {
var ngWordReg = new RegExp(ngWord);
var isStandardMode = !this.isTreeMode();
var tts = null;
if (!isStandardMode) {
var tts = document.getElementsByTagName('tt');
} else {
tts = document.getElementsByTagName('div');
}
if (!tts || tts.length <= 0 ) return;
var ngWordSilent = this.isNgWordSilent();
var silentList = [];
var vanishTree = true;
var getContentFun = tts[0].textContent ? function(n) {return n.textContent;} : function(){return n.innerHTML;};
for (var i = 0; i < tts.length; i++) {
var ttNode = tts[i];
if (isStandardMode && ttNode.className != 'ZANGZANGarticle') continue;
if (!ngWord || ngWord == '' || ttNode.innerHTML.search(ngWordReg) == -1) {
ttNode.style.display = '';
if (this.isLastMessageInBlock(ttNode)) {
this.getNextElement(ttNode).style.display = '';
vanishTree = true;
} else vanishTree = false;
} else {
var reDispLink = document.createElement('a');
reDispLink.className = 'ZANGZANGNgWordReDisp';
reDispLink.href = '#';
(function(){
var ttNode_ = ttNode;
var reDispLink_ = reDispLink;
var isView = false;
reDispLink.onclick = function(e) {
if (isView) {
ttNode_.style.display = 'none';
reDispLink_.style.position = '';
reDispLink_.removeChild(reDispLink_.childNodes[0]);
reDispLink_.insertBefore(document.createTextNode('出'), reDispLink_.childNodes[0]);
} else {
ttNode_.style.display = '';
reDispLink_.style.position = 'absolute';
//reDispLink_.style.display = 'none';
//this.parentNode.removeChild(this);
reDispLink_.removeChild(reDispLink_.childNodes[0]);
reDispLink_.insertBefore(document.createTextNode('戻'), reDispLink_.childNodes[0]);
}
isView = isView ? false : true;
return false;
}
})();
reDispLink.appendChild(document.createTextNode('出'));
reDispLink.appendChild(document.createElement('br'));
var hr = this.getNextElement(ttNode);
if (ngWordSilent) reDispLink.style.display = 'none';
silentList.push(reDispLink);
if (this.isLastMessageInBlock(ttNode)) {
if (!isStandardMode) {
if (vanishTree) {
if (ngWordSilent) ttNode.parentNode.style.display = 'none';
silentList.push(ttNode.parentNode);
}
} else {
if (ngWordSilent) hr.style.display = 'none';
silentList.push(hr);
}
vanishTree = true;
}
ttNode.parentNode.insertBefore(reDispLink,ttNode);
ttNode.style.display = 'none';
this.ngWordCount++;
}
}
this.ngWordSilentList = silentList;
},
isNgWordSilent:function() {
return cookie.get('ngWordSilent') != '' ? true : false;
},
skipReadMessage:function() {
if (!this.isTreeMode()) return;
if (!this.isSkipRead()) return;
var tts = document.getElementsByTagName('tt');
if (!tts || tts.length <= 0) return;
var rootNode = null;
var ngWordSilent = this.isNgWordSilent();
// すべての投稿を走査し、既読投稿を非表示にする.
// 既読投稿がNGであれば再表示リンクも非表示にする.
// 未読投稿であればその親投稿と親の親投稿を表示させる.
// ツリーの最後の投稿の処理が終われば、表示すべきツリーであるか調べ
// そうであれば再表示ボタンを作成し、表示位置の調整をする.
// 表示しないツリーであれば全体を消去する.
for (var i = 0; i < tts.length; i++) {
var ttNode = tts[i];
if (!rootNode) rootNode = ttNode;
if (ttNode.childNodes[0].color == '#ffffff') {
if (ttNode.previousSibling.tagName == 'A')
ttNode.previousSibling.style.display = 'none';
ttNode.style.display = 'none';
} else {
if (ttNode != rootNode && ttNode.style.display != 'none') {
var currentNodeNest = this.getNestLevel(ttNode, i);
var readMessageDispCount = 2;
for (var j = i - 1; j >= 0; j--) {
var prevNodeNest = this.getNestLevel(tts[j], j);
if (prevNodeNest < currentNodeNest) {
if (tts[j].previousSibling.tagName != 'A') {
tts[j].style.display = '';
}
if (--readMessageDispCount != 0)
currentNodeNest = prevNodeNest;
else
break;
} else if (tts[j] == rootNode) {
if (tts[j].previousSibling.tagName != 'A') {
tts[j].style.display = '';
}
break;
}
}
}
}
if (this.isLastMessageInBlock(ttNode)) {
var needViewLink = false;
var dispMessage = false;
var nodes = new Array();
var ngLinks = new Array();
var leastNestLevel = 1000;
// treeを下から上まで辿る
for (var j = i; j >= 0; j--) {
if (tts[j].previousSibling.tagName == 'A') {
// NGにヒットしている投稿
if (!ngWordSilent) {
needViewLink = true;
nodes.push(tts[j].previousSibling);
dispMessage = true;
var l = this.getNestLevel(tts[j], j);
if (leastNestLevel > l) leastNestLevel = l;
} else {
dispMessage = true;
}
ngLinks.push(tts[j].previousSibling);
} else {
if (tts[j].style.display == 'none') {
needViewLink = true;
nodes.push(tts[j]);
} else {
dispMessage = true;
var l = this.getNestLevel(tts[j], j);
if (leastNestLevel > l) leastNestLevel = l;
}
}
if (tts[j] == rootNode) break;
}
if (!dispMessage) {
if (ttNode.parentNode.style.display == 'none') {
// NGにより消去済み
needViewLink = false;
} else {
ttNode.parentNode.style.display = 'none';
//nodes.push(ttNode.parentNode);
//this.skipReadList.push(nodes);
this.skipReadList.push(ttNode.parentNode);
}
}
if (needViewLink) {
//this.skipReadList.push(nodes);
var reDispLink = document.createElement('a');
reDispLink.className = 'ZANGZANGSkipReadDisp';
reDispLink.href = '#';
// 新しいスコープにして値を保存
(function(){
var nodes_ = nodes;
var reDispLink_ = reDispLink;
var leastNestLevel_ = leastNestLevel;
var ngLinks_ = ngLinks;
reDispLink_.onclick = function(e) {
foreach(nodes_, function(node) {
if (!node.previousSibling || node.previousSibling.tagName != 'A') {
node.style.display = '';
}
});
if (leastNestLevel_ > 1) {
nodes_[0].parentNode.style.whiteSpace = '';
nodes_[0].parentNode.style.marginLeft = '';
nodes_[0].parentNode.firstChild.style.marginLeft = '';
foreach(ngLinks_, function(l) {
l.style.marginLeft = '';
});
}
reDispLink_.parentNode.removeChild(reDispLink_);
return false;
}
})();
reDispLink.appendChild(document.createTextNode('再'));
reDispLink.style.marginLeft = '1em';
rootNode.parentNode.insertBefore(reDispLink, rootNode.parentNode.childNodes[4]);
if (leastNestLevel > 1) {
// 既読部分の幅だけ左に寄せる
rootNode.parentNode.style.whiteSpace = 'nowrap';
rootNode.parentNode.style.marginLeft = '-'+leastNestLevel+'em';
rootNode.parentNode.insertBefore(document.createElement('span'), rootNode.parentNode.childNodes[0]);
rootNode.parentNode.firstChild.style.marginLeft = leastNestLevel+'em';
foreach(ngLinks, function(l) {
l.style.marginLeft = leastNestLevel+'em';
});
}
}
rootNode = null;
}
}
},
resetSkipReadMessage:function(force) {
if (!force && !this.isTreeMode()) return;
if (!force && !this.isSkipRead()) return;
foreachTagWithClass('a', 'ZANGZANGSkipReadDisp', function(node) {
node.style.display = 'none';
node.onclick();
});
var fun = function(elem) {
elem.style.display = '';
};
foreach(vanisher.skipReadList, fun /*function(list) { foreach(list, fun); }*/);
vanisher.skipReadList = [];
},
isSkipRead:function() {
return cookie.get('skipRead') != '' ? true : false;
},
isTreeMode:function() {
var ts = document.getElementsByName('tree');
if (ts && ts[0] && ts[0].value) return true;
return false
},
// 遅いのでキャッシュを使う
getNestLevel:function(node, index) {
if (this.nestLevelCache[index])
return this.nestLevelCache[index];
return this.nestLevelCache[index] = this.getNestLevelImpl(node);
},
getNestLevelImpl:function(ttNode) {
var nodes = ttNode.childNodes[0].childNodes;
var len = 0;
foreach(nodes, function(node) {
if (node.nodeName == '#text')
len += node.length;
else if (node.tagName == 'FONT') {
len += node.firstChild.length;
if (node.childNodes[1] && node.childNodes[1].tagName == 'A')
return stopIteration;
}
});
return len - 3;
},
isLastMessageInBlock:function(node) {
var ne = this.getNextElement(node);
return ne && ne.tagName == 'HR';
},
getNextElement:function(elem) {
if (isIE) return elem.nextSibling;
else return elem.nextSibling.nextSibling;
},
count:0,
resetLink:null,
ngWordLink:null,
ngWordBox:null,
ngWordCount:0,
ngWordSilentList:[],
settinglink:null,
settingBox:null,
skipReadList:[],
nestLevelCache:[]
}
vanisher.init();
/*
FILE ARCHIVED ON 13:00:53 Sep 24, 2018 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 11:38:43 Oct 19, 2018.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
*/
/*
playback timings (ms):
LoadShardBlock: 105.388 (3)
esindex: 0.005
captures_list: 120.043
CDXLines.iter: 9.581 (3)
PetaboxLoader3.datanode: 43.384 (4)
exclusion.robots: 0.244
exclusion.robots.policy: 0.231
RedisCDXSource: 2.56
PetaboxLoader3.resolve: 153.78 (3)
load_resource: 132.057
*/