B站评论区开盒

B站评论区直接展示 ip 属地

目前为 2024-07-05 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name B站评论区开盒
  3. // @namespace mscststs
  4. // @version 0.98
  5. // @description B站评论区直接展示 ip 属地
  6. // @author mscststs
  7. // @match *://*.bilibili.com/*
  8. // @exclude *://member.bilibili.com*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
  10. // @require https://gf.qytechs.cn/scripts/38220-mscststs-tools/code/MSCSTSTS-TOOLS.js?version=713767
  11. // @run-at document-start
  12. // @license ISC
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16.  
  17.  
  18. var utils = {
  19. uncurryThis: function uncurryThis(f) {
  20. return function () {
  21. return f.call.apply(f, arguments);
  22. };
  23. },
  24. curryThis: function curryThis(f) {
  25. return function () {
  26. var a = Array.prototype.slice.call(arguments);
  27. a.unshift(this);
  28. return f.apply(null, a);
  29. };
  30. },
  31. bindFn: function bindFn(fn, context) {
  32. var _args = Array.prototype.slice.call(arguments, 2);
  33.  
  34. return function () {
  35. return fn.apply(context, _args.concat(Array.prototype.slice.call(arguments)));
  36. };
  37. },
  38. extend: function extend(child, parent) {
  39. for (var key in parent) {
  40. if (parent.hasOwnProperty(key)) child[key] = parent[key];
  41. }
  42.  
  43. function ctor() {}
  44.  
  45. ctor.prototype = parent.prototype;
  46. child.prototype = new ctor();
  47. child.prototype.constructor = child;
  48. child.__super__ = parent.prototype;
  49. return child;
  50. },
  51. mixin: function mixin(dest) {
  52. var sources = Array.prototype.slice.call(arguments, 1);
  53.  
  54. for (var i = 0; i < sources.length; i++) {
  55. var src = sources[i];
  56.  
  57. for (var key in src) {
  58. if (!dest[key]) {
  59. dest[key] = src[key];
  60. }
  61. }
  62. }
  63. },
  64. distinctArray: function distinctArray(arr) {
  65. var newArray = [],
  66. dict = {},
  67. i = 0,
  68. item;
  69.  
  70. for (; i < arr.length; i++) {
  71. item = arr[i];
  72.  
  73. var key = item + ':' + _typeof(item);
  74.  
  75. if (!dict[key]) {
  76. newArray.push(item);
  77. dict[key] = true;
  78. }
  79. }
  80.  
  81. return newArray;
  82. },
  83.  
  84. /*
  85. * 访问终端信息判断
  86. */
  87. browser: {
  88. version: function () {
  89. var u = navigator.userAgent,
  90. app = navigator.appVersion;
  91. return {
  92. //移动终端浏览器版本信息
  93. trident: /Trident/i.test(u),
  94. //IE内核
  95. presto: /Presto/i.test(u),
  96. //opera内核
  97. webKit: /AppleWebKit/i.test(u),
  98. //苹果、谷歌内核
  99. gecko: /Gecko/i.test(u) && !/KHTML/i.test(u),
  100. //火狐内核
  101. mobile: /AppleWebKit.*Mobile.*/i.test(u),
  102. //是否为移动终端
  103. ios: /\(i[^;]+;( U;)? CPU.+Mac OS X/i.test(u),
  104. //ios终端
  105. android: /Android/i.test(u) || /Linux/i.test(u),
  106. //android终端或者uc浏览器
  107. windowsphone: /Windows Phone/i.test(u),
  108. //Windows Phone
  109. iPhone: /iPhone/i.test(u),
  110. //是否为iPhone或者QQHD浏览器
  111. iPad: /iPad/i.test(u),
  112. //是否iPad
  113. MicroMessenger: /MicroMessenger/i.test(u),
  114. //是否为微信
  115. webApp: !/Safari/i.test(u),
  116. //是否web应该程序,没有头部与底部
  117. edge: /edge/i.test(u),
  118. weibo: /Weibo/i.test(u),
  119. uc: /UCBrowser/i.test(u),
  120. qq: /MQQBrowser/i.test(u),
  121. baidu: /Baidu/i.test(u),
  122. comicApp: /BiliComic|ComicWebView/i.test(u) //是否在漫画的app,或者漫画自己封装的webview
  123.  
  124. };
  125. }(),
  126. language: (navigator.browserLanguage || navigator.language).toLowerCase(),
  127. lteIE: function lteIE(ver) {
  128. return $.browser.msie && parseInt($.browser.version) <= ver;
  129. }
  130. },
  131. cookie: {
  132. get: function get(cookieName) {
  133. var theCookie = "" + document.cookie;
  134. var ind = theCookie.indexOf(cookieName + "=");
  135. if (ind == -1 || cookieName == "") return "";
  136. var ind1 = theCookie.indexOf(';', ind);
  137. if (ind1 == -1) ind1 = theCookie.length;
  138. return unescape(theCookie.substring(ind + cookieName.length + 1, ind1));
  139. },
  140. set: function set(name, value, days) {
  141. days = days !== undefined ? days : 365;
  142. var exp = new Date();
  143. exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000);
  144. document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString() + "; path=/; domain=.bilibili.com";
  145. },
  146. 'delete': function _delete(name) {
  147. this.set(name, '', -1);
  148. }
  149. },
  150. readFromLocal: function readFromLocal(key) {
  151. if (this.localStorage._support) {
  152. return localStorage.getItem(key);
  153. } else {
  154. return this.cookie.get(key);
  155. }
  156. },
  157. saveToLocal: function saveToLocal(key, val, days) {
  158. if (this.localStorage._support) {
  159. return localStorage.setItem(key, val);
  160. } else {
  161. return this.cookie.set(key, val, days);
  162. }
  163. },
  164. localStorage: {
  165. _support: window.localStorage && typeof (window.localStorage) == 'object' ? true : false,
  166. getItem: function getItem(key) {
  167. if (this._support) {
  168. return window.localStorage.getItem(key);
  169. } else {
  170. return null;
  171. }
  172. },
  173. setItem: function setItem(key, value) {
  174. if (this._support) {
  175. window.localStorage.setItem(key, value);
  176. }
  177. },
  178. removeItem: function removeItem(key) {
  179. if (this.getItem(key)) {
  180. window.localStorage.removeItem(key);
  181. }
  182. }
  183. },
  184. unhtml: function unhtml(str, reg) {
  185. return str ? str.replace(reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g, function (a, b) {
  186. if (b) {
  187. return a;
  188. } else {
  189. return {
  190. '<': '&lt;',
  191. '&': '&amp;',
  192. '"': '&quot;',
  193. '>': '&gt;',
  194. "'": '&apos;'
  195. }[a];
  196. }
  197. }) : '';
  198. },
  199. html: function html(str) {
  200. return str ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) {
  201. return {
  202. '&lt;': '<',
  203. '&amp;': '&',
  204. '&quot;': '"',
  205. '&gt;': '>',
  206. '&#39;': "'",
  207. '&nbsp;': ' '
  208. }[m];
  209. }) : '';
  210. },
  211. hashManage: {
  212. prependHash: '!',
  213. _change: function _change(key, value) {
  214. var hash = location.hash,
  215. hashArray,
  216. hashMap = {},
  217. hashString = '',
  218. index = 0;
  219.  
  220. if (hash) {
  221. hash = hash.substring(1);
  222.  
  223. if (this.prependHash) {
  224. hash = hash.replace(new RegExp('^' + this.prependHash.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")), '');
  225. }
  226. }
  227.  
  228. hashArray = hash.split('&');
  229.  
  230. for (var i = 0; i < hashArray.length; i++) {
  231. var _k = hashArray[i].split('=')[0],
  232. _v = hashArray[i].split('=')[1];
  233.  
  234. if (_k) {
  235. hashMap[_k] = decodeURIComponent(_v);
  236. }
  237. }
  238.  
  239. if (_typeof(key) == 'object') {
  240. for (var j in key) {
  241. var _val = key[j];
  242.  
  243. if (_val) {
  244. hashMap[j] = encodeURIComponent(_val);
  245. } else if (_val === false) {
  246. delete hashMap[j];
  247. }
  248. }
  249. } else {
  250. if (value) {
  251. hashMap[key] = encodeURIComponent(value);
  252. } else if (value === false) {
  253. delete hashMap[key];
  254. } else if (typeof key == 'undefined') {
  255. return hashMap;
  256. } else {
  257. return hashMap[key] || null;
  258. }
  259. }
  260.  
  261. for (var k in hashMap) {
  262. if (index != 0) {
  263. hashString += '&';
  264. } else {
  265. hashString += this.prependHash;
  266. }
  267.  
  268. hashString += k + '=' + hashMap[k];
  269. index++;
  270. }
  271.  
  272. location.hash = hashString;
  273. return hashMap;
  274. },
  275. get: function get(key) {
  276. return this._change(key, null);
  277. },
  278. set: function set(key, value) {
  279. return this._change(key, value);
  280. },
  281. clear: function clear() {
  282. location.hash = '';
  283. }
  284. },
  285. getColor16: function getColor16(rgb) {
  286. function _to16(d) {
  287. var color = parseInt(d).toString(16);
  288. return color.length == 1 ? "0" + color : color;
  289. }
  290.  
  291. function _parse(array) {
  292. var value = "#";
  293.  
  294. for (var i = 0; i < 3; i++) {
  295. value += _to16(array[i]);
  296. }
  297.  
  298. return value;
  299. }
  300.  
  301. var result = "";
  302. var rgbArray = [];
  303.  
  304. if (rgb.match(/\((.*)\)/) != null) {
  305. rgbArray = rgb.match(/\((.*)\)/)[1].split(",");
  306. result = _parse(rgbArray);
  307. } else if (rgb.match(/,+/g) != null) {
  308. rgbArray = rgb.split(",");
  309. result = _parse(rgbArray);
  310. } else {
  311. result = _to16(rgb);
  312. }
  313.  
  314. return result;
  315. },
  316. serializeParam: function serializeParam(json) {
  317. var strArr = [];
  318.  
  319. for (var i in json) {
  320. if (!(_typeof(json[i]).toLowerCase() == "function" || _typeof(json[i]).toLowerCase() == "object")) {
  321. strArr.push(encodeURIComponent(i) + "=" + encodeURIComponent(json[i]));
  322. } else if ($.isArray(json[i])) {
  323. //支持传数组内容
  324. for (var j = 0; j < json[i].length; j++) {
  325. strArr.push(encodeURIComponent(i) + "[]=" + encodeURIComponent(json[i][j]));
  326. }
  327. }
  328. }
  329.  
  330. return strArr.join("&");
  331. },
  332. query2json: function query2json(query) {
  333. if ($.isPlainObject(query)) {
  334. return query;
  335. }
  336.  
  337. if (query === undefined) {
  338. return {};
  339. }
  340.  
  341. var q = query.split("&"),
  342. j = {};
  343.  
  344. for (var i = 0; i < q.length; i++) {
  345. var arr = q[i].split('=');
  346. j[arr[0]] = arr[1];
  347. }
  348.  
  349. return j;
  350. },
  351. hash2json: function hash2json() {
  352. if (window.location.href.split('#').length > 1) {
  353. return this.query2json(window.location.href.split('#')[1].split('?')[0].replace(/#/, ""));
  354. } else {
  355. return {};
  356. }
  357. },
  358. query: {
  359. get: function get(key) {
  360. var queryJson = utils.query2json(this._getQuery());
  361.  
  362. if (key) {
  363. return queryJson[key];
  364. } else {
  365. return queryJson;
  366. }
  367. },
  368. set: function set(key, value) {
  369. var queryJson = utils.query2json(this._getQuery());
  370. var hashJson = utils.hash2json();
  371.  
  372. if (_typeof(key) == 'object') {
  373. for (var k in key) {
  374. this._set(queryJson, k, key[k]);
  375. }
  376. } else {
  377. this._set(queryJson, key, value);
  378. }
  379.  
  380. return utils.makeUrl('', queryJson, hashJson);
  381. },
  382. _set: function _set(json, key, value) {
  383. if (value === null) {
  384. delete json[key];
  385. } else {
  386. json[key] = value;
  387. }
  388.  
  389. return json;
  390. },
  391. _getQuery: function _getQuery() {
  392. if (window.location.search !== undefined) {
  393. return window.location.search.substring(1);
  394. } else {
  395. return window.location.href.split('?')[1] ? window.location.href.split('?')[1].split('#')[0] : '';
  396. }
  397. }
  398. },
  399. makeUrl: function makeUrl(url, queryJson, hashJson) {
  400. var query = this.serializeParam(queryJson),
  401. hash = this.serializeParam(hashJson),
  402. _url;
  403.  
  404. if (query) {
  405. _url = (url || location.pathname) + '?' + query;
  406. } else {
  407. _url = url || location.pathname;
  408. }
  409.  
  410. if (hash) {
  411. _url = _url + '#' + hash;
  412. }
  413.  
  414. return _url;
  415. },
  416. formatNum: function formatNum(num, unit) {
  417. if (num === undefined || typeof num == 'string' && isNaN(parseInt(num))) return '--';
  418. var unitMap = {
  419. '万': 10000
  420. },
  421. defaultUnit = '万';
  422. unit = typeof unit == 'string' ? unit : defaultUnit;
  423. var factor = unitMap[unit] || unitMap[defaultUnit];
  424. if (typeof num == 'string' && num.indexOf(unit) >= 0) return;
  425.  
  426. if (typeof num == 'string' && num.indexOf(",") >= 0) {
  427. var nums = num.split(",");
  428. var total = "";
  429.  
  430. for (var i = 0; i < nums.length; i++) {
  431. total += nums[i];
  432. }
  433.  
  434. num = total;
  435. }
  436.  
  437. num = parseInt(num);
  438.  
  439. if (num >= factor) {
  440. num = (num / factor).toFixed(1) + unit;
  441. }
  442.  
  443. return num;
  444. },
  445. parseCardProps: function parseCardProps(dataItem, type) {
  446. var props = {
  447. 'data-gk': dataItem.play,
  448. 'data-sc': dataItem.favorites,
  449. 'data-pl': dataItem.review,
  450. 'data-dm': dataItem.video_review,
  451. 'data-up': dataItem.author,
  452. 'data-subtitle': dataItem.subtitle,
  453. 'data-lm': dataItem.typename || '',
  454. 'data-tg': dataItem.created ? new Date(dataItem.created * 1000).format('yyyy-MM-dd hh:mm') : dataItem.create || dataItem.created_at,
  455. 'data-txt': dataItem.description,
  456. 'data-yb': dataItem.coins
  457. },
  458. str = "";
  459.  
  460. if (type == 'string') {
  461. for (var k in props) {
  462. if (str != "") {
  463. str += " ";
  464. }
  465.  
  466. str += k + '="' + props[k] + '"';
  467. }
  468.  
  469. return str;
  470. } else {
  471. return props;
  472. }
  473. },
  474. newParseCardProps: function newParseCardProps(dataItem, type) {
  475. var props = {
  476. 'data-gk': dataItem.stat.view,
  477. 'data-sc': dataItem.stat.favorite,
  478. 'data-pl': dataItem.stat.reply,
  479. 'data-dm': dataItem.stat.danmaku,
  480. 'data-up': dataItem.owner.name,
  481. 'data-lm': dataItem.tname || '',
  482. 'data-tg': new Date(dataItem.pubdate * 1000).format('yyyy-MM-dd hh:mm'),
  483. 'data-txt': dataItem.desc,
  484. 'data-yb': dataItem.stat.coin
  485. };
  486. return props;
  487. },
  488. // protocol-relative 为了兼容ie8以下
  489. protocolRelative: function protocolRelative(url) {
  490. if (/http:|https:/.test(url)) {
  491. return url.replace(/http:|https:/, window.location.protocol);
  492. } else if ($.browser.msie && parseInt($.browser.version) <= 8) {
  493. return window.location.protocol + url;
  494. } else {
  495. return url;
  496. }
  497. },
  498. formatDuration: function formatDuration(duration, isToHour, minHeadBits) {
  499. if (typeof duration !== 'number') {
  500. return duration;
  501. }
  502.  
  503. minHeadBits = minHeadBits || -1;
  504. var second = this.toFixed(duration % 60, 2);
  505. var minute = isToHour ? this.toFixed(Math.floor(duration % 3600 / 60), 2) : this.toFixed(Math.floor(duration / 60), minHeadBits);
  506. var hour = isToHour ? this.toFixed(Math.floor(duration / 3600), minHeadBits) : null;
  507. return hour === null ? [minute, second].join(':') : [hour, minute, second].join(':');
  508. },
  509. isObject: function isObject(obj) {
  510. return _typeof(obj) === 'object' && obj !== null;
  511. },
  512. isNothing: function isNothing(obj) {
  513. return obj == null; // Only deal with null/undefined values
  514. },
  515. isUndefined: function isUndefined(obj) {
  516. return typeof obj === 'undefined';
  517. },
  518. join: function join() {
  519. return Array.prototype.join.call(arguments, '');
  520. },
  521. random: function random(start, end) {
  522. if (this.isNothing(end)) {
  523. end = start;
  524. start = 0;
  525. }
  526.  
  527. return Math.floor(Math.random() * (end - start + 1)) + start;
  528. },
  529. debounce: function debounce(func, delay, isImmediate) {
  530. var timeout;
  531.  
  532. function debounced() {
  533. clearTimeout(timeout);
  534.  
  535. if (isImmediate && utils.isNothing(timeout)) {
  536. func();
  537. }
  538.  
  539. timeout = setTimeout(func, delay || 100);
  540. }
  541.  
  542. debounced.clearNext = function () {
  543. clearTimeout(timeout);
  544. };
  545.  
  546. return debounced;
  547. },
  548. throttle: function throttle(func, delay, options) {
  549. var timeout,
  550. prev = 0;
  551. delay = delay || 200;
  552. options = options || {};
  553.  
  554. function later() {
  555. prev = options.head ? 0 : new Date().getTime();
  556. timeout = null;
  557. func();
  558. }
  559.  
  560. function throttled() {
  561. var remain,
  562. now = new Date().getTime();
  563.  
  564. if (!prev && options.head) {
  565. prev = now;
  566. }
  567.  
  568. remain = delay - (now - prev);
  569.  
  570. if (remain <= 0 || remain > delay) {
  571. clearTimeout(timeout);
  572. timeout = null;
  573. prev = now;
  574. func();
  575. } else if (!timeout && !options.tail) {
  576. timeout = setTimeout(later, remain);
  577. }
  578. }
  579.  
  580. throttled.clearNext = function () {
  581. clearTimeout(timeout);
  582. timeout = null;
  583. prev = 0;
  584. };
  585.  
  586. return throttled;
  587. },
  588. toFixed: function toFixed(data, bits) {
  589. if (typeof data !== 'number' && typeof data !== 'string') {
  590. return data;
  591. }
  592.  
  593. data = String(data);
  594. bits = Number(bits) || 2;
  595.  
  596. while (data.length < bits) {
  597. data = '0' + data;
  598. }
  599.  
  600. return data.length > bits ? data : data.slice(-bits);
  601. },
  602. thumbnail: function thumbnail(src, width, height) {
  603. if (typeof src !== 'string') {
  604. return src;
  605. }
  606.  
  607. if (typeof width === 'undefined') {
  608. return src;
  609. }
  610.  
  611. var urls = src.split('?');
  612. var sizes, rules, feature, matches;
  613. height = height || width;
  614. sizes = {
  615. midfix: '/' + width + '_' + height,
  616. suffix: '_' + width + 'x' + height
  617. };
  618. rules = {
  619. cdn: /^http.+i[0-2]\.hdslb\.com\//,
  620. bfs: /^http.+i\d\.hdslb\.com\/bfs\//,
  621. group1: /^http.+i\d\.hdslb\.com\/group1\//,
  622. other: /(^http.+i\d\.hdslb\.com)(\/.+)/
  623. };
  624. feature = {
  625. bfs: /_\d+x\d+\./,
  626. other: /\/\d+_\d+\//
  627. };
  628.  
  629. if (!rules.cdn.test(urls[0])) {
  630. return src;
  631. }
  632.  
  633. if (feature.bfs.test(urls[0]) || feature.other.test(urls[0])) {
  634. return src;
  635. }
  636.  
  637. if (rules.bfs.test(urls[0]) || rules.group1.test(urls[0])) {
  638. urls[0] += sizes.suffix + urls[0].slice(urls[0].lastIndexOf('.'));
  639. src = urls.join('?');
  640. } else {
  641. matches = rules.other.exec(urls[0]);
  642.  
  643. if (matches) {
  644. urls[0] = matches[1] + sizes.midfix + matches[2];
  645. src = urls.join('?');
  646. }
  647. }
  648.  
  649. return src;
  650. },
  651. //检查是否支持webp
  652. isWebp: function () {
  653. try {
  654. return document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;
  655. } catch (err) {
  656. return false;
  657. }
  658. }(),
  659. webp: function webp(url, args) {
  660. if (!url) {
  661. return url;
  662. }
  663.  
  664. var suffix = url.match(/(.*\.(jpg|jpeg|gif|png|bmp))(\?.*)?/); //路径是否包含/bfs/
  665.  
  666. var isBfs = url.indexOf('/bfs/') != -1 ? true : false; //是否是GIF图片
  667.  
  668. if (!suffix || suffix[2] === 'bmp' || !isBfs) {
  669. return url;
  670. }
  671.  
  672. var w = args.w,
  673. h = args.h; //裁剪规则
  674.  
  675. var filter = [];
  676.  
  677. if (w && h) {
  678. filter.push(w + 'w');
  679. filter.push(h + 'h');
  680. }
  681.  
  682. if (args.freeze) {
  683. filter.push('1s');
  684. } // var cut = (w && h) ? '@' + w + 'w_' + h + 'h' : '@'
  685. //图片后参数 比如视频动态图
  686.  
  687.  
  688. var args = suffix[3] ? suffix[3] : '';
  689.  
  690. if (this.isWebp) {
  691. return suffix[1] + '@' + filter.join('_') + '.webp' + args;
  692. } else {
  693. return suffix[1] + '@' + filter.join('_') + '.' + suffix[2] + args;
  694. }
  695. },
  696. isAlpha: function isAlpha(items, rate) {
  697. var machineDna;
  698.  
  699. if (localStorage.getItem('machineDna')) {
  700. machineDna = localStorage.getItem('machineDna');
  701. } else {
  702. machineDna = parseInt(Math.random() * 10 + 1);
  703. localStorage.setItem('machineDna', machineDna);
  704. }
  705.  
  706. if (this.isBeta(items) || rate < machineDna) {
  707. return true;
  708. } else {
  709. return false;
  710. }
  711. },
  712. isBeta: function isBeta(items) {
  713. var isOpen = false;
  714. var mantissa = utils.cookie.get('DedeUserID').slice(-1);
  715.  
  716. if (mantissa && $.isArray(items)) {
  717. isOpen = $.inArray(+mantissa, items) > -1;
  718. }
  719.  
  720. return isOpen;
  721. },
  722. trimHttp: function trimHttp(url) {
  723. return url ? url.replace(/^http:/, '') : '';
  724. },
  725. getByteLen: function getByteLen(val) {
  726. var len = 0;
  727.  
  728. for (var i = 0; i < val.length; i++) {
  729. var a = val.charAt(i);
  730.  
  731. if (a.match(/[^\x00-\xff]/ig) != null) {
  732. len += 1;
  733. } else {
  734. len += .5;
  735. }
  736. }
  737.  
  738. return len;
  739. },
  740. // to do mreporter
  741. //评论在播放页日志上报
  742. videoReport: function videoReport(name) {
  743. // MReporter logic
  744. if (window.MReporter) {
  745. window.MReporter.click && window.MReporter.click({
  746. evt: "selfDef.".concat(name),
  747. msg: {
  748. event: name,
  749. value: name
  750. }
  751. });
  752. return;
  753. } // log-reporter logic
  754.  
  755.  
  756. if (window.spmReportData) {
  757. window.spmReportData[name] = name;
  758. }
  759. },
  760. //埋点上报
  761. customReport: function customReport(name, ops) {
  762. if (window.MReporter) {
  763. window.MReporter.click && window.MReporter.click({
  764. evt: "selfDef.".concat(name),
  765. msg: {
  766. event: name,
  767. value: ops || name
  768. }
  769. });
  770. }
  771.  
  772. if (window.reportConfig && window[reportConfig['msgObjects']]) {
  773. var reportObj = window[reportConfig['msgObjects']];
  774. var obj = ops ? ops : name;
  775. reportObj[name] = obj;
  776. }
  777. },
  778. formatLotteryTime: function formatLotteryTime(time) {
  779. time = time * 1000;
  780. var date = new Date(time);
  781. var year = date.getFullYear();
  782. var month = date.getMonth() + 1;
  783. var day = date.getDate();
  784. var hour = date.getHours();
  785. var minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
  786. return year + '年' + month + '月' + day + '日 ' + hour + ':' + minute;
  787. },
  788. hexToRgbA: function hexToRgbA(hex) {
  789. var localHex = hex.toString();
  790.  
  791. if (hex.length === 6) {
  792. localHex = 'ff' + localHex;
  793. }
  794.  
  795. var r = parseInt(localHex.slice(2, 4), 16),
  796. g = parseInt(localHex.slice(4, 6), 16),
  797. b = parseInt(localHex.slice(6, 8), 16),
  798. alpha = parseInt(localHex.slice(0, 2), 16);
  799. return "rgba(" + r + ", " + g + ", " + b + ", " + alpha / 255 + ")";
  800. },
  801. asyncScript: function asyncScript(url) {
  802. return new Promise(function (resolve) {
  803. var script = document.createElement('script');
  804. script.setAttribute('src', url);
  805. document.body.appendChild(script);
  806. script.onload = resolve;
  807. });
  808. },
  809. cmGetUrl: function cmGetUrl(cmData, id) {
  810. if (!window.BiliCm) return '';
  811. return window.BiliCm.Base.getSyncUrl(cmData, Number(id));
  812. },
  813. cmSendData: function cmSendData(cmData, id) {
  814. if (!window.BiliCm) return;
  815. window.BiliCm.Base.sendShowData(cmData, Number(id));
  816. },
  817. cmSendStrictData: function cmSendStrictData(cmData, id) {
  818. if (!window.BiliCm) return;
  819. window.BiliCm.Base.sendStrictShowData(cmData, Number(id));
  820. },
  821. cmSendCloseData: function cmSendCloseData(cmData, id) {
  822. if (!window.BiliCm) return;
  823. window.BiliCm.Base.sendCloseData(cmData, Number(id));
  824. },
  825. checkInView: function checkInView(el, padding) {
  826. if (!el) return;
  827. var rect = el.getBoundingClientRect();
  828. var p = padding || 0; // 只判断了纵向
  829.  
  830. return rect.top < window.innerHeight + p && rect.bottom >= 0;
  831. },
  832. // to do mreporter
  833.  
  834. /**
  835. * 完全自定义上报 可自定义上报通道和公共参数
  836. * @param {*} options
  837. * spm_id : spmid 非必传 取meta中spmid
  838. * c : C段 非必传 默认 0
  839. * d : D段 非必传 默认 0
  840. * e : E段 非必传 默认 0
  841. * type : pv, click, appear 上报类型通道
  842. * @param {*} info
  843. */
  844. allCustomReport: function allCustomReport() {
  845. var _document$getElements;
  846.  
  847. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  848. var info = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  849. var spm_idAB = options.spm_id || ((_document$getElements = document.getElementsByTagName('meta').spm_prefix) === null || _document$getElements === void 0 ? void 0 : _document$getElements.content) || '0.0';
  850. var spmidC = options.c || '0';
  851. var spmidD = options.d || '0';
  852. var spmidE = options.e || '0';
  853. var spm_id = spmidE ? "".concat(spm_idAB, ".").concat(spmidC, ".").concat(spmidD, ".").concat(spmidE) : "".concat(spm_idAB, ".").concat(spmidC, ".").concat(spmidD);
  854.  
  855. if (!options.type) {
  856. throw new Error('report need type');
  857. }
  858.  
  859. info.spm_id = spm_id; // MReporter logic
  860.  
  861. if (window.MReporter) {
  862. var input = {
  863. msg: info,
  864. spm: {
  865. id: options.spm_id,
  866. mol: spmidC,
  867. pos: spmidD,
  868. ext: spmidE
  869. }
  870. };
  871. window.MReporter[options.type] && window.MReporter[options.type](input);
  872. return;
  873. } // log-reporter logic
  874.  
  875.  
  876. if (window.reportObserver && window.reportObserver.reportCustomData) {
  877. window.reportObserver.reportCustomData(options.type, info);
  878. }
  879. },
  880. getImgSrc: function getImgSrc(file) {
  881. var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  882. return utils.trimHttp(utils.webp(file, option));
  883. },
  884. // MReporter mr-show attribute 组装
  885. mrShowAttr: function mrShowAttr(msg, evtName, index) {
  886. var payload = {
  887. msg: msg,
  888. evt: "".concat(evtName, ".show.").concat(index)
  889. };
  890. return JSON.stringify(payload);
  891. }
  892. };
  893.  
  894.  
  895.  
  896. (function() {
  897. 'use strict';
  898.  
  899. function getLocationSpanByReply(reply, attrs=""){
  900. if(reply && reply.reply_control && reply.reply_control.location){
  901. return `<span class="reply-location" ${attrs}>${reply.reply_control.location || ''}</span>`;
  902. }else{
  903. return "";
  904. }
  905.  
  906. }
  907.  
  908. hackEle(HTMLBodyElement.prototype, "insertBefore", hack);
  909. hackEle(HTMLHeadElement.prototype, "insertBefore", hack);
  910.  
  911. hackEle(HTMLBodyElement.prototype, "appendChild", hack);
  912. hackEle(HTMLHeadElement.prototype, "appendChild", hack);
  913.  
  914. StartObserveNewPage(); // 对新版视频页的进行inject ,just Test
  915.  
  916. async function StartObserveNewPage(){
  917. await mscststs.wait(".browser-pc")
  918. // 本来相对 Vue-next 的 render 做注入的,想了想感觉太麻烦了,还是简单点,做成 MutationObserver 算了
  919. const targetNode = document.querySelector("body");
  920. function setCode(){
  921. const nodes = [
  922. ...document.querySelectorAll(".browser-pc .reply-item .reply-time"),
  923. ...document.querySelectorAll(".browser-pc .sub-reply-item .sub-reply-time")
  924. ];
  925. nodes.forEach(node=>{
  926. if(!node.__vueParentComponent){
  927. return;
  928. }
  929. if(node.settled){
  930. return;
  931. }
  932. node.settled = true;
  933. const item = node.__vueParentComponent.props.reply || node.__vueParentComponent.props.subReply
  934. let locationSpan = getLocationSpanByReply(item,`style="margin-right:20px;"`);
  935.  
  936. node.outerHTML = node.outerHTML + locationSpan ;
  937. //console.log(node)
  938. })
  939. }
  940. const config = { childList: true, subtree: true };
  941. const callback = function(mutationsList, observer) {
  942. setCode()
  943. };
  944. const observer = new MutationObserver(callback);
  945. observer.observe(targetNode, config);
  946. setCode()
  947. }
  948.  
  949.  
  950. function hackEle(ele, func, callback){
  951. const ori = ele[func];
  952. ele[func] = function(...args){
  953. // console.log(this, ...args)
  954. return callback(ori.bind(this), ...args)
  955. }
  956. };
  957.  
  958.  
  959. function injectbbComment(){
  960. const bbComment = window.bbComment;
  961. if( !bbComment.prototype._createSubReplyUserFace ){
  962. //console.log("inject Old ")
  963. injectOldbbComment();
  964. }else{
  965. //console.log("inject New ")
  966. injectNewbbComment();
  967. }
  968. };
  969.  
  970. // 旧版评论,为啥会有旧版评论呢,因为有人在用 403348 ~
  971. function injectOldbbComment(){
  972. const g = window.bbComment;
  973. const f = utils;
  974. g.prototype._createListCon = function(e, n, t) {
  975. var locationSpan = getLocationSpanByReply(e);
  976. var r = this._parentBlacklistDom(e, n, t)
  977. , i = ['<div class="con ' + (t == n ? "no-border" : "") + '">', '<div class="user">' + this._identity(e.mid, e.assist, e.member.fans_detail), '<a data-usercard-mid="' + e.mid + '" href="//space.bilibili.com/' + e.mid + '" target="_blank" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + '</a><a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>' + this._createNameplate(e.member.nameplate) + this._createUserSailing(e.member && e.member.user_sailing || {}) + "</div>", this._createMsgContent(e), '<div class="info">', e.floor ? '<span class="floor">#' + e.floor + "</span>" : "", this._createPlatformDom(e.content.plat), '<span class="time">' + this._formateTime(e.ctime) + "</span>",locationSpan, e.lottery_id ? "" : '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", e.lottery_id ? "" : '<span class="hate ' + (2 == e.action ? "hated" : "") + '"><i></i></span>', e.lottery_id ? "" : this._createReplyBtn(e.rcount), e.lottery_id && e.mid !== this.userStatus.mid ? "" : '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(e) ? '<li class="set-top">' + (e.isUpTop ? "取消置顶" : "设为置顶") + "</li>" : "") + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) && !e.isTop ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", this._createLotteryContent(e.content), this._createVoteContent(e.content), this._createTags(e), "</div>", '<div class="reply-box">', this._createSubReplyList(e.replies, e.rcount, !1, e.rpid, e.folder && e.folder.has_folded), "</div>", '<div class="paging-box">', "</div>", "</div>"].join("");
  978. return f.browser.version.mobile && (i = ['<div class="con ' + (t == n ? "no-border" : "") + '">', '<div class="user">' + this._identity(e.mid, e.assist, e.member.fans_detail), '<a data-usercard-mid="' + e.mid + '" href="//space.bilibili.com/' + e.mid + '" target="_blank" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + '</a><a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>' + this._createNameplate(e.member.nameplate) + '<div class="right">', e.floor ? '<span class="floor">#' + e.floor + "</span>" : "", '<span class="time">' + this._formateMobileTime(e.ctime) + "</span></div>", "</div>", this._createMsgContent(e), this._createVoteContent(e.content), '<div class="info">', this._createPlatformDom(e.content.plat), '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", '<span class="hate ' + (2 == e.action ? "hated" : "") + '"><i></i></span>', this._createReplyBtn(e.rcount), '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(e) ? '<li class="set-top">' + (e.isUpTop ? "取消置顶" : "设为置顶") + "</li>" : "") + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) && !e.isTop ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", this._createTags(e), '<div class="reply-box">', this._createSubReplyList(e.replies, e.rcount, !1, e.rpid, e.folder && e.folder.has_folded), "</div>", '<div class="paging-box">', "</div>", "</div>"].join("")),
  979. e.state === this.blacklistCode ? r : i
  980. }
  981. g.prototype._createSubFoldedListCon = function(e) {
  982. var locationSpan = getLocationSpanByReply(e);
  983. var n = this._parentBlacklistDom(e, 0)
  984. , t = ['<div class="con">', '<div class="user">' + this._identity(e.mid, e.assist, e.member.fans_detail), '<a data-usercard-mid="' + e.mid + '" href="//space.bilibili.com/' + e.mid + '" target="_blank" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + '</a><a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>' + this._createNameplate(e.member.nameplate), "</div>", this._createMsgContent(e), '<div class="info">', '<span class="time">' + this._formateTime(e.ctime) + "</span>",locationSpan, '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", this._createReplyBtn(e.rcount), '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(e) ? '<li class="set-top">' + (e.isUpTop ? "取消置顶" : "设为置顶") + "</li>" : "") + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) && !e.isTop ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", "</div>"].join("");
  985. return f.browser.version.mobile && (t = ['<div class="con">', '<div class="user">' + this._identity(e.mid, e.assist, e.member.fans_detail), '<a data-usercard-mid="' + e.mid + '" href="//space.bilibili.com/' + e.mid + '" target="_blank" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + '</a><a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>' + this._createNameplate(e.member.nameplate), '<div class="right">', '<span class="time">' + this._formateMobileTime(e.ctime) + "</span></div>", "</div>", this._createMsgContent(e), '<div class="info">', this._createPlatformDom(e.content.plat), '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", this._createReplyBtn(e.rcount), '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(e) ? '<li class="set-top">' + (e.isUpTop ? "取消置顶" : "设为置顶") + "</li>" : "") + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) && !e.isTop ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", "</div>"].join("")),
  986. e.state === this.blacklistCode ? n : t
  987. }
  988. g.prototype._createTopFoldedListCon = function(e) {
  989. var locationSpan = getLocationSpanByReply(e);
  990. var n = this._parentBlacklistDom(e, 0)
  991. , t = ['<div class="con">', '<div class="user">' + this._identity(e.mid, e.assist, e.member.fans_detail), '<a data-usercard-mid="' + e.mid + '" href="//space.bilibili.com/' + e.mid + '" target="_blank" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + '</a><a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>' + this._createNameplate(e.member.nameplate), "</div>", this._createMsgContent(e), '<div class="info">', e.floor ? '<span class="floor">#' + e.floor + "</span>" : "", this._createPlatformDom(e.content.plat), '<span class="time">' + this._formateTime(e.ctime) + "</span>",locationSpan, '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", '<span class="hate ' + (2 == e.action ? "hated" : "") + '"><i></i></span>', this._createReplyBtn(e.rcount), '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(e) ? '<li class="set-top">' + (e.isUpTop ? "取消置顶" : "设为置顶") + "</li>" : "") + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) && !e.isTop ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", "</div>"].join("");
  992. return f.browser.version.mobile && (t = ['<div class="con">', '<div class="user">' + this._identity(e.mid, e.assist, e.member.fans_detail), '<a data-usercard-mid="' + e.mid + '" href="//space.bilibili.com/' + e.mid + '" target="_blank" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + '</a><a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>' + this._createNameplate(e.member.nameplate), '<div class="right">', e.floor ? '<span class="floor">#' + e.floor + "</span>" : "", '<span class="time">' + this._formateMobileTime(e.ctime) + "</span></div>", "</div>", this._createMsgContent(e), '<div class="info">', this._createPlatformDom(e.content.plat), '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", '<span class="hate ' + (2 == e.action ? "hated" : "") + '"><i></i></span>', this._createReplyBtn(e.rcount), '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(e) ? '<li class="set-top">' + (e.isUpTop ? "取消置顶" : "设为置顶") + "</li>" : "") + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) && !e.isTop ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", "</div>"].join("")),
  993. e.state === this.blacklistCode ? n : t
  994. }
  995.  
  996. g.prototype._parentBlacklistDom = function(e, n, t) {
  997. var locationSpan = getLocationSpanByReply(e);
  998. return ['<div class="con ' + (t == n ? "no-border" : "") + '">', '<div class="user blacklist-font-color">黑名单用户</div>', '<p class="text">由于黑名单设置,该评论已被隐藏。</p>', '<div class="info">', e.floor ? '<span class="floor">#' + e.floor + "</span>" : "", this._createPlatformDom(e.content.plat), '<span class="time">' + this._formateTime(e.ctime) + "</span>", locationSpan, this._canDel(e.mid) ? '<div class="operation btn-hover"><div class="spot"></div><div class="opera-list"><ul><li class="del" data-mid="' + e.mid + '">删除</li></ul></div></div>' : "", "</div>", "</div>"].join("")
  999. }
  1000. g.prototype._subBlacklistDom = function(e) {
  1001. var locationSpan = getLocationSpanByReply(e);
  1002. return ['<div class="reply-item reply-wrap" data-id="' + e.rpid + '">', '<a class="reply-face"><img src="' + this.noface + '"></a>', '<div class="reply-con">', '<div class="user">', '<span class="blacklist-font-color name">黑名单用户 </span> <span class="text-con">由于黑名单设置,该回复已被隐藏。</span>', "</div>", "</div>", '<div class="info">', '<span class="time">' + this._formateTime(e.ctime) + "</span>", locationSpan, this._canDel(e.mid) ? '<div class="operation btn-hover btn-hide-re"><div class="spot"></div><div class="opera-list"><ul><li class="del" data-mid="' + e.mid + '">删除</li></ul></div></div>' : "", "</div>", "</div>"].join("")
  1003. }
  1004. g.prototype._createSubReplyItem = function(e, n) {
  1005. var locationSpan = getLocationSpanByReply(e);
  1006. var t = ['<div class="reply-item reply-wrap" data-id="' + e.rpid + '" data-index="' + n + '">', '<a href="//space.bilibili.com/' + e.mid + '" data-usercard-mid="' + e.mid + '" target="_blank" class="reply-face">', '<img src="' + f.trimHttp(f.webp(e.member.avatar, {
  1007. w: 52,
  1008. h: 52
  1009. })) + '" alt="">', "</a>", '<div class="reply-con">', '<div class="user">', '<a href="//space.bilibili.com/' + e.mid + '" target="_blank" data-usercard-mid="' + e.mid + '" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + "</a>", '<a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i></a>', this._createSubMsgContent(e), "</div>", "</div>", '<div class="info">', '<span class="time">' + this._formateTime(e.ctime) + "</span>", locationSpan, '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", '<span class="hate ' + (2 == e.action ? "hated" : "") + '"><i></i></span>', '<span class="reply btn-hover">回复</span>', '<div class="operation btn-hover btn-hide-re"><div class="spot"></div><div class="opera-list"><ul>' + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", "</div>"].join("");
  1010. return f.browser.version.mobile && (t = ['<div class="reply-item reply-wrap" data-id="' + e.rpid + '" data-index="' + n + '">', '<div class="reply-con">', '<div class="user">', '<a href="//space.bilibili.com/' + e.mid + '" target="_blank" data-usercard-mid="' + e.mid + '" class="name ' + this._createVipClass(e.member.vip.vipType, e.member.vip.vipStatus, e.member.vip.themeType) + '">' + f.unhtml(e.member.uname) + "</a>", '<a class="level-link" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l' + e.member.level_info.current_level + '"></i>', '<div class="right"><span class="time">' + this._formateMobileTime(e.ctime) + "</span></div>", "</a>", this._createSubMsgContent(e), "</div>", '<div class="info">', '<span class="like ' + (1 == e.action ? "liked" : "") + '"><i></i><span>' + (e.like || "") + "</span></span>", '<span class="reply btn-hover">回复</span>', '<div class="operation btn-hover btn-hide-re"><div class="spot"></div><div class="opera-list"><ul>' + (this._canBlackList(e.mid) ? '<li class="blacklist">加入黑名单</li>' : "") + (this._canReport(e.mid) ? '<li class="report">举报</li>' : "") + (this._canDel(e.mid) ? '<li class="del" data-mid="' + e.mid + '">删除</li>' : "") + "</ul></div></div>", "</div>", "</div>", "</div>"].join("")),
  1011. t
  1012. }
  1013. }
  1014.  
  1015. function injectNewbbComment(){
  1016. const bbComment = window.bbComment;
  1017. // console.log("inject New ")
  1018. bbComment.prototype._createListCon = function (item, i, pos) {
  1019. //黑名单结构
  1020. var blCon = this._parentBlacklistDom(item, i, pos); //正常结构
  1021.  
  1022.  
  1023. var con = ['<div class="con ' + (pos == i ? 'no-border' : '') + '">', '<div class="user">' + this._createNickNameDom(item), this._createLevelLink(item), this._identity(item.mid, item.assist, item.member.fans_detail), this._createNameplate(item.member.nameplate) + this._createUserSailing(item) + '</div>', this._createMsgContent(item), this._createPerfectReply(item), '<div class="info">', this._createPlatformDom(item.content.plat), "<span class=\"time-location\">", "<span class=\"reply-time\">".concat(this._formateTime(item.ctime), "</span>"), getLocationSpanByReply(item),
  1024. "</span>", item.lottery_id ? '' : '<span class="like ' + (item.action == 1 ? 'liked' : '') + '"><i></i><span>' + (item.like ? item.like : '') + '</span></span>', item.lottery_id ? '' : '<span class="hate ' + (item.action == 2 ? 'hated' : '') + '"><i></i></span>', item.lottery_id ? '' : this._createReplyBtn(item.rcount), item.lottery_id && item.mid !== this.userStatus.mid ? '' : '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(item) ? '<li class="set-top">' + (item.isUpTop ? '取消置顶' : '设为置顶') + '</li>' : '') + (this._canBlackList(item.mid) ? '<li class="blacklist">加入黑名单</li>' : '') + (this._canReport(item.mid) ? '<li class="report">举报</li>' : '') + (this._canDel(item.mid) && !item.isTop ? '<li class="del" data-mid="' + item.mid + '">删除</li>' : '') + '</ul></div></div>', this._createLotteryContent(item.content), this._createVoteContent(item.content), this._createTags(item), '</div>', '<div class="reply-box">', this._createSubReplyList(item.replies, item.rcount, false, item.rpid, item.folder && item.folder.has_folded, item.reply_control), '</div>', '<div class="paging-box">', '</div>', '</div>'].join('');
  1025.  
  1026. if (utils.browser.version.mobile) {
  1027. con = ['<div class="con ' + (pos == i ? 'no-border' : '') + '">', '<div class="user">' + this._identity(item.mid, item.assist, item.member.fans_detail), this._createNickNameDom(item), this._createLevelLink(item), this._createNameplate(item.member.nameplate) + '<div class="right">', '<span class="time">' + this._formateMobileTime(item.ctime) + '</span></div>', '</div>', this._createMsgContent(item), this._createVoteContent(item.content), '<div class="info">', this._createPlatformDom(item.content.plat), '<span class="like ' + (item.action == 1 ? 'liked' : '') + '"><i></i><span>' + (item.like ? item.like : '') + '</span></span>', '<span class="hate ' + (item.action == 2 ? 'hated' : '') + '"><i></i></span>', this._createReplyBtn(item.rcount), '<div class="operation more-operation"><div class="spot"></div><div class="opera-list"><ul>' + (this._canSetTop(item) ? '<li class="set-top">' + (item.isUpTop ? '取消置顶' : '设为置顶') + '</li>' : '') + (this._canBlackList(item.mid) ? '<li class="blacklist">加入黑名单</li>' : '') + (this._canReport(item.mid) ? '<li class="report">举报</li>' : '') + (this._canDel(item.mid) && !item.isTop ? '<li class="del" data-mid="' + item.mid + '">删除</li>' : '') + '</ul></div></div>', '</div>', this._createTags(item), '<div class="reply-box">', this._createSubReplyList(item.replies, item.rcount, false, item.rpid, item.folder && item.folder.has_folded, item.reply_control), '</div>', '<div class="paging-box">', '</div>', '</div>'].join('');
  1028. }
  1029.  
  1030. return item.state === this.blacklistCode ? blCon : con;
  1031. };
  1032. bbComment.prototype._createSubReplyItem = function (item, i) {
  1033. if (item.invisible) {
  1034. return '';
  1035. }
  1036.  
  1037. var dom = ['<div class="reply-item reply-wrap" data-id="' + item.rpid + '" data-index="' + i + '">', this._createSubReplyUserFace(item), // '<a href="//space.bilibili.com/' + item.mid + '" data-usercard-mid="' + item.mid + '" target="_blank" class="reply-face">',
  1038. // '<img src="' + utils.trimHttp(utils.webp(item.member.avatar, { w: 52, h: 52, freeze: true })) + '" alt="">',
  1039. // '</a>',
  1040. '<div class="reply-con">', '<div class="user">', this._createNickNameDom(item), this._createLevelLink(item), this._identity(item.mid), this._createSubMsgContent(item), '</div>', '</div>', '<div class="info">', "<span class=\"time-location\">", "<span class=\"reply-time\">".concat(this._formateTime(item.ctime), "</span>"), getLocationSpanByReply(item),
  1041. "</span>", '<span class="like ' + (item.action == 1 ? 'liked' : '') + '"><i></i><span>' + (item.like ? item.like : '') + '</span></span>', '<span class="hate ' + (item.action == 2 ? 'hated' : '') + '"><i></i></span>', '<span class="reply btn-hover">回复</span>', '<div class="operation btn-hover btn-hide-re"><div class="spot"></div><div class="opera-list"><ul>' + (this._canBlackList(item.mid) ? '<li class="blacklist">加入黑名单</li>' : '') + (this._canReport(item.mid) ? '<li class="report">举报</li>' : '') + (this._canDel(item.mid) ? '<li class="del" data-mid="' + item.mid + '">删除</li>' : '') + '</ul></div></div>', '</div>', '</div>'].join('');
  1042.  
  1043. if (utils.browser.version.mobile) {
  1044. dom = ['<div class="reply-item reply-wrap" data-id="' + item.rpid + '" data-index="' + i + '">', // '<a href="//space.bilibili.com/' + item.mid + '" data-usercard-mid="' + item.mid + '" target="_blank" class="reply-face">',
  1045. // '<img src="' + utils.trimHttp(utils.webp(item.member.avatar, {w: 52, h: 52})) +'" alt="">',
  1046. // '</a>',
  1047. '<div class="reply-con">', '<div class="user">', this._createNickNameDom(item), this._createLevelLink(item), this._identity(item.mid), '<div class="right"><span class="time">' + this._formateMobileTime(item.ctime) + '</span></div>', '</a>', this._createSubMsgContent(item), '</div>', '<div class="info">', '<span class="like ' + (item.action == 1 ? 'liked' : '') + '"><i></i><span>' + (item.like ? item.like : '') + '</span></span>', '<span class="reply btn-hover">回复</span>', '<div class="operation btn-hover btn-hide-re"><div class="spot"></div><div class="opera-list"><ul>' + (this._canBlackList(item.mid) ? '<li class="blacklist">加入黑名单</li>' : '') + (this._canReport(item.mid) ? '<li class="report">举报</li>' : '') + (this._canDel(item.mid) ? '<li class="del" data-mid="' + item.mid + '">删除</li>' : '') + '</ul></div></div>', '</div>', '</div>', '</div>'].join('');
  1048. }
  1049.  
  1050. return dom;
  1051. }
  1052.  
  1053.  
  1054.  
  1055.  
  1056. }
  1057.  
  1058.  
  1059.  
  1060.  
  1061. // 使用 setter 监听 comment 脚本的注册(不可用)
  1062. let f = undefined;
  1063. Object.defineProperty(window,'bbComment',{
  1064. get: function(){
  1065. return f;
  1066. },
  1067.  
  1068. set: function(val){
  1069. f = val;
  1070. injectbbComment();
  1071. },
  1072. configurable: true,
  1073. });
  1074.  
  1075.  
  1076.  
  1077. function hack(origin, ...args){
  1078. const [ele, target] = [...args];
  1079. if( ele.src && ~ele.src.indexOf("/x/v2/reply")){
  1080. // 确定是评论类型,执行额外流程
  1081. injectbbComment()
  1082. }
  1083.  
  1084. // 监听 comment 组件的注入
  1085. if(ele.src && ele.src.endsWith("comment.min.js")){
  1086. const ori = ele.onload;
  1087. ele.onload = function(...args){
  1088. injectbbComment();
  1089. ori && ori(...args);
  1090. }
  1091. };
  1092.  
  1093.  
  1094. // 监听 comment_vue_next 组件的注入,直接在dynamic import 时修改源码,也是一种权宜之计
  1095. if(ele.src && ele.src.endsWith("comment-pc-vue.next.js")){
  1096.  
  1097. // console.log("新版评论,启用源码注入");
  1098. !(async function(){
  1099. let code = await (await fetch(ele.src)).text();
  1100.  
  1101. const Ref1Index = code.indexOf("getReplyFloorInfo=");
  1102. const Ref2Index = code.indexOf("getReplyBoxStatus=");
  1103. if( Ref2Index > Ref1Index && Ref1Index > -1){
  1104.  
  1105. code = code.replace(`getReplyFloorInfo=`,`_RAWgetReplyFloorInfo=`);
  1106. code = code.replace(`getReplyBoxStatus=`,`getReplyFloorInfo=Q=>{return {
  1107. ..._RAWgetReplyFloorInfo(Q),
  1108. replyLocation: computed(()=>{ return Q.value.reply_control.location || ""})
  1109. }
  1110. },getReplyBoxStatus=`);
  1111. }else{
  1112. console.error("【评论区开盒】Patch 失败,无法找到正确的 Patch 位置,请反馈后等待开发者修复");
  1113. }
  1114.  
  1115.  
  1116. /* code = code.replace(`replyLocation:$`, `replyLocation:computed(()=>{
  1117. var Ge, rt;
  1118. return Q?.value?.reply_control?.location??"";
  1119. }
  1120. )`);*/
  1121. eval(code);
  1122.  
  1123. ele.dispatchEvent(new Event("load",{
  1124. bubbles:true,
  1125. }));
  1126. ele.onload && ele.onload();
  1127.  
  1128. })();
  1129.  
  1130. return;
  1131. };
  1132.  
  1133.  
  1134. //console.log(ele,ele.src,origin)
  1135. let res = origin(...args);
  1136. //console.log(res)
  1137. return res;
  1138. //return ele;
  1139. }
  1140.  
  1141.  
  1142. // 2024年7月5日 先解决灰度期间的新版评论区
  1143. let rawState = null;
  1144. Object.defineProperty(window, '__INITIAL_STATE__', {
  1145. get(){
  1146. if(rawState){
  1147. return rawState;
  1148. }
  1149. },
  1150. set(value){
  1151. value.abtest.comment_next_version = "";
  1152. rawState = value;
  1153. }
  1154. })
  1155.  
  1156. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址