您需要先安装一个扩展,例如 篡改猴、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);