您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
ニコニコ大百科のBBSの拡張
// ==UserScript== // @name NicoDicBBSViewer // @description ニコニコ大百科のBBSの拡張 // @namespace http://threeaster.net // @include http://dic.nicovideo.jp/a/* // @include http://dic.nicovideo.jp/b/* // @include http://dic.nicovideo.jp/l/* // @include http://dic.nicovideo.jp/v/* // @include http://dic.nicovideo.jp/i/* // @include http://dic.nicovideo.jp/u/* // @include https://dic.nicovideo.jp/a/* // @include https://dic.nicovideo.jp/b/* // @include https://dic.nicovideo.jp/l/* // @include https://dic.nicovideo.jp/v/* // @include https://dic.nicovideo.jp/i/* // @include https://dic.nicovideo.jp/u/* // @require https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js // @grant GM_getValue // @grant GM_setValue // @version 1.2.1 // ==/UserScript== $.noConflict(); var net_threeaster_NicoDicBBSViewer = {}; (function($){ //-----UrlAnalyzer----- function UrlAnalyzer(){}; UrlAnalyzer.prototype.getNowUrl = function(){ return document.URL; }; UrlAnalyzer.prototype.inArticlePage = function(){ return this.getNowUrl().indexOf("//dic.nicovideo.jp/b/") === -1; }; UrlAnalyzer.prototype.getBBSURLs = function(pager){ if(pager.size() === 0){ return []; } var urls = pager.find("a").not(".navi").map(function(){return this.href}).get(); var bbsURLs = []; if(urls.length){ var lastURLParts = urls[urls.length - 1].split("/"); var lastNumber = lastURLParts[lastURLParts.length - 1].replace("-", ""); if(!this.inArticlePage()){ var nowURLParts = this.getNowUrl().split("#")[0].split("/"); var nowNumber = nowURLParts[nowURLParts.length - 1].replace("-", ""); lastNumber = (lastNumber - 0 >= nowNumber - 0) ? lastNumber : nowNumber; } lastURLParts.pop(); var basicURL = lastURLParts.join("/") + "/"; for(var i = lastNumber; i > 0; i -= 30){ bbsURLs.unshift(basicURL + i + "-"); } }else{ var url = this.getNowUrl(); if(url.indexOf("#") !== -1){ url = url.substring(0, url.indexOf("#")); if(url.indexOf("-") === -1){ url = url + "-"; } } bbsURLs.push(url); } return bbsURLs; }; UrlAnalyzer.prototype.isPageOf = function(url){ var nowUrl = this.getNowUrl(); type = this.getPageType(url); nowType = type !== undefined ? this.getPageType(nowUrl): undefined; //idPageOfの仕様のつじつま合わせ url = this.getPageName(url); nowUrl = this.getPageName(nowUrl); return type === nowType && url === nowUrl; }; UrlAnalyzer.prototype.getPageName = function(url){ var type = this.getPageType(url); if(type !== undefined && url.indexOf(type) !== -1){ url = url.split(type + "/")[1]; } url = url.split("/")[0]; url = url.split(":")[0]; url = url.split("#")[0]; return url; } UrlAnalyzer.prototype.getNowPageName = function(){ return this.getPageName(this.getNowUrl()); } UrlAnalyzer.prototype.getPageType = function(url) { if(url.indexOf('//dic.nicovideo.jp') !== -1){ url = url.replace('//dic.nicovideo.jp', ''); } var parts = url.split('/'); if(parts[1] === 'b'){ return parts[2]; }else{ return parts[1]; } }; UrlAnalyzer.prototype.getNowPageType = function(){ return this.getPageType(this.getNowUrl()); } UrlAnalyzer.prototype.changeNumber = function(url){ if(this.inArticlePage()){ return url; }else{ var parts = url.split("/"); var last = parts.pop(); var lastParts = last.split("-"); var lastNum = lastParts.shift(); var lastTail = lastParts.join("-"); var base = parts.join("/"); var nowNum = this.getNowUrl().split("/").pop().split("-")[0]; var newUrl = base + "/" + nowNum + "-" + lastTail; return newUrl; } } //-----ResCollection----- function ResCollection(ana){ if(ana === undefined){ this.urlAnalyzer = new UrlAnalyzer(); }else{ this.urlAnalyzer = ana; } } ResCollection.prototype.createResList = function(dl){ dl.find("dt").each(function(){ var self = $(this); self.attr("data-number", self.find("a").eq(0).attr("name")); self.attr("data-name", self.find(".st-bbs_name").text()); var id = self.text().split(":"); id = id[id.length - 1].split("["); id = id[0]; self.attr("data-id", $.trim(id)); }); var resheads = dl.find("dt"); var resbodies = dl.find("dd"); this.resList = new Array(resheads.size()); for(var i = 0; i < resheads.size(); i++){ this.resList[i] = new Res(resheads.eq(i), resbodies.eq(i), this.urlAnalyzer); } }; ResCollection.prototype.createResListById = function(){ this.resListById = {}; for(var i = 0; i < this.resList.length; i++){ if(!this.resListById[$(this.resList[i].reshead).attr("data-id")]){ this.resListById[$(this.resList[i].reshead).attr("data-id")] = []; } this.resListById[$(this.resList[i].reshead).attr("data-id")].push(this.resList[i]); } }; ResCollection.prototype.createResListByNumber = function(){ this.resListByNumber = []; for(var i = 0; i < this.resList.length; i++){ var res = this.resList[i] this.resListByNumber[res.reshead.attr("data-number")] = res; } }; ResCollection.prototype.makeTooltips = function(){ var cannotMakeTooltip = !GM_getValue("tooltipOnDicPage") && this.urlAnalyzer.inArticlePage(); for(var i = 0; i < this.resList.length; i++){ this.resList[i].makeIDDiv(this.resListById, !cannotMakeTooltip); this.resList[i].makeNumberDiv(this.resList); if(cannotMakeTooltip){ continue; } if(GM_getValue("showIDTooltip")){ this.resList[i].makeIDTooltip(this.resListById); } if(GM_getValue("showResAnchorTooltip")){ this.resList[i].makeNumTooltip(this.resListByNumber); } if(GM_getValue("showResNumberTooltip")){ this.resList[i].makeLinkedNumberTooltip(); } if(GM_getValue("showResHandleTooltip")){ this.resList[i].makeNumberHandleTooltip(this.resListByNumber); } } }; ResCollection.prototype.showRes = function(){ var dl = $(".st-bbs-contents dl"); for(var i = 0; i < this.resList.length; i++){ dl.append(this.resList[i].reshead); dl.append(this.resList[i].resbody); } }; ResCollection.prototype.revivalAllRes = function(){ for(var i = 0; i < this.resList.length; i++){ if(this.resList[i].reshead.hasClass("deleted")){ this.resList[i].reshead.removeClass("deleted").find(".name").html(this.resList[i].trueReshead.attr("data-name"));//ここで.nameと.tripが一緒になる。.tripを個別に処理する場合は修正すること this.resList[i].resbody.html("").append(this.resList[i].trueResbody.clone(true).contents()).removeClass("deleted"); } } }; ResCollection.prototype.setContextMenu = function(){ for(var i = 0; i < this.resList.length; i++){ this.resList[i].reshead.find(".ID, .IDMulti, .IDMany").unbind("click").click(function(e){ $(this).parent(".st-bbs_resInfo").append($("#contextMenu").css({left : e.pageX, top : e.pageY}).show()); e.stopPropagation(); }); } $("html").unbind("click").click(function(){ $("#contextMenu").hide(); }); }; //-----Res----- function Res(reshead, resbody, ana){ this.reshead = reshead; this.resbody = resbody; if(ana === undefined){ this.urlAnalyzer = new UrlAnalyzer(); }else{ this.urlAnalyzer = ana; } }; Res.prototype.backupRes = function(){ this.trueReshead = this.reshead.clone(true); this.trueResbody = this.resbody.clone(true); } Res.prototype.makeIDDiv = function(resListById){ var reflectSameId = GM_getValue("classificationID") && (GM_getValue("tooltipOnDicPage") || !this.urlAnalyzer.inArticlePage()); var addOrdinalAndTotal = function(res, sameIDRes){ if(reflectSameId){ return "[" + (sameIDRes.indexOf(res) + 1) + "/" + sameIDRes.length + "]" }else{ return ""; } } var insertFractionIntoDiv = function(html, fraction){ return html.replace('</div>', fraction + '</div>') } var sameIDRes = resListById[this.reshead.attr("data-id")]; if(reflectSameId){ var addIDMulti = "IDMulti"; var addIDMany = "IDMany"; }else{ var addIDMulti = "ID"; var addIDMany = "ID"; } if(this.reshead.find(".ID, .IDMulti, .IDMany").size() === 0){ var s = this.reshead.html().split(":"); if(sameIDRes.length == 1){ s[s.length - 2] = s[s.length - 2].replace("ID", "<div class='ID'>ID</div>"); }else if(sameIDRes.length < 5){ s[s.length - 2] = s[s.length - 2].replace("ID", "<div class='" + addIDMulti + "'>ID</div>"); s[s.length - 1] = insertFractionIntoDiv(s[s.length - 1], addOrdinalAndTotal(this, sameIDRes)); }else{ s[s.length - 2] = s[s.length - 2].replace("ID", "<div class='" + addIDMany + "'>ID</div>"); s[s.length - 1] = insertFractionIntoDiv(s[s.length - 1], addOrdinalAndTotal(this, sameIDRes)); } this.reshead.html(s.join(":")); }else if(this.reshead.find(".ID").size() !== 0){ if(sameIDRes.length == 1){ }else if(sameIDRes.length < 5){ this.reshead.find(".ID, .IDMulti, .IDMany").removeClass("ID IDMulti IDMany").addClass(addIDMulti); var s = this.reshead.html().split(":"); s[s.length - 1] = insertFractionIntoDiv(s[s.length - 1], addOrdinalAndTotal(this, sameIDRes)); this.reshead.html(s.join(":")); }else{ this.reshead.find(".ID, .IDMulti, .IDMany").removeClass("ID IDMulti IDMany").addClass(addIDMany); var s = this.reshead.html().split(":"); s[s.length - 1] = insertFractionIntoDiv(s[s.length - 1], addOrdinalAndTotal(this, sameIDRes)); this.reshead.html(s.join(":")); } }else{ if(sameIDRes.length < 5){ this.reshead.find(".ID, .IDMulti, .IDMany").removeClass("ID IDMulti IDMany").addClass(addIDMulti); var s = this.reshead.html().split("["); s[s.length - 1] = addOrdinalAndTotal(this, sameIDRes); this.reshead.html(s.join("")); }else{ this.reshead.find(".ID, .IDMulti, .IDMany").removeClass("ID IDMulti IDMany").addClass(addIDMany); var s = this.reshead.html().split("["); s[s.length - 1] = addOrdinalAndTotal(this, sameIDRes); this.reshead.html(s.join("")); } } } Res.prototype.makeNumberDiv = function(resList){ this.linkedResponds = []; var myNumber = this.reshead.attr("data-number") - 0; for(var i = 0; i < resList.length; i++){ var numberAnchorsWrapset = resList[i].resbody.find("a.dic"); var numberAnchors = []; if(numberAnchorsWrapset.size() !== 0){ numberAnchorsWrapset.each(function(){ numberAnchors.push($(this).html().split(">").join("")); }); }else{ continue; } for(var j = 0; j < numberAnchors.length; j++){ var num = numberAnchors[j]; if(num.indexOf("-") === -1 && myNumber === num - 0){ this.linkedResponds.push(resList[i]); break; }else if(num.indexOf("-") !== -1){ num = num.split("-"); if(num[0] <= myNumber && myNumber <= num[1]){ this.linkedResponds.push(resList[i]); break; } } } } this.reshead.find("div.Number, div.NumberMulti, div.NumberMany").contents().unwrap(); if(this.linkedResponds.length === 0){ }else if(!GM_getValue("classificationResNumber") || this.linkedResponds.length === 1){ this.reshead.find('.st-bbs_resNo').html("<div class='Number'>" + this.reshead.find('.st-bbs_resNo').html() + "</div>") }else if(this.linkedResponds.length <= 3){ this.reshead.find('.st-bbs_resNo').html("<div class='NumberMulti'>" + this.reshead.find('.st-bbs_resNo').html() + "</div>") }else{ this.reshead.find('.st-bbs_resNo').html("<div class='NumberMany'>" + this.reshead.find('.st-bbs_resNo').html() + "</div>") } } Res.prototype.makeIDTooltip = function(resListById){ var sameIDRes = resListById[this.reshead.attr("data-id")]; var divID = this.reshead.find("div[class^='ID']"); var that = this; divID.unbind("mouseenter").unbind("mouseleave").hover(function(){ var tooltip = $("<div></div>").click(function(e){e.stopPropagation();}); for(var i = 0; i < sameIDRes.length; i++){ tooltip.append(sameIDRes[i].reshead.clone().find("a").removeAttr("id").end()); tooltip.append(sameIDRes[i].resbody.clone().find("a").removeAttr("id").end()); } divID.append(tooltip); divID.focus(); that.adjustHeightOfTooltip(tooltip); }, function(){ divID.find("div").remove(); }); }; Res.prototype.makeNumTooltip = function(resListByNumber){ var that = this; this.resbody.find(".numTooltip > a.dic").unwrap(); this.resbody.find("a.dic").filter(function(){return $(this).html().indexOf(">>") !== -1}).each(function(){ var self = $(this); var num = self.html().split(">").join("").split("-"); for(var i = 0; i < num.length; i++){ num[i] = num[i] - 0; } self.wrap("<span class='numTooltip'></span>").parent().unbind("mouseenter").unbind("mouseleave").hover(function(){ var self = $(this); var tooltip = $("<div></div>"); if(num.length === 1 || !num[1]){ var res = resListByNumber[num[0]]; if(res === undefined){ return; } var cloneBody = res.resbody.clone(); cloneBody.find(".numTooltip > a.dic").unwrap(); tooltip.append(res.reshead.clone().find("a").removeAttr("id").end()); tooltip.append(cloneBody.find("a").removeAttr("id").end()); }else{ for(var i = num[0]; i <= num[1]; i++){ var res = resListByNumber[i]; if(res === undefined){ continue; } var cloneBody = res.resbody.clone(); cloneBody.find(".numTooltip > a.dic").unwrap(); tooltip.append(res.reshead.clone().find("a").removeAttr("id").end()); tooltip.append(cloneBody.find("a").removeAttr("id").end()); } if(tooltip.html() === $("<div></div>").html()){ return; } } self.append(tooltip); self.focus(); that.adjustHeightOfTooltip(tooltip); }, function(){ $(this).find("div").remove(); }); }); }; Res.prototype.makeLinkedNumberTooltip = function(){ var divNumber = this.reshead.find("div[class^='Number']"); var linkedResponds = this.linkedResponds; var that = this; divNumber.unbind("mouseenter").unbind("mouseleave").hover(function(){ var tooltip = $("<div></div>").click(function(e){e.stopPropagation();}); for(var i = 0; i < linkedResponds.length; i++){ tooltip.append(linkedResponds[i].reshead.clone().find("a").removeAttr("id").end()); tooltip.append(linkedResponds[i].resbody.clone().find("a").removeAttr("id").end()); } divNumber.append(tooltip); divNumber.focus(); that.adjustHeightOfTooltip(tooltip); }, function(){ divNumber.find("div").remove(); }); } Res.prototype.makeNumberHandleTooltip = function(resListByNumber){ var nameSpan = this.reshead.find(".st-bbs_name"); var name = nameSpan.html(); var transformedName = name.replace(/[0123456789]/g, function(c){return "0123456789".indexOf(c);}); var that = this; if(/^[0-9]+$/.test(transformedName)){ nameSpan.wrap("<span class='NumberHandle'></span>").parent().unbind("mouseenter").unbind("mouseleave").hover(function(){ var self = $(this); var tooltip = $("<div></div>"); var res = resListByNumber[transformedName]; if(res === undefined){ return; } tooltip.append(res.reshead.clone().find("a").removeAttr("id").end()); tooltip.append(res.resbody.clone().find("a").removeAttr("id").end()); self.append(tooltip); self.focus(); that.adjustHeightOfTooltip(tooltip); }, function(){ $(this).find("div").remove(); }); } } Res.prototype.adjustHeightOfTooltip = function(tooltip){ var a = $("html").scrollTop() + $("#topline").height(); var b = tooltip.offset().top; var c = $(window).height() - $("#topline").height(); var d = tooltip.height(); if(a < b && b < a + c && a < b + d && b + d < a + c){ }else if(d < c){ if(b > a){ tooltip.offset({top : (a + c - d) }); }else{ tooltip.offset({top : a}); } }else{ tooltip.offset({top : a}); tooltip.height(c - $("#topline").height()); } }; //-----NgOperator----- function NgOperator(ana){ this.ngList = {}; this.ngList.ngid = []; this.ngList.ngname = []; this.ngList.ngword = []; this.ngList.ngres = []; if(ana === undefined){ this.urlAnalyzer = new UrlAnalyzer(); }else{ this.urlAnalyzer = ana; } } NgOperator.prototype.initNg = function(){ this.ngList = {}; this.ngList.ngidText = removeUselessLines(GM_getValue("ngid")); if(this.ngList.ngidText){ this.ngList.ngid = this.ngList.ngidText.split("\n"); for(var i = 0; i < this.ngList.ngid.length; i++){ this.ngList.ngid[i] = $.trim(this.ngList.ngid[i]); } }else{ this.ngList.ngid = []; } this.ngList.ngnameText = removeUselessLines(GM_getValue("ngname")); if(this.ngList.ngnameText){ this.ngList.ngname = this.ngList.ngnameText.split("\n"); for(var i = 0; i < this.ngList.ngname.length; i++){ this.ngList.ngname[i] = $.trim(this.ngList.ngname[i]); } }else{ this.ngList.ngname = []; } this.ngList.ngwordText = removeUselessLines(GM_getValue("ngword")); if(this.ngList.ngwordText){ this.ngList.ngword = this.ngList.ngwordText.split("\n"); for(var i = 0; i < this.ngList.ngword.length; i++){ this.ngList.ngword[i] = $.trim(this.ngList.ngword[i]); } }else{ this.ngList.ngword = []; } this.ngList.ngresText = removeUselessLines(GM_getValue("ngres")); if(this.ngList.ngresText){ this.ngList.ngres = this.ngList.ngresText.split("\n"); for(var i = 0; i < this.ngList.ngres.length; i++){ this.ngList.ngres[i] = $.trim(this.ngList.ngres[i]); } }else{ this.ngList.ngres = []; } }; NgOperator.prototype.applyNg = function(resList){ for(var i = 0; i < resList.length; i++){ var r = resList[i]; var applied = false; if(GM_getValue("useNG")){ var id = r.trueReshead.attr("data-id"); var name = r.trueReshead.attr("data-name"); for(var j = 0; !applied && j < this.ngList.ngid.length; j++){ if(this.ngList.ngid[j] === id){ applied = true; } } for(var j = 0; !applied && j < this.ngList.ngname.length; j++){ if(name.indexOf(this.ngList.ngname[j]) !== -1){ applied = true; } } for(var j = 0; !applied && j < this.ngList.ngword.length; j++){ if(r.trueResbody.text().indexOf(this.ngList.ngword[j]) !== -1){ applied = true; } } for(var j = 0; !applied && j < this.ngList.ngres.length; j++){ var ngres = this.ngList.ngres[j].split(":"); var number = ngres.pop(); var URL = ngres.join(":"); if(this.urlAnalyzer.isPageOf(URL) && r.reshead.attr("data-number") == number){ applied = true; } } } if(applied){ $("#contextMenu").insertAfter("#ng"); r.reshead.find(".name").html("削除しました"); r.reshead.find(".trip").remove(); r.reshead.addClass("deleted"); r.resbody.html("削除しました").addClass("deleted"); }else if(r.reshead.hasClass("deleted")){ r.reshead.removeClass("deleted").find(".name").html(r.trueReshead.attr("data-name"));//ここで.nameと.tripが一緒になる。.tripを個別に処理する場合は修正すること r.resbody.html("").append(r.trueResbody.clone(true).contents()).removeClass("deleted"); } var css = $("#nicoDicBBSViewerCSS"); if(GM_getValue("seethroughNG")){ if(css.html().indexOf("deleted") === -1){ css.html(css.html() + ".deleted{display:none;}"); } }else{ if(css.html().indexOf("deleted") !== -1){ css.html(css.html().replace(".deleted{display:none;}", "")); } } } }; //-----MenuOperator----- function MenuOperator(resCollection, ngOperator){ this.resCollection = resCollection; this.ngOperator = ngOperator; this.urlAnalyzer = new UrlAnalyzer(); this.bbsScroll = 0; }; MenuOperator.prototype.bindContextMenu = function(){ var self = this; $("#ngidMenu").click(function(){ $("#contextMenu").hide(); if($(this).parents(".st-bbs_reshead").hasClass("deleted")){ return false; } var id = $(this).parents(".st-bbs_reshead").attr("data-id"); var gm_ngid = GM_getValue("ngid") ? GM_getValue("ngid") : ""; var ngidText = gm_ngid + "\n" + id; ngidText = removeUselessLines(ngidText); $("#ngidTextarea").val(ngidText); GM_setValue("ngid", ngidText); self.ngOperator.initNg(); self.ngOperator.applyNg(self.resCollection.resList); }); $("#ngnameMenu").click(function(){ $("#contextMenu").hide(); if($(this).parents(".st-bbs_reshead").hasClass("deleted")){ return false; } var name = $(this).parents(".st-bbs_reshead").attr("data-name"); var gm_ngname = GM_getValue("ngname") ? GM_getValue("ngname") : ""; var ngnameText = gm_ngname + "\n" + name; ngnameText = removeUselessLines(ngnameText); $("#ngnameTextarea").val(ngnameText); GM_setValue("ngname", ngnameText); self.ngOperator.initNg(); self.ngOperator.applyNg(self.resCollection.resList); }); $("#ngresMenu").click(function(){ $("#contextMenu").hide(); if($(this).parents(".st-bbs_reshead").hasClass("deleted")){ return false; } var number = $(this).parents(".st-bbs_reshead").attr("data-number"); var gm_ngresText = GM_getValue("ngres") ? GM_getValue("ngres") : ""; var pageName = self.urlAnalyzer.getNowPageName(); var ngresText = gm_ngresText + "\n" + pageName + ":" + number; ngresText = removeUselessLines(ngresText); $("#ngresTextarea").val(ngresText); GM_setValue("ngres", ngresText); self.ngOperator.initNg(); self.ngOperator.applyNg(self.resCollection.resList); }); }; MenuOperator.prototype.insertConfigHtml = function(){ var self = this; var appendNgTextarea = function(labelcore, idcore){ var text = ""; text = text + '<div style="float:left; width:24%"><p>改行で区切って' + labelcore + 'を入力or削除してください。</p>'; text = text + '<textarea id="' + idcore + 'Textarea" cols="20" rows="10" placeholder="' + labelcore + 'を改行で区切って入力してください。">'; text = text + (GM_getValue(idcore) ? GM_getValue(idcore) : ""); text = text + '</textarea></div>'; $("#ng").append(text); } var appendConfigLi = function(parent, id, label){ var text = ""; text = text + '<li><input id="' + id + 'Checkbox" type="checkbox" ' + (GM_getValue(id) ? "checked = 'checked'" : "") + '/>' + label + '</li>'; parent.append(text); } var appendSubList = function(parent, list, label){ var li = $("<li>" + label + "</li>"); li.append(list); parent.append(li); } var getSubUl = function(){ return $('<ul style="list-style-type: none; margin-left:5px;"></ul>'); } $("#topbarLogoutMenu").after('<li>NicoDicBBSViewer</li><li id="bbsLi" class="selected"><a href="#">掲示板を表示する</a></li><li id="ngLi"><a href="#">設定画面を表示する</a></li>'); $(".st-bbs-contents").after('<div id="ng"></div>'); appendNgTextarea("NGID", "ngid"); appendNgTextarea("NGName", "ngname"); appendNgTextarea("NGワード", "ngword"); appendNgTextarea("NGレスを(BBSのURL:レス番号)の書式で", "ngres"); $("#ng").append('<div style="clear:left;"><form><ul style="list-style-type: none;"></ul></form><div>'); var parentUl = $("#ng form ul"); //appendConfigLi(parentUl, "addToOnePage", '一つのページに継ぎ足す(更新時有効)'); //appendConfigLi(parentUl, "autoLoad", "下までスクロールした時に次のページを読み込む"); var ngUl = getSubUl(); appendConfigLi(ngUl, "useNG", "NG機能を使用する"); appendConfigLi(ngUl, "seethroughNG", "NGが適用されたレスを表示しない"); appendSubList(parentUl, ngUl, "NG機能"); appendConfigLi(parentUl, "tooltipOnDicPage", "記事ページでもID、番号の色分けやツールチップを表示する"); var tooltipUl = getSubUl(); appendConfigLi(tooltipUl, "showIDTooltip", 'ID(<span style="text-decoration:underline;">ID</span>)ツールチップを表示する'); appendConfigLi(tooltipUl, "showResAnchorTooltip", 'レスアンカー(<span style="color: rgb(0, 102, 204);">>>1</span>)ツールチップを表示する'); appendConfigLi(tooltipUl, "showResNumberTooltip", 'レス番(<span style="text-decoration:underline;">1</span>)ツールチップを表示する'); appendConfigLi(tooltipUl, "showResHandleTooltip", 'レス番ハンドル(<span style="color: rgb(0, 136, 0); font-weight: bold;">1</span>)ツールチップを表示する'); appendSubList(parentUl, tooltipUl, "ツールチップ(更新時有効)"); var colorUl = getSubUl(); appendConfigLi(colorUl, "classificationID", "IDを色分けし、そのIDのレスの回数を表示する"); appendConfigLi(colorUl, "classificationResNumber", "参照されているレス番を色分けする"); appendSubList(parentUl, colorUl, "色分け(更新時有効)"); $("#ng").append('<button id="decideNG">保存</button> <button id="cancelNG">キャンセル</button> <button id="backToBbsButton">掲示板に戻る</button></div>' + ' <ul id="contextMenu"><li id="ngidMenu">NGIDに追加</li><li id="ngnameMenu">NGNameに追加</li><li id="ngresMenu">このレスを削除</li></ul>'); }; MenuOperator.prototype.bindMenu = function(){ var self = this; var contents = $(".st-bbs-contents, #ng"); var backBBS = function(){ if($(".selected").attr("id") === "bbsLi"){ self.bbsScroll = $("html").scrollTop(); } $(".selected").removeClass("selected"); $("#bbsLi").addClass("selected"); contents.not(".st-bbs-contents").css("display", "none"); $(".st-bbs-contents").css("display", "block"); $("html").scrollTop(self.bbsScroll); return false; }; $("#bbsLi").click(backBBS); $("#backToBbsButton").click(backBBS); $("#ngLi").click(function(){ if($(".selected").attr("id") === "bbsLi"){ self.bbsScroll = $("html").scrollTop(); } $(".selected").removeClass("selected"); $(this).addClass("selected"); contents.not("#ng").css("display", "none"); $("#ng").css("display", "block"); $("html").scrollTop($("#ng").offset().top - $("#topline").height()); return false; }); var setcbConfig = function(id){ GM_setValue(id, $("#" + id + "Checkbox").is(":checked")); } var checkcbConfig = function(id){ if(GM_getValue(id)){ $("#" + id + "Checkbox").attr("checked", true); }else{ $("#" + id + "Checkbox").attr("checked", false); } } $("#decideNG").click(function(){ GM_setValue("ngid", $("#ngidTextarea").val()); GM_setValue("ngname", $("#ngnameTextarea").val()); GM_setValue("ngword", $("#ngwordTextarea").val()); GM_setValue("ngres", $("#ngresTextarea").val()); setcbConfig("seethroughNG"); setcbConfig("loadAll"); setcbConfig("addToOnePage"); setcbConfig("autoLoad"); setcbConfig("useNG"); setcbConfig("tooltipOnDicPage"); setcbConfig("showIDTooltip"); setcbConfig("showResAnchorTooltip"); setcbConfig("showResNumberTooltip"); setcbConfig("showResHandleTooltip"); setcbConfig("classificationID"); setcbConfig("classificationResNumber"); setcbConfig("switcherInTopMenu"); self.ngOperator.initNg(); self.ngOperator.applyNg(self.resCollection.resList); }); $("#cancelNG").click(function(){ $("#ngidTextarea").val(GM_getValue("ngid") ? GM_getValue("ngid") : ""); $("#ngnameTextarea").val(GM_getValue("ngname") ? GM_getValue("ngname") : ""); $("#ngwordTextarea").val(GM_getValue("ngword") ? GM_getValue("ngword") : ""); $("#ngresTextarea").val(GM_getValue("ngres") ? GM_getValue("ngres") : ""); checkcbConfig("seethroughNG"); checkcbConfig("loadAll"); checkcbConfig("addToOnePage"); checkcbConfig("autoLoad"); checkcbConfig("useNG"); checkcbConfig("tooltipOnDicPage"); checkcbConfig("showIDTooltip"); checkcbConfig("showResAnchorTooltip"); checkcbConfig("showResNumberTooltip"); checkcbConfig("showResHandleTooltip"); checkcbConfig("classificationID"); checkcbConfig("classificationResNumber"); checkcbConfig("switcherInTopMenu"); }); }; //-----ManegerToReadBbs----- function ManagerToReadBbs(urls, ana){ if(ana === undefined){ ana = new UrlAnalyzer(); } this.urlAnalyzer = ana; this.bbsUrls = urls; var nowUrl = ana.getNowUrl(); if(!ana.inArticlePage()){ if(nowUrl.indexOf("#") === -1){ this.startIndex = urls.indexOf(nowUrl); }else{ var mainurl = nowUrl.substring(0, nowUrl.indexOf("#")); if(mainurl.indexOf("-") === -1){ mainurl = mainurl + "-"; } this.startIndex = urls.indexOf(mainurl); } } this.endIndex = this.startIndex; this.isNowLoading = false; this.resCollection = new ResCollection(ana); this.ngOperator = new NgOperator(ana); this.menuOperator = new MenuOperator(this.resCollection, this.ngOperator); }; ManagerToReadBbs.prototype.readPreviousBbs = function(){ if(this.isNowLoading || this.startIndex <= 0){ return; } $("#bbsmain").prepend("<p id='loading'>now loading...</p>"); this.isNowLoading = true; this.startIndex--; var self = this; $.get(this.bbsUrls[this.startIndex], function(r){ self.prependBbs($(r).find("dl")); }); if(this.startIndex === 0){ $("#loadPreviousPageLinks").remove(); } }; ManagerToReadBbs.prototype.prependBbs = function(dl){ this.resCollection.revivalAllRes(); $(".st-bbs-contents dl").prepend(dl.contents()); this.createAndSetResList(); $("#loading").remove(); this.isNowLoading = false; }; ManagerToReadBbs.prototype.readNextBbs = function(){ if(this.isNowLoading || this.endIndex >= this.bbsUrls.length - 1){ return; } $("#bbsmain").append("<p id='loading'>now loading...</p>"); this.isNowLoading = true; this.endIndex++; var self = this; $.get(this.bbsUrls[this.endIndex], function(r){ self.appendBbs($(r).find("dl")); }); if(this.endIndex === this.bbsUrls.length - 1){ $("#loadNextPageLinks").remove(); } }; ManagerToReadBbs.prototype.appendBbs = function(dl){ this.resCollection.revivalAllRes(); $(".st-bbs-contents dl").append(dl.contents()); this.createAndSetResList(); $("#loading").remove(); this.isNowLoading = false; }; ManagerToReadBbs.prototype.initSmallBbs = function(){ this.initPager(); this.ngOperator.initNg(); this.createAndSetResList(); this.menuOperator.insertConfigHtml(); this.menuOperator.bindMenu(); this.menuOperator.bindContextMenu(); }; ManagerToReadBbs.prototype.initPager = function(){ return if(!GM_getValue("addToOnePage")){ return; } var pager = $(".st-bbs-contents .pager"); var self = this; if(this.urlAnalyzer.inArticlePage()){ pager.find(".navi").remove(); }else{ pager.eq(0).find("a:not(:first), .current, span").remove(); if(this.startIndex > 0){ pager.eq(0).append("<a id='loadPreviousPageLinks' href='#'>前へ</a>"); pager.find("#loadPreviousPageLinks").click(function(){self.readPreviousBbs(); return false;}); } pager.eq(1).find("a:not(:first), .current, span").remove(); if(this.endIndex < this.bbsUrls.length - 1){ pager.eq(1).append("<a id='loadNextPageLinks' href='#'>次へ</a>"); pager.find("#loadNextPageLinks").click(function(){self.readNextBbs(); return false;}); } } }; ManagerToReadBbs.prototype.scrollLoader = function(){ this.reserved = false; var self = this; setInterval(function(){ if(self.reserved){ self.reserved = false; self.readNextBbs(); } }, 1000); $(window).scroll(function(){ if($(".selected").attr("id") === "bbsLi" && GM_getValue("autoLoad") && $("html").scrollTop() + $(window).height() > $("#bbsmain").position().top + $("#bbsmain").height()){ self.reserved = true; } }); }; ManagerToReadBbs.prototype.createAndSetResList = function(){ this.resCollection.createResList($(".st-bbs-contents dl")); this.resCollection.createResListById(); this.resCollection.createResListByNumber(); this.resCollection.makeTooltips(); this.resCollection.setContextMenu(); var resList = this.resCollection.resList; for(var i = 0; i < resList.length; i++){ resList[i].backupRes(); } this.ngOperator.applyNg(resList); }; //-----単体の関数----- var removeUselessLines = function(s){ if(!s){ return; } var lines = s.split("\n"); var storage = {}; for(var i = 0; i < lines.length;){ if(!lines[i] || lines[i] in storage){ lines.splice(i, 1); }else{ storage[lines[i]] = 0; i++; } } return lines.join("\n"); }; var initConfig = function(ids){ for(var i = 0; i < ids.length; i++){ if(GM_getValue(ids[i]) === undefined){ GM_setValue(ids[i], true); } } } var insertStyle = function(){ var idStyle = ".ID{text-decoration:underline; color:black; display:inline;} .IDMulti{text-decoration:underline; color:blue; display:inline;}" + ".IDMany{text-decoration:underline; color:red; display:inline;}"; var numberStyle = ".Number{text-decoration: underline; display:inline;} .NumberMulti{text-decoration: underline; display:inline; color:blue;}" + ".NumberMany{text-decoration: underline; display:inline; color:red;}"; var insideTooltipStyle = ".dic{display:inline;}"; var onMouseIdStyle = ".ID:hover, .IDMulti:hover, .IDMany:hover, .dic:hover{text-decoration:none;}"; var defaultTooltipStyle = ".ID>div, .IDMulti>div, .IDMany>div, .dic>div, .Number>div, .NumberMulti>div, .NumberMany>div, .NumberHandle>div{display:none;}"; var onMouseTooltipStyle = ".ID:hover>div, .IDMulti:hover>div, .IDMany:hover>div, .numTooltip:hover>div," + " .Number:hover>div, .NumberMulti:hover>div, .NumberMany:hover>div, .NumberHandle:hover>div" + "{color:black; display:inline; position:absolute; background:#f5f5b5; border:solid black 1px; padding;5px; font-size:8pt; overflow:auto;" + " box-shadow:1px 1px; z-index:10000;font-weight:normal;}"; var leftboxStyle = "div.left-box{border: groove 1px gray; border-radius: 5px; background-image:none;}"; var ngStyle = "#ng{display:none;}"; var hideMenu = "#topbarRightMenu #bbsLi.selected,#topbarRightMenu #ngLi.selected{display:none;}"; var sidemenu = "ul#sidemenu li{border:solid 1px; width:100px;} ul#sidemenu li.selected{color:red;}"; var contextMenuStyle = "#contextMenu{background : #d4d0c8;color : #000000;display : none;position : absolute;list-style : none; padding-left : 0px;box-shadow : 1px 1px;}"; var contextItemStyle = "#contextMenu li{padding : 3px;}#contextMenu li:hover{background : #0a246a;color : #ffffff;}"; var styleTag = "<style id='nicoDicBBSViewerCSS' type='text/css'>" + idStyle + numberStyle + insideTooltipStyle + onMouseIdStyle + defaultTooltipStyle + onMouseTooltipStyle + leftboxStyle + ngStyle + hideMenu + sidemenu + contextMenuStyle + contextItemStyle + "</style>"; $("link").last().after($(styleTag)); }; var counterAutopagerize = function(){ $(document).bind("AutoPagerize_DOMNodeInserted", function(){ $("[class^='autopagerize'] , dl:not(#bbsmain) , #autopagerize_message_bar").remove(); }); }; //以下main var main = function(ana){ initConfig(["useNG", "tooltipOnDicPage", "showIDTooltip", "showResAnchorTooltip", "showResNumberTooltip", "showResHandleTooltip", "classificationID", "classificationResNumber"]); insertStyle(); $(".st-bbs-contents dl").attr("id", "bbsmain"); $(".border").remove(); if(ana === undefined){ var urlAnalyzer = new UrlAnalyzer(); }else{ var urlAnalyzer = ana; } var manager = new ManagerToReadBbs(urlAnalyzer.getBBSURLs($(".st-bbs-contents .pager").eq(0)), urlAnalyzer); manager.initSmallBbs(); counterAutopagerize(); //if(!urlAnalyzer.inArticlePage()){ // manager.scrollLoader(); //} }; //-----test用----- var c = net_threeaster_NicoDicBBSViewer; c.removeUselessLines = removeUselessLines; c.Res = Res; c.ManagerToReadBbs = ManagerToReadBbs; c.initConfig = initConfig; c.insertStyle = insertStyle; c.UrlAnalyzer = UrlAnalyzer; c.ResCollection = ResCollection; c.NgOperator = NgOperator; c.MenuOperator = MenuOperator; c.main = main; //-----main実行/テスト時には途中で止まる----- if(typeof GM_getValue === 'function'){ main(); } })(jQuery);