Unlimit-Web

解除网页限制: 恢复文本的选中和复制, 过滤文本小尾巴, 恢复右键菜单. Remove webpage restrictions: restore the selection and copy of text, clear the text tail, and restore the right-click menu.

当前为 2025-02-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Unlimit-Web
  3. // @description 解除网页限制: 恢复文本的选中和复制, 过滤文本小尾巴, 恢复右键菜单. Remove webpage restrictions: restore the selection and copy of text, clear the text tail, and restore the right-click menu.
  4. // @version 12.0
  5. // @author xcanwin
  6. // @namespace https://github.com/xcanwin/Unlimit-Web/
  7. // @supportURL https://github.com/xcanwin/Unlimit-Web/
  8. // @icon data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" stroke-width="2" fill="none" stroke="currentColor"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
  9. // @license GPL-2.0-only
  10. // @match *://www.zhihu.com/*
  11. // @match *://blog.csdn.net/*
  12. // @match *://www.bilibili.com/*
  13. // @match *://www.360doc.com/*
  14. // @match *://guofeng.yuedu.163.com/*
  15. // @match *://www.kuwo.cn/*
  16. // @match *://chuangshi.qq.com/*
  17. // @match *://read.qidian.com/*
  18. // @match *://dafrok.github.io/*
  19. // @match *://shushan.zhangyue.net/*
  20. // @match *://aqistudy.cn/*
  21. // @match *://www.xuexila.com/*
  22. // @match *://www.51test.net/*
  23. // @match *://www.laokaoya.com/*
  24. // @match *://utaten.com/*
  25. // @match *://book.qq.com/*
  26. // @match *://doc.mbalib.com/*
  27. // @match *://www.oh100.com/*
  28. // @match *://51test.net/*
  29. // @match *://www.cspengbo.com/*
  30. // @match *://www.diyifanwen.com/*
  31. // @match *://www.ahsrst.cn/*
  32. // @match *://kt250.com/*
  33. // @match *://*/*
  34. // @grant GM_getValue
  35. // @grant GM_setValue
  36. // @grant GM_registerMenuCommand
  37. // @grant GM_unregisterMenuCommand
  38. // @run-at document-end
  39. // ==/UserScript==
  40.  
  41. (function() {
  42. 'use strict';
  43.  
  44. const $ = (Selector, el) => (el || document).querySelector(Selector);
  45. const $$ = (Selector, el) => (el || document).querySelectorAll(Selector);
  46.  
  47. const muob = (Selector, el, func) => {
  48. const observer = new MutationObserver((mutationsList, observer2) => {
  49. for (let mutation of mutationsList) {
  50. if (mutation.type === 'childList') {
  51. const target = mutation.target.querySelector(Selector);
  52. if (target && !target.hasAttribute('data-duplicate')) {
  53. target.setAttribute('data-duplicate', 'true');
  54. func(target);
  55. }
  56. }
  57. }
  58. });
  59. observer.observe(el, {
  60. childList: true,
  61. subtree: true
  62. });
  63. };
  64.  
  65. const symbol = ["❎", "✅"];
  66. const symbol2 = ["未勾选", "已勾选"];
  67. let mc = [];
  68.  
  69. const sv = (key, value = "") => {
  70. GM_setValue(key, value);
  71. };
  72.  
  73. const gv = (key, value = "") => {
  74. return GM_getValue(key, value);
  75. };
  76.  
  77. /*枚举元素*/
  78. const eNum = (EL = null) => {
  79. $$("*", EL).forEach(unLimit);
  80. try {
  81. console.clear = () => {};
  82. window.debugger = () => {};
  83. } catch (e) {
  84. }
  85. };
  86.  
  87. /*解除限制*/
  88. const unLimit = (el = null) => {
  89. [
  90. "user-select", "-webkit-user-select", "-moz-user-select", "-ms-user-select", "-khtml-user-select", "pointer-events",
  91. ].forEach(xcanwin => {
  92. const ec = el.childNodes;
  93. const j1 = ec && ec.length == 1 && ec[0] && ec[0].nodeType && ec[0].nodeType == 3;
  94. const style = document.defaultView.getComputedStyle(el, null)[xcanwin];
  95. const j2 = style && style != 'auto';
  96. if (j1 || j2){
  97. // 处理第一个子标签是text类型的标签 或者 处理select值被修改过的标签
  98. el.style.setProperty(xcanwin, "unset", "important");
  99. }
  100. });
  101.  
  102. [
  103. "onselect", "onselectstart", "onselectionchange",
  104. "oncopy", "onbeforecopy",
  105. "onpaste", "onbeforepaste", "oncut", "onbeforecut",
  106. "onpointercancel", "onpointerdown", "onpointerenter", "onpointerleave", "onpointerlockchange", "onpointerlockerror", "onpointermove", "onpointerout", "onpointerover", "onpointerrawupdate", "onpointerup",
  107. ].forEach(xcanwin => {
  108. el[xcanwin] = e => {
  109. // 处理能影响文本的事件
  110. e.stopImmediatePropagation();
  111. }
  112. });
  113.  
  114. [
  115. "onmouseenter", "onmousedown", "onmouseup", "onmouseout", "onmouseleave", "onmouseover",
  116. ].forEach(xcanwin => {
  117. el[xcanwin] = e => {
  118. if ([ "P" ].indexOf(e.target.nodeName) >=0 && e.button == 0) {
  119. // 处理单击左键和滑动左键下的html文本标签
  120. e.stopImmediatePropagation();
  121. }
  122. }
  123. });
  124.  
  125. [
  126. "onkeypress", "onkeyup", "onkeydown",
  127. ].forEach(xcanwin => {
  128. el[xcanwin] = e => {
  129. const keyCode = e.keyCode || e.which || e.charCode;
  130. const ctrlKey = e.ctrlKey || e.metaKey;
  131. if ((ctrlKey && keyCode == 67) || keyCode == 123) {
  132. // 处理ctrl+c和F12
  133. e.stopImmediatePropagation();
  134. }
  135. }
  136. });
  137.  
  138. [
  139. "oncontextmenu",
  140. ].forEach(xcanwin => {
  141. el[xcanwin] = e => {
  142. if (e.target && e.target.points == undefined){
  143. // 处理普通的单击右键,跳过滑动右键
  144. e.stopImmediatePropagation();
  145. }
  146. }
  147. });
  148. };
  149.  
  150. /*加入自动破解列表*/
  151. const switchAuto = (domain) => {
  152. let autolist = JSON.parse(gv("ul_autolist", "[]"));
  153. domain = domain ? domain : getdomain();
  154. if (autolist.includes(domain)) {
  155. autolist = autolist.filter(el => el !== domain);
  156. } else {
  157. autolist.push(domain);
  158. }
  159. sv("ul_autolist", JSON.stringify(autolist));
  160. rmc();
  161. unLimit();
  162. };
  163.  
  164. /*查看自动破解列表*/
  165. const showAuto = () => {
  166. prompt("自动破解列表", gv("ul_autolist", "[]"));
  167. };
  168.  
  169. /*初始化自动破解列表*/
  170. const initAutoList = () => {
  171. const defaultal = ["www.zhihu.com", "blog.csdn.net","www.bilibili.com","www.360doc.com","guofeng.yuedu.163.com","www.kuwo.cn","chuangshi.qq.com","read.qidian.com","dafrok.github.io","shushan.zhangyue.net","aqistudy.cn","www.xuexila.com","www.51test.net","www.laokaoya.com","utaten.com","book.qq.com","doc.mbalib.com","www.oh100.com","51test.net","www.cspengbo.com","www.diyifanwen.com","www.ahsrst.cn","kt250.com"];
  172. //为空或者为[]时,说明首次运行,进行初始化
  173. if (gv("ul_autolist", "[]") === "[]") {
  174. sv("ul_autolist", JSON.stringify(defaultal));
  175. }
  176. //解析移除时,进行初始化
  177. try {
  178. JSON.parse(gv("ul_autolist", "[]"));
  179. } catch (e) {
  180. sv("ul_autolist", JSON.stringify(defaultal));
  181. }
  182. };
  183.  
  184. /*取消注册菜单*/
  185. const unrmc = () => {
  186. mc.forEach(x => GM_unregisterMenuCommand(x));
  187. };
  188.  
  189. /*注册菜单*/
  190. const rmc = () => {
  191. unrmc();
  192. let isauto;
  193. const autolist = JSON.parse(gv("ul_autolist", "[]"));
  194. const domain = getdomain();
  195. if (autolist.includes(domain)) {
  196. isauto = 1;
  197. } else {
  198. isauto = 0;
  199. }
  200. mc.push(GM_registerMenuCommand(`查看自动破解列表`, showAuto));
  201. mc.push(GM_registerMenuCommand(`临时破解:${domain}`, unLimit));
  202. mc.push(GM_registerMenuCommand(`自动破解:${domain} ${symbol[isauto]}${symbol2[isauto]}`, () => switchAuto(domain)));
  203. };
  204.  
  205. const getdomain = () => {
  206. return (new URL(location.href)).hostname;
  207. };
  208.  
  209. const main = () => {
  210. initAutoList();
  211. rmc();
  212. const autolist = JSON.parse(gv("ul_autolist", "[]"));
  213. const domain = getdomain();
  214. if (autolist.includes(domain)) {
  215. eNum();
  216. setInterval(eNum, 3000);
  217. muob(`*`, $(`body`), (el) => {
  218. unLimit(el);
  219. });
  220. }
  221. };
  222.  
  223. main();
  224.  
  225. })();