欢迎来到纸飞机Wiki !

纸飞机Wiki目前包含43个页面,303次编辑,6个用户。

MediaWiki:Common.js:修订间差异

来自纸飞机Wiki
(创建页面,内容为“→‎这里的任何JavaScript将为所有用户在每次页面加载时加载。:​ console.log("欢迎来到纸飞机Wiki")”
 
无编辑摘要
标签已被回退
第1行: 第1行:
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
console.log("欢迎来到纸飞机Wiki")
console.log("欢迎来到纸飞机Wiki")
"use strict";
window.RLQ.push(async () => {
    const errMsg = {
        id: '此处填写的id有误,请参考<a href="https://zh.moegirl.org.cn/Template:BilibiliVideo#firstHeading" target="_blank">模板文档</a>修正……',
        error: "执行出现问题,请复制以下内容并在提问求助区处粘贴寻求帮助:$$$",
        attr: '下方填写的参数 $$$ 有误,请参考<a href="https://zh.moegirl.org.cn/Template:BilibiliVideo#firstHeading" target="_blank">模板文档</a>修正……',
    };
    await $.ready;
    const ifNamespaceAllow = [0, 4, 10, 12].includes(mw.config.get("wgNamespaceNumber"));
    const sanNode = $(`<${"span/"}>`);
    const genErr = (type, msg = "") => type in errMsg ? `<${"div"} style="font-style: italic; border: 1px dashed red;">BilibiliVideo模板:${errMsg[type].replace("$$$", sanNode.text(msg).html())}<${"/div"}>` : "";
    const injectErrMsgBefore = ($ele, type, msg = "") => $ele.before(genErr(type, msg));
    const getErrorType = (code) => {
        switch (code) {
            case 62003: {
                return false;
            }
            case -403: {
                return "forbidden";
            }
            default: {
                return "failed";
            }
        }
    };
    try {
        const isNaN = Number.isNaN || window.isNaN;
        const cssLengthUnitValidator = (length, defaultValue, callback, paramName, $ele) => {
            if (typeof length !== "string" || length.length === 0) {
                callback(false);
                return defaultValue;
            }
            const parsedNumber = parseFloat(length.replace(/[a-z]+/i, ""));
            if (isNaN(parsedNumber) || parsedNumber <= 0) {
                callback(false);
                injectErrMsgBefore($ele, "attr", paramName);
                return defaultValue;
            }
            if (/^(?:\d+|\d*\.\d+)(?:em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|Q|in|pc|pt|px|%)$/.test(length)) {
                callback(true);
                return length;
            }
            if (/^(?:\d+|\d*\.\d+)$/.test(length)) {
                callback(true);
                return `${length}px`;
            }
            callback(false);
            injectErrMsgBefore($ele, "attr", paramName);
            return defaultValue;
        };
        const fixedNumber = (number) => `${+number < 10 ? "0" : ""}${number}`;
        const secondsParser = (seconds) => `${Math.floor(+seconds / 60)}:${fixedNumber(+seconds % 60)}`;
        const idCorrector = (id) => {
            if (/^(?:av)?\d{1,9}$/i.test(id)) {
                return {
                    id: id.replace(/^av/i, ""),
                    prefix: {
                        href: "av",
                        iframe: "aid",
                    },
                };
            } else if (/^(?:(?:[bB][vV])?1)?[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}$/.test(id)
                && /4.1.7..$/.test(id)) {
                return {
                    id: id.replace(/^.*([fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9})$/i, "1$1"),
                    prefix: {
                        href: "BV",
                        iframe: "bvid",
                    },
                };
            }
            return false;
        };
        const submit = (ids) => {
            if (!ifNamespaceAllow) {
                return;
            }
            if (--ids.pending > 0) {
                return;
            }
            let changed = false;
            if (ids.failed.aid.size + ids.failed.bvid.size > 0 && !mw.config.get("wgCategories").includes("带有失效视频的条目")) {
                changed = true;
            }
            if (ids.forbidden.aid.size + ids.forbidden.bvid.size > 0 && !mw.config.get("wgCategories").includes("带有受限视频的条目")) {
                changed = true;
            }
            if (ids.failed.aid.size + ids.failed.bvid.size === 0 && mw.config.get("wgCategories").includes("带有失效视频的条目")) {
                changed = true;
            }
            if (ids.forbidden.aid.size + ids.forbidden.bvid.size === 0 && mw.config.get("wgCategories").includes("带有受限视频的条目")) {
                changed = true;
            }
            if (changed) {
                const url = new URL("https://moegirlpedia.annangela.cn/bilibiliCollector/videoCheck");
                url.searchParams.set("pageid", mw.config.get("wgArticleId"));
                $.get(`${url}`);
            }
        };
        if (mw.config.get("skin") === "MoeMobileSkin") {
            const ids = {
                failed: {
                    aid: new Set(),
                    bvid: new Set(),
                },
                forbidden: {
                    aid: new Set(),
                    bvid: new Set(),
                },
                pending: 0,
            };
            const targets = $(".bilibili-video-container:not(.bilibili-video-initialized)");
            ids.pending = targets.length;
            targets.each((_, ele) => {
                const element = $(ele),
                    dataset = ele.dataset;
                element.addClass("bilibili-video-initialized");
                const _id = dataset.id,
                    title = dataset.title,
                    pagename = dataset.pagename,
                    t = parseInt(dataset.t),
                    tIsInvalid = isNaN(t) || t <= 0,
                    subtitle = dataset.subtitle === "true" ? true : false;
                let page = parseInt(dataset.page);
                if (isNaN(page) || page < 1) {
                    page = 1;
                    if (typeof dataset.page === "string" && dataset.page !== "") {
                        injectErrMsgBefore(element, "attr", "page");
                    }
                }
                if ((isNaN(t) || t <= 0) && typeof dataset.t === "string" && dataset.t !== "") {
                    injectErrMsgBefore(element, "attr", "t");
                }
                const validation = idCorrector(_id);
                let id,
                    prefix;
                if (validation) {
                    id = validation.id;
                    prefix = validation.prefix;
                } else {
                    ele.outerHTML = genErr("id");
                    return;
                }
                ele.innerText = "正在加载中,若长时间空白则说明是网络问题……";
                $.ajax({
                    url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
                    type: "GET",
                    dataType: "jsonp",
                    timeout: 10000,
                    success: function ({ code, message, data }) {
                        if (code !== 0) {
                            element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + (![0, 1].includes(page) && !isNaN(page) ? ` (P${page})` : ""))).remove();
                            console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
                            const errorType = getErrorType(code);
                            if (errorType) {
                                ids[errorType][prefix.iframe].add(id);
                            }
                            return;
                        }
                        const list = data.pages;
                        let _page = 1;
                        const name = title || (data.title ? data.title : prefix.href + id);
                        let index;
                        let length;
                        if (pagename) {
                            for (index = 0, length = list.length; index < length; index++) {
                                if (list[index].part !== pagename) { continue; }
                                _page = list[index].page;
                                break;
                            }
                        } else { _page = page; }
                        index = _page - 1;
                        const time = secondsParser(t);
                        const button = $("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${_page}${tIsInvalid ? "" : `&t=${t}`}`).text(`${name} [${_page}/${secondsParser(list[index].duration)}]${tIsInvalid ? "" : `[跳转至${time}]`}`);
                        if (list[index] !== undefined && list[index].cid !== undefined && subtitle) {
                            button.append(`<br>(${_page}、${list[index].part})`);
                        }
                        element.before(button).remove();
                    },
                    error: function () {
                        element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + (![0, 1].includes(page) && !isNaN(page) ? ` (P${page})` : ""))).remove();
                    },
                    complete: () => {
                        submit(ids);
                    },
                });
            });
        }
        else {
            const global_element = $("#mw-content-text");
            const placeholderToggle = (iframe) => {
                if (iframe.data("displayFlag")) {
                    iframe.data("displayFlag", false);
                    iframe.data("placeholder").fadeOut(370);
                }
            };
            let lazyLoadObserver;
            if ("IntersectionObserver" in window &&
                "IntersectionObserverEntry" in window &&
                "intersectionRatio" in window.IntersectionObserverEntry.prototype &&
                "isIntersecting" in window.IntersectionObserverEntry.prototype) {
                lazyLoadObserver = new IntersectionObserver((entries) => {
                    entries.forEach((entry) => {
                        if (entry.isIntersecting) {
                            entry.target.src = entry.target.dataset.src;
                            setTimeout(() => {
                                placeholderToggle($(entry.target));
                            }, 13070);
                            lazyLoadObserver.unobserve(entry.target);
                        }
                    });
                });
            } else {
                lazyLoadObserver = {
                    observe: (target) => {
                        target.src = target.dataset.src;
                        setTimeout(() => {
                            placeholderToggle($(target));
                        }, 13070);
                    },
                };
            }
            const iframe_href_base = "https://www.bilibili.com/blackboard/newplayer.html?playlist=true&playlist_order=sequential&musth5=1&noEndPanel=1&crossDomain=1&autoplay=0&";
            const EPSILON = 2.220446049250313e-16,
                rememberWH = function rememberWH(ele) {
                    ele.data({ width: ele.width(), height: ele.height() });
                },
                setTureHeight = function setTureHeight(ele) {
                    const barHeight = ele.data("height") - ele.data("width") * 9 / 16; //计算标题和播放器控制栏高度
                    ele.height(ele.width() * 9 / 16 + barHeight);
                },
                setWH = function setWH(ele) {
                    ele.css({ width: "100%", height: "100%" });
                },
                recallWH = function recallWH(ele) {
                    ele.width(ele.data("width")).height(ele.data("height"));
                },
                setMaxHeight = function setMaxHeight(container, target) {
                    const h = container.outerHeight(true);
                    let t = 0;
                    container.children().each((_, ele) => {
                        t += $(ele).outerHeight(true);
                    });
                    target.css("max-height", `calc(100% - ${parseInt(t - h + 2 - (Number.EPSILON || EPSILON))}px)`);
                };
            const run = () => {
                const ids = {
                    failed: {
                        aid: new Set(),
                        bvid: new Set(),
                    },
                    forbidden: {
                        aid: new Set(),
                        bvid: new Set(),
                    },
                    pending: 0,
                };
                const targets = $(".bilibili-video-container:not(.exec)");
                ids.pending = targets.length;
                targets.addClass("exec").each((_, ele) => {
                    const dataset = ele.dataset;
                    const _id = dataset.id;
                    const selfbox = $(ele);
                    const toggleButton = selfbox.find(".bilibili-toggle");
                    const widescreenButton = selfbox.find(".bilibili-widescreen");
                    const validation = idCorrector(_id);
                    let id,
                        prefix;
                    if (validation) {
                        id = validation.id;
                        prefix = validation.prefix;
                    } else {
                        ele.outerHTML = genErr("id");
                        return;
                    }
                    let page = parseInt(+(dataset.page || 1));
                    if (isNaN(page) || page < 1) {
                        page = 1;
                        if (typeof dataset.page === "string" && dataset.page !== "") {
                            injectErrMsgBefore(selfbox, "attr", "page");
                        }
                    }
                    const pagename = dataset.pagename;
                    const title = dataset.title;
                    const height = cssLengthUnitValidator(dataset.height, "441px", (isValidated) => isValidated || selfbox.removeAttr("data-height"), "height", selfbox);
                    const width = cssLengthUnitValidator(dataset.width, "665px", (isValidated) => isValidated || selfbox.removeAttr("data-width"), "width", selfbox);
                    const maxHeight = cssLengthUnitValidator(dataset.maxHeight, "100vh", (isValidated) => isValidated || selfbox.removeAttr("data-max-height"), "maxHeight", selfbox);
                    const maxWidth = cssLengthUnitValidator(dataset.maxWidth, "100%", (isValidated) => isValidated || selfbox.removeAttr("data-max-width"), "maxWidth", selfbox);
                    const subtitle = dataset.subtitle === "true" ? true : false;
                    const t = parseInt(dataset.t);
                    const tIsInvalid = isNaN(t) || t <= 0;
                    const iframeContainer = selfbox.find(".bilibili-iframe-container");
                    const title_text = $("<a/>").attr("rel", "nofollow noreferrer noopener").addClass("external text").attr({
                        href: `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`,
                        target: "_blank",
                    }).prependTo(selfbox.find(".bilibili-title"));
                    const iframe = $("<iframe/>").attr({
                        allow: "fullscreen",
                        allowfullscreen: true,
                        frameborder: 0,
                        scrolling: "no",
                        src: "",
                        "class": "bilibili-iframe",
                    }).css({
                        width: width,
                        height: height,
                        "max-width": maxWidth,
                        "max-height": maxHeight,
                    });
                    if (!tIsInvalid) {
                        selfbox.removeAttr("data-auto-expand");
                    } else if (typeof dataset.t === "string" && dataset.t !== "") {
                        injectErrMsgBefore(selfbox, "attr", "t");
                    }
                    const time = secondsParser(t);
                    title_text.text(`${(title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`)}【视频信息加载中……】`);
                    iframeContainer.css({
                        width: width,
                        height: height,
                        "max-width": maxWidth,
                        "max-height": maxHeight,
                    });
                    iframe.appendTo(iframeContainer);
                    const div = $("<div/>");
                    div.css({
                        position: "absolute",
                        top: "0",
                        left: "0",
                        bottom: "0",
                        right: "0",
                        "z-index": "99",
                        display: "flex",
                        "align-items": "center",
                        background: "rgba(255, 255, 255, .37)",
                    });
                    const text = $("<div/>");
                    text.css({
                        "text-align": "center",
                        width: "100%",
                    }).text("正在加载中,若长时间空白则说明是网络问题……");
                    div.append(text).appendTo(iframeContainer);
                    iframe.data({
                        placeholder: div,
                        displayFlag: true,
                    });
                    iframe[0].addEventListener("load", () => {
                        placeholderToggle(iframe);
                    });
                    $.ajax({
                        url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
                        type: "GET",
                        dataType: "jsonp",
                        timeout: 10000,
                        success: function ({ code, message, data }) {
                            if (code !== 0) {
                                title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                                iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                                lazyLoadObserver.observe(iframe[0]);
                                console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
                                const errorType = getErrorType(code);
                                if (errorType) {
                                    ids[errorType][prefix.iframe].add(id);
                                }
                                return;
                            }
                            const list = data.pages;
                            let _page = 1;
                            const name = title || (data.title ? data.title : prefix.href + id);
                            let index;
                            let length;
                            if (pagename) {
                                for (index = 0, length = list.length; index < length; index++) {
                                    if (list[index].part !== pagename) { continue; }
                                    _page = list[index].page;
                                    break;
                                }
                            } else { _page = page; }
                            index = _page - 1;
                            const href = title_text.attr("href");
                            if (list[index] !== undefined && list[index].cid !== undefined) {
                                iframe.attr("data-src", `${iframe_href_base}${prefix.iframe}=${id}&cid=${list[index].cid}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                                title_text.attr("href", href.replace(new RegExp(`\\?p=${page}`, "g"), `?p=${_page}`));
                                title_text.text(`${name} [${_page}/${list.length}]${tIsInvalid ? "" : `[视频从${time}开始播放]`}`);
                                if (subtitle) { title_text.append(`<br>(${_page}、${list[index].part})`); }
                            } else {
                                title_text.text(name + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                                iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                            }
                            lazyLoadObserver.observe(iframe[0]);
                        },
                        error: function () {
                            title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                            iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                            lazyLoadObserver.observe(iframe[0]);
                        },
                        complete: function () {
                            if (selfbox.is('[data-auto-expand="true"]')) {
                                selfbox.addClass("onshow");
                                iframeContainer.show();
                                toggleButton.text("隐藏视频");
                                selfbox.removeAttr("style");
                            }
                            submit(ids);
                        },
                    });
                    //toggle
                    toggleButton.on("click", () => {
                        selfbox.width(iframeContainer.outerWidth(true));
                        selfbox.toggleClass("onshow");
                        iframeContainer.toggle();
                        if (toggleButton.text() === "显示视频") {
                            toggleButton.text("隐藏视频");
                            $(window).resize();
                        } else {
                            toggleButton.text("显示视频");
                            selfbox.removeAttr("style");
                        }
                    });
                    widescreenButton.on("click", () => {
                        if (selfbox.is(":not(.onshow)")) { return; }
                        if (selfbox.is(".widescreen")) {
                            selfbox.removeClass("widescreen");
                            widescreenButton.text("显示宽屏");
                            recallWH(iframeContainer);
                            recallWH(iframe);
                            recallWH(selfbox);
                        } else {
                            selfbox.addClass("widescreen");
                            widescreenButton.text("退出宽屏");
                            rememberWH(selfbox);
                            selfbox.css("width", selfbox.parent().width() > Math.min(911, global_element.width()) ? "73%" : "100%"); //可以看见按钮的最小宽度 665 的 1/0.73 倍
                            setTureHeight(selfbox);
                            rememberWH(iframe);
                            rememberWH(iframeContainer);
                            setWH(iframe);
                            setWH(iframeContainer);
                            iframeContainer.height(selfbox.height() - title_text.parent().height());
                            setMaxHeight(selfbox, iframeContainer);
                        }
                    });
                });
            };
            $(run);
            mw.hook("wikipage.content").add(run);
            $(window).on("load", run);
            $(window).on("resize", () => {
                $(".bilibili-video-container.onshow.widescreen").each((_, ele) => {
                    const selfbox = $(ele);
                    selfbox.css("width", selfbox.parent().width() > Math.min(911, global_element.width()) ? "73%" : "100%");
                    setTureHeight(selfbox);
                    setMaxHeight(selfbox, selfbox.find(".bilibili-iframe-container"));
                });
            });
        }
    } catch (e) {
        /* eslint-disable */
        var msg = genErr("error", navigator.userAgent + " : " + e + " " + e.stack.split("\n")[1].trim());
        $(".bilibili-video-container").each(function (_, ele) {
            ele.outerHTML = msg;
        });
        /* eslint-enable */
    }
});

2023年5月1日 (一) 13:01的版本

/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
console.log("欢迎来到纸飞机Wiki")



"use strict";
window.RLQ.push(async () => {
    const errMsg = {
        id: '此处填写的id有误,请参考<a href="https://zh.moegirl.org.cn/Template:BilibiliVideo#firstHeading" target="_blank">模板文档</a>修正……',
        error: "执行出现问题,请复制以下内容并在提问求助区处粘贴寻求帮助:$$$",
        attr: '下方填写的参数 $$$ 有误,请参考<a href="https://zh.moegirl.org.cn/Template:BilibiliVideo#firstHeading" target="_blank">模板文档</a>修正……',
    };
    await $.ready;
    const ifNamespaceAllow = [0, 4, 10, 12].includes(mw.config.get("wgNamespaceNumber"));
    const sanNode = $(`<${"span/"}>`);
    const genErr = (type, msg = "") => type in errMsg ? `<${"div"} style="font-style: italic; border: 1px dashed red;">BilibiliVideo模板:${errMsg[type].replace("$$$", sanNode.text(msg).html())}<${"/div"}>` : "";
    const injectErrMsgBefore = ($ele, type, msg = "") => $ele.before(genErr(type, msg));
    const getErrorType = (code) => {
        switch (code) {
            case 62003: {
                return false;
            }
            case -403: {
                return "forbidden";
            }
            default: {
                return "failed";
            }
        }
    };
    try {
        const isNaN = Number.isNaN || window.isNaN;
        const cssLengthUnitValidator = (length, defaultValue, callback, paramName, $ele) => {
            if (typeof length !== "string" || length.length === 0) {
                callback(false);
                return defaultValue;
            }
            const parsedNumber = parseFloat(length.replace(/[a-z]+/i, ""));
            if (isNaN(parsedNumber) || parsedNumber <= 0) {
                callback(false);
                injectErrMsgBefore($ele, "attr", paramName);
                return defaultValue;
            }
            if (/^(?:\d+|\d*\.\d+)(?:em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|Q|in|pc|pt|px|%)$/.test(length)) {
                callback(true);
                return length;
            }
            if (/^(?:\d+|\d*\.\d+)$/.test(length)) {
                callback(true);
                return `${length}px`;
            }
            callback(false);
            injectErrMsgBefore($ele, "attr", paramName);
            return defaultValue;
        };
        const fixedNumber = (number) => `${+number < 10 ? "0" : ""}${number}`;
        const secondsParser = (seconds) => `${Math.floor(+seconds / 60)}:${fixedNumber(+seconds % 60)}`;
        const idCorrector = (id) => {
            if (/^(?:av)?\d{1,9}$/i.test(id)) {
                return {
                    id: id.replace(/^av/i, ""),
                    prefix: {
                        href: "av",
                        iframe: "aid",
                    },
                };
            } else if (/^(?:(?:[bB][vV])?1)?[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}$/.test(id)
                && /4.1.7..$/.test(id)) {
                return {
                    id: id.replace(/^.*([fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9})$/i, "1$1"),
                    prefix: {
                        href: "BV",
                        iframe: "bvid",
                    },
                };
            }
            return false;
        };
        const submit = (ids) => {
            if (!ifNamespaceAllow) {
                return;
            }
            if (--ids.pending > 0) {
                return;
            }
            let changed = false;
            if (ids.failed.aid.size + ids.failed.bvid.size > 0 && !mw.config.get("wgCategories").includes("带有失效视频的条目")) {
                changed = true;
            }
            if (ids.forbidden.aid.size + ids.forbidden.bvid.size > 0 && !mw.config.get("wgCategories").includes("带有受限视频的条目")) {
                changed = true;
            }
            if (ids.failed.aid.size + ids.failed.bvid.size === 0 && mw.config.get("wgCategories").includes("带有失效视频的条目")) {
                changed = true;
            }
            if (ids.forbidden.aid.size + ids.forbidden.bvid.size === 0 && mw.config.get("wgCategories").includes("带有受限视频的条目")) {
                changed = true;
            }
            if (changed) {
                const url = new URL("https://moegirlpedia.annangela.cn/bilibiliCollector/videoCheck");
                url.searchParams.set("pageid", mw.config.get("wgArticleId"));
                $.get(`${url}`);
            }
        };
        if (mw.config.get("skin") === "MoeMobileSkin") {
            const ids = {
                failed: {
                    aid: new Set(),
                    bvid: new Set(),
                },
                forbidden: {
                    aid: new Set(),
                    bvid: new Set(),
                },
                pending: 0,
            };
            const targets = $(".bilibili-video-container:not(.bilibili-video-initialized)");
            ids.pending = targets.length;
            targets.each((_, ele) => {
                const element = $(ele),
                    dataset = ele.dataset;
                element.addClass("bilibili-video-initialized");
                const _id = dataset.id,
                    title = dataset.title,
                    pagename = dataset.pagename,
                    t = parseInt(dataset.t),
                    tIsInvalid = isNaN(t) || t <= 0,
                    subtitle = dataset.subtitle === "true" ? true : false;
                let page = parseInt(dataset.page);
                if (isNaN(page) || page < 1) {
                    page = 1;
                    if (typeof dataset.page === "string" && dataset.page !== "") {
                        injectErrMsgBefore(element, "attr", "page");
                    }
                }
                if ((isNaN(t) || t <= 0) && typeof dataset.t === "string" && dataset.t !== "") {
                    injectErrMsgBefore(element, "attr", "t");
                }
                const validation = idCorrector(_id);
                let id,
                    prefix;
                if (validation) {
                    id = validation.id;
                    prefix = validation.prefix;
                } else {
                    ele.outerHTML = genErr("id");
                    return;
                }
                ele.innerText = "正在加载中,若长时间空白则说明是网络问题……";
                $.ajax({
                    url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
                    type: "GET",
                    dataType: "jsonp",
                    timeout: 10000,
                    success: function ({ code, message, data }) {
                        if (code !== 0) {
                            element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + (![0, 1].includes(page) && !isNaN(page) ? ` (P${page})` : ""))).remove();
                            console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
                            const errorType = getErrorType(code);
                            if (errorType) {
                                ids[errorType][prefix.iframe].add(id);
                            }
                            return;
                        }
                        const list = data.pages;
                        let _page = 1;
                        const name = title || (data.title ? data.title : prefix.href + id);
                        let index;
                        let length;
                        if (pagename) {
                            for (index = 0, length = list.length; index < length; index++) {
                                if (list[index].part !== pagename) { continue; }
                                _page = list[index].page;
                                break;
                            }
                        } else { _page = page; }
                        index = _page - 1;
                        const time = secondsParser(t);
                        const button = $("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${_page}${tIsInvalid ? "" : `&t=${t}`}`).text(`${name} [${_page}/${secondsParser(list[index].duration)}]${tIsInvalid ? "" : `[跳转至${time}]`}`);
                        if (list[index] !== undefined && list[index].cid !== undefined && subtitle) {
                            button.append(`<br>(${_page}、${list[index].part})`);
                        }
                        element.before(button).remove();
                    },
                    error: function () {
                        element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + (![0, 1].includes(page) && !isNaN(page) ? ` (P${page})` : ""))).remove();
                    },
                    complete: () => {
                        submit(ids);
                    },
                });
            });
        }
        else {
            const global_element = $("#mw-content-text");
            const placeholderToggle = (iframe) => {
                if (iframe.data("displayFlag")) {
                    iframe.data("displayFlag", false);
                    iframe.data("placeholder").fadeOut(370);
                }
            };
            let lazyLoadObserver;
            if ("IntersectionObserver" in window &&
                "IntersectionObserverEntry" in window &&
                "intersectionRatio" in window.IntersectionObserverEntry.prototype &&
                "isIntersecting" in window.IntersectionObserverEntry.prototype) {
                lazyLoadObserver = new IntersectionObserver((entries) => {
                    entries.forEach((entry) => {
                        if (entry.isIntersecting) {
                            entry.target.src = entry.target.dataset.src;
                            setTimeout(() => {
                                placeholderToggle($(entry.target));
                            }, 13070);
                            lazyLoadObserver.unobserve(entry.target);
                        }
                    });
                });
            } else {
                lazyLoadObserver = {
                    observe: (target) => {
                        target.src = target.dataset.src;
                        setTimeout(() => {
                            placeholderToggle($(target));
                        }, 13070);
                    },
                };
            }
            const iframe_href_base = "https://www.bilibili.com/blackboard/newplayer.html?playlist=true&playlist_order=sequential&musth5=1&noEndPanel=1&crossDomain=1&autoplay=0&";
            const EPSILON = 2.220446049250313e-16,
                rememberWH = function rememberWH(ele) {
                    ele.data({ width: ele.width(), height: ele.height() });
                },
                setTureHeight = function setTureHeight(ele) {
                    const barHeight = ele.data("height") - ele.data("width") * 9 / 16; //计算标题和播放器控制栏高度
                    ele.height(ele.width() * 9 / 16 + barHeight);
                },
                setWH = function setWH(ele) {
                    ele.css({ width: "100%", height: "100%" });
                },
                recallWH = function recallWH(ele) {
                    ele.width(ele.data("width")).height(ele.data("height"));
                },
                setMaxHeight = function setMaxHeight(container, target) {
                    const h = container.outerHeight(true);
                    let t = 0;
                    container.children().each((_, ele) => {
                        t += $(ele).outerHeight(true);
                    });
                    target.css("max-height", `calc(100% - ${parseInt(t - h + 2 - (Number.EPSILON || EPSILON))}px)`);
                };
            const run = () => {
                const ids = {
                    failed: {
                        aid: new Set(),
                        bvid: new Set(),
                    },
                    forbidden: {
                        aid: new Set(),
                        bvid: new Set(),
                    },
                    pending: 0,
                };
                const targets = $(".bilibili-video-container:not(.exec)");
                ids.pending = targets.length;
                targets.addClass("exec").each((_, ele) => {
                    const dataset = ele.dataset;
                    const _id = dataset.id;
                    const selfbox = $(ele);
                    const toggleButton = selfbox.find(".bilibili-toggle");
                    const widescreenButton = selfbox.find(".bilibili-widescreen");
                    const validation = idCorrector(_id);
                    let id,
                        prefix;
                    if (validation) {
                        id = validation.id;
                        prefix = validation.prefix;
                    } else {
                        ele.outerHTML = genErr("id");
                        return;
                    }
                    let page = parseInt(+(dataset.page || 1));
                    if (isNaN(page) || page < 1) {
                        page = 1;
                        if (typeof dataset.page === "string" && dataset.page !== "") {
                            injectErrMsgBefore(selfbox, "attr", "page");
                        }
                    }
                    const pagename = dataset.pagename;
                    const title = dataset.title;
                    const height = cssLengthUnitValidator(dataset.height, "441px", (isValidated) => isValidated || selfbox.removeAttr("data-height"), "height", selfbox);
                    const width = cssLengthUnitValidator(dataset.width, "665px", (isValidated) => isValidated || selfbox.removeAttr("data-width"), "width", selfbox);
                    const maxHeight = cssLengthUnitValidator(dataset.maxHeight, "100vh", (isValidated) => isValidated || selfbox.removeAttr("data-max-height"), "maxHeight", selfbox);
                    const maxWidth = cssLengthUnitValidator(dataset.maxWidth, "100%", (isValidated) => isValidated || selfbox.removeAttr("data-max-width"), "maxWidth", selfbox);
                    const subtitle = dataset.subtitle === "true" ? true : false;
                    const t = parseInt(dataset.t);
                    const tIsInvalid = isNaN(t) || t <= 0;
                    const iframeContainer = selfbox.find(".bilibili-iframe-container");
                    const title_text = $("<a/>").attr("rel", "nofollow noreferrer noopener").addClass("external text").attr({
                        href: `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`,
                        target: "_blank",
                    }).prependTo(selfbox.find(".bilibili-title"));
                    const iframe = $("<iframe/>").attr({
                        allow: "fullscreen",
                        allowfullscreen: true,
                        frameborder: 0,
                        scrolling: "no",
                        src: "",
                        "class": "bilibili-iframe",
                    }).css({
                        width: width,
                        height: height,
                        "max-width": maxWidth,
                        "max-height": maxHeight,
                    });
                    if (!tIsInvalid) {
                        selfbox.removeAttr("data-auto-expand");
                    } else if (typeof dataset.t === "string" && dataset.t !== "") {
                        injectErrMsgBefore(selfbox, "attr", "t");
                    }
                    const time = secondsParser(t);
                    title_text.text(`${(title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`)}【视频信息加载中……】`);
                    iframeContainer.css({
                        width: width,
                        height: height,
                        "max-width": maxWidth,
                        "max-height": maxHeight,
                    });
                    iframe.appendTo(iframeContainer);
                    const div = $("<div/>");
                    div.css({
                        position: "absolute",
                        top: "0",
                        left: "0",
                        bottom: "0",
                        right: "0",
                        "z-index": "99",
                        display: "flex",
                        "align-items": "center",
                        background: "rgba(255, 255, 255, .37)",
                    });
                    const text = $("<div/>");
                    text.css({
                        "text-align": "center",
                        width: "100%",
                    }).text("正在加载中,若长时间空白则说明是网络问题……");
                    div.append(text).appendTo(iframeContainer);
                    iframe.data({
                        placeholder: div,
                        displayFlag: true,
                    });
                    iframe[0].addEventListener("load", () => {
                        placeholderToggle(iframe);
                    });
                    $.ajax({
                        url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
                        type: "GET",
                        dataType: "jsonp",
                        timeout: 10000,
                        success: function ({ code, message, data }) {
                            if (code !== 0) {
                                title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                                iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                                lazyLoadObserver.observe(iframe[0]);
                                console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
                                const errorType = getErrorType(code);
                                if (errorType) {
                                    ids[errorType][prefix.iframe].add(id);
                                }
                                return;
                            }
                            const list = data.pages;
                            let _page = 1;
                            const name = title || (data.title ? data.title : prefix.href + id);
                            let index;
                            let length;
                            if (pagename) {
                                for (index = 0, length = list.length; index < length; index++) {
                                    if (list[index].part !== pagename) { continue; }
                                    _page = list[index].page;
                                    break;
                                }
                            } else { _page = page; }
                            index = _page - 1;
                            const href = title_text.attr("href");
                            if (list[index] !== undefined && list[index].cid !== undefined) {
                                iframe.attr("data-src", `${iframe_href_base}${prefix.iframe}=${id}&cid=${list[index].cid}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                                title_text.attr("href", href.replace(new RegExp(`\\?p=${page}`, "g"), `?p=${_page}`));
                                title_text.text(`${name} [${_page}/${list.length}]${tIsInvalid ? "" : `[视频从${time}开始播放]`}`);
                                if (subtitle) { title_text.append(`<br>(${_page}、${list[index].part})`); }
                            } else {
                                title_text.text(name + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                                iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                            }
                            lazyLoadObserver.observe(iframe[0]);
                        },
                        error: function () {
                            title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                            iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                            lazyLoadObserver.observe(iframe[0]);
                        },
                        complete: function () {
                            if (selfbox.is('[data-auto-expand="true"]')) {
                                selfbox.addClass("onshow");
                                iframeContainer.show();
                                toggleButton.text("隐藏视频");
                                selfbox.removeAttr("style");
                            }
                            submit(ids);
                        },
                    });
                    //toggle
                    toggleButton.on("click", () => {
                        selfbox.width(iframeContainer.outerWidth(true));
                        selfbox.toggleClass("onshow");
                        iframeContainer.toggle();
                        if (toggleButton.text() === "显示视频") {
                            toggleButton.text("隐藏视频");
                            $(window).resize();
                        } else {
                            toggleButton.text("显示视频");
                            selfbox.removeAttr("style");
                        }
                    });
                    widescreenButton.on("click", () => {
                        if (selfbox.is(":not(.onshow)")) { return; }
                        if (selfbox.is(".widescreen")) {
                            selfbox.removeClass("widescreen");
                            widescreenButton.text("显示宽屏");
                            recallWH(iframeContainer);
                            recallWH(iframe);
                            recallWH(selfbox);
                        } else {
                            selfbox.addClass("widescreen");
                            widescreenButton.text("退出宽屏");
                            rememberWH(selfbox);
                            selfbox.css("width", selfbox.parent().width() > Math.min(911, global_element.width()) ? "73%" : "100%"); //可以看见按钮的最小宽度 665 的 1/0.73 倍
                            setTureHeight(selfbox);
                            rememberWH(iframe);
                            rememberWH(iframeContainer);
                            setWH(iframe);
                            setWH(iframeContainer);
                            iframeContainer.height(selfbox.height() - title_text.parent().height());
                            setMaxHeight(selfbox, iframeContainer);
                        }
                    });
                });
            };
            $(run);
            mw.hook("wikipage.content").add(run);
            $(window).on("load", run);
            $(window).on("resize", () => {
                $(".bilibili-video-container.onshow.widescreen").each((_, ele) => {
                    const selfbox = $(ele);
                    selfbox.css("width", selfbox.parent().width() > Math.min(911, global_element.width()) ? "73%" : "100%");
                    setTureHeight(selfbox);
                    setMaxHeight(selfbox, selfbox.find(".bilibili-iframe-container"));
                });
            });
        }
    } catch (e) {
        /* eslint-disable */
        var msg = genErr("error", navigator.userAgent + " : " + e + " " + e.stack.split("\n")[1].trim());
        $(".bilibili-video-container").each(function (_, ele) {
            ele.outerHTML = msg;
        });
        /* eslint-enable */
    }
});