// ==UserScript==
// @name 【移动端】微博优化
// @namespace https://github.com/WhiteSevs/TamperMonkeyScript
// @version 2025.10.18
// @author WhiteSevs
// @description 劫持自动跳转登录,修复用户主页正确跳转,伪装客户端,可查看名人堂日程表,解锁视频清晰度(1080p、2K、2K-60、4K、4K-60)
// @license GPL-3.0-only
// @icon data:image/png;base64,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
// @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
// @match *://m.weibo.cn/*
// @match *://huati.weibo.cn/*
// @match *://h5.video.weibo.com/*
// @match *://card.weibo.com/*
// @match *://weibo.com/l/wblive/m/show/*
// @require https://fastly.jsdelivr.net/gh/WhiteSevs/TamperMonkeyScript@86be74b83fca4fa47521cded28377b35e1d7d2ac/lib/CoverUMD/index.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.9.4/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.7.4/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/@whitesev/pops@2.5.5/dist/index.umd.js
// @require https://fastly.jsdelivr.net/npm/qmsg@1.5.0/dist/index.umd.js
// @connect m.weibo.cn
// @connect www.weibo.com
// @connect passport.weibo.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) {
"use strict";
var _GM_deleteValue = (() => (typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0))();
var _GM_getResourceText = (() => (typeof GM_getResourceText != "undefined" ? GM_getResourceText : void 0))();
var _GM_getValue = (() => (typeof GM_getValue != "undefined" ? GM_getValue : void 0))();
var _GM_info = (() => (typeof GM_info != "undefined" ? GM_info : void 0))();
var _GM_registerMenuCommand = (() =>
typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
var _GM_setValue = (() => (typeof GM_setValue != "undefined" ? GM_setValue : void 0))();
var _GM_unregisterMenuCommand = (() =>
typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)();
var _GM_xmlhttpRequest = (() => (typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0))();
var _unsafeWindow = (() => (typeof unsafeWindow != "undefined" ? unsafeWindow : void 0))();
var _monkeyWindow = (() => window)();
const CommonUtil = {
waitRemove(...args) {
args.forEach((selector) => {
if (typeof selector !== "string") {
return;
}
DOMUtils.waitNodeList(selector).then((nodeList) => {
nodeList.forEach(($el) => $el.remove());
});
});
},
createBlockCSSNode(...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 DOMUtils.createElement("style", {
type: "text/css",
innerHTML: `${selectorList.join(",\n")}{display: none !important;}`,
});
},
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;}`);
},
setGMResourceCSS(resourceMapData) {
const cssText = typeof _GM_getResourceText === "function" ? _GM_getResourceText(resourceMapData.keyName) : null;
if (typeof cssText === "string" && cssText) {
return addStyle(cssText);
} else {
return CommonUtil.loadStyleLink(resourceMapData.url);
}
},
async loadStyleLink(url) {
let $link = document.createElement("link");
$link.rel = "stylesheet";
$link.type = "text/css";
$link.href = url;
return new Promise((resolve) => {
DOMUtils.ready(() => {
document.head.appendChild($link);
resolve($link);
});
});
},
async loadScript(url) {
let $script = document.createElement("script");
$script.src = url;
return new Promise((resolve) => {
$script.onload = () => {
resolve(null);
};
(document.head || document.documentElement).appendChild($script);
});
},
fixUrl(url) {
url = url.trim();
if (url.startsWith("data:")) {
return url;
}
if (url.match(/^http(s|):\/\//i)) {
return url;
} else if (url.startsWith("//")) {
if (url.startsWith("///"));
else {
url = window.location.protocol + url;
}
return url;
} else {
if (!url.startsWith("/")) {
url += "/";
}
url = window.location.origin + url;
return url;
}
},
fixHttps(url) {
if (url.startsWith("https://")) {
return url;
}
if (!url.startsWith("http://")) {
return url;
}
try {
let urlInstance = new URL(url);
urlInstance.protocol = "https:";
return urlInstance.toString();
} catch {
return url;
}
},
lockScroll(...args) {
let $hidden = document.createElement("style");
$hidden.innerHTML = `
.pops-overflow-hidden-important {
overflow: hidden !important;
}
`;
let $elList = [document.documentElement, document.body].concat(...(args || []));
$elList.forEach(($el) => {
$el.classList.add("pops-overflow-hidden-important");
});
(document.head || document.documentElement).appendChild($hidden);
return {
recovery() {
$elList.forEach(($el) => {
$el.classList.remove("pops-overflow-hidden-important");
});
$hidden.remove();
},
};
},
async getClipboardText() {
function readClipboardText(resolve) {
navigator.clipboard
.readText()
.then((clipboardText) => {
resolve(clipboardText);
})
.catch((error) => {
log.error("读取剪贴板内容失败👉", error);
resolve("");
});
}
function requestPermissionsWithClipboard(resolve) {
navigator.permissions
.query({
name: "clipboard-read",
})
.then((permissionStatus) => {
readClipboardText(resolve);
})
.catch((error) => {
log.error("申请剪贴板权限失败,尝试直接读取👉", error.message ?? error.name ?? error.stack);
readClipboardText(resolve);
});
}
function checkClipboardApi() {
if (typeof navigator?.clipboard?.readText !== "function") {
return false;
}
if (typeof navigator?.permissions?.query !== "function") {
return false;
}
return true;
}
return new Promise((resolve) => {
if (!checkClipboardApi()) {
resolve("");
return;
}
if (document.hasFocus()) {
requestPermissionsWithClipboard(resolve);
} else {
window.addEventListener(
"focus",
() => {
requestPermissionsWithClipboard(resolve);
},
{
once: true,
}
);
}
});
},
escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/©/g, "©")
.replace(/®/g, "®")
.replace(/™/g, "™")
.replace(/→/g, "→")
.replace(/←/g, "←")
.replace(/↑/g, "↑")
.replace(/↓/g, "↓")
.replace(/—/g, "—")
.replace(/–/g, "–")
.replace(/…/g, "…")
.replace(/ /g, " ")
.replace(/\r\n/g, "
")
.replace(/\r/g, "
")
.replace(/\n/g, "
")
.replace(/\t/g, " ");
},
interval(fn, intervalTime, timeout = 5e3) {
let timeId;
let maxTimeout = timeout - intervalTime;
let intervalTimeCount = intervalTime;
let loop = async (isTimeout) => {
let result = await fn(isTimeout);
if ((typeof result === "boolean" && !result) || isTimeout) {
utils.workerClearTimeout(timeId);
return;
}
intervalTimeCount += intervalTime;
if (intervalTimeCount > maxTimeout) {
loop(true);
return;
}
timeId = utils.workerSetTimeout(() => {
loop(false);
}, intervalTime);
};
loop(false);
},
findParentNode($el, selector, parentSelector) {
if (parentSelector) {
let $parent = DOMUtils.closest($el, parentSelector);
if ($parent) {
let $target = $parent.querySelector(selector);
return $target;
}
} else {
if (DOMUtils.matches($el, selector)) {
return $el;
}
let $parent = DOMUtils.closest($el, selector);
return $parent;
}
},
};
const PanelSettingConfig = {
qmsg_config_position: {
key: "qmsg-config-position",
defaultValue: "bottom",
},
qmsg_config_maxnums: {
key: "qmsg-config-maxnums",
defaultValue: 3,
},
qmsg_config_showreverse: {
key: "qmsg-config-showreverse",
defaultValue: false,
},
};
const utils = Utils.noConflict();
const domUtils = DOMUtils.noConflict();
const __pops = pops;
const log = new utils.Log(_GM_info, _unsafeWindow.console || _monkeyWindow.console);
let SCRIPT_NAME = _GM_info?.script?.name || void 0;
pops.config.Utils.AnyTouch();
const DEBUG = false;
log.config({
debug: false,
logMaxCount: 250,
autoClearConsole: true,
tag: true,
});
Qmsg.config({
isHTML: true,
autoClose: true,
showClose: false,
consoleLogContent(qmsgInst) {
const qmsgType = qmsgInst.getSetting().type;
if (qmsgType === "loading") {
return false;
}
const content = qmsgInst.getSetting().content;
if (qmsgType === "warning") {
log.warn(content);
} else if (qmsgType === "error") {
log.error(content);
} else {
log.info(content);
}
return true;
},
get position() {
return Panel.getValue(
PanelSettingConfig.qmsg_config_position.key,
PanelSettingConfig.qmsg_config_position.defaultValue
);
},
get maxNums() {
return Panel.getValue(
PanelSettingConfig.qmsg_config_maxnums.key,
PanelSettingConfig.qmsg_config_maxnums.defaultValue
);
},
get showReverse() {
return Panel.getValue(
PanelSettingConfig.qmsg_config_showreverse.key,
PanelSettingConfig.qmsg_config_showreverse.defaultValue
);
},
get zIndex() {
let maxZIndex = Utils.getMaxZIndex();
let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex;
return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
},
});
__pops.GlobalConfig.setGlobalConfig({
zIndex: () => {
let maxZIndex = Utils.getMaxZIndex(void 0, void 0, ($ele) => {
if ($ele?.classList?.contains("qmsg-shadow-container")) {
return false;
}
if ($ele?.closest("qmsg") && $ele.getRootNode() instanceof ShadowRoot) {
return false;
}
});
let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex;
return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
},
mask: {
enable: true,
clickEvent: {
toClose: false,
toHide: false,
},
},
drag: true,
});
const GM_Menu = new utils.GM_Menu({
GM_getValue: _GM_getValue,
GM_setValue: _GM_setValue,
GM_registerMenuCommand: _GM_registerMenuCommand,
GM_unregisterMenuCommand: _GM_unregisterMenuCommand,
});
const httpx = new utils.Httpx({
xmlHttpRequest: _GM_xmlhttpRequest,
logDetails: DEBUG,
});
httpx.interceptors.request.use((data) => {
return data;
});
httpx.interceptors.response.use(void 0, (data) => {
log.error("拦截器-请求错误", data);
if (data.type === "onabort") {
Qmsg.warning("请求取消", { consoleLogContent: true });
} else if (data.type === "onerror") {
Qmsg.error("请求异常", { consoleLogContent: true });
} else if (data.type === "ontimeout") {
Qmsg.error("请求超时", { consoleLogContent: true });
} else {
Qmsg.error("其它错误", { consoleLogContent: true });
}
return data;
});
({
Object: {
defineProperty: _unsafeWindow.Object.defineProperty,
},
Function: {
apply: _unsafeWindow.Function.prototype.apply,
call: _unsafeWindow.Function.prototype.call,
},
Element: {
appendChild: _unsafeWindow.Element.prototype.appendChild,
},
setTimeout: _unsafeWindow.setTimeout,
});
const addStyle = domUtils.addStyle.bind(domUtils);
const $ = DOMUtils.selector.bind(DOMUtils);
const $$ = DOMUtils.selectorAll.bind(DOMUtils);
new utils.GM_Cookie();
const KEY = "GM_Panel";
const ATTRIBUTE_INIT = "data-init";
const ATTRIBUTE_KEY = "data-key";
const ATTRIBUTE_DEFAULT_VALUE = "data-default-value";
const ATTRIBUTE_INIT_MORE_VALUE = "data-init-more-value";
const PROPS_STORAGE_API = "data-storage-api";
const PanelSizeUtil = {
get width() {
return globalThis.innerWidth;
},
get height() {
return globalThis.innerHeight;
},
};
const PanelUISize = {
setting: {
get width() {
if (PanelSizeUtil.width < 550) {
return "88vw";
} else if (PanelSizeUtil.width < 700) {
return "550px";
} else {
return "700px";
}
},
get height() {
if (PanelSizeUtil.height < 450) {
return "70vh";
} else if (PanelSizeUtil.height < 550) {
return "450px";
} else {
return "550px";
}
},
},
settingMiddle: {
get width() {
return PanelSizeUtil.width < 350 ? "88vw" : "350px";
},
},
};
class StorageUtils {
storageKey;
listenerData;
constructor(key) {
if (typeof key === "string") {
const trimKey = key.trim();
if (trimKey == "") {
throw new Error("key参数不能为空字符串");
}
this.storageKey = trimKey;
} else {
throw new Error("key参数类型错误,必须是字符串");
}
this.listenerData = new Utils.Dictionary();
this.getLocalValue = this.getLocalValue.bind(this);
this.set = this.set.bind(this);
this.get = this.get.bind(this);
this.getAll = this.getAll.bind(this);
this.delete = this.delete.bind(this);
this.has = this.has.bind(this);
this.keys = this.keys.bind(this);
this.values = this.values.bind(this);
this.clear = this.clear.bind(this);
this.addValueChangeListener = this.addValueChangeListener.bind(this);
this.removeValueChangeListener = this.removeValueChangeListener.bind(this);
this.triggerValueChangeListener = this.triggerValueChangeListener.bind(this);
}
getLocalValue() {
let localValue = _GM_getValue(this.storageKey);
if (localValue == null) {
localValue = {};
this.setLocalValue(localValue);
}
return localValue;
}
setLocalValue(value) {
_GM_setValue(this.storageKey, value);
}
set(key, value) {
const oldValue = this.get(key);
const localValue = this.getLocalValue();
Reflect.set(localValue, key, value);
this.setLocalValue(localValue);
this.triggerValueChangeListener(key, oldValue, value);
}
get(key, defaultValue) {
const localValue = this.getLocalValue();
return Reflect.get(localValue, key) ?? defaultValue;
}
getAll() {
const localValue = this.getLocalValue();
return localValue;
}
delete(key) {
const oldValue = this.get(key);
const localValue = this.getLocalValue();
Reflect.deleteProperty(localValue, key);
this.setLocalValue(localValue);
this.triggerValueChangeListener(key, oldValue, void 0);
}
has(key) {
const localValue = this.getLocalValue();
return Reflect.has(localValue, key);
}
keys() {
const localValue = this.getLocalValue();
return Reflect.ownKeys(localValue);
}
values() {
const localValue = this.getLocalValue();
return Reflect.ownKeys(localValue).map((key) => Reflect.get(localValue, key));
}
clear() {
_GM_deleteValue(this.storageKey);
}
addValueChangeListener(key, callback) {
const listenerId = Math.random();
const listenerData = this.listenerData.get(key) || [];
listenerData.push({
id: listenerId,
key,
callback,
});
this.listenerData.set(key, listenerData);
return listenerId;
}
removeValueChangeListener(listenerId) {
let flag = false;
for (const [key, listenerData] of this.listenerData.entries()) {
for (let index = 0; index < listenerData.length; index++) {
const value = listenerData[index];
if (
(typeof listenerId === "string" && value.key === listenerId) ||
(typeof listenerId === "number" && value.id === listenerId)
) {
listenerData.splice(index, 1);
index--;
flag = true;
}
}
this.listenerData.set(key, listenerData);
}
return flag;
}
async triggerValueChangeListener(...args) {
const [key, oldValue, newValue] = args;
if (!this.listenerData.has(key)) {
return;
}
let listenerData = this.listenerData.get(key);
for (let index = 0; index < listenerData.length; index++) {
const data = listenerData[index];
if (typeof data.callback === "function") {
let value = this.get(key);
let __newValue;
let __oldValue;
if (typeof oldValue !== "undefined" && args.length >= 2) {
__oldValue = oldValue;
} else {
__oldValue = value;
}
if (typeof newValue !== "undefined" && args.length > 2) {
__newValue = newValue;
} else {
__newValue = value;
}
await data.callback(key, __oldValue, __newValue);
}
}
}
}
const PopsPanelStorageApi = new StorageUtils(KEY);
const PanelContent = {
$data: {
__contentConfig: null,
get contentConfig() {
if (this.__contentConfig == null) {
this.__contentConfig = new utils.Dictionary();
}
return this.__contentConfig;
},
__defaultBottomContentConfig: [],
},
addContentConfig(configList) {
if (!Array.isArray(configList)) {
configList = [configList];
}
let index = this.$data.contentConfig.keys().length;
this.$data.contentConfig.set(index, configList);
},
getAllContentConfig() {
return this.$data.contentConfig.values().flat();
},
getConfig(index = 0) {
return this.$data.contentConfig.get(index) ?? [];
},
getDefaultBottomContentConfig() {
if (this.$data.__defaultBottomContentConfig.length) {
return this.$data.__defaultBottomContentConfig;
}
return [
{
id: "script-version",
title: `版本:${_GM_info?.script?.version || "未知"}`,
isBottom: true,
forms: [],
clickFirstCallback(event, rightHeaderElement, rightContainerElement) {
let supportURL = _GM_info?.script?.supportURL || _GM_info?.script?.namespace;
if (typeof supportURL === "string" && utils.isNotNull(supportURL)) {
window.open(supportURL, "_blank");
}
return false;
},
},
];
},
setDefaultBottomContentConfig(config) {
this.$data.__defaultBottomContentConfig = config;
},
};
const PanelMenu = {
$data: {
__menuOption: [
{
key: "show_pops_panel_setting",
text: "⚙ 设置",
autoReload: false,
isStoreValue: false,
showText(text) {
return text;
},
callback: () => {
Panel.showPanel(PanelContent.getConfig(0));
},
},
],
get menuOption() {
return this.__menuOption;
},
},
init() {
this.initExtensionsMenu();
},
initExtensionsMenu() {
if (!Panel.isTopWindow()) {
return;
}
GM_Menu.add(this.$data.menuOption);
},
addMenuOption(option) {
if (!Array.isArray(option)) {
option = [option];
}
this.$data.menuOption.push(...option);
},
updateMenuOption(option) {
if (!Array.isArray(option)) {
option = [option];
}
option.forEach((optionItem) => {
let findIndex = this.$data.menuOption.findIndex((it) => {
return it.key === optionItem.key;
});
if (findIndex !== -1) {
this.$data.menuOption[findIndex] = optionItem;
}
});
},
getMenuOption(index = 0) {
return this.$data.menuOption[index];
},
deleteMenuOption(index = 0) {
this.$data.menuOption.splice(index, 1);
},
};
const Panel = {
$data: {
__contentConfigInitDefaultValue: null,
__onceExecMenuData: null,
__urlChangeReloadMenuExecOnce: null,
__onceExecData: null,
__panelConfig: {},
$panel: null,
panelContent: [],
get contentConfigInitDefaultValue() {
if (this.__contentConfigInitDefaultValue == null) {
this.__contentConfigInitDefaultValue = new utils.Dictionary();
}
return this.__contentConfigInitDefaultValue;
},
contentConfigInitDisabledKeys: [],
get onceExecMenuData() {
if (this.__onceExecMenuData == null) {
this.__onceExecMenuData = new utils.Dictionary();
}
return this.__onceExecMenuData;
},
get urlChangeReloadMenuExecOnce() {
if (this.__urlChangeReloadMenuExecOnce == null) {
this.__urlChangeReloadMenuExecOnce = new utils.Dictionary();
}
return this.__urlChangeReloadMenuExecOnce;
},
get onceExecData() {
if (this.__onceExecData == null) {
this.__onceExecData = new utils.Dictionary();
}
return this.__onceExecData;
},
get scriptName() {
return SCRIPT_NAME;
},
get panelConfig() {
return this.__panelConfig;
},
set panelConfig(value) {
this.__panelConfig = value;
},
key: KEY,
attributeKeyName: ATTRIBUTE_KEY,
attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE,
},
init() {
this.initContentDefaultValue();
PanelMenu.init();
},
isTopWindow() {
return _unsafeWindow.top === _unsafeWindow.self;
},
initContentDefaultValue() {
const initDefaultValue = (config) => {
if (!config.attributes) {
return;
}
if (config.type === "button" || config.type === "forms" || config.type === "deepMenu") {
return;
}
const attributes = config.attributes;
let __attr_init__ = attributes[ATTRIBUTE_INIT];
if (typeof __attr_init__ === "function") {
let __attr_result__ = __attr_init__();
if (typeof __attr_result__ === "boolean" && !__attr_result__) {
return;
}
}
let menuDefaultConfig = new Map();
let key = attributes[ATTRIBUTE_KEY];
if (key != null) {
const defaultValue = attributes[ATTRIBUTE_DEFAULT_VALUE];
menuDefaultConfig.set(key, defaultValue);
}
let moreMenuDefaultConfig = attributes[ATTRIBUTE_INIT_MORE_VALUE];
if (typeof moreMenuDefaultConfig === "object" && moreMenuDefaultConfig) {
Object.keys(moreMenuDefaultConfig).forEach((key2) => {
menuDefaultConfig.set(key2, moreMenuDefaultConfig[key2]);
});
}
if (!menuDefaultConfig.size) {
log.warn(["请先配置键", config]);
return;
}
if (config.type === "switch") {
let disabled = typeof config.disabled === "function" ? config.disabled() : config.disabled;
if (typeof disabled === "boolean" && disabled) {
this.$data.contentConfigInitDisabledKeys.push(...menuDefaultConfig.keys());
}
}
for (const [__key, __defaultValue] of menuDefaultConfig.entries()) {
this.setDefaultValue(__key, __defaultValue);
}
};
const loopInitDefaultValue = (configList) => {
for (let index = 0; index < configList.length; index++) {
let configItem = configList[index];
initDefaultValue(configItem);
let child_forms = configItem.forms;
if (child_forms && Array.isArray(child_forms)) {
loopInitDefaultValue(child_forms);
}
}
};
const contentConfigList = [...PanelContent.getAllContentConfig()];
for (let index = 0; index < contentConfigList.length; index++) {
let leftContentConfigItem = contentConfigList[index];
if (!leftContentConfigItem.forms) {
continue;
}
const rightContentConfigList = leftContentConfigItem.forms;
if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
loopInitDefaultValue(rightContentConfigList);
}
}
this.$data.contentConfigInitDisabledKeys = [...new Set(this.$data.contentConfigInitDisabledKeys)];
},
setDefaultValue(key, defaultValue) {
if (this.$data.contentConfigInitDefaultValue.has(key)) {
log.warn("请检查该key(已存在): " + key);
}
this.$data.contentConfigInitDefaultValue.set(key, defaultValue);
},
getDefaultValue(key) {
return this.$data.contentConfigInitDefaultValue.get(key);
},
setValue(key, value) {
PopsPanelStorageApi.set(key, value);
},
getValue(key, defaultValue) {
const localValue = PopsPanelStorageApi.get(key);
if (localValue == null) {
if (this.$data.contentConfigInitDefaultValue.has(key)) {
return this.$data.contentConfigInitDefaultValue.get(key);
}
return defaultValue;
}
return localValue;
},
deleteValue(key) {
PopsPanelStorageApi.delete(key);
},
hasKey(key) {
return PopsPanelStorageApi.has(key);
},
addValueChangeListener(key, callback) {
const listenerId = PopsPanelStorageApi.addValueChangeListener(key, (__key, __newValue, __oldValue) => {
callback(key, __oldValue, __newValue);
});
return listenerId;
},
removeValueChangeListener(listenerId) {
PopsPanelStorageApi.removeValueChangeListener(listenerId);
},
triggerMenuValueChange(key, newValue, oldValue) {
PopsPanelStorageApi.triggerValueChangeListener(key, oldValue, newValue);
},
async exec(queryKey, callback, checkExec, once = true) {
const that = this;
let queryKeyFn;
if (typeof queryKey === "string" || Array.isArray(queryKey)) {
queryKeyFn = () => queryKey;
} else {
queryKeyFn = queryKey;
}
let isArrayKey = false;
const queryKeyResult = queryKeyFn();
let keyList = [];
if (Array.isArray(queryKeyResult)) {
isArrayKey = true;
keyList = queryKeyResult;
} else {
keyList.push(queryKeyResult);
}
const findNotInDataKey = keyList.find((it) => !this.$data.contentConfigInitDefaultValue.has(it));
if (findNotInDataKey) {
log.warn(`${findNotInDataKey} 键不存在`);
return;
}
const storageKey = JSON.stringify(keyList);
if (once) {
if (this.$data.onceExecMenuData.has(storageKey)) {
return this.$data.onceExecMenuData.get(storageKey);
}
}
let storeValueList = [];
const listenerIdList = [];
let destoryFnList = [];
const addStoreValueCallback = (enableValue, args) => {
let dynamicMenuStoreValueList = [];
let dynamicDestoryFnList = [];
let resultValueList = [];
if (Array.isArray(args)) {
resultValueList = resultValueList.concat(args);
} else {
if (typeof args === "object" && args != null) {
if (args instanceof Element) {
resultValueList.push(args);
} else {
const { $css, destory } = args;
if ($css != null) {
if (Array.isArray($css)) {
resultValueList = resultValueList.concat($css);
} else {
resultValueList.push($css);
}
}
if (typeof destory === "function") {
resultValueList.push(destory);
}
}
} else {
resultValueList.push(args);
}
}
for (const it of resultValueList) {
if (it == null) {
continue;
}
if (it instanceof Element) {
dynamicMenuStoreValueList.push(it);
continue;
}
if (typeof it === "function") {
destoryFnList.push(it);
continue;
}
}
if (enableValue) {
storeValueList = storeValueList.concat(dynamicMenuStoreValueList);
destoryFnList = destoryFnList.concat(dynamicDestoryFnList);
} else {
execClearStoreStyleElements();
execDestory();
}
};
const getMenuValue = (key) => {
const value = this.getValue(key);
return value;
};
const execClearStoreStyleElements = () => {
for (let index = 0; index < storeValueList.length; index++) {
const $css = storeValueList[index];
$css?.remove();
storeValueList.splice(index, 1);
index--;
}
};
const execDestory = () => {
for (let index = 0; index < destoryFnList.length; index++) {
const destoryFnItem = destoryFnList[index];
destoryFnItem();
destoryFnList.splice(index, 1);
index--;
}
};
const checkMenuExec = () => {
let flag = false;
if (typeof checkExec === "function") {
flag = checkExec(keyList);
} else {
flag = keyList.every((key) => getMenuValue(key));
}
return flag;
};
const valueChangeCallback = async (valueOption) => {
const execFlag = checkMenuExec();
if (execFlag) {
const valueList = keyList.map((key) => this.getValue(key));
const callbackResult = await callback({
value: isArrayKey ? valueList : valueList[0],
addStoreValue: (...args) => {
return addStoreValueCallback(true, args);
},
});
addStoreValueCallback(true, callbackResult);
} else {
addStoreValueCallback(false, []);
}
};
once &&
keyList.forEach((key) => {
const listenerId = this.addValueChangeListener(key, (key2, newValue, oldValue) => {
return valueChangeCallback();
});
listenerIdList.push(listenerId);
});
await valueChangeCallback();
const result = {
reload() {
this.clearStoreStyleElements();
this.destory();
valueChangeCallback();
},
clear() {
this.clearStoreStyleElements();
this.destory();
this.removeValueChangeListener();
this.clearOnceExecMenuData();
},
clearStoreStyleElements: () => {
return execClearStoreStyleElements();
},
destory() {
return execDestory();
},
removeValueChangeListener: () => {
listenerIdList.forEach((listenerId) => {
this.removeValueChangeListener(listenerId);
});
},
clearOnceExecMenuData() {
once && that.$data.onceExecMenuData.delete(storageKey);
},
};
this.$data.onceExecMenuData.set(storageKey, result);
return result;
},
async execMenu(key, callback, isReverse = false, once = false) {
return await this.exec(
key,
async (option) => {
return await callback(option);
},
(keyList) => {
const execFlag = keyList.every((__key__) => {
let flag = !!this.getValue(__key__);
const disabled = Panel.$data.contentConfigInitDisabledKeys.includes(__key__);
if (disabled) {
flag = false;
log.warn(`.execMenu${once ? "Once" : ""} ${__key__} 被禁用`);
}
isReverse && (flag = !flag);
return flag;
});
return execFlag;
},
once
);
},
async execMenuOnce(key, callback, isReverse = false, listenUrlChange = false) {
const result = await this.execMenu(key, callback, isReverse, true);
if (listenUrlChange) {
if (result) {
const urlChangeEvent = () => {
result.reload();
};
this.removeUrlChangeWithExecMenuOnceListener(key);
this.addUrlChangeWithExecMenuOnceListener(key, urlChangeEvent);
}
}
return result;
},
deleteExecMenuOnce(key) {
key = this.transformKey(key);
this.$data.onceExecMenuData.delete(key);
this.$data.urlChangeReloadMenuExecOnce.delete(key);
const flag = PopsPanelStorageApi.removeValueChangeListener(key);
return flag;
},
onceExec(key, callback) {
key = this.transformKey(key);
if (typeof key !== "string") {
throw new TypeError("key 必须是字符串");
}
if (this.$data.onceExecData.has(key)) {
return;
}
callback();
this.$data.onceExecData.set(key, 1);
},
deleteOnceExec(key) {
key = this.transformKey(key);
this.$data.onceExecData.delete(key);
},
addUrlChangeWithExecMenuOnceListener(key, callback) {
key = this.transformKey(key);
this.$data.urlChangeReloadMenuExecOnce.set(key, callback);
},
removeUrlChangeWithExecMenuOnceListener(key) {
key = this.transformKey(key);
this.$data.urlChangeReloadMenuExecOnce.delete(key);
},
hasUrlChangeWithExecMenuOnceListener(key) {
key = this.transformKey(key);
return this.$data.urlChangeReloadMenuExecOnce.has(key);
},
async triggerUrlChangeWithExecMenuOnceEvent(config) {
const values = this.$data.urlChangeReloadMenuExecOnce.values();
for (const callback of values) {
await callback(config);
}
},
showPanel(
content,
title = `${SCRIPT_NAME}-设置`,
preventDefaultContentConfig = false,
preventRegisterSearchPlugin = false
) {
this.$data.$panel = null;
this.$data.panelContent = [];
let checkHasBottomVersionContentConfig =
content.findIndex((it) => {
let isBottom = typeof it.isBottom === "function" ? it.isBottom() : Boolean(it.isBottom);
return isBottom && it.id === "script-version";
}) !== -1;
if (!preventDefaultContentConfig && !checkHasBottomVersionContentConfig) {
content.push(...PanelContent.getDefaultBottomContentConfig());
}
let $panel = __pops.panel({
...{
title: {
text: title,
position: "center",
html: false,
style: "",
},
content,
btn: {
close: {
enable: true,
callback: (details, event) => {
details.close();
this.$data.$panel = null;
},
},
},
mask: {
enable: true,
clickEvent: {
toClose: true,
toHide: false,
},
clickCallBack: (originalRun, config) => {
originalRun();
this.$data.$panel = null;
},
},
width: PanelUISize.setting.width,
height: PanelUISize.setting.height,
drag: true,
only: true,
},
...this.$data.panelConfig,
});
this.$data.$panel = $panel;
this.$data.panelContent = content;
if (!preventRegisterSearchPlugin) {
this.registerConfigSearch({ $panel, content });
}
},
registerConfigSearch(config) {
const { $panel, content } = config;
let asyncQueryProperty = async (target, handler) => {
if (target == null) {
return;
}
let handleResult = await handler(target);
if (handleResult && typeof handleResult.isFind === "boolean" && handleResult.isFind) {
return handleResult.data;
}
return await asyncQueryProperty(handleResult.data, handler);
};
let scrollToElementAndListen = ($el, callback) => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
callback?.();
observer.disconnect();
}
});
},
{
root: null,
threshold: 1,
}
);
observer.observe($el);
$el.scrollIntoView({ behavior: "smooth", block: "center" });
};
let addFlashingClass = ($el) => {
const flashingClassName = "pops-flashing";
domUtils.animationend($el, () => {
$el.classList.remove(flashingClassName);
});
$el.classList.add(flashingClassName);
};
let dbclick_event = (evt, selectorTarget) => {
domUtils.preventEvent(evt);
let $alert = __pops.alert({
title: {
text: "搜索配置",
position: "center",
},
content: {
text: `