MCBBS Extender

MCBBS行为拓展/样式修复

当前为 2020-02-15 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         MCBBS Extender
// @namespace    https://i.zapic.cc
// @version      release-1.0.2
// @description  MCBBS行为拓展/样式修复
// @author       Zapic
// @match        https://*.mcbbs.net/*
// @run-at       document-body
// ==/UserScript==

(function () {
    if (typeof jQuery == "undefined") {
        console.error("This page does NOT contain JQuery,MCBBS Extender will not work.");
        return false;
    }
    var dlg = function (m) {
        console.debug("[MCBBS Extender]" + m)
    };
    try {
        var conf = JSON.parse(getcookie("MExt_config"));
    } catch (e) {
        dlg("Failed to load config" + e);
    }
    if (!conf) {
        setcookie("MExt_config", JSON.stringify({
            "fixCodeBlock": true,
            "fixCodeCopy": true,
            "fixTableLayout": true,
            "queryMessage": true,
            "queryMessageInterval": 60,
            "rememberPage": true,
            "animateGoToTopButton": true,
            "pinnedTopBar": true,
            "fixTopBarPopMenu": true,
            "hoverPreviewTheme": true,
            "hoverableMedal": true
        }), 2147483647);
        conf = JSON.parse(getcookie("MExt_config"));
        dlg("Config init.");
    }
    var jq = jQuery;
    jq(document).ready(function () {
        jq("#user_info_menu .user_info_menu_btn").append("<li><a href='javascript: void(0);' id=\"MExt_config\">MCBBS Extender 设置</a></li>");
        dlg("Appended Config button");
        jq("head").append('<style id="ConfWindowStyle">.conf_item{line-height: 1.2;margin-bottom:5px;} .conf_title{font-weight: 1000;} .conf_subtitle{font-size: 10px;color: #0000007a;padding-right:40px;display:block;} .conf_check{float: right;margin-top: -25px;} .conf_input{float: right;width:30px;margin-top:-27px;}</style>');
        dlg("Appended Config window style")
        jq("#MExt_config").on("click", function () {
            hideMenu("user_info_menu");
            showDialog(
                '<style>.alert_info {background-image: unset;padding-left: 20px;padding-right: 17px;}</style><div><p class="conf_item"><span class="conf_title">美化代码块样式</span><br><span class="conf_subtitle">优化代码块样式,如滚动条</span><input class="conf_check" type="checkbox" id="c_fixcodeblock"></input></p><p class="conf_item"><span class="conf_title">"复制代码"换行修复</span><br><span class="conf_subtitle">在复制代码时自动加上换行</span><input class="conf_check" type="checkbox" id="c_fixcopycode"></input></p><p class="conf_item"><span class="conf_title">快捷键修复当前页面表格</span><br><span class="conf_subtitle">某些情况可能导致元素顶破表格,通过Shift+F快速修复此类问题.</span><input class="conf_check" type="checkbox" id="c_fixtablelayout"></input></p><p class="conf_item"><span class="conf_title">后台轮询消息</span><br><span class="conf_subtitle">在后台自动查询是否有新的消息并推送,需保证至少打开一个页面.</span><input class="conf_check" type="checkbox" id="c_querymsg"></input></p><p class="conf_item"><span class="conf_title">后台轮询消息间隔</span><br><span class="conf_subtitle">两次轮询消息之间的间隔,单位秒.</span><input type="number" class="conf_input" id="i_querymsginterval"></input></p><p class="conf_item"><span class="conf_title">板块内翻页记忆</span><br><span class="conf_subtitle">点击板块内下一页按钮时记忆当前页.</span><input class="conf_check" type="checkbox" id="c_rempage"></input></p><p class="conf_item"><span class="conf_title">美化右侧回到顶部按钮</span><br><span class="conf_subtitle">为右侧回到顶部按钮增加动画</span><input class="conf_check" type="checkbox" id="c_fixgoupbtn"></input></p><p class="conf_item"><span class="conf_title">固定顶栏</span><br><span class="conf_subtitle">将顶栏固定到页面顶部,不随页面滚动</span><input class="conf_check" type="checkbox" id="c_fixtopbar"></input></p><p class="conf_item"><span class="conf_title">弹出菜单美化</span><br><span class="conf_subtitle">美化弹出菜单的样式,如个人信息菜单</span><input class="conf_check" type="checkbox" id="c_fixpopmenu"></input></p><p class="conf_item"><span class="conf_title">主题悬浮预览</span><br><span class="conf_subtitle">将鼠标指针放在切换主题按钮上即可预览主题</span><input class="conf_check" type="checkbox" id="c_hoverpreview"></input></p><p class="conf_item"><span class="conf_title">玻璃质感勋章</span><br><span class="conf_subtitle">亮闪闪的勋章~</span><input class="conf_check" type="checkbox" id="c_glassmedal"></input></p></div>',
                "confirm",
                "MCBBS Extender 设置",
                function () {
                    var cf = {};
                    cf.fixCodeBlock = jq("#c_fixcodeblock").prop("checked");
                    cf.fixCodeCopy = jq("#c_fixcopycode").prop("checked");
                    cf.fixTableLayout = jq("#c_fixtablelayout").prop("checked");
                    cf.queryMessage = jq("#c_querymsg").prop("checked");
                    cf.queryMessageInterval = jq("#i_querymsginterval").val();
                    cf.rememberPage = jq("#c_rempage").prop("checked");
                    cf.animateGoToTopButton = jq("#c_fixgoupbtn").prop("checked");
                    cf.pinnedTopBar = jq("#c_fixtopbar").prop("checked");
                    cf.fixTopBarPopMenu = jq("#c_fixpopmenu").prop("checked");
                    cf.hoverPreviewTheme = jq("#c_hoverpreview").prop("checked");
                    cf.hoverableMedal = jq("#c_glassmedal").prop("checked");
                    setcookie("MExt_config", JSON.stringify(cf), 2147483647);
                    dlg("Config cookie set.");
                    setTimeout(function () {
                        showDialog("设置已保存,刷新生效", "right");
                    });
                },
                true,
                function () {},
                "MCBBS Extender v1.0.2"
            );
            jq("#c_fixcodeblock").prop("checked", conf.fixCodeBlock);
            jq("#c_fixcopycode").prop("checked", conf.fixCodeCopy);
            jq("#c_fixtablelayout").prop("checked", conf.fixTableLayout);
            jq("#c_querymsg").prop("checked", conf.queryMessage);
            jq("#i_querymsginterval").val(conf.queryMessageInterval);
            jq("#c_rempage").prop("checked", conf.rememberPage);
            jq("#c_fixgoupbtn").prop("checked", conf.animateGoToTopButton);
            jq("#c_fixtopbar").prop("checked", conf.pinnedTopBar);
            jq("#c_fixpopmenu").prop("checked", conf.fixTopBarPopMenu);
            jq("#c_hoverpreview").prop("checked", conf.hoverPreviewTheme);
            jq("#c_glassmedal").prop("checked", conf.hoverableMedal);
            dlg("Config cookie loaded.");
        });
        dlg("Config button event attached.");
    });
    if (conf.fixCodeBlock) {
        jq("head").append("<style id=\"fixCodeBlock\">.hljs > ::-webkit-scrollbar {background: #f7f7f7;height: 7px;width:7px}.hljs > ::-webkit-scrollbar-thumb:hover{background:#0000005c;}.hljs > ::-webkit-scrollbar-thumb{background:#0000002c;}.pl .blockcode{max-height:483px;overflow:auto;padding: 10px 0 5px 10px;background-attachment: local}.blockcode ol{overflow-x: unset!important;}.hljs{display:unset;}.pl .blockcode ol{margin: 0 0 0px -10px!important;padding: 0 0 0px 20px !important;}.pl .blockcode ol li:hover {background-color: #00000010;color: #666;}.pl .blockcode ol li {margin-left: 23px;min-width: fit-content;padding-right: 10px;transition-duration:.2s;}.pl .blockcode em {display: block;margin-top: 5px;}</style>");
        dlg("Code block fix style appended.");
    }
    if (conf.fixTableLayout) {
        document.onkeydown = (e) => {
            if (e.shiftKey && e.keyCode == 70 && jq("#fixTableLayout").length == 0) {
                dlg("Table layout fix actived");
                showDialog("是否尝试修复此页表格?", "confirm", "MCBBS Extender", function () {
                    jq("head").append("<style id=\"fixTableLayout\">.t_table .hljs li {width: 0;background:#00000000!important}.t_table img{max-width:100%;object-fit:contain}</style>");
                })
            }
        };
        dlg("Table layout fix event attached.");
    }
    if (conf.fixCodeCopy) {
        copycode = function (obj) {
            if (!obj) {
                dlg("Code copy with invalid object.");
                return false;
            }
            var count = obj.children[0].children.length;
            var code = "";
            for (i = 0; i < count; i++) {
                code += obj.children[0].children[i].innerText + "\r\n";
            }
            setCopy(code, '代码已复制到剪贴板');
            dlg("Code copied.");
        };
        dlg("Code copy fix actived.");
    }
    if (conf.queryMessage) {
        var queryId = hash(new Date().getTime().toLocaleString(), 16);
        dlg("Query id is " + queryId + ".");
        if (!window.Html5notification) {
            jq.getScript("data/cache/html5notification.js?xm6");
            dlg("Html5notification added.");
        }
        setInterval(function () {
            if (getcookie("MExt_LastQuery") == "") {
                setcookie("MExt_LastQuery", 0, 0);
            }
            var nowtime = Math.floor(new Date().getTime() / 1000);
            if (getcookie("MExt_ActiveQueryId") == "" || nowtime - getcookie("MExt_LastQuery") > 5) {
                setcookie("MExt_ActiveQueryId", queryId, 0);
                dlg("Kick off inactive querier,start query.");
            }
            setcookie("MExt_LastQuery", nowtime, 0);
        }, 1000);
        dlg("Running checker actived.");
        setInterval(function () {
            localStorage.setItem('notifica-time', new Date().getTime());
            jq.getJSON("/api/mobile/index.php?module=profile", function (data) {
                var notices = data.Variables.notice;
                var noticecontent = JSON.stringify(notices);
                jq.get("/forum.php?mod=misc", function (d) {
                    var dom = jq(d);
                    var ut = dom.find(".user_tools");
                    var pum = dom.filter("#myprompt_menu");
                    jq(".user_tools").html(ut.html());
                    jq("#myprompt_menu").html(pum.html());
                    jq("title").text(NOTICECURTITLE);
                    var s = dom.filter("script[src*=html5notification]").nextUntil("div").last().text();
                    if (getcookie("MExt_ActiveQueryId") == queryId && noticecontent != getcookie("MExt_LastNoticeContent")) {
                        localStorage.setItem('notifica-time', 1);
                        eval(s);
                        dlg("Notification sent.");
                    }
                    setcookie("MExt_LastNoticeContent", noticecontent, 0);
                });
            });
        }, conf.queryMessageInterval * 1000);
        dlg("Start query messages.");
    }
    if (conf.rememberPage) {
        jq(document).ready(function () {
            if ($('autopbn')) {
                var npbtn = $('autopbn')
                var dc = npbtn.onclick;
                npbtn.onclick = function () {
                    var nextpageurl = this.getAttribute('rel').valueOf();
                    var curpage = parseInt(this.getAttribute('curpage').valueOf());
                    this.setAttribute('curpage', curpage + 1);
                    nextpageurl = nextpageurl.replace(/&page=\d+/, '&page=' + (curpage + 1));
                    history.replaceState(null, null, nextpageurl);
                    dc();
                };
            }
            dlg("Page remember actived.");
        });
    }
    if (conf.animateGoToTopButton) {
        jq("head").append("<style id=\"GoToTopButton\">#scrolltop{bottom: 270px!important;visibility:visible;overflow-x:hidden;width:75px;}.scrolltopa{transition-duration:.15s;margin-left:-40px;opacity:0;}.scrolltopashow{margin-left:0px;opacity:1;}</style>");
        dlg("Animate go to top buttom style appended.");
        showTopLink = function () {
            var ft = $('ft');
            if (ft) {
                var scrolltop = $('scrolltop');
                if (!scrolltop) {
                    return false;
                }
                var scrolltopbtn = jq(".scrolltopa");
                var viewPortHeight = parseInt(document.documentElement.clientHeight);
                var scrollHeight = parseInt(document.body.getBoundingClientRect().top);
                var basew = parseInt(ft.clientWidth);
                var sw = scrolltop.clientWidth;
                if (basew < 1000) {
                    var left = parseInt(fetchOffset(ft)['left']);
                    left = left < sw ? left * 2 - sw : left;
                    scrolltop.style.left = (basew + left + 44) + 'px';
                } else {
                    scrolltop.style.left = 'auto';
                    scrolltop.style.right = 0;
                }
                if (scrollHeight < -100) {
                    scrolltopbtn.addClass("scrolltopashow");
                } else {
                    scrolltopbtn.removeClass("scrolltopashow");
                }
            }
        }
        showTopLink();
        dlg("Animate go to top buttom actived.");
    }
    if (conf.pinnedTopBar) {
        jq("head").append("<style id=\"pinnedTopBar\">#toptb{position: fixed;width: 100%;z-index:790;top:0;box-shadow: #0000004f 3px 3px 5px 1px;}.mc_map_wp{padding-top: 45px;}#scbar_type_menu{top:38px!important}#user_info_menu,#myprompt_menu,#usertools_menu,#sslct_menu {position:fixed!important;top:47px!important}</style>");
        dlg("Pinned top bar style appended.");
    }
    if (conf.fixTopBarPopMenu) {
        jq("head").append("<style id=\"fixTopBarPopMenu\">div#user_info_menu {margin-top: 5px;}.user_info_menu_info > li {margin-top: 2px;}a.rank {padding: 2px 7px!important; border-radius: 14px;}a.rank:hover {text-decoration: none;}ul.user_info_menu_btn {padding-top: 6px;}ul.user_info_menu_btn>li>a:hover {background: #36b030;color: white;}ul.user_info_menu_btn>li>a {padding: 5px 8px;border-radius: 5px;}ul.user_info_menu_btn>li>a[onclick]:hover {background: red!important;}#myprompt_menu {margin-left: -10px;}#myprompt_menu,#usertools_menu,#sslct_menu { z-index:791!important;margin-top: 5px!}.p_pop:not(.h_pop){important;border: 1px solid #d1d1d1;min-width: unset;border-radius: 5px;}#myprompt_menu>li>a, #usertools_menu>li>a {border: none; border-radius: 5px;text-align: center;padding: 3px 15px;}#myprompt_menu>li>a:hover, #usertools_menu>li>a:hover {background: #36b030;color: white;}div#sslct_menu {margin-left: 16px;padding-left: 14px;}.sslct_btn {border: none!important;width: 15px;height: 15px;padding: 2px;}.sslct_btn i {border-radius: 50%;width: 13px;height: 13px;}</style>");
        dlg("Pop menu fix style appended.");
        var __extstyle = extstyle;
        extstyle = function (style) {
            __extstyle(style);
            jq("#fixTopBarPopMenuWinter").remove();
            if (style == "./template/mcbbs/style/winter") {
                jq("head").append("<style id=\"fixTopBarPopMenuWinter\">.user_info_menu_info li a.rank {background-color: #5c8dff!important;}ul.user_info_menu_btn>li>a:hover,#myprompt_menu>li>a:hover, #usertools_menu>li>a:hover {background: #5c8dff!important;}</style>");
            }
        }
        var theme = getcookie('extstyle');
        if (theme == "./template/mcbbs/style/winter") {
            jq("head").append("<style id=\"fixTopBarPopMenuWinter\">.user_info_menu_info li a.rank {background-color: #5c8dff!important;}ul.user_info_menu_btn>li>a:hover,#myprompt_menu>li>a:hover, #usertools_menu>li>a:hover {background: #5c8dff!important;}</style>");
        }
        dlg("Overwrite extstyle function");
    }
    if (conf.hoverPreviewTheme) {
        jq(document).ready(function () {
            jq(".sslct_btn").on("mouseover", function () {
                var previewstyle = getcookie('extstyle');
                jq(this).trigger('click');
                setcookie('extstyle', previewstyle);
            });
            jq(".sslct_btn").on("mouseout", function () {
                extstyle(getcookie('extstyle'));
            });
            dlg("Hover preview theme event attached.");
        });
    }
    if (conf.hoverableMedal) {
        jq(document).ready(function () {
            jq('.md_ctrl').each(function (t, v) {
                jq(v).children(0).children('img').each(function (b, n) {
                    var id = 'md' + new RegExp('\\_\\d*$').exec(jq(n).attr('id'))[0];
                    jq(v).append(
                        jq(
                            jq('<span class="hoverable-medal" id="' + jq(n).attr('id') + '" style="background-image:url(' + jq(n).attr('src') + ')"><div></div></span>').on('mouseover', function () {
                                showMenu({
                                    'ctrlid': jq(n).attr('id'),
                                    'menuid': id + '_menu',
                                    'pos': '12!'
                                });
                            })
                        )
                    );
                    jq("#" + id + "_menu .tip_horn").css("background-image", "url(" + jq(n).attr('src') + ")");
                    jq(n).remove();
                });
            });
            dlg("Hoverable medal rewrote.");
        });
        jq("head").append("<style id=\"hoverableMedal\">.hoverable-medal:hover div {margin-top: 0px!important;opacity: 1!important;}.hoverable-medal div {margin-top: -15px;opacity: 0.6;transition-duration: .4s;background-image:url(//i.loli.net/2020/02/10/6qauEUHK8cty4lR.png);width:100%;height:100%;filter: blur(2px);}div.tip.tip_4[id*=md_] {width: 105px;height: 165px;border: none;box-shadow: black 0px 2px 10px -3px;margin-left: 38px;margin-top: 115px;background: black;overflow: hidden;pointer-events:none!important;border-radius: 5px;padding: 0px;}div.tip.tip_4[id*=md_] .tip_horn {background-size: cover;background-position: center;height: 200%;width: 200%;z-index: -1;filter: blur(7px) brightness(0.8);top: -50%;left: -50%;}div.tip.tip_4[id*=md_] .tip_c {color: #fffffffc;}div.tip.tip_4[id*=md_] h4 {text-align: center;padding: 10px 5px;background-color: #ffffff52;}div.tip.tip_4[id*=md_] p {padding: 20px 10px;}.md_ctrl{margin-left:17px!important}.hoverable-medal {width: 31px;height: 53px;transition-duration: 0.4s;border-radius: 3px;display: inline-block;margin: 5px;background-position: center;box-shadow: 0px 2px 5px 0px black;overflow:hidden;}.hoverable-medal:hover {transform: matrix3d(1, 0, 0, 0, 0, 1, 0, -0.003, 0, 0, 1, 0, 0, -1.5, 0, 0.9);box-shadow: 0px 2px 10px -3px black;}</style>");
        dlg("Hoverable medal style appended.");
    }
})();