// ==UserScript==
// @name 【移动端】MT论坛优化
// @namespace https://greasyfork.org/zh-CN/scripts/401359
// @version 2024.12.17
// @author WhiteSevs
// @description MT论坛效果增强,如自动签到、自动展开帖子、滚动加载评论、显示UID、自定义屏蔽、手机版小黑屋、编辑器优化、在线用户查看、便捷式图床、自定义用户标签、积分商城商品上架提醒等
// @license GPL-3.0-only
// @icon data:image/png;base64,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
// @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
// @match *://bbs.binmt.cc/*
// @exclude /^http(s|)://bbs.binmt.cc/uc_server.*$/
// @require https://update.greasyfork.org/scripts/494167/1413255/CoverUMD.js
// @require https://update.greasyfork.org/scripts/452322/1470429/js-watermark.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.5.5/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.4.8/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/pops@1.9.5/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/qmsg@1.2.8/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/viewerjs@1.11.7/dist/viewer.min.js
// @require https://fastly.jsdelivr.net/npm/@highlightjs/cdn-assets@11.11.0/highlight.min.js
// @resource HljsCSS https://fastly.jsdelivr.net/npm/highlight.js@11.11.0/styles/github-dark.min.css
// @resource ViewerCSS https://fastly.jsdelivr.net/npm/viewerjs@1.11.7/dist/viewer.min.css
// @connect *
// @connect *
// @connect helloimg.com
// @connect z4a.net
// @connect kggzs.cn
// @connect woozooo.com
// @grant GM_deleteValue
// @grant GM_getResourceText
// @grant GM_getValue
// @grant GM_info
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_unregisterMenuCommand
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// @run-at document-start
// ==/UserScript==
(function (Qmsg, DOMUtils, Utils, pops, Viewer, hljs) {
'use strict';
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var require_entrance_001 = __commonJS({
"entrance-CZ8XgvVO.js"(exports, module) {
var _a;
var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
var _GM_getResourceText = /* @__PURE__ */ (() => typeof GM_getResourceText != "undefined" ? GM_getResourceText : void 0)();
var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
var _GM_unregisterMenuCommand = /* @__PURE__ */ (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)();
var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
var _monkeyWindow = /* @__PURE__ */ (() => window)();
const HttpxCookieManager = {
$data: {
/** 是否启用 */
get enable() {
return PopsPanel.getValue("httpx-use-cookie-enable");
},
/** 是否使用document.cookie */
get useDocumentCookie() {
return PopsPanel.getValue("httpx-use-document-cookie");
},
cookieRule: [
{
key: "httpx-cookie-bbs.binmt.cc",
hostname: /bbs.binmt.cc/g
}
]
},
/**
* 补充cookie末尾分号
*/
fixCookieSplit(str) {
if (utils.isNotNull(str) && !str.trim().endsWith(";")) {
str += ";";
}
return str;
},
/**
* 合并两个cookie
*/
concatCookie(targetCookie, newCookie) {
if (utils.isNull(targetCookie)) {
return newCookie;
}
targetCookie = targetCookie.trim();
newCookie = newCookie.trim();
targetCookie = this.fixCookieSplit(targetCookie);
if (newCookie.startsWith(";")) {
newCookie = newCookie.substring(1);
}
return targetCookie.concat(newCookie);
},
/**
* 处理cookie
* @param details
* @returns
*/
handle(details) {
if (details.fetch) {
return;
}
if (!this.$data.enable) {
return;
}
let ownCookie = "";
let url = details.url;
if (url.startsWith("//")) {
url = window.location.protocol + url;
}
let urlObj = new URL(url);
if (this.$data.useDocumentCookie && urlObj.hostname.endsWith(
window.location.hostname.split(".").slice(-2).join(".")
)) {
ownCookie = this.concatCookie(ownCookie, document.cookie.trim());
}
for (let index = 0; index < this.$data.cookieRule.length; index++) {
let rule = this.$data.cookieRule[index];
if (urlObj.hostname.match(rule.hostname)) {
let cookie = PopsPanel.getValue(rule.key);
if (utils.isNull(cookie)) {
break;
}
ownCookie = this.concatCookie(ownCookie, cookie);
}
}
if (utils.isNotNull(ownCookie)) {
if (details.headers && details.headers["Cookie"]) {
details.headers.Cookie = this.concatCookie(
details.headers.Cookie,
ownCookie
);
} else {
details.headers["Cookie"] = ownCookie;
}
log.info(["Httpx => 设置cookie:", details]);
}
if (details.headers && details.headers.Cookie != null && utils.isNull(details.headers.Cookie)) {
delete details.headers.Cookie;
}
}
};
const GM_RESOURCE_MAPPING = {
ElementPlus: {
keyName: "ElementPlusResourceCSS",
url: "https://fastly.jsdelivr.net/npm/element-plus@latest/dist/index.min.css"
},
Viewer: {
keyName: "ViewerCSS",
url: "https://fastly.jsdelivr.net/npm/viewerjs@latest/dist/viewer.min.css"
},
Hljs: {
keyName: "HljsCSS",
url: "https://fastly.jsdelivr.net/npm/highlight.js@latest/styles/github-dark.min.css"
}
};
(function(global, factory) {
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = factory();
} else {
global = typeof globalThis !== "undefined" ? globalThis : global || self;
global.Watermark = factory(global.Watermark);
}
})(typeof window !== "undefined" ? window : void 0, function(AnotherWatermark) {
let Watermark = function() {
};
CanvasRenderingContext2D.prototype.letterSpacingText = function(text, x, y, letterSpacing) {
var context = this;
var canvas = context.canvas;
if (!letterSpacing && canvas) {
letterSpacing = parseFloat(window.getComputedStyle(canvas).letterSpacing);
}
if (!letterSpacing) {
return this.fillText(text, x, y);
}
var arrText = text.split("");
var align = context.textAlign || "left";
var originWidth = context.measureText(text).width;
var actualWidth = originWidth + letterSpacing * (arrText.length - 1);
if (align == "center") {
x = x - actualWidth / 2;
} else if (align == "right") {
x = x - actualWidth;
}
context.textAlign = "left";
arrText.forEach(function(letter) {
var letterWidth = context.measureText(letter).width;
context.fillText(letter, x, y);
x = x + letterWidth + letterSpacing;
});
context.textAlign = align;
};
CanvasRenderingContext2D.prototype.wrapText = function(text, x, y, maxWidth, lineHeight, stroke) {
if (typeof text != "string" || typeof x != "number" || typeof y != "number") {
return;
}
var context = this;
var canvas = context.canvas;
if (typeof maxWidth == "undefined") {
maxWidth = canvas && canvas.width || 300;
}
if (typeof lineHeight == "undefined") {
lineHeight = canvas && parseInt(window.getComputedStyle(canvas).lineHeight) || parseInt(window.getComputedStyle(document.body).lineHeight);
}
var arrText = text.split("");
var line = "";
for (var n = 0; n < arrText.length; n++) {
var testLine = line + arrText[n];
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
if (stroke) {
context.strokeText(line, x, y, canvas.width);
} else {
context.fillText(line, x, y);
}
line = arrText[n];
y += lineHeight;
} else {
line = testLine;
}
}
if (stroke) {
context.strokeText(line, x, y, canvas.width);
} else {
context.fillText(line, x, y);
}
};
CanvasRenderingContext2D.prototype.fillTextVertical = function(text, x, y) {
var context = this;
context.canvas;
var arrText = text.split("");
var arrWidth = arrText.map(function(letter) {
return context.measureText(letter).width;
});
var align = context.textAlign;
var baseline = context.textBaseline;
if (align == "left") {
x = x + Math.max.apply(null, arrWidth) / 2;
} else if (align == "right") {
x = x - Math.max.apply(null, arrWidth) / 2;
}
if (baseline == "bottom" || baseline == "alphabetic" || baseline == "ideographic") {
y = y - arrWidth[0] / 2;
} else if (baseline == "top" || baseline == "hanging") {
y = y + arrWidth[0] / 2;
}
context.textAlign = "center";
context.textBaseline = "middle";
arrText.forEach(function(letter, index) {
var letterWidth = arrWidth[index];
var code = letter.charCodeAt(0);
if (code <= 256) {
context.translate(x, y);
context.rotate(90 * Math.PI / 180);
context.translate(-x, -y);
} else if (index > 0 && text.charCodeAt(index - 1) < 256) {
y = y + arrWidth[index - 1] / 2;
}
context.fillText(letter, x, y);
context.setTransform(1, 0, 0, 1, 0, 0);
var letterWidth = arrWidth[index];
y = y + letterWidth;
});
context.textAlign = align;
context.textBaseline = baseline;
};
function loadFile(file) {
let fileReader = new FileReader();
return new Promise((resolve) => {
fileReader.onloadend = async function(event) {
resolve(event);
};
fileReader.readAsDataURL(file);
});
}
function loadImage(src) {
let image = new Image();
return new Promise((resolve) => {
image.onload = () => {
resolve(image);
};
image.src = src;
});
}
function checkInArrayByPos(arrayData, x, y) {
let flag = false;
Array.from(arrayData).forEach((item) => {
if (item["x"] == x && item["y"] == y) {
flag = true;
return;
}
});
return flag;
}
function getRandValue(arr) {
if (arr instanceof Array) {
return arr[Math.floor(Math.random() * arr.length)];
} else {
return arr;
}
}
Watermark.prototype.setFile = function(file) {
let that = this;
return new Promise(async (resolve) => {
try {
var fileReader = await loadFile(file);
await that.setImage(fileReader.target.result);
resolve(true);
} catch (error) {
resolve(false);
}
});
};
Watermark.prototype.setImage = function(src) {
this.dataUrl = src;
let that = this;
return new Promise(async (res) => {
var image = await loadImage(src);
that.sizes = {
width: image.width,
height: image.height
};
var canvas = document.createElement("canvas");
canvas.width = that.sizes.width;
canvas.height = that.sizes.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
image = null;
that.canvas = canvas;
res(true);
});
};
Watermark.prototype.hasImage = function() {
return !!this.dataUrl;
};
Watermark.prototype.getSize = function() {
return this.sizes;
};
Watermark.prototype.clearMark = function() {
let that = this;
if (typeof that.canvas === "undefined") {
return;
}
function _clearMark_() {
var ctx = that.canvas.getContext("2d");
ctx.clearRect(0, 0, that.canvas.width, that.canvas.height);
var w = that.canvas.width;
var h = that.canvas.height;
that.canvas.width = w;
that.canvas.height = h;
ctx.beginPath();
var image = new Image();
image.src = that.dataUrl;
ctx.drawImage(image, 0, 0);
image = null;
}
_clearMark_();
};
Watermark.prototype.addText = function(opts) {
var options = {
text: ["Call By waterMark.addText"],
fontSize: "6vw",
fontFamily: "Microsoft Yahei",
color: "#000000",
textAlign: "center",
/* 描边 */
stroke: false,
globalAlpha: 0.7,
/* -360 ~ 360 */
rotateAngle: 50,
/* 必须大于0 */
maxWidth: 100,
/* 必须大于0 */
xMoveDistance: 30,
/* 必须大于0 */
yMoveDistance: 30
};
for (let key in options) {
if (typeof opts[key] !== "undefined") {
options[key] = opts[key];
}
}
options.maxWidth = parseInt(options.maxWidth) > 0 ? options.maxWidth : 1;
options.xMoveDistance = parseInt(options.xMoveDistance) > 0 ? options.xMoveDistance : 1;
options.yMoveDistance = parseInt(options.yMoveDistance) > 0 ? options.yMoveDistance : 1;
var ctx = this.canvas.getContext("2d");
var fontSize = options.fontSize;
fontSize = fontSize.toString();
if (~fontSize.indexOf("vw")) {
fontSize = (this.sizes.width / 100 * parseInt(fontSize)).toFixed(0);
}
fontSize = parseInt(fontSize);
ctx.font = fontSize + "px " + options.fontFamily;
ctx.fillStyle = options.color;
ctx.textAlign = options.textAlign;
ctx.globalAlpha = options.globalAlpha;
let canvasWidth = this.sizes.width, canvasHeight = this.sizes.height;
let rotateAngle = options.rotateAngle * Math.PI / 180;
let xMoveDistance = options.xMoveDistance;
let yMoveDistance = options.yMoveDistance;
let maxWidth = options.maxWidth;
let lineHeight = fontSize;
let pos = [];
for (var i = canvasWidth / 2; i < canvasWidth; i += xMoveDistance) {
for (var j = canvasHeight / 2; j < canvasHeight; j += yMoveDistance) {
if (!checkInArrayByPos(pos, i, j)) {
pos = pos.concat({
x: i,
y: j
});
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.translate(i, j);
ctx.rotate(rotateAngle);
ctx.wrapText(
getRandValue(options.text),
0,
0,
maxWidth,
lineHeight,
options.stroke
);
}
}
for (var k = canvasHeight / 2; k > 0; k -= yMoveDistance) {
if (!checkInArrayByPos(pos, i, k)) {
pos = pos.concat({
x: i,
y: k
});
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.translate(i, k);
ctx.rotate(rotateAngle);
ctx.wrapText(
getRandValue(options.text),
0,
0,
maxWidth,
lineHeight,
options.stroke
);
}
}
}
for (var i = canvasWidth / 2; i > 0; i -= xMoveDistance) {
for (var j = canvasHeight / 2; j < canvasHeight; j += yMoveDistance) {
if (!checkInArrayByPos(pos, i, j)) {
pos = pos.concat({
x: i,
y: j
});
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.translate(i, j);
ctx.rotate(rotateAngle);
ctx.wrapText(
getRandValue(options.text),
0,
0,
maxWidth,
lineHeight,
options.stroke
);
}
}
for (var k = canvasHeight / 2; k > 0; k -= yMoveDistance) {
if (!checkInArrayByPos(pos, i, k)) {
pos = pos.concat({
x: i,
y: k
});
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.translate(i, k);
ctx.rotate(rotateAngle);
ctx.wrapText(
getRandValue(options.text),
0,
0,
maxWidth,
lineHeight,
options.stroke
);
}
}
}
};
Watermark.prototype.addPixelText = function(opts) {
var options = {
text: "像素文字水印",
/* 像素文字 */
big: {
fontSize: 150,
fontFamily: "微软雅黑",
textAlign: "center",
rotateAngle: 0,
/* 描边 */
stroke: false
},
/* 绘制像素的文字 */
small: {
fontSize: 10,
fontFamily: "微软雅黑",
color: "#000",
textAlign: "center",
globalAlpha: 0.7
}
};
for (let key in options) {
if (typeof opts[key] !== "undefined") {
options[key] = opts[key];
}
}
var ctx = this.canvas.getContext("2d");
var tmpCanvas = document.createElement("canvas");
var tmpctx = tmpCanvas.getContext("2d");
tmpCanvas.width = this.sizes.width;
tmpCanvas.height = this.sizes.height;
tmpctx.font = options.big.fontSize + "px " + options.big.fontFamily;
tmpctx.textAlign = options.big.textAlign;
tmpctx.textBaseline = "middle";
tmpctx.translate(tmpCanvas.width / 2, tmpCanvas.height / 2);
tmpctx.rotate(options.big.rotateAngle * Math.PI / 180);
tmpctx.translate(-tmpCanvas.width / 2, -tmpCanvas.height / 2);
if (options.big.stroke) {
tmpctx.strokeText(
options.text,
tmpCanvas.width / 2,
tmpCanvas.height / 2,
tmpCanvas.width
);
} else {
tmpctx.fillText(options.text, tmpCanvas.width / 2, tmpCanvas.height / 2);
}
var textArray = options.text.split("");
var textPixleInfo = tmpctx.getImageData(
0,
0,
tmpCanvas.width,
tmpCanvas.height
);
var pixelArray = [];
for (var i = 0; i < tmpCanvas.height; i += options.small.fontSize) {
for (var j = 0; j < tmpCanvas.width; j += options.small.fontSize) {
var index = j + i * tmpCanvas.width;
var a = textPixleInfo.data[index * 4 + 3];
if (a > 128) {
pixelArray.push({
text: getRandValue(textArray),
x: j,
y: i
});
}
}
}
ctx.font = options.small.fontSize + "px " + options.small.fontFamily;
ctx.fillStyle = options.small.color;
ctx.textAlign = options.small.textAlign;
ctx.textBaseline = "middle";
ctx.globalAlpha = options.small.globalAlpha;
pixelArray.forEach((item) => {
ctx.fillText(item.text, item.x, item.y);
});
};
Watermark.prototype.addImage = function(opts) {
if (opts.imageArray == null) {
alert("参数缺少imageArray");
return false;
}
if (opts.imageArray.length === 0) {
alert("参数imageArray不能为空");
return false;
}
let options = {
imageArray: [],
/* 里面为水印Image对象 */
width: 50,
/* 必须大于0 */
height: 50,
/* 必须大于0 */
globalAlpha: 0.5,
rotateAngle: 0,
xMoveDistance: 70,
/* 必须大于0 */
yMoveDistance: 70
/* 必须大于0 */
};
for (let key in options) {
if (typeof opts[key] !== "undefined") {
options[key] = opts[key];
}
}
options.width = parseInt(options.width) > 0 ? options.width : 1;
options.height = parseInt(options.height) > 0 ? options.height : 1;
options.xMoveDistance = parseInt(options.xMoveDistance) > 0 ? options.xMoveDistance : 1;
options.yMoveDistance = parseInt(options.yMoveDistance) > 0 ? options.yMoveDistance : 1;
let ctx = this.canvas.getContext("2d");
let waterImageCanvasArray = [];
let waterImageCanvasDiagonal = parseInt(
Math.sqrt(options.width * options.width + options.height * options.height)
);
let canvasWidth = this.sizes.width, canvasHeight = this.sizes.height;
let rotateAngle = options.rotateAngle * Math.PI / 180;
let xMoveDistance = options.xMoveDistance;
let yMoveDistance = options.yMoveDistance;
let centerDrawLeftPosX = canvasWidth / 2 - waterImageCanvasDiagonal / 2;
let centerDrawLeftPosY = canvasHeight / 2 - waterImageCanvasDiagonal / 2;
let waterDrawPosX = (waterImageCanvasDiagonal - options.width) / 2;
let waterDrawPosY = (waterImageCanvasDiagonal - options.height) / 2;
Array.from(options.imageArray).forEach((item) => {
var waterImageCanvas = document.createElement("canvas");
var waterctx = waterImageCanvas.getContext("2d");
waterImageCanvas.width = waterImageCanvasDiagonal;
waterImageCanvas.height = waterImageCanvasDiagonal;
waterctx.globalAlpha = options.globalAlpha;
waterctx.translate(
waterImageCanvasDiagonal / 2,
waterImageCanvasDiagonal / 2
);
waterctx.rotate(rotateAngle);
waterctx.translate(
-waterImageCanvasDiagonal / 2,
-waterImageCanvasDiagonal / 2
);
waterctx.drawImage(
item,
waterDrawPosX,
waterDrawPosY,
options.width,
options.height
);
waterImageCanvasArray = waterImageCanvasArray.concat(waterImageCanvas);
});
function randomArrayData(array_data) {
return array_data[Math.floor(Math.random() * array_data.length)];
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
let pos = [];
for (let i = centerDrawLeftPosX; i < canvasWidth; i += xMoveDistance) {
for (let j = centerDrawLeftPosY; j < canvasHeight; j += yMoveDistance) {
if (!checkInArrayByPos(pos, i, j)) {
pos = pos.concat({
x: i,
y: j
});
ctx.drawImage(
randomArrayData(waterImageCanvasArray),
i,
j
);
}
}
for (let k = centerDrawLeftPosY; k > -Math.abs(waterImageCanvasDiagonal); k -= yMoveDistance) {
if (!checkInArrayByPos(pos, i, k)) {
pos = pos.concat({
x: i,
y: k
});
ctx.drawImage(randomArrayData(waterImageCanvasArray), i, k);
}
}
}
for (let i = centerDrawLeftPosX; i > -Math.abs(waterImageCanvasDiagonal); i -= xMoveDistance) {
for (let j = centerDrawLeftPosY; j < canvasHeight; j += yMoveDistance) {
if (!checkInArrayByPos(pos, i, j)) {
pos = pos.concat({
x: i,
y: j
});
ctx.drawImage(randomArrayData(waterImageCanvasArray), i, j);
}
}
for (let k = centerDrawLeftPosY; k > -Math.abs(waterImageCanvasDiagonal); k -= yMoveDistance) {
if (!checkInArrayByPos(pos, i, k)) {
pos = pos.concat({
x: i,
y: k
});
ctx.drawImage(randomArrayData(waterImageCanvasArray), i, k);
}
}
}
};
Watermark.prototype.getPreview = function() {
return this.dataUrl;
};
Watermark.prototype.render = function(type) {
type = type === "png" ? "png" : "jpeg";
return this.canvas.toDataURL("image/" + type);
};
Watermark.prototype.renderBlob = function() {
let that = this;
return new Promise((res) => {
that.canvas.toBlob(function(blob) {
res(window.URL.createObjectURL(blob));
});
});
};
Watermark.prototype.noConflict = function() {
if (window.Watermark) {
delete window.Watermark;
}
if (AnotherWatermark) {
window.Watermark = AnotherWatermark;
}
return Watermark;
};
return Watermark;
});
const CommonUtil = {
/**
* 添加屏蔽CSS
* @param args
* @example
* addBlockCSS("")
* addBlockCSS("","")
* addBlockCSS(["",""])
*/
addBlockCSS(...args) {
let selectorList = [];
if (args.length === 0) {
return;
}
if (args.length === 1 && typeof args[0] === "string" && args[0].trim() === "") {
return;
}
args.forEach((selector) => {
if (Array.isArray(selector)) {
selectorList = selectorList.concat(selector);
} else {
selectorList.push(selector);
}
});
return addStyle(`${selectorList.join(",\n")}{display: none !important;}`);
},
/**
* 设置GM_getResourceText的style内容
* @param resourceMapData 资源数据
* @example
* setGMResourceCSS({
* keyName: "ViewerCSS",
* url: "https://example.com/example.css",
* })
*/
setGMResourceCSS(resourceMapData) {
let cssText = typeof _GM_getResourceText === "function" ? _GM_getResourceText(resourceMapData.keyName) : "";
if (typeof cssText === "string" && cssText) {
addStyle(cssText);
} else {
CommonUtil.loadStyleLink(resourceMapData.url);
}
},
/**
* 添加标签
* @param url
* @example
* loadStyleLink("https://example.com/example.css")
*/
async loadStyleLink(url) {
let $link = document.createElement("link");
$link.rel = "stylesheet";
$link.type = "text/css";
$link.href = url;
domUtils.ready(() => {
document.head.appendChild($link);
});
},
/**
* 添加