Widget:BilibiliVideo:修订间差异

跳到导航 跳到搜索
添加1,311字节 、​ 2020年10月12日 (星期一)
无编辑摘要
imported>=海豚=
(文本替换 - 替换“zh.moegirl.org”为“zh.moegirl.org.cn”)
imported>=海豚=
无编辑摘要
第1行: 第1行:
<noinclude>{{BilibiliVideo/doc/copyright}}
<noinclude>{{BilibiliVideo/doc/copyright}}
'''本Widget不能单独使用''',请使用{{tl|BilibiliVideo}}!</noinclude><includeonly>
'''本Widget不能单独使用''',请使用{{tl|BilibiliVideo}}!</noinclude><includeonly><!--{if !isset($wgBilibili) || !$wgBilibili}--><!--{assign var="wgBilibili" value=true scope="global"}--><style>
<!--{if !isset($wgBilibili) || !$wgBilibili}-->
<!--{assign var="wgBilibili" value=true scope="global"}-->
<style>
.bilibili-video-container {
.bilibili-video-container {
    border: 1px solid rgba(170,170,170,0.37);
    border: 1px solid rgba(170,170,170,0.37);
第112行: 第109行:
"use strict";
"use strict";
window.RLQ.push(() => {
window.RLQ.push(() => {
   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>修正……',
   };
   const sanNode = $(decodeURIComponent("%3Cspan%2F%3E"));
   const genErr = (type, msg = "") => type in errMsg ? `${decodeURIComponent("%3Cdiv%20style%3D%22font-style%3A%20italic%3B%22%3E")}BilibiliVideo模板:${errMsg[type].replace("$$$", sanNode.text(msg).html())}${decodeURIComponent("%3C%2Fdiv%3E")}` : "";
   const injectErrMsgBefore = ($ele, type, msg = "") => $ele.before(genErr(type, msg));
    try {
    try {
      const isNaN = Number.isNaN || window.isNaN;
      const isNaN = Number.isNaN || window.isNaN;
      const temp = new Set();
      const temp = new Set();
      const cssLengthUnitValidator = (length, defaultValue, callback) => {
      const cssLengthUnitValidator = (length, defaultValue, callback, paramName, $ele) => {
        if (typeof length !== "string" || length.length === 0) {
        if (typeof length !== "string" || length.length === 0) {
          callback(false);
          callback(false);
第123行: 第128行:
        if (isNaN(parsedNumber) || parsedNumber <= 0) {
        if (isNaN(parsedNumber) || parsedNumber <= 0) {
          callback(false);
          callback(false);
         injectErrMsgBefore($ele, "attr", paramName);
          return defaultValue;
          return defaultValue;
        }
        }
第134行: 第140行:
        }
        }
        callback(false);
        callback(false);
       injectErrMsgBefore($ele, "attr", paramName);
        return defaultValue;
        return defaultValue;
      };
      };
      const converter = new class Converter {
      /* const converter = new class Converter {
        constructor() {
        constructor() {
          this._base58Table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
          this._base58Table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
第187行: 第194行:
          });
          });
        }
        }
      };
      }; */
     const fixedNumber = (number) => `${+number < 10 ? "0" : ""}${number}`;
     const secondsParser = (seconds) => `${Math.floor(+seconds / 60)}:${fixedNumber(+seconds % 60)}`;
      if (mw.config.get("skin") === "minerva") {
      if (mw.config.get("skin") === "minerva") {
        $(".bilibili-video-container:not(.bilibili-video-initialized)").each((_, ele) => {
        $(".bilibili-video-container:not(.bilibili-video-initialized)").each((_, ele) => {
第201行: 第210行:
            subtitle = dataset.subtitle === "true" ? true : false;
            subtitle = dataset.subtitle === "true" ? true : false;
          let page = parseInt(dataset.page);
          let page = parseInt(dataset.page);
          if (isNaN(page) || page < 1) { page = 1; }
          if (isNaN(page) || page < 1) {
           page = 1;
           if (typeof dataset.page === "string" && dataset.page !== "") {
             injectErrMsgBefore(element, "attr", "page");
           }
         }
         if (typeof dataset.t === "string" && dataset.t !== "") {
           injectErrMsgBefore(element, "attr", "t");
         }
          let prefix;
          let prefix;
         let decode = null;
          if (/^(?:av)?\d{1,9}$/i.test(_id)) {
          if (/^(?:av)?\d{1,9}$/i.test(_id)) {
            prefix = {
            prefix = {
第209行: 第225行:
              iframe: "aid",
              iframe: "aid",
            };
            };
          } else if (/^(?:bv)?[\da-z]{10}$/i.test(_id)) {
          } else if (/^(?:[bB][vV])?1?[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}$/.test(_id)) {
            prefix = {
            prefix = {
              href: "BV",
              href: "BV",
              iframe: "bvid",
              iframe: "bvid",
            };
            };
           if (!converter._bvidRegExp.test(_id)) {
             temp.add(_id);
           } else {
             decode = converter.bvidToAid(_id);
           }
          } else {
          } else {
            if (/^(?:av)?\d{10,}$/i.test(_id)) {
            temp.add(_id);
             temp.add(_id);
            return ele.outerHTML = genErr("id");
           }
            return ele.outerHTML = "<i>id 错误</i>";
          }
          }
          ele.innerText = "正在加载中,若长时间空白则说明是网络问题……";
          ele.innerText = "正在加载中,若长时间空白则说明是网络问题……";
          $.ajax({
          $.ajax({
            url: `https://mgwbcprd.azureedge.net/BilibiliMeta/Index/${encodeURIComponent(typeof decode === "string" ? decode : prefix.href + id)}`,
            url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
            type: "GET",
            type: "GET",
           dataType: "jsonp",
            timeout: 10000,
            timeout: 10000,
            success: function (data) {
            success: function ({ code, message, data }) {
              const list = data.VideoEntities
              if (code !== 0) {
                .map((e, i) => {
                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();
                 e.page = i + 1;
               console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
                 e.title = e.Title.replace(/^\d+、/, "");
               return;
                 return e;
             }
               });
             const list = data.pages;
              let _page = 1;
              let _page = 1;
              const name = title || (data.Title ? data.Title : prefix.href + id);
              const name = title || (data.title ? data.title : prefix.href + id);
              let index;
              let index;
              let length;
              let length;
              if (pagename) {
              if (pagename) {
                for (index = 0, length = list.length; index < length; index++) {
                for (index = 0, length = list.length; index < length; index++) {
                  if (list[index].Title !== pagename && list[index].title !== pagename) { continue; }
                  if (list[index].part !== pagename) { continue; }
                  _page = list[index].page;
                  _page = list[index].page;
                  break;
                  break;
第249行: 第259行:
              } else { _page = page; }
              } else { _page = page; }
              index = _page - 1;
              index = _page - 1;
             let sec = `${t % 60}`;
              const time = secondsParser(t);
             if (sec.length === 1) { sec = `0${sec}`; }
              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}]`}`);
              const time = `${Math.floor(t / 60)}:${sec}`;
              if (list[index] !== undefined && list[index].cid !== undefined && subtitle) {
              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}/${list.length}]${tIsInvalid ? "" : `[跳转至${time}]`}`);
                button.append(`<br>(${_page}、${list[index].part})`);
              if (list[index] !== undefined && list[index].VideoCid !== undefined && subtitle) {
                button.append(`<br>(${_page}、${list[index].Title})`);
              }
              }
              element.before(button).remove();
              element.before(button).remove();
            },
            },
            error: function () {
            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].indexOf(page) !== -1 && !isNaN(page) ? ` (P${page})` : ""))).remove();
              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();
            },
            },
          });
          });
第328行: 第336行:
              selfbox = $(ele);
              selfbox = $(ele);
            let prefix;
            let prefix;
           let decode = null;
            if (/^(?:av)?\d{1,9}$/i.test(_id)) {
            if (/^(?:av)?\d{1,9}$/i.test(_id)) {
              prefix = {
              prefix = {
第334行: 第341行:
                iframe: "aid",
                iframe: "aid",
              };
              };
            } else if (/^(?:bv)?[\da-z]{10}$/i.test(_id)) {
            } else if (/^(?:[bB][vV])?1?[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}$/.test(_id)) {
              prefix = {
              prefix = {
                href: "BV",
                href: "BV",
                iframe: "bvid",
                iframe: "bvid",
              };
              };
             if (!converter._bvidRegExp.test(_id)) {
               temp.add(_id);
             } else {
               decode = converter.bvidToAid(_id);
             }
            } else {
            } else {
              if (/^(?:av)?\d{10,}$/i.test(_id)) {
              temp.add(_id);
                temp.add(_id);
             return ele.outerHTML = genErr("id");
           }
           let page = parseInt(+(dataset.page || 1));
           if (isNaN(page) || page < 1) {
             page = 1;
             if (typeof dataset.page === "string" && dataset.page !== "") {
                injectErrMsgBefore(selfbox, "attr", "page");
              }
              }
             return ele.outerHTML = "<i>id错误</i>";
            }
            }
           let page = parseInt(+(dataset.page || 1));
           if (isNaN(page) || page < 1) { page = 1; }
            const pagename = dataset.pagename;
            const pagename = dataset.pagename;
            const title = dataset.title;
            const title = dataset.title;
            const height = cssLengthUnitValidator(dataset.height, "441px", (isValidated) => isValidated || selfbox.removeAttr("data-height"));
            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"));
            const width = cssLengthUnitValidator(dataset.width, "665px", (isValidated) => isValidated || selfbox.removeAttr("data-width"), "width", selfbox);
            const maxHeight = cssLengthUnitValidator(dataset.maxHeight, undefined, (isValidated) => isValidated || selfbox.removeAttr("data-max-height"));
            const maxHeight = cssLengthUnitValidator(dataset.maxHeight, "100vh", (isValidated) => isValidated || selfbox.removeAttr("data-max-height"), "maxHeight", selfbox);
            const maxWidth = cssLengthUnitValidator(dataset.maxWidth, undefined, (isValidated) => isValidated || selfbox.removeAttr("data-max-width"));
            const maxWidth = cssLengthUnitValidator(dataset.maxWidth, "100%", (isValidated) => isValidated || selfbox.removeAttr("data-max-width"), "maxWidth", selfbox);
            const subtitle = dataset.subtitle === "true" ? true : false;
            const subtitle = dataset.subtitle === "true" ? true : false;
            const t = parseInt(dataset.t);
            const t = parseInt(dataset.t);
第378行: 第383行:
              "max-height": maxHeight,
              "max-height": maxHeight,
            });
            });
            if (!tIsInvalid) { selfbox.removeAttr("data-auto-expand"); }
            if (tIsInvalid) {
           let sec = `${t % 60}`;
             selfbox.removeAttr("data-auto-expand");
           if (sec.length === 1) { sec = `0${sec}`; }
             if (typeof dataset.t === "string" && dataset.t !== "") {
            const time = `${Math.floor(t / 60)}:${sec}`;
               injectErrMsgBefore(selfbox, "attr", "t");
            title_text.text(`${(title || prefix.href + id) + ([0, 1].indexOf(page) === -1 ? ` (${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`)}【视频信息加载中……】`);
             }
           }
            const time = secondsParser(t);
            title_text.text(`${(title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`)}【视频信息加载中……】`);
            iframeContainer.css({
            iframeContainer.css({
              width: width,
              width: width,
第415行: 第423行:
              placeholderToggle(iframe);
              placeholderToggle(iframe);
            });
            });
            window.setTimeout(() => { //异步出去不要卡主线程
            $.ajax({
             $.ajax({
             url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
               url: `https://mgwbcprd.azureedge.net/BilibiliMeta/Index/${encodeURIComponent(typeof decode === "string" ? decode : prefix.href + id)}`,
             type: "GET",
               type: "GET",
             dataType: "jsonp",
               timeout: 10000,
             timeout: 10000,
               success: function (data) {
             success: function ({ code, message, data }) {
                 const list = data.VideoEntities
               if (code !== 0) {
                   .map((e, i) => {
                  title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                     e.page = i + 1;
                     e.title = e.Title.replace(/^\d+、/, "");
                     return e;
                   });
                 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].Title !== pagename && list[index].title !== 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].VideoCid !== undefined) {
                   iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&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].Title})`); }
                 } 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 (e) {
                  title_text.text((title || prefix.href + id) + ([0, 1].indexOf(page) === -1 ? ` (${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                 if (e && e.responseJSON && e.responseJSON.message && e.responseJSON.message === "Authentication is required for accessing this video.") { title_text.parent().append('<sup title="“Bilibili采用会员制,大部分投稿视频会员与游客都可以观看,\n  但部分视频在UP主设定下只有会员才可以观看(这些视频常被称为‘只有会员才知道的世界’)。”\n  - Bilibili#用户制度 @ ZhMoegirl\n在这种情况下我们无法为您解析视频及其分P标题、分P数量等。">(只有会员才知道的世界)</sup>'); }
                  iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                  iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                  lazyLoadObserver.observe(iframe[0]);
                  lazyLoadObserver.observe(iframe[0]);
                },
                 console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
              });
                 return;
            }, 13);
               }
               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}&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();
                 selfbox.find(".bilibili-toggle").text("隐藏视频");
                 selfbox.removeAttr("style");
               }
             },
            });
            //toggle
            //toggle
            selfbox.find(".bilibili-toggle").on("click", (_, ele) => {
            selfbox.find(".bilibili-toggle").on("click", (_, ele) => {
第509行: 第525行:
          });
          });
        });
        });
       setTimeout(() => {
         $('.bilibili-video-container.exec[data-auto-expand="true"]').find(".bilibili-toggle").click();
       }, 100);
      }
      }
      setTimeout(async () => {
      setTimeout(async () => {
第541行: 第554行:
      }, 1);
      }, 1);
    } catch (e) {
    } catch (e) {
      // eslint-disable-next-line prefer-template
      /* eslint-disable */
      prompt("BilibiliVideo模板执行出现问题,请复制以下内容并在提问求助区处粘贴寻求帮助:", navigator.userAgent + " : " + e + " " + e.stack.split("\n")[1].trim());
      var msg = genErr("error", navigator.userAgent + " : " + e + " " + e.stack.split("\n")[1].trim());
     $(".bilibili-video-container").each(function (_, ele) {
       ele.outerHTML = msg;
     });
     /* eslint-enable */
    }
    }
});
});
</script><!--{/if}-->
</script><!--{/if}--></includeonly>
</includeonly>
匿名用户

导航菜单