- // ==UserScript==
- // @name 简书优化
- // @namespace https://github.com/WhiteSevs/TamperMonkeyScript
- // @version 2025.2.12
- // @author WhiteSevs
- // @description 支持手机端和PC端、屏蔽广告、优化浏览体验、重定向链接、全文居中、自动展开全文、允许复制文字、劫持唤醒/跳转App、自定义屏蔽元素等
- // @license GPL-3.0-only
- // @icon data:image/png;base64,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
- // @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
- // @match *://*.jianshu.com/*
- // @match *://*.jianshu.io/*
- // @require https://fastly.jsdelivr.net/gh/WhiteSevs/TamperMonkeyScript@86be74b83fca4fa47521cded28377b35e1d7d2ac/lib/CoverUMD/index.js
- // @require https://fastly.jsdelivr.net/npm/@whitesev/utils@2.6.1/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.7/dist/index.umd.js
- // @require https://fastly.jsdelivr.net/npm/qmsg@1.2.8/dist/index.umd.js
- // @connect *
- // @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 _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 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);
- }
- },
- /**
- * 添加<link>标签
- * @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);
- });
- },
- /**
- * 添加<script>标签
- * @param url
- * @example
- * loadStyleLink("https://example.com/example.js")
- */
- 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);
- });
- },
- /**
- * 将url修复,例如只有search的链接修复为完整的链接
- *
- * 注意:不包括http转https
- * @param url 需要修复的链接
- * @example
- * 修复前:`/xxx/xxx?ss=ssss`
- * 修复后:`https://xxx.xxx.xxx/xxx/xxx?ss=ssss`
- * @example
- * 修复前:`//xxx/xxx?ss=ssss`
- * 修复后:`https://xxx.xxx.xxx/xxx/xxx?ss=ssss`
- * @example
- * 修复前:`https://xxx.xxx.xxx/xxx/xxx?ss=ssss`
- * 修复后:`https://xxx.xxx.xxx/xxx/xxx?ss=ssss`
- * @example
- * 修复前:`xxx/xxx?ss=ssss`
- * 修复后:`https://xxx.xxx.xxx/xxx/xxx?ss=ssss`
- */
- fixUrl(url) {
- url = url.trim();
- if (url.match(/^http(s|):\/\//i)) {
- return url;
- } else {
- if (!url.startsWith("/")) {
- url += "/";
- }
- url = window.location.origin + url;
- return url;
- }
- },
- /**
- * http转https
- * @param url 需要修复的链接
- * @example
- * 修复前:
- * 修复后:
- * @example
- * 修复前:
- * 修复后:
- */
- fixHttps(url) {
- if (url.startsWith("https://")) {
- return url;
- }
- if (!url.startsWith("http://")) {
- return url;
- }
- let urlObj = new URL(url);
- urlObj.protocol = "https:";
- return urlObj.toString();
- }
- };
- const _SCRIPT_NAME_ = "简书优化";
- const utils = Utils.noConflict();
- const domUtils = DOMUtils.noConflict();
- const log = new utils.Log(
- _GM_info,
- _unsafeWindow.console || _monkeyWindow.console
- );
- const SCRIPT_NAME = ((_a = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _a.name) || _SCRIPT_NAME_;
- const DEBUG = false;
- log.config({
- debug: DEBUG,
- logMaxCount: 1e3,
- autoClearConsole: true,
- tag: true
- });
- Qmsg.config(
- Object.defineProperties(
- {
- html: true,
- autoClose: true,
- showClose: false
- },
- {
- position: {
- get() {
- return PopsPanel.getValue("qmsg-config-position", "bottom");
- }
- },
- maxNums: {
- get() {
- return PopsPanel.getValue("qmsg-config-maxnums", 5);
- }
- },
- showReverse: {
- get() {
- return PopsPanel.getValue("qmsg-config-showreverse", true);
- }
- },
- zIndex: {
- get() {
- let maxZIndex = Utils.getMaxZIndex();
- let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex().zIndex;
- return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
- }
- }
- }
- )
- );
- 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(_GM_xmlhttpRequest);
- httpx.interceptors.response.use(void 0, (data) => {
- log.error("拦截器-请求错误", data);
- if (data.type === "onabort") {
- Qmsg.warning("请求取消");
- } else if (data.type === "onerror") {
- Qmsg.error("请求异常");
- } else if (data.type === "ontimeout") {
- Qmsg.error("请求超时");
- } else {
- Qmsg.error("其它错误");
- }
- return data;
- });
- httpx.config({
- logDetails: DEBUG
- });
- ({
- 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 = utils.addStyle.bind(utils);
- document.querySelector.bind(document);
- document.querySelectorAll.bind(document);
- 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 UISwitch = function(text, key, defaultValue, clickCallBack, description, afterAddToUListCallBack) {
- let result = {
- text,
- type: "switch",
- description,
- attributes: {},
- props: {},
- getValue() {
- return Boolean(
- this.props[PROPS_STORAGE_API].get(key, defaultValue)
- );
- },
- callback(event, __value) {
- let value = Boolean(__value);
- log.success(`${value ? "开启" : "关闭"} ${text}`);
- this.props[PROPS_STORAGE_API].set(key, value);
- },
- afterAddToUListCallBack
- };
- Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
- Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
- Reflect.set(result.props, PROPS_STORAGE_API, {
- get(key2, defaultValue2) {
- return PopsPanel.getValue(key2, defaultValue2);
- },
- set(key2, value) {
- PopsPanel.setValue(key2, value);
- }
- });
- return result;
- };
- const SettingUIPC = {
- id: "jianshu-panel-config-pc",
- title: "桌面端",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- {
- text: "功能",
- type: "deepMenu",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- UISwitch("全文居中", "JianShuArticleCenter", true),
- UISwitch("自动展开全文", "JianShuAutoExpandFullText", true),
- UISwitch(
- "重定向链接",
- "JianShuAutoJumpRedirect_PC",
- true,
- void 0,
- "自动跳转简书拦截的Url链接"
- )
- ]
- }
- ]
- },
- {
- text: "屏蔽",
- type: "deepMenu",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- UISwitch(
- "【屏蔽】底部推荐阅读",
- "JianShuShieldRecommendedReading",
- false
- ),
- UISwitch("【屏蔽】评论区", "JianShuShieldUserComments", false),
- UISwitch(
- "【屏蔽】相关文章",
- "JianShuShieldRelatedArticles",
- false
- ),
- UISwitch(
- "【屏蔽】客户端弹窗",
- "jianshu-shieldClientDialog",
- true,
- void 0,
- "弹出的【扫码安装简书客户端 畅享全文阅读体验】"
- ),
- UISwitch("【屏蔽】顶部导航栏", "jianshu-shieldTopNav", false),
- UISwitch(
- "【屏蔽】底部工具栏",
- "jianshu-shieldBottomToolbar",
- false,
- void 0,
- "屏蔽掉底部悬浮的评论输入框、评论、点赞..."
- )
- ]
- }
- ]
- },
- {
- text: "劫持/拦截",
- type: "deepMenu",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- UISwitch(
- "拦截-剪贴板",
- "JianShuRemoveClipboardHijacking",
- true,
- void 0,
- "去除禁止复制"
- )
- ]
- }
- ]
- }
- ]
- }
- ]
- };
- const SettingUIMobile = {
- id: "jianshu-panel-config-mobile",
- title: "移动端",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- {
- text: "功能",
- type: "deepMenu",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- UISwitch(
- "自动展开全文",
- "JianShuAutoExpandFullText_Mobile",
- true
- ),
- UISwitch(
- "重定向链接",
- "JianShuAutoJumpRedirect_Mobile",
- true,
- void 0,
- "自动跳转简书拦截的Url链接"
- )
- ]
- }
- ]
- },
- {
- text: "屏蔽",
- type: "deepMenu",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- UISwitch(
- "【屏蔽】底部推荐阅读",
- "JianShuremoveFooterRecommendRead",
- false
- ),
- UISwitch(
- "【屏蔽】评论区",
- "JianShuShieldUserCommentsMobile",
- false
- )
- ]
- }
- ]
- },
- {
- text: "劫持/拦截",
- type: "deepMenu",
- forms: [
- {
- text: "",
- type: "forms",
- forms: [
- UISwitch(
- "拦截-剪贴板",
- "JianShuRemoveClipboardHijacking_Mobile",
- true,
- void 0,
- "去除禁止复制"
- ),
- UISwitch(
- "劫持-唤醒/跳转App",
- "JianShuHijackSchemeScriptLabel_Mobile",
- true,
- void 0,
- "去除简书唤醒调用App"
- )
- ]
- }
- ]
- }
- ]
- }
- ]
- };
- const UISelect = function(text, key, defaultValue, data, callback, description) {
- let selectData = [];
- if (typeof data === "function") {
- selectData = data();
- } else {
- selectData = data;
- }
- let result = {
- text,
- type: "select",
- description,
- attributes: {},
- props: {},
- getValue() {
- return this.props[PROPS_STORAGE_API].get(key, defaultValue);
- },
- callback(event, isSelectedValue, isSelectedText) {
- let value = isSelectedValue;
- log.info(`选择:${isSelectedText}`);
- this.props[PROPS_STORAGE_API].set(key, value);
- if (typeof callback === "function") {
- callback(event, value, isSelectedText);
- }
- },
- data: selectData
- };
- Reflect.set(result.attributes, ATTRIBUTE_KEY, key);
- Reflect.set(result.attributes, ATTRIBUTE_DEFAULT_VALUE, defaultValue);
- Reflect.set(result.props, PROPS_STORAGE_API, {
- get(key2, defaultValue2) {
- return PopsPanel.getValue(key2, defaultValue2);
- },
- set(key2, value) {
- PopsPanel.setValue(key2, value);
- }
- });
- return result;
- };
- const SettingUICommon = {
- id: "jianshu-panel-common",
- title: "通用",
- forms: [
- {
- text: "Toast配置",
- type: "forms",
- forms: [
- UISelect(
- "Toast位置",
- "qmsg-config-position",
- "bottom",
- [
- {
- value: "topleft",
- text: "左上角"
- },
- {
- value: "top",
- text: "顶部"
- },
- {
- value: "topright",
- text: "右上角"
- },
- {
- value: "left",
- text: "左边"
- },
- {
- value: "center",
- text: "中间"
- },
- {
- value: "right",
- text: "右边"
- },
- {
- value: "bottomleft",
- text: "左下角"
- },
- {
- value: "bottom",
- text: "底部"
- },
- {
- value: "bottomright",
- text: "右下角"
- }
- ],
- (event, isSelectValue, isSelectText) => {
- log.info("设置当前Qmsg弹出位置" + isSelectText);
- },
- "Toast显示在页面九宫格的位置"
- ),
- UISelect(
- "最多显示的数量",
- "qmsg-config-maxnums",
- 3,
- [
- {
- value: 1,
- text: "1"
- },
- {
- value: 2,
- text: "2"
- },
- {
- value: 3,
- text: "3"
- },
- {
- value: 4,
- text: "4"
- },
- {
- value: 5,
- text: "5"
- }
- ],
- void 0,
- "限制Toast显示的数量"
- ),
- UISwitch(
- "逆序弹出",
- "qmsg-config-showreverse",
- false,
- void 0,
- "修改Toast弹出的顺序"
- )
- ]
- }
- ]
- };
- const PanelUISize = {
- /**
- * 一般设置界面的尺寸
- */
- setting: {
- get width() {
- return window.innerWidth < 550 ? "88vw" : "550px";
- },
- get height() {
- return window.innerHeight < 450 ? "70vh" : "450px";
- }
- }
- };
- const PopsPanel = {
- /** 数据 */
- $data: {
- __data: null,
- __oneSuccessExecMenu: null,
- __onceExec: null,
- __listenData: null,
- /**
- * 菜单项的默认值
- */
- get data() {
- if (PopsPanel.$data.__data == null) {
- PopsPanel.$data.__data = new utils.Dictionary();
- }
- return PopsPanel.$data.__data;
- },
- /**
- * 成功只执行了一次的项
- */
- get oneSuccessExecMenu() {
- if (PopsPanel.$data.__oneSuccessExecMenu == null) {
- PopsPanel.$data.__oneSuccessExecMenu = new utils.Dictionary();
- }
- return PopsPanel.$data.__oneSuccessExecMenu;
- },
- /**
- * 成功只执行了一次的项
- */
- get onceExec() {
- if (PopsPanel.$data.__onceExec == null) {
- PopsPanel.$data.__onceExec = new utils.Dictionary();
- }
- return PopsPanel.$data.__onceExec;
- },
- /** 脚本名,一般用在设置的标题上 */
- get scriptName() {
- return SCRIPT_NAME;
- },
- /** 菜单项的总值在本地数据配置的键名 */
- key: KEY,
- /** 菜单项在attributes上配置的菜单键 */
- attributeKeyName: ATTRIBUTE_KEY,
- /** 菜单项在attributes上配置的菜单默认值 */
- attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE
- },
- /** 监听器 */
- $listener: {
- /**
- * 值改变的监听器
- */
- get listenData() {
- if (PopsPanel.$data.__listenData == null) {
- PopsPanel.$data.__listenData = new utils.Dictionary();
- }
- return PopsPanel.$data.__listenData;
- }
- },
- init() {
- this.initPanelDefaultValue();
- this.initExtensionsMenu();
- },
- /** 判断是否是顶层窗口 */
- isTopWindow() {
- return _unsafeWindow.top === _unsafeWindow.self;
- },
- initExtensionsMenu() {
- if (!this.isTopWindow()) {
- return;
- }
- GM_Menu.add([
- {
- key: "show_pops_panel_setting",
- text: "⚙ 设置",
- autoReload: false,
- isStoreValue: false,
- showText(text) {
- return text;
- },
- callback: () => {
- this.showPanel();
- }
- }
- ]);
- },
- /** 初始化菜单项的默认值保存到本地数据中 */
- initPanelDefaultValue() {
- let that = this;
- function initDefaultValue(config) {
- if (!config.attributes) {
- return;
- }
- let needInitConfig = {};
- let key = config.attributes[ATTRIBUTE_KEY];
- if (key != null) {
- needInitConfig[key] = config.attributes[ATTRIBUTE_DEFAULT_VALUE];
- }
- let __attr_init__ = config.attributes[ATTRIBUTE_INIT];
- if (typeof __attr_init__ === "function") {
- let __attr_result__ = __attr_init__();
- if (typeof __attr_result__ === "boolean" && !__attr_result__) {
- return;
- }
- }
- let initMoreValue = config.attributes[ATTRIBUTE_INIT_MORE_VALUE];
- if (initMoreValue && typeof initMoreValue === "object") {
- Object.assign(needInitConfig, initMoreValue);
- }
- let needInitConfigList = Object.keys(needInitConfig);
- if (!needInitConfigList.length) {
- log.warn(["请先配置键", config]);
- return;
- }
- needInitConfigList.forEach((__key) => {
- let __defaultValue = needInitConfig[__key];
- if (that.$data.data.has(__key)) {
- log.warn("请检查该key(已存在): " + __key);
- }
- that.$data.data.set(__key, __defaultValue);
- });
- }
- function loopInitDefaultValue(configList) {
- for (let index = 0; index < configList.length; index++) {
- let configItem = configList[index];
- initDefaultValue(configItem);
- let childForms = configItem.forms;
- if (childForms && Array.isArray(childForms)) {
- loopInitDefaultValue(childForms);
- }
- }
- }
- let contentConfigList = this.getPanelContentConfig();
- for (let index = 0; index < contentConfigList.length; index++) {
- let leftContentConfigItem = contentConfigList[index];
- if (!leftContentConfigItem.forms) {
- continue;
- }
- let rightContentConfigList = leftContentConfigItem.forms;
- if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
- loopInitDefaultValue(rightContentConfigList);
- }
- }
- },
- /**
- * 设置值
- * @param key 键
- * @param value 值
- */
- setValue(key, value) {
- let locaData = _GM_getValue(KEY, {});
- let oldValue = locaData[key];
- locaData[key] = value;
- _GM_setValue(KEY, locaData);
- if (this.$listener.listenData.has(key)) {
- this.$listener.listenData.get(key).callback(key, oldValue, value);
- }
- },
- /**
- * 获取值
- * @param key 键
- * @param defaultValue 默认值
- */
- getValue(key, defaultValue) {
- let locaData = _GM_getValue(KEY, {});
- let localValue = locaData[key];
- if (localValue == null) {
- if (this.$data.data.has(key)) {
- return this.$data.data.get(key);
- }
- return defaultValue;
- }
- return localValue;
- },
- /**
- * 删除值
- * @param key 键
- */
- deleteValue(key) {
- let locaData = _GM_getValue(KEY, {});
- let oldValue = locaData[key];
- Reflect.deleteProperty(locaData, key);
- _GM_setValue(KEY, locaData);
- if (this.$listener.listenData.has(key)) {
- this.$listener.listenData.get(key).callback(key, oldValue, void 0);
- }
- },
- /**
- * 监听调用setValue、deleteValue
- * @param key 需要监听的键
- * @param callback
- */
- addValueChangeListener(key, callback) {
- let listenerId = Math.random();
- this.$listener.listenData.set(key, {
- id: listenerId,
- key,
- callback
- });
- return listenerId;
- },
- /**
- * 移除监听
- * @param listenerId 监听的id
- */
- removeValueChangeListener(listenerId) {
- let deleteKey = null;
- for (const [key, value] of this.$listener.listenData.entries()) {
- if (value.id === listenerId) {
- deleteKey = key;
- break;
- }
- }
- if (typeof deleteKey === "string") {
- this.$listener.listenData.delete(deleteKey);
- } else {
- console.warn("没有找到对应的监听器");
- }
- },
- /**
- * 主动触发菜单值改变的回调
- * @param key 菜单键
- * @param newValue 想要触发的新值,默认使用当前值
- * @param oldValue 想要触发的旧值,默认使用当前值
- */
- triggerMenuValueChange(key, newValue, oldValue) {
- if (this.$listener.listenData.has(key)) {
- let listenData = this.$listener.listenData.get(key);
- if (typeof listenData.callback === "function") {
- let value = this.getValue(key);
- let __newValue = value;
- let __oldValue = value;
- if (typeof newValue !== "undefined" && arguments.length > 1) {
- __newValue = newValue;
- }
- if (typeof oldValue !== "undefined" && arguments.length > 2) {
- __oldValue = oldValue;
- }
- listenData.callback(key, __oldValue, __newValue);
- }
- }
- },
- /**
- * 判断该键是否存在
- * @param key 键
- */
- hasKey(key) {
- let locaData = _GM_getValue(KEY, {});
- return key in locaData;
- },
- /**
- * 自动判断菜单是否启用,然后执行回调
- * @param key
- * @param callback 回调
- * @param [isReverse=false] 逆反判断菜单启用
- */
- execMenu(key, callback, isReverse = false) {
- if (!(typeof key === "string" || typeof key === "object" && Array.isArray(key))) {
- throw new TypeError("key 必须是字符串或者字符串数组");
- }
- let runKeyList = [];
- if (typeof key === "object" && Array.isArray(key)) {
- runKeyList = [...key];
- } else {
- runKeyList.push(key);
- }
- let value = void 0;
- for (let index = 0; index < runKeyList.length; index++) {
- const runKey = runKeyList[index];
- if (!this.$data.data.has(runKey)) {
- log.warn(`${key} 键不存在`);
- return;
- }
- let runValue = PopsPanel.getValue(runKey);
- if (isReverse) {
- runValue = !runValue;
- }
- if (!runValue) {
- break;
- }
- value = runValue;
- }
- if (value) {
- callback(value);
- }
- },
- /**
- * 自动判断菜单是否启用,然后执行回调,只会执行一次
- * @param key
- * @param callback 回调
- * @param getValueFn 自定义处理获取当前值,值true是启用并执行回调,值false是不执行回调
- * @param handleValueChangeFn 自定义处理值改变时的回调,值true是启用并执行回调,值false是不执行回调
- */
- execMenuOnce(key, callback, getValueFn, handleValueChangeFn) {
- if (typeof key !== "string") {
- throw new TypeError("key 必须是字符串");
- }
- if (!this.$data.data.has(key)) {
- log.warn(`${key} 键不存在`);
- return;
- }
- if (this.$data.oneSuccessExecMenu.has(key)) {
- return;
- }
- this.$data.oneSuccessExecMenu.set(key, 1);
- let __getValue = () => {
- let localValue = PopsPanel.getValue(key);
- return typeof getValueFn === "function" ? getValueFn(key, localValue) : localValue;
- };
- let resultStyleList = [];
- let dynamicPushStyleNode = ($style) => {
- let __value = __getValue();
- let dynamicResultList = [];
- if ($style instanceof HTMLStyleElement) {
- dynamicResultList = [$style];
- } else if (Array.isArray($style)) {
- dynamicResultList = [
- ...$style.filter(
- (item) => item != null && item instanceof HTMLStyleElement
- )
- ];
- }
- if (__value) {
- resultStyleList = resultStyleList.concat(dynamicResultList);
- } else {
- for (let index = 0; index < dynamicResultList.length; index++) {
- let $css = dynamicResultList[index];
- $css.remove();
- dynamicResultList.splice(index, 1);
- index--;
- }
- }
- };
- let changeCallBack = (currentValue) => {
- let resultList = [];
- if (currentValue) {
- let result = callback(currentValue, dynamicPushStyleNode);
- if (result instanceof HTMLStyleElement) {
- resultList = [result];
- } else if (Array.isArray(result)) {
- resultList = [
- ...result.filter(
- (item) => item != null && item instanceof HTMLStyleElement
- )
- ];
- }
- }
- for (let index = 0; index < resultStyleList.length; index++) {
- let $css = resultStyleList[index];
- $css.remove();
- resultStyleList.splice(index, 1);
- index--;
- }
- resultStyleList = [...resultList];
- };
- this.addValueChangeListener(
- key,
- (__key, oldValue, newValue) => {
- let __newValue = newValue;
- if (typeof handleValueChangeFn === "function") {
- __newValue = handleValueChangeFn(__key, newValue, oldValue);
- }
- changeCallBack(__newValue);
- }
- );
- let value = __getValue();
- if (value) {
- changeCallBack(value);
- }
- },
- /**
- * 父子菜单联动,自动判断菜单是否启用,然后执行回调,只会执行一次
- * @param key 菜单键
- * @param childKey 子菜单键
- * @param callback 回调
- * @param replaceValueFn 用于修改mainValue,返回undefined则不做处理
- */
- execInheritMenuOnce(key, childKey, callback, replaceValueFn) {
- let that = this;
- const handleInheritValue = (key2, childKey2) => {
- let mainValue = that.getValue(key2);
- let childValue = that.getValue(childKey2);
- if (typeof replaceValueFn === "function") {
- let changedMainValue = replaceValueFn(mainValue, childValue);
- if (changedMainValue !== void 0) {
- return changedMainValue;
- }
- }
- return mainValue;
- };
- this.execMenuOnce(
- key,
- callback,
- () => {
- return handleInheritValue(key, childKey);
- },
- () => {
- return handleInheritValue(key, childKey);
- }
- );
- this.execMenuOnce(
- childKey,
- () => {
- },
- () => false,
- () => {
- this.triggerMenuValueChange(key);
- return false;
- }
- );
- },
- /**
- * 根据key执行一次
- * @param key
- */
- onceExec(key, callback) {
- if (typeof key !== "string") {
- throw new TypeError("key 必须是字符串");
- }
- if (this.$data.onceExec.has(key)) {
- return;
- }
- callback();
- this.$data.onceExec.set(key, 1);
- },
- /**
- * 显示设置面板
- */
- showPanel() {
- pops.panel({
- title: {
- text: `${SCRIPT_NAME}-设置`,
- position: "center",
- html: false,
- style: ""
- },
- content: this.getPanelContentConfig(),
- mask: {
- enable: true,
- clickEvent: {
- toClose: true,
- toHide: false
- }
- },
- width: PanelUISize.setting.width,
- height: PanelUISize.setting.height,
- drag: true,
- only: true
- });
- },
- /**
- * 获取配置内容
- */
- getPanelContentConfig() {
- let configList = [
- SettingUICommon,
- SettingUIPC,
- SettingUIMobile
- ];
- return configList;
- }
- };
- const blockCSS = `.download-app-guidance,\r
- .call-app-btn,\r
- .collapse-tips,\r
- .note-graceful-button,\r
- .app-open,\r
- .header-wrap,\r
- .recommend-wrap.recommend-ad,\r
- .call-app-Ad-bottom,\r
- #recommended-notes p.top-title span.more,\r
- #homepage .modal,\r
- button.index_call-app-btn,\r
- span.note__flow__download,\r
- .download-guide,\r
- #footer,\r
- .comment-open-app-btn-wrap,\r
- .nav.navbar-nav + div,\r
- .self-flow-ad,\r
- #free-reward-panel,\r
- div[id*='AdFive'],\r
- #index-aside-download-qrbox,\r
- .baidu-app-download-2eIkf_1,\r
- /* 底部的"小礼物走一走,来简书关注我"、赞赏支持和更多精彩内容,就在简书APP */\r
- div[role="main"] > div > section:first-child > div:nth-last-child(2),\r
- /* 它的内部是script标签,可能影响部分评论之间的高度问题 */\r
- div.adad_container ,\r
- /* 顶部导航栏的【下载App】 */\r
- #__next nav a[href*="navbar-app"] {\r
- display: none !important;\r
- }\r
- body.reader-day-mode.normal-size {\r
- overflow: auto !important;\r
- }\r
- .collapse-free-content {\r
- height: auto !important;\r
- }\r
- .copyright {\r
- color: #000 !important;\r
- }\r
- #note-show .content .show-content-free .collapse-free-content:after {\r
- background-image: none !important;\r
- }\r
- footer > div > div {\r
- justify-content: center;\r
- }\r
- /* 修复底部最后编辑于:。。。在某些套壳浏览器上的错位问题 */\r
- #note-show .content .show-content-free .note-meta-time {\r
- margin-top: 0px !important;\r
- }\r
- `;
- const JianshuRouter = {
- /**
- * 简书拦截跳转的网址
- */
- isGoWild() {
- return window.location.pathname === "/go-wild";
- }
- };
- const waitForElementToRemove = function(selectorText = "") {
- utils.waitNodeList(selectorText).then((nodeList) => {
- nodeList.forEach((item) => item.remove());
- });
- };
- const Jianshu = {
- init() {
- this.addCSS();
- PopsPanel.execMenu("JianShuAutoJumpRedirect_PC", () => {
- this.jumpRedirect();
- });
- PopsPanel.execMenu("JianShuRemoveClipboardHijacking", () => {
- this.removeClipboardHijacking();
- });
- PopsPanel.execMenu("JianShuAutoExpandFullText", () => {
- this.autoExpandFullText();
- });
- PopsPanel.execMenu("JianShuArticleCenter", () => {
- return this.articleCenter();
- });
- PopsPanel.execMenu("JianShuShieldRelatedArticles", () => {
- return this.blockRelatedArticles();
- });
- PopsPanel.execMenu("jianshu-shieldClientDialog", () => {
- this.blockClientDialog();
- });
- PopsPanel.execMenuOnce("JianShuShieldUserComments", () => {
- return this.blockUserComments();
- });
- PopsPanel.execMenuOnce("JianShuShieldRecommendedReading", () => {
- return this.blockRecommendedReading();
- });
- PopsPanel.execMenuOnce("jianshu-shieldTopNav", () => {
- return this.blockTopNav();
- });
- PopsPanel.execMenuOnce("jianshu-shieldBottomToolbar", () => {
- return this.blockBottomToolbar();
- });
- },
- /**
- * 添加屏蔽CSS
- */
- addCSS() {
- log.info("添加屏蔽CSS");
- return addStyle(blockCSS);
- },
- /**
- * 全文居中
- */
- articleCenter() {
- log.info("全文居中");
- let result = [];
- result.push(
- CommonUtil.addBlockCSS("div[role=main] aside", "div._3Pnjry"),
- addStyle(
- /*css*/
- `
- div[role=main] aside,
- div._3Pnjry{
- display: none !important;
- }
- div._gp-ck{
- width: 100% !important;
- }`
- )
- );
- waitForElementToRemove("div[role=main] aside");
- waitForElementToRemove("div._3Pnjry");
- utils.waitNodeList("div._gp-ck").then((nodeList) => {
- nodeList.forEach((item) => {
- item.style["width"] = "100%";
- });
- });
- return result;
- },
- /**
- * 去除剪贴板劫持
- */
- removeClipboardHijacking() {
- log.info("去除剪贴板劫持");
- const stopNativePropagation = (event) => {
- event.stopPropagation();
- };
- window.addEventListener("copy", stopNativePropagation, true);
- document.addEventListener("copy", stopNativePropagation, true);
- },
- /**
- * 自动展开全文
- */
- autoExpandFullText() {
- utils.waitNode(`div#homepage div[class*="dialog-"]`).then((element) => {
- element.style["visibility"] = "hidden";
- log.info("自动展开全文");
- utils.mutationObserver(element, {
- callback: (mutations) => {
- if (mutations.length == 0) {
- return;
- }
- mutations.forEach((mutationItem) => {
- var _a2;
- if (mutationItem.target.style["display"] != "none") {
- log.success("自动展开全文-自动点击");
- (_a2 = document.querySelector(
- 'div#homepage div[class*="dialog-"] .cancel'
- )) == null ? void 0 : _a2.click();
- }
- });
- },
- config: {
- /* 子节点的变动(新增、删除或者更改) */
- childList: false,
- /* 属性的变动 */
- attributes: true,
- /* 节点内容或节点文本的变动 */
- characterData: true,
- /* 是否将观察器应用于该节点的所有后代节点 */
- subtree: true
- }
- });
- });
- },
- /**
- * 去除简书拦截其它网址的url并自动跳转
- */
- jumpRedirect() {
- if (JianshuRouter.isGoWild()) {
- log.success("去除简书拦截其它网址的url并自动跳转");
- window.stop();
- let search = window.location.href.replace(
- window.location.origin + "/",
- ""
- );
- search = decodeURIComponent(search);
- let newURL = search.replace(/^go-wild\?ac=2&url=/gi, "").replace(/^https:\/\/link.zhihu.com\/\?target\=/gi, "");
- window.location.href = newURL;
- }
- },
- /**
- * 屏蔽相关文章
- */
- blockRelatedArticles() {
- log.info("屏蔽相关文章");
- return CommonUtil.addBlockCSS(
- 'div[role="main"] > div > section:nth-child(2)'
- );
- },
- /**
- * 【屏蔽】客户端弹窗
- */
- blockClientDialog() {
- log.info("【屏蔽】客户端弹窗");
- CommonUtil.addBlockCSS(
- 'div:has(>div[class*="-mask"]:not([class*="-mask-hidden"]) + div[tabindex="-1"][role="dialog"])'
- );
- utils.waitNode(
- `div[class*="-mask"]:not([class*="-mask-hidden"]) + div[tabindex="-1"][role="dialog"]`
- ).then((element) => {
- log.success("弹窗出现");
- utils.waitPropertyByInterval(
- element,
- () => {
- var _a2, _b, _c, _d;
- let react = utils.getReactObj(element);
- return (_d = (_c = (_b = (_a2 = react == null ? void 0 : react.reactInternalInstance) == null ? void 0 : _a2.return) == null ? void 0 : _b.return) == null ? void 0 : _c.memoizedProps) == null ? void 0 : _d.onClose;
- },
- 250,
- 1e4
- ).then(() => {
- let react = utils.getReactObj(element);
- react.reactInternalInstance.return.return.memoizedProps.onClose(
- new Event("click")
- );
- log.success("调用函数关闭弹窗");
- });
- });
- },
- /**
- * 屏蔽评论区
- */
- blockUserComments() {
- log.info("屏蔽评论区");
- return CommonUtil.addBlockCSS("div#note-page-comment");
- },
- /**
- * 屏蔽底部推荐阅读
- */
- blockRecommendedReading() {
- log.info("屏蔽底部推荐阅读");
- return CommonUtil.addBlockCSS(
- 'div[role="main"] > div > section:last-child'
- );
- },
- /**
- * 【屏蔽】顶部导航栏
- */
- blockTopNav() {
- log.info("【屏蔽】顶部导航栏");
- return CommonUtil.addBlockCSS("header");
- },
- /**
- * 【屏蔽】底部工具栏
- */
- blockBottomToolbar() {
- log.info("【屏蔽】底部工具栏");
- return CommonUtil.addBlockCSS("footer");
- }
- };
- const M_Jianshu = {
- init() {
- this.addCSS();
- PopsPanel.execMenu("JianShuAutoJumpRedirect_Mobile", () => {
- Jianshu.jumpRedirect();
- });
- PopsPanel.execMenu("JianShuHijackSchemeScriptLabel_Mobile", () => {
- this.handlePrototype();
- });
- PopsPanel.execMenu("JianShuRemoveClipboardHijacking_Mobile", () => {
- Jianshu.removeClipboardHijacking();
- });
- PopsPanel.execMenu("JianShuAutoExpandFullText_Mobile", () => {
- Jianshu.autoExpandFullText();
- });
- PopsPanel.execMenuOnce("JianShuremoveFooterRecommendRead", () => {
- return this.blockeFooterRecommendRead();
- });
- PopsPanel.execMenu("JianShuShieldUserCommentsMobile", () => {
- return this.blockUserComments();
- });
- },
- /**
- * 添加屏蔽CSS
- */
- addCSS() {
- Jianshu.addCSS();
- },
- /**
- * 手机-屏蔽底部推荐阅读
- */
- blockeFooterRecommendRead() {
- log.info("屏蔽底部推荐阅读");
- return CommonUtil.addBlockCSS("#recommended-notes");
- },
- /**
- * 处理原型
- */
- handlePrototype() {
- log.info("处理原型添加script标签");
- let originalAppendChild = Node.prototype.appendChild;
- _unsafeWindow.Node.prototype.appendChild = function(element) {
- let allowElementLocalNameList = ["img"];
- if (element.src && !element.src.includes("jianshu.io") && !allowElementLocalNameList.includes(element.localName)) {
- log.success(["禁止添加的元素", element]);
- return null;
- } else {
- return originalAppendChild.call(this, element);
- }
- };
- },
- /**
- * 屏蔽评论区
- */
- blockUserComments() {
- log.info("屏蔽评论区");
- return CommonUtil.addBlockCSS("#comment-main");
- }
- };
- PopsPanel.init();
- let isMobile = utils.isPhone();
- let CHANGE_ENV_SET_KEY = "change_env_set";
- let chooseMode = _GM_getValue(CHANGE_ENV_SET_KEY);
- GM_Menu.add({
- key: CHANGE_ENV_SET_KEY,
- text: `⚙ 自动: ${isMobile ? "移动端" : "PC端"}`,
- autoReload: false,
- isStoreValue: false,
- showText(text) {
- if (chooseMode == null) {
- return text;
- }
- return text + ` 手动: ${chooseMode == 1 ? "移动端" : chooseMode == 2 ? "PC端" : "未知"}`;
- },
- callback: () => {
- let allowValue = [0, 1, 2];
- let chooseText = window.prompt(
- "请输入当前脚本环境判定\n\n自动判断: 0\n移动端: 1\nPC端: 2",
- "0"
- );
- if (!chooseText) {
- return;
- }
- let chooseMode2 = parseInt(chooseText);
- if (isNaN(chooseMode2)) {
- Qmsg.error("输入的不是规范的数字");
- return;
- }
- if (!allowValue.includes(chooseMode2)) {
- Qmsg.error("输入的值必须是0或1或2");
- return;
- }
- if (chooseMode2 == 0) {
- _GM_deleteValue(CHANGE_ENV_SET_KEY);
- } else {
- _GM_setValue(CHANGE_ENV_SET_KEY, chooseMode2);
- }
- }
- });
- if (chooseMode != null) {
- log.info(`手动判定为${chooseMode === 1 ? "移动端" : "PC端"}`);
- if (chooseMode == 1) {
- M_Jianshu.init();
- } else if (chooseMode == 2) {
- Jianshu.init();
- } else {
- Qmsg.error("意外,手动判定的值不在范围内");
- _GM_deleteValue(CHANGE_ENV_SET_KEY);
- }
- } else {
- if (isMobile) {
- log.info("自动判定为移动端");
- M_Jianshu.init();
- } else {
- log.info("自动判定为PC端");
- Jianshu.init();
- }
- }
-
- })(Qmsg, DOMUtils, Utils, pops);