[NikoAd] simplizer

ニコニ広告設定窓の表示物制御

目前為 2024-12-09 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         [NikoAd] simplizer
// @namespace    http://tampermonkey.net/
// @version      2024-12-10
// @description  ニコニ広告設定窓の表示物制御
// @author       anonymous
// @match        https://nicoad.nicovideo.jp/video/publish/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=nicovideo.jp
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    const collapse_settings = [
        { id: 'header-bar', def_value:true },
        { id: 'conductor', def_value:true },
        { id: 'secondary-content-info', def_value:true },
        { id: 'entry-basic-info', def_value:true },
        { id: 'entry-thanks', def_value:true },
        { id: 'frame-grade-visualizer', def_value:true },
        { id: 'nicoad-impact', def_value:true },
        { id: 'campaign-info', def_value:true },
    ];

    const SHRINK_SETTING_ID = "shrink";
    const REPLACE_PUBLISH_BUTTON_SETTING_ID = "replace_publish_button";
    const REPLACE_BACK_BUTTON_SETTING_ID = "replace_back_button";

    // ------------------------------------------------------------------------------------------------------

    function saveValueToStorage(id, value) {
        console.debug(`save ${id} : ${value}` );
        localStorage.setItem(id, value);
    }

    function loadValueFromStorage(id, def_value) {
        const value = localStorage.getItem(id);

        if((value === undefined) || (value === null)){
            return def_value.toString();
        }

        console.debug(`load ${id} : ${value}` );
        return value;
    }

    function stringToBool(str) {
        return str.toLowerCase() === 'true'; }

    // ------------------------------------------------------------------------------------------------------
    // ドロップダウンメニューをページの最下段に追加する関数を定義
    function addDropdownMenuToBottom() {
        // メニューのコンテナを作成
        const menuContainer = document.createElement('div');
        menuContainer.className = 'bottom-menu-container';

        // スタイルプロパティに直値を代入
        menuContainer.style.position = 'fixed';
        menuContainer.style.bottom = '4px';
        menuContainer.style.left = '14x';
        menuContainer.style.backgroundColor = 'white';
        menuContainer.style.border = '1px solid #ccc';
        menuContainer.style.padding = '4px';
        menuContainer.style.zIndex = '1000';

        // メニューの内容を作成
        const menuContent = document.createElement('div');
        menuContent.id = 'menuContent';
        menuContent.style.display = 'none'; // 初期状態は非表示
        menuContent.style.position = 'absolute';
        menuContent.style.bottom = '24px';
        menuContent.style.left = '4px';
        menuContent.style.backgroundColor = '#f9f9f9';
        menuContent.style.boxShadow = '0px 8px 16px 0px rgba(0,0,0,0.2)';
        menuContent.style.zIndex = '1001';
        menuContent.style.width = '300px'; // メニューの幅を設定

        function createCheckBoxContainer(id, text, checked, onchange){
            const checkboxContainer = document.createElement('div');
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.id = "cbx_" + id;
            checkbox.checked = checked;

            // チェック状態の保存
            checkbox.addEventListener('change', function(){
                saveValueToStorage(id, checkbox.checked);
            } );

            // 外部指定のアクション
            if(onchange){
                checkbox.addEventListener('change', function(){ onchange(checkbox); } );
            }
           
            const label = document.createElement('label');
            label.htmlFor = checkbox.id;
            label.appendChild(document.createTextNode(text));

            checkboxContainer.appendChild(checkbox);
            checkboxContainer.appendChild(label);

            return checkboxContainer;
        }

        // 項目別の表示非表示
        collapse_settings.forEach((item) => {
            const checked = stringToBool(loadValueFromStorage(item.id, item.def_value));

            let visible_func = function(checkbox){
                let elements = getElements(item.id);
                Array.from(elements).forEach((elm)=>{
                    elm.style.display = checkbox.checked ? "block" : "none";
                });
            }

            let container = createCheckBoxContainer(item.id, item.id, checked, visible_func);
            menuContent.appendChild(container);
        });

        {
            const horizontalRule = document.createElement('hr');
            menuContent.appendChild(horizontalRule);
        }
        // 圧縮
        {
            const id = SHRINK_SETTING_ID;
            const checked = stringToBool(loadValueFromStorage(id, false));
            let text = "隙間を詰める(要リロード)";
            let container = createCheckBoxContainer(id, text, checked);
            menuContent.appendChild(container);
        }

        // ボタン上下入れ替え
        {
            const id = REPLACE_PUBLISH_BUTTON_SETTING_ID;
            const checked = stringToBool(loadValueFromStorage(id, false));
            let text = "決定ボタンを上に移動(要リロード)";
            let container = createCheckBoxContainer(id, text, checked);
            menuContent.appendChild(container);
        }

        // ボタン上下入れ替え
        {
            const id = REPLACE_BACK_BUTTON_SETTING_ID;
            const checked = stringToBool(loadValueFromStorage(id, false));
            let text = "さらに広告ボタンを上に移動(要リロード)";
            let container = createCheckBoxContainer(id, text, checked);
            menuContent.appendChild(container);
        }

        // メニューボタンを作成
        {
            const menuButton = document.createElement('button');
            menuButton.innerText = '表示編集';
            menuButton.onclick = function() {
                menuContent.style.display = menuContent.style.display === 'block' ? 'none' : 'block';
            };

            // コンテナにボタンとメニューの内容を追加
            menuContainer.appendChild(menuButton);
        }
        menuContainer.appendChild(menuContent);

        // コンテナをボディに追加
        document.body.appendChild(menuContainer);
    }

    // ドロップダウンメニューを追加する関数を呼び出し
    addDropdownMenuToBottom();


    // ------------------------------------------------------------------------------------------------------
    // 項目の非表示処理
    // ------------------------------------------------------------------------------------------------------
    function waitForElement(elementName, callback) {
        return new Promise((resolve, reject) => {
            console.debug(elementName + " wait...");

            var interval = setInterval(function() {
                var elements = getElements(elementName);
                if (elements && elements.length > 0) {
                    Array.from(elements).forEach((elm)=>{
                        callback(elm); // 要素をコールバック関数に渡す
                    });

                    clearInterval(interval);
                    resolve();
                    console.debug(elementName + " done.");
                } else {
                    //console.log(elementName + " still not found");
                }
            }, 100); // ミリ秒ごとにチェック
        });
    }

    function getElementsById(id) {
        var element = document.getElementById(id);
        return element ? [element] : []; // 配列として返すことで、他のセレクタ関数と形式を揃える
    }

    function getElementsByClassName(className) {
        return document.getElementsByClassName(className);
    }

    function getElements(key){
        let elements = getElementsByClassName(key);
        if(elements.length > 0){
            return elements;
        }

        return getElementsById(key);
    }

    function collapseElement(element){
        element.style.display = "none";
    }

    function shrinkElement(element){
        element.style.minHeight = "0vh";
        element.style.padding = "0px";
    }

    function replaceElementToFirst(element){
        let parent = element.parentElement;
        parent.insertBefore(element, parent.firstChild);
    }

    async function simplize(){
        // 隙間埋め
        {
            const value = getElements("cbx_" + SHRINK_SETTING_ID)[0].checked;
            if(value){
                await waitForElement("next", collapseElement);
                await waitForElement("wrapper", shrinkElement);
                await waitForElement("heading", collapseElement);
            }
        }

        // 項目非表示
        collapse_settings.forEach((item) => {
            const value = getElements("cbx_" + item.id)[0].checked;
            if(!value){
                waitForElement(item.id, collapseElement);
            }
        });

        // 決定ボタン移動
        {
            const value = getElements("cbx_" + REPLACE_PUBLISH_BUTTON_SETTING_ID)[0].checked;
            if(value){
                waitForElement("publish-button", replaceElementToFirst);
            }
        }

        // 戻るボタン移動
        {
            const value = getElements("cbx_" + REPLACE_BACK_BUTTON_SETTING_ID)[0].checked;
            if(value){
                waitForElement("back-button", replaceElementToFirst);
            }
        }

    }

    simplize();


})();