B站|bilibili 收藏夹名称完全显示+高度调整

B站|bilibili 收藏夹名称完全显示+高度自适应或完全铺开

// ==UserScript==
// @name         B站|bilibili 收藏夹名称完全显示+高度调整
// @license      MIT
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAyZJREFUaEPtWlFy2jAQ3XXof5pewJkpmekpAidJ+IQeAnKIwifkJDin6EzoTNwDlOYA4O2sVIEsFFuSkQdm8CfI0r6VdvftkxHO/MEQ+7/8eH3cJtvsffgtD3nf9s71bNV7H3Yz3/m8AdzMVmMgmPBCBW5um4K4nv1MkTpzBOgBwmQ97D75gPAHMH19A8BULdIEBBufUOdtbzDl69HdbVQActGrZVMQh8bzjkLf9xh57wB7xwYCiQZ/vt8tXLx3LON5rSAATUBwsCYESx1oiOfV+8EAQkAcGk95gTjwPTY6+AMAYhHAByJKEWgXrNVHYx/Uchx9kF7NcXIsDamY0TICtg8m1mvBODzdLUU6eyEHzPWdgDOwfidX7V6IQDoxemEnV827T8ItKW0cwHBRRQ/8j6fNeY7pwGmkyZEc714ihpANMCb2a85ED2WDfUv6bGB2uoHIC7QGrwBpCo2ABGr0xXp6xBAdgHQhufVGpcdqPK2T5fGqRugkwJscp+G6Gg7wMYKFpMk90BFT6U3V0qtp24ORJESBdeBlypQwQBEsYNPY91Y624gLtbDr4O6uKiv/JLgEW4G+g41A1Bq/ewmsjf/jrr9OgCuvGs96pbIZjAAmYPLvXDJSMQF02Is6LdLVyYpO9wTQU9SdjvNNvvjZgBExS56gEmGRfGyTZjD+wVh1c4cgBLHsaxQNAJQdyza+P8CoA0vV61x2YGQHeCi55KZXOaOvgMmnVAFS5cfFY0IkVKiAmDjCXEu6gHBk6QZWqOEMOE6IceECcNRAezFATZaFSbKuW6YFMSVM5nHKjoAXlAVJPa2ukNQvwnPW8Qpl/N/4chcvRRzXCtHqE0AImFYZRVHXh/TWHNuqwDHmW2f/kqCRV7gtu/T7sUGY22CGEAV1xe6C9ZL37GNl1K/qZpL8e38xV3lPbvEGNu3YfPrrWu557TqpGGLxHrL7LutV0xIMG73poavpA77YiW5sDM4FgugZ5MEOl3yWZVhOJ6Cbc2EjgKzEwBbpmpyNWo7Xqbq4foFgDMARdSuCkqP/aGHnJvFs86DTgJd4sgLgMuEbY/5B0Ybna/xpe4TAAAAAElFTkSuQmCC
// @namespace    https://sumver.cn
// @version      0.0.5
// @description  B站|bilibili 收藏夹名称完全显示+高度自适应或完全铺开
// @author       lonelylizard
// @match        https://space.bilibili.com/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    // 注册右键菜单命令
    const fold_fn_menu = GM_registerMenuCommand("收藏夹设置", function () {
        let cur_choose = window.confirm("当前状态:\n" + (GM_getValue("fold_status") === true ? "始终展示全部收藏夹(无滚动条)" : "收藏夹高度自适应(可能有滚动条)") +
            "\n\n按【确认】修改为" + (GM_getValue("fold_status") === true ? "收藏夹高度自适应(可能有滚动条)" : "始终展示全部收藏夹(无滚动条)") + ",按【取消】保持设置不变\n设置后请手动刷新一次网页");
        if (cur_choose) {
            GM_setValue("fold_status", !GM_getValue("fold_status"));
        }
    });

    // 样式注入函数
    function setStyle(css) {
        let css_list = css.split("}");
        css_list.forEach((item, index, array) => {
            GM_addStyle(item + "}")
        });
    }

    // 折叠处理函数
    function fold_fn() {
        let css = `
            .text{
                white-space:normal !important;
                line-height:25px !important;
                word-break:break-all;
            }
            .fav-item:last-child{
                border-bottom: none;
            }
            .icon-cursor{
                background-position:unset !important;
                height:100% !important;
            }
            .space-favlist .favlist-aside[data-v-995f8755]{
                --aside-width:400px;
            }
            @media (min-width: 1860px) {
                .space-favlist .favlist-aside[data-v-995f8755] {
                    --aside-width: 400px;
                }
                .fav-sidebar-item .vui_sidebar-item-title .vui_ellipsis{
                    max-width:unset;
                }
            }
        `;
        setStyle(css);

        if (GM_getValue("fold_status")) {
            let scrollHeight = document.querySelector(".fav-sortable-list")?.scrollHeight || 0;
            if (scrollHeight > 0) {
                let css_folded = `
                    .fav-collapse-wrap{
                        // max-height: ${scrollHeight}px !important;
                        max-height: unset !important;
                    }
                `;
                setStyle(css_folded);
            }
        } else {
            let fav_height = document.querySelector(".fav-sortable-list")?.scrollHeight || 0;
            let res_height = window.innerHeight;
            let dif_height = res_height - 320;

            if (fav_height > dif_height) {
                let css_responsive = `
                    .fav-collapse,.vui_collapse_item{
                        height:${dif_height}px !important;
                    }
                    .vui_collapse_item{
                        max-height:${dif_height+30}px !important;
                    }
                    .fav-collapse-wrap{
                        max-height:${dif_height}px !important;
                        height:${dif_height-50}px !important;
                    }
                `
                setStyle(css_responsive);
            } else {
                let css_full = `
                    .fav-collapse,.vui_collapse_item,.fav-collapse-wrap{
                        height:100% !important
                    }
                    .fav-collapse-wrap{
                        max-height:100% !important;
                `;
                setStyle(css_full);
            }
        }
    }

    // 等待收藏夹异步加载完成,获取到高度后才能进行处理(scrollHeight > 0)
    function waitForElementWithScroll(selector, timeout = 5000) {
        return new Promise((resolve, reject) => {
            const startTime = Date.now();

            const checkElement = () => {
                const element = document.querySelector(selector);
                if (element) {
                    if (element.scrollHeight > 0) {
                        resolve(element);
                    } else {
                        setTimeout(checkElement, 100);
                    }
                } else {
                    // console.log("未找到目标元素:" + selector);
                    const now = Date.now();
                    if (now - startTime < timeout) {
                        setTimeout(checkElement, 100);
                    } else {
                        // reject(new Error("等待元素出现超时:" + selector));
                    }
                }
            };

            checkElement(); // 立即开始检测
        });
    }

    // 主运行函数
    function run() {
        waitForElementWithScroll('.fav-sortable-list', 5000)
            .then(() => {
                fold_fn();
            })
            .catch(error => {
                // console.warn("等待失败:", error.message);
            });
    }

    // 页面加载完成后执行
    window.addEventListener('DOMContentLoaded', function () {
        run();
    });

    // 监听窗口变化和页面切换
    const debounce = (fn, delay) => {
        let timer;
        return function () {
            clearTimeout(timer);
            timer = setTimeout(() => fn(), delay);
        };
    };

    window.addEventListener('resize', debounce(run, 500));
    window.addEventListener('pushState', run);
    window.addEventListener('replaceState', run);
    window.onpopstate = run;

    // 重写 history 方法以便监听页面切换
    const bindEventListener = function (type) {
        const historyEvent = history[type];
        return function () {
            const newEvent = historyEvent.apply(this, arguments);
            const e = new Event(type);
            e.arguments = arguments;
            window.dispatchEvent(e);
            return newEvent;
        };
    };
    history.pushState = bindEventListener('pushState');
    history.replaceState = bindEventListener('replaceState');

})();