Greasy Fork

ニコニコ除ニコレポEx

ニコレポをフィルタリングします

当前为 2018-10-14 提交的版本,查看 最新版本

// ==UserScript==
// @name         ニコニコ除ニコレポEx
// @namespace    https://greasyfork.org/users/175598
// @description  ニコレポをフィルタリングします
// @match        https://www.nicovideo.jp/my/top
// @match        https://www.nicovideo.jp/my/top/*
// @match        https://www.nicovideo.jp/user/*
// @match        http://www.nicovideo.jp/my/top
// @match        http://www.nicovideo.jp/my/top/*
// @match        http://www.nicovideo.jp/user/*
// @grant        none
// @author       Original by Fushihara,Modded by Boyu
// @license      Creative Commons Zero 1.0 Universal
// @version      2018.10.14
// ==/UserScript==
// Original by Fushihara:https://github.com/fushihara/nico-repo

(function(){
    var localStorageKey="niconicoRemoveNicorepoEx_modBoyu";
    // cssに付ける接頭語
    var IdPrefix="niconicoRemoveNicorepoEx_modBoyu_";
    // UIのバージョン数
    var UIversion=180606;
    // styleに追加するスタイルシート
    var myStyle=`
a#${IdPrefix}a_toggle_button[data-openflag="false"] + div {
    display:none;
}
a#${IdPrefix}a_toggle_button > span ~ span {
    display: inline;
    background: rgba(0, 0, 0, 0);
    width: auto;
    font-size: 11px;
    color: red;
    background-color: white;
    border-radius: 6px;
    padding: 0px 3px;
    font-weight: bold;
}
a#${IdPrefix}a_toggle_button + div {
    overflow:hidden;
    font-weight:normal;
    display:block;
}
a#${IdPrefix}a_toggle_button + div > button {
    float:right;
}
a#${IdPrefix}a_toggle_button + div > div {
    overflow:hidden;
    clear:right;
}
a#${IdPrefix}a_toggle_button + div > div > label {
    line-height:2.0em;
    color:black;
    padding:1px 8px 1px 5px;
    border-radius:10px;
    display:block;
    float:left;
    margin:5px 3px;
    background:#C7C7C7;
    background:linear-gradient(white,#8F8F8F);
}
a#${IdPrefix}a_toggle_button + div > div > label[data-checkflag="true"] {
    background:#8EFFFF;
    background:linear-gradient(white 25%,#1DFFFF);
}`;
    var init=function(){
        if(document.querySelector(`#nicorepo`)){
            load();
            contentsSet();
            initQ(document.querySelector(`#nicorepo > [id$="PageNicorepoApp"]`));
            addStyle();
            addToggleQ(document.querySelector(`#nicorepo > h3`));
            setToggleArea(document.querySelector(`#nicorepo > h3`));
        }
    };
    //ローカルストレージ
    var checkSave={};
    var SetcheckSave=function(Id,flag){
        checkSave[Id]=(flag=="true");
    };
    var GetcheckSave=function(Id){
        return (Id in checkSave)?checkSave[Id]:true;
    };
    var save=function(){
        var savePat=JSON.stringify(checkSave);
        localStorage.setItem(localStorageKey,savePat);
    };
    var load=function(){
        var savePat={};
        savePat=localStorage.getItem(localStorageKey);
        savePat=JSON.parse(savePat);
        if(savePat!==null){
            checkSave=savePat;
        }
    };
    //contentsの追加
    //参考:http://nicovideo.cdn.nimg.jp/uni/scripts/pages/my/nicorepo/message/ja-jp.js
    var contentsSet=function(){
        contentsAdd("nicovideo_user_video_upload"                        ,1,"動画を投稿"            );
        contentsAdd("nicovideo_user_video_kiriban_play"                  ,1,"再生数達成"            );
        contentsAdd("nicovideo_user_video_update_highest_rankings"       ,1,"ランキング達成"          );
        contentsAdd("nicovideo_user_video_live_introduce"                ,1,"生放送で紹介"           );
        contentsAdd("nicoad_user_advertised_video_announce"              ,1,"広告された"            );
        contentsAdd("nicoad_user_advertise_video"                        ,1,"広告した"             );
        contentsAdd("nicovideo_user_community_member_only_video_upload"  ,1,"コミュニティ専用動画を投稿"    );
        contentsAdd("nicoseiga_user_illust_upload"                       ,1,"イラストを投稿"          );
        contentsAdd("nicoseiga_user_illust_clip"                         ,1,"イラストをクリップ"        );
        contentsAdd("nicoseiga_user_manga_episode_upload"                ,1,"マンガを投稿"           );
        contentsAdd("nicoseiga_user_manga_content_favorite"              ,1,"マンガをお気に入り登録"      );
        contentsAdd("nicovideo_user_nicogame_upload"                     ,1,"ゲームを投稿"           );
        contentsAdd("nicovideo_user_nicogame_update"                     ,1,"ゲームを更新"           );
        contentsAdd("nicovideo_user_blomaga_upload"                      ,1,"記事を投稿"            );
        contentsAdd("nicovideo_user_solid_upload"                        ,1,"立体を投稿"            );
        contentsAdd("nicovideo_user_solid_distribute"                    ,1,"立体の配布データを公開"      );
        contentsAdd("nicovideo_user_solid_update"                        ,1,"立体の配布データを更新"      );
        contentsAdd("nicovideo_user_solid_favorite"                      ,1,"立体をお気に入り登録"       );
        contentsAdd("nicovideo_user_knowledge_upload"                    ,1,"ナレッジを投稿"          );
        contentsAdd("nicovideo_user_app_install"                         ,1,"アプリを開始"           );
        contentsAdd("nicovideo_user_stamp_obtain"                        ,1,"スタンプを取得"          );
        contentsAdd("nicovideo_user_followed_announce"                   ,1,"あなたをフォロー"         );
        contentsAdd("nicovideo_user_mylist_followed_announce"            ,1,"あなたのマイリストをフォロー"   );
        contentsAdd("nicovideo_user_mylist_add_video"                    ,1,"動画をマイリスト登録"       );
        contentsAdd("nicovideo_user_mylist_add_manga_episode"            ,1,"マンガをマイリスト登録"      );
        contentsAdd("nicovideo_user_mylist_add_book"                     ,1,"書籍をマイリスト登録"       );
        contentsAdd("nicovideo_user_mylist_add_blomaga_article"          ,1,"ブロマガをマイリスト登録"     );
        contentsAdd("nicovideo_user_temporary_mylist_add_video"          ,1,"動画をとりあえずマイリスト登録"  );
        contentsAdd("nicovideo_user_temporary_mylist_add_manga_episode"  ,1,"マンガをとりあえずマイリスト登録" );
        contentsAdd("nicovideo_user_temporary_mylist_add_book"           ,1,"書籍をとりあえずマイリスト登録"  );
        contentsAdd("nicovideo_user_temporary_mylist_add_blomaga_article",1,"ブロマガをとりあえずマイリスト登録");
        contentsAdd("nicovideo_user_video_advertised_announce"           ,1,"広告された(旧式)"         );
        contentsAdd("nicovideo_user_video_advertise"                     ,1,"広告した(旧式)"          );
        contentsAdd("nicoad_user_advertised_program_announce"            ,1,"生放送が広告された"        );
        contentsAdd("nicoad_user_advertise_program"                      ,1,"生放送を広告した"         );
        contentsAdd("live_user_program_cas_onairs"                       ,1,"nicocasを開始"           );
        contentsAdd("nicoad_user_advertised_program_cas_announce"        ,1,"nicocasが広告された"        );
        contentsAdd("nicoad_user_advertise_program_cas"                  ,1,"nicocasを広告した"         );
        contentsAdd("live_user_program_onairs"                           ,2,"生放送を開始"           );
        contentsAdd("live_user_program_reserve"                          ,2,"生放送を予約"           );
        contentsAdd("nicovideo_community_level_raise"                    ,2,"レベル上昇"            );
        contentsAdd("nicovideo_user_community_info_add"                  ,2,"お知らせを追加"          );
        contentsAdd("nicovideo_user_community_video_add"                 ,2,"動画を追加"            );
        contentsAdd("live_channel_program_onairs"                        ,3,"生放送を開始"           );
        contentsAdd("live_channel_program_reserve"                       ,3,"生放送を予約"           );
        contentsAdd("nicovideo_channel_blomaga_upload"                   ,3,"記事を追加"            );
        contentsAdd("nicovideo_channel_info_add"                         ,3,"お知らせを追加"          );
        contentsAdd("nicovideo_channel_video_upload"                     ,3,"動画を追加"            );
        contentsAdd("filter_unknown_pattern"                             ,4,"新パターン"            );
    };
    //切り替え出来る要素 contents={ contentId:{"userType","buttonLabel"} }
    //userType:1=ユーザーが 2=コミュニティが 3=チャンネルが
    var contents={};var contentIdlist=[];
    var contentsAdd=function(contentId,userType,buttonLabel){
        // contentIdが重複してる場合はアラートを出す
        if(contentId in contents){
            alert(`contentsIdが重複しています ${contentId}`);
        }else{
            contentIdlist.push(contentId);
            contents[contentId]={
                userType   :userType,
                buttonLabel:buttonLabel
            };
        }
    };
    //各ニコレポにクラス名を追加
    var initQ=function(observeTarget){
        // ノードが追加された時にイベントを仕込む
        (new MutationObserver(mutationRecords =>
            mutationRecords.forEach(
                //m => {for(let n of m.addedNodes)if(n.nodeName==="SPAN")initializeOneLog(n);}
                ({target:t}) => {if(t.className==="log-body")initializeOneLog(t);}
            )
        )).observe(observeTarget,{childList:true,subtree:true});
        //起動遅延時の保険用
        for(let t of observeTarget.querySelectorAll(`.log-body`))initializeOneLog(t);
    };
    var initializeOneLog=function(bodyElement){
        const baseElement=bodyElement.offsetParent;
        if(baseElement===null)return;
        // bodyからリンクを抽出して解析する
        for(let {href} of bodyElement.querySelectorAll("a")){
            const searchResult=/[?&]_topic=([a-z_]+)/.exec(href);
            if(searchResult && (searchResult[1] in contents)){
                baseElement.id=IdPrefix+searchResult[1];
              //console.log("addedlog-body:"+searchResult[1]);
                return;
            }
        }
        baseElement.id=IdPrefix+"filter_unknown_pattern";
        console.log("ニコニコ除ニコレポEx:新パターン:"+bodyElement.innerHTML);
    };
    //styleタグを追加。ここにどんどん追加していく
    var thisText={};
    var addStyle=function(){
        //セーブされてるスタイル情報を適用する
        const thisStyle=document.createElement("style");
        for(let Id of contentIdlist){
            thisText[Id]=thisStyle.appendChild(document.createTextNode(GetcheckSave(Id)?"":`#${IdPrefix+Id},`));
        }
        thisStyle.insertAdjacentHTML("beforeend",myStyle);
        document.body.appendChild(thisStyle);
    };
    var updateStyle=function(Id,flag){
        thisText[Id].data=(flag=="true")?"":`#${IdPrefix+Id},`;
    };
    //トグルボタンそのものを作る
    var addToggleQ=function(addTarget){
        const toggleButton=document.createElement("a");
        toggleButton.id=IdPrefix+"a_toggle_button";
        toggleButton.innerHTML=`<span></span>表示フィルタリング切り替え${GetShowUpdate()?`<span>更新</span>`:""}`;
        toggleButton.href="http://";
        toggleButton.dataset.openflag="false";
        toggleButton.onclick=({target:This}) => {
            SetShowUpdate();
            This.setAttribute("onclick",`this.dataset.openflag=(this.dataset.openflag!="true");return false;`);
            return This.onclick();
        };
        addTarget.appendChild(toggleButton);
    };
    var GetShowUpdate=function(){
        const version=localStorage.getItem(`${localStorageKey}-last-click-version`) || 1;
        //最後にクリックしたバージョンが、今のバージョンより前だったら表示する
        return (version < UIversion);
    };
    var SetShowUpdate=function(){
        localStorage.setItem(`${localStorageKey}-last-click-version`,UIversion);
    };
    //トグルボタンで表示されるフィルタリング対象切り替えエリアを作る
    var setToggleArea=function(addTarget){
        const toggleArea=document.createElement("div");

        //UserTypeごとのエリアを作る
        let addElementArea=[];
        const addElementAreainnerHTML={
            1:"ユーザーが… or ユーザーが投稿した動画が…",
            2:"コミュニティが…",
            3:"チャンネルが…",
            4:"それ以外の…"
        };
        const toggleUserType=document.createElement("button");
        toggleUserType.innerHTML="全て表示/非表示";
        for(let n=1;n<=4;n++){
            toggleArea.insertAdjacentHTML("beforeend",addElementAreainnerHTML[n]);
            if(n!=4){
                toggleArea.appendChild(toggleUserType.cloneNode(true))
                    .addEventListener("click",toggleUserTypeEvent);
            }
            addElementArea[n]=toggleArea.appendChild(document.createElement("div"));
        }

        //~が…のチェックボックスを作る
        const addElement=document.createElement("label");
        addElement.innerHTML=`<input type="checkbox">`;
        for(let Id of contentIdlist){
            addElement.dataset.checkflag=GetcheckSave(Id);
            addElement.dataset.contentId=Id;
            addElement.firstChild.checked=GetcheckSave(Id);
            addElementArea[contents[Id].userType].appendChild(addElement.cloneNode(true))
                .insertAdjacentHTML("beforeend",contents[Id].buttonLabel);
        }

        //設定保存ボタンを作る
        const toggleSaveButton=document.createElement("button");
        toggleSaveButton.innerHTML="設定保存";
        toggleSaveButton.addEventListener("click",({target:This}) => {
            save();
            This.disabled=true;
        });
        toggleSaveButton.disabled=true;
        toggleArea.appendChild(toggleSaveButton);

        //チェックボックスのイベントを登録する
        toggleArea.addEventListener("change",toggleButtonEvent);
        addTarget.appendChild(toggleArea);
    };
    var toggleButtonEvent=function({target:{parentNode:{dataset}},currentTarget:{lastChild:toggleSaveButton}}){
        //ラベルの外見を変える
        dataset.checkflag=(dataset.checkflag!="true");
        //セーブ時の為の変数を更新する
        SetcheckSave(dataset.contentId,dataset.checkflag);
        updateStyle (dataset.contentId,dataset.checkflag);
        if(toggleSaveButton.disabled)toggleSaveButton.disabled=false;
    };
    var toggleUserTypeEvent=function({target:{nextSibling:{childNodes:toggleButtons},parentNode:toggleArea}}){
        if(toggleButtons.length==0){return;}//無いとは思うけど、要素が無い時はそのまま返す
        const firstChecked=toggleButtons[0].firstChild.checked;
        for(let {firstChild:control} of toggleButtons){
            //一番目のボタンの状態と同じ=>クリックする
            if(control.checked===firstChecked){
                control.checked=!firstChecked;
                toggleButtonEvent({target:control,currentTarget:toggleArea});
            }
        }
    };
    init();
// TODO アロー関数置き換え Regex '((\w+)|\(([{}: \w]*)\)) *=> *' 'function($2$3)'
})();