Greasy Fork镜像 支持简体中文。

Remove Restrictions and Restore Default Behavior

Allows you select, cut, copy, paste, save and open the DevTools on any website.

目前為 2024-05-05 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Remove Restrictions and Restore Default Behavior
  3. // @name:zh-CN 解除网页限制,恢复默认行为
  4. // @name:en-US Remove Restrictions and Restore Default Behavior
  5. // @namespace http://hl-bo.github.io/namespaces/user-script/remove-limits
  6. // @source https://github.com/HL-Bo/user-script
  7. // @supportURL https://github.com/HL-Bo/user-script/issues
  8. // @version 2.2
  9. // @license AGPLv3
  10. // @description Allows you select, cut, copy, paste, save and open the DevTools on any website.
  11. // @description:zh-CN 恢复选择、剪切、复制、粘贴、保存、右键菜单和打开开发者工具的默认行为。
  12. // @description:en-US Allows you select, cut, copy, paste, save and open the DevTools on any website.
  13. // @author HL-Bo
  14. // @match *://*/**
  15. // @exclude *://vscode.dev
  16. // @exclude *://vscode.dev/**
  17. // @exclude *://*.github.dev
  18. // @exclude *://*.github.dev/**
  19. // @exclude *://github.com/*/*/edit/**
  20. // @exclude *://gitee.com/*/*/edit/**
  21. // @exclude *://codeberg.org/*/*/_edit/**
  22. // @exclude *://www.figma.com/file/**
  23. // @exclude *://www.notion.so/**
  24. // @exclude *://outlook.live.com/**
  25. // @exclude *://mail.netease.com/**
  26. // @exclude *://mail.163.com/**
  27. // @exclude *://mail.126.com/**
  28. // @exclude *://www.yeah.net/**
  29. // @exclude *://mail.qq.com/**
  30. // @exclude *://uutool.cn/*
  31. // @exclude *://anytexteditor.com/*/online-notepad
  32. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAspJREFUWEfVl89PE1EQx7/TdpcabKFAoEKQH22ktEYSqRevXiRijEr8cSDe/DNM9D/xhPFn4oF4MeBZuJi0SiiQikTjD2gLCLS7jNmFLt2mu/uWYtB36G73zWQ+b2bevDeEijE5Od/Q3ut5CNA9gMOVc3bvG7+3MLeYRU9nhxqP9r2WURoPh8ObIvpUKTSbzkww6I6IYqWMAdAVxmCkF8z8zk/KFREIA2BmbilGu7tpZpigRGCqATQdAk3LKI46QRjGZtOZ6wx6KWKwWqYWgCbDzNN+UmwhDID3HxduEuP5UQKIQPx1gDJEnpTRoRqJaQnw/dcqVvPrANf2iST50N/dCSKCVQjMmjyVg3K1GsISILvyFT/X8pYRkXw+nD3TD4/HIwigp+ZUDkUThG0I9MVbeIAq9srW9g7SmSW0t4ZwPjHglEZvf3xZGkkmk6W93bI/qpNQUVVs7xRtPOBFgyzr88yM1PwidoolRE53oS3UbAuhMo8Mx/re2ALMZ5dRWLcuZlrsh2JReL1e3ZiWB5nsMlR118kDII/39v2xy09tAQobm8jrALVjIEsSOtpaTMZKioLVXAHaU/OK1fAAt65duvjMFsBxGXUIMGHswmDkhS2AtpK1wnodZg5UQ8EAWpqDxgchgIXPK8gdEUBzMKAnZ3kIAWgxLCmq9T4U9g1B8nn1gvV/ARx7CI49CYVDfAhBoSR0KkTidglNgUYETza6S0KtrO5VwvqHBhDt6XYH4HQYucHyN8jw7Z8Z+uElUgl1QePHjbkqWao4cvenhACcLiRukNpCTejpOuUuBE5XMmEAAlqaAmhvPTg5hTwgbOAQgv8mQD2NiVsnEPjGcDz6ynQfmPkwFyPJd6jWzA0AEZhLSjx5buCTCUD7M5temGDAdXPqCgB4MhyP3C3rmBrRVColb5H/kdv2XAyAvgH8+ARvP0gkEsZ1+w+ixcUwoQ+80AAAAABJRU5ErkJggg==
  33. // @grant none
  34. // @run-at document-start
  35. // ==/UserScript==
  36.  
  37. (function () {
  38. 'use strict';
  39. console.info('Start the installation of user-script/remove-limits');
  40.  
  41. // 尝试禁用 debugger
  42. // 仅在 eval('debugger') 或 setInterval('debugger', sec) 构造前执行才能阻止
  43. try {
  44. Function.prototype.__constructor_back = Function.prototype.constructor;
  45. Function.prototype.constructor = function () {
  46. if (arguments && typeof arguments[0] === 'string') {
  47. if ('debugger' === arguments[0]) {
  48. console.debug('Disable an function which may execute debugger');
  49. return;
  50. }
  51. }
  52. return Function.prototype.__constructor_back.apply(this, arguments);
  53. }
  54. } catch (error) { } finally { }
  55.  
  56. let executeWithInterval = function (func, delay) {
  57. setTimeout(func, 0); // 异步执行,防止阻塞
  58. setInterval(func, delay);
  59. };
  60. let setEventListener = function (element, event_name, listener) {
  61. if (element.rl_events) {
  62. if (element.rl_events.has(event_name)) {
  63. element.removeEventListener(event_name, element.rl_events.get(event_name));
  64. }
  65. } else {
  66. element.rl_events = new Map();
  67. }
  68. element.rl_events.set(event_name, listener);
  69. element.addEventListener(event_name, listener);
  70. };
  71. let returnEventAllowed = function (event, event_name) {
  72. try {
  73. event.returnValue = true;
  74. } catch (error) { } finally { }
  75. if (event_name !== null) {
  76. console.debug(`Allow ${event_name}`);
  77. }
  78. };
  79. let allowEvent = function (element, event_name) {
  80. setEventListener(element, event_name, function (event) { returnEventAllowed(event, event_name); return true; });
  81. };
  82. let onKeyEvents = function (event) {
  83. let keyCode = event.keyCode || event.which || event.charCode;
  84. let ctrlKey = event.ctrlKey || event.metaKey;
  85. let shiftKey = event.shiftKey;
  86. if (ctrlKey && (keyCode == 65 || keyCode == 88 || keyCode == 67 || keyCode == 86 || keyCode == 83 || keyCode == 85)) {
  87. // Ctrl+A (select-all), Ctrl+X (cut), Ctrl+C (copy), Ctrl+V (paste), Ctrl+S (save), Ctrl+U (view-source)
  88. returnEventAllowed(event, 'hotkey');
  89. } else if (ctrlKey && shiftKey && (keyCode == 73 || keyCode == 74 || keyCode == 67)) {
  90. // Ctrl+Shift+I (devtools), Ctrl+Shift+J (console), Ctrl+Shift+C (elements)
  91. returnEventAllowed(event, 'hotkey (DevTools)');
  92. } else if (keyCode && keyCode == 123) { // F12
  93. returnEventAllowed(event, 'hotkey (F12)');
  94. }
  95. return true;
  96. };
  97. let allowKeyEvents = function (element, event_name) {
  98. setEventListener(element, event_name, onKeyEvents);
  99. };
  100. let preventEventChecks = function (element) {
  101. Object.defineProperty(element, 'onbeforecopy', { get: () => (event) => false });
  102. Object.defineProperty(element, 'oncopy', { get: () => (event) => false });
  103. Object.defineProperty(element, 'onbeforecut', { get: () => (event) => false });
  104. Object.defineProperty(element, 'oncut', { get: () => (event) => false });
  105. Object.defineProperty(element, 'onbeforepaste', { get: () => (event) => false });
  106. Object.defineProperty(element, 'onpaste', { get: () => (event) => false });
  107. Object.defineProperty(element, 'onselectstart', { get: () => (event) => false });
  108. Object.defineProperty(element, 'oncontextmenu', { get: () => (event) => false });
  109. Object.defineProperty(element, 'ondragstart', { get: () => (event) => false });
  110. Object.defineProperty(element, 'ondragenter', { get: () => (event) => false });
  111. Object.defineProperty(element, 'ondragover', { get: () => (event) => false });
  112. Object.defineProperty(element, 'ondragleave', { get: () => (event) => false });
  113. Object.defineProperty(element, 'ondragend', { get: () => (event) => false });
  114. Object.defineProperty(element, 'ondrop', { get: () => (event) => false });
  115. Object.defineProperty(element, 'onkeypress', { get: () => (event) => false });
  116. Object.defineProperty(element, 'onkeydown', { get: () => (event) => false });
  117. Object.defineProperty(element, 'onkeyup', { get: () => (event) => false });
  118. Object.defineProperty(element, 'onvisibilitychange', { get: () => (event) => false });
  119. Object.defineProperty(element, 'onmousedown', { get: () => (event) => false });
  120. Object.defineProperty(element, 'onmouseup', { get: () => (event) => false });
  121. Object.defineProperty(element, 'onmousewheel', { get: () => (event) => false });
  122. Object.defineProperty(element, 'onwheel', { get: () => (event) => false });
  123. Object.defineProperty(element, 'onmouseenter', { get: () => (event) => false });
  124. Object.defineProperty(element, 'onmousemove', { get: () => (event) => false });
  125. Object.defineProperty(element, 'onmouseover', { get: () => (event) => false });
  126. Object.defineProperty(element, 'onmouseout', { get: () => (event) => false });
  127. Object.defineProperty(element, 'onmouseleave', { get: () => (event) => false });
  128. Object.defineProperty(element, 'ongotpointercapture', { get: () => (event) => false });
  129. Object.defineProperty(element, 'onlostpointercapture', { get: () => (event) => false });
  130. Object.defineProperty(element, 'onpointerdown', { get: () => (event) => false });
  131. Object.defineProperty(element, 'onpointerrawupdate', { get: () => (event) => false });
  132. Object.defineProperty(element, 'onpointerup', { get: () => (event) => false });
  133. Object.defineProperty(element, 'onpointerenter', { get: () => (event) => false });
  134. Object.defineProperty(element, 'onpointermove', { get: () => (event) => false });
  135. Object.defineProperty(element, 'onpointerover', { get: () => (event) => false });
  136. Object.defineProperty(element, 'onpointerout', { get: () => (event) => false });
  137. Object.defineProperty(element, 'onpointerleave', { get: () => (event) => false });
  138. Object.defineProperty(element, 'onpointercancel', { get: () => (event) => false });
  139. Object.defineProperty(element, 'onfocus', { get: () => (event) => false });
  140. Object.defineProperty(element, 'onfocusin', { get: () => (event) => false });
  141. Object.defineProperty(element, 'onfocusout', { get: () => (event) => false });
  142. Object.defineProperty(element, 'onblur', { get: () => (event) => false });
  143. };
  144. let allowElement = function (element) {
  145. // 取消通过 JavaScript 实现的禁止复制
  146. try { element.onbeforecopy = null; } catch (error) { } finally { allowEvent(element, 'beforecopy'); }
  147. try { element.oncopy = null; } catch (error) { } finally { allowEvent(element, 'copy'); }
  148. // 取消通过 JavaScript 实现的禁止剪切实现的禁止复制
  149. try { element.onbeforecut = null; } catch (error) { } finally { allowEvent(element, 'beforecut'); }
  150. try { element.oncut = null; } catch (error) { } finally { allowEvent(element, 'cut'); }
  151. // 取消通过 JavaScript 实现的禁止粘贴
  152. try { element.onbeforepaste = null; } catch (error) { } finally { allowEvent(element, 'beforepaste'); }
  153. try { element.onpaste = null; } catch (error) { } finally { allowEvent(element, 'paste'); }
  154. // 取消通过 JavaScript 实现的禁止文字选择
  155. try { element.onselectstart = null; } catch (error) { } finally { allowEvent(element, 'selectstart'); }
  156. // 取消通过 JavaScript 实现的禁止右键菜单
  157. try { element.oncontextmenu = null; } catch (error) { } finally { allowEvent(element, 'contextmenu'); }
  158. // 取消通过 JavaScript 实现的禁止拖动
  159. try { element.ondragstart = null; } catch (error) { } finally { allowEvent(element, 'dragstart'); }
  160. try { element.ondragenter = null; } catch (error) { } finally { allowEvent(element, 'dragenter'); }
  161. try { element.ondragover = null; } catch (error) { } finally { allowEvent(element, 'dragover'); }
  162. try { element.ondragleave = null; } catch (error) { } finally { allowEvent(element, 'dragleave'); }
  163. try { element.ondragend = null; } catch (error) { } finally { allowEvent(element, 'dragend'); }
  164. // try { element.ondrop = null; } catch (error) { } finally { allowEvent(element, 'drop'); }
  165. // 取消通过 CSS 实现的禁止选中
  166. try { element.style.mozUserSelect = 'auto'; } catch (error) { } finally { }
  167. try { element.style.webkitUserSelect = 'auto'; } catch (error) { } finally { }
  168. try { element.style.msUserSelect = 'auto'; } catch (error) { } finally { }
  169. try { element.style.userSelect = 'auto'; } catch (error) { } finally { }
  170. // 取消通过 JavaScript 实现的禁用快捷键
  171. try { element.onkeypress = null; } catch (error) { } finally { allowKeyEvents(element, 'keypress'); }
  172. try { element.onkeydown = null; } catch (error) { } finally { allowKeyEvents(element, 'keydown'); }
  173. try { element.onkeyup = null; } catch (error) { } finally { allowKeyEvents(element, 'keyup'); }
  174. // 取消通过 JavaScript 实现的页面离开检测
  175. try { element.onvisibilitychange = null; } catch (error) { } finally { allowEvent(element, 'visibilitychange'); }
  176. // 取消通过 JavaScript 实现的鼠标离开检测
  177. // try { element.onmousedown = null; } catch (error) { } finally { allowEvent(element, 'mousedown'); }
  178. // try { element.onmouseup = null; } catch (error) { } finally { allowEvent(element, 'mouseup'); }
  179. // try { element.onmousewheel = null; } catch (error) { } finally { allowEvent(element, 'mousewheel'); }
  180. // try { element.onwheel = null; } catch (error) { } finally { allowEvent(element, 'wheel'); }
  181. // try { element.onmouseenter = null; } catch (error) { } finally { allowEvent(element, 'mouseenter'); }
  182. // try { element.onmousemove = null; } catch (error) { } finally { allowEvent(element, 'mousemove'); }
  183. // try { element.onmouseover = null; } catch (error) { } finally { allowEvent(element, 'mouseover'); }
  184. try { element.onmouseout = null; } catch (error) { } finally { allowEvent(element, 'mouseout'); }
  185. try { element.onmouseleave = null; } catch (error) { } finally { allowEvent(element, 'mouseleave'); }
  186. // 取消通过 JavaScript 实现的指针离开检测
  187. // try { element.ongotpointercapture = null; } catch (error) { } finally { allowEvent(element, 'gotpointercapture'); }
  188. try { element.onlostpointercapture = null; } catch (error) { } finally { allowEvent(element, 'lostpointercapture'); }
  189. // try { element.onpointerdown = null; } catch (error) { } finally { allowEvent(element, 'pointerdown'); }
  190. // try { element.onpointerrawupdate = null; } catch (error) { } finally { allowEvent(element, 'pointerrawupdate'); }
  191. try { element.onpointerup = null; } catch (error) { } finally { allowEvent(element, 'pointerup'); }
  192. // try { element.onpointerenter = null; } catch (error) { } finally { allowEvent(element, 'pointerenter'); }
  193. // try { element.onpointermove = null; } catch (error) { } finally { allowEvent(element, 'pointermove'); }
  194. // try { element.onpointerover = null; } catch (error) { } finally { allowEvent(element, 'pointerover'); }
  195. try { element.onpointerout = null; } catch (error) { } finally { allowEvent(element, 'pointerout'); }
  196. try { element.onpointerleave = null; } catch (error) { } finally { allowEvent(element, 'pointerleave'); }
  197. try { element.onpointercancel = null; } catch (error) { } finally { allowEvent(element, 'pointercancel'); }
  198. // 取消通过 JavaScript 实现的焦点离开检测
  199. try { element.onfocus = null; } catch (error) { } finally { allowEvent(element, 'focus'); }
  200. try { element.onfocusin = null; } catch (error) { } finally { allowEvent(element, 'focusin'); }
  201. try { element.onfocusout = null; } catch (error) { } finally { allowEvent(element, 'focusout'); }
  202. try { element.onblur = null; } catch (error) { } finally { allowEvent(element, 'blur'); }
  203. // 防止 JavaScript 事件检测
  204. preventEventChecks(element);
  205. };
  206. let allowElementRecursion = function (element) {
  207. allowElement(element);
  208. for (let i = 0; i < element.children.length; i++) {
  209. allowElementRecursion(element.children.item(i));
  210. }
  211. };
  212. // let removeAllListeners = function (old_element) {
  213. // let new_element = old_element.cloneNode(true);
  214. // old_element.parentNode.replaceChild(new_element, old_element);
  215. // };
  216. let removeHiddenElements = function (element, recursion) {
  217. if ((element.hidden || element.style.display == 'none' || element.style.visibility == 'hidden' || ((element.style.height <= 0 || element.style.width <= 0) && element.style.overflow == 'hidden') && element.children.length == 0)) {
  218. console.info(`Remove <${element.tagName} id='${element.id}' class='${element.className}' />`);
  219. element.remove();
  220. } else if (recursion) {
  221. for (let i = 0; i < element.children.length; i++) {
  222. removeHiddenElements(element.children.item(i), recursion);
  223. }
  224. }
  225. };
  226. let getMainContainerElement = function () {
  227. // 获取正文节点
  228. let main_container_element = null;
  229. if (document) {
  230. if (main_container_element === null) { // 检查 main 标签
  231. let elements = document.getElementsByTagName('main');
  232. if (elements.length > 0) { main_container_element = elements[0]; }
  233. }
  234. if (main_container_element === null) { // 检查 id='main' 的标签
  235. main_container_element = document.getElementById('main');
  236. }
  237. if (main_container_element === null) { // 检查 id='main-content' 的标签
  238. main_container_element = document.getElementById('main-content');
  239. }
  240. if (main_container_element === null) { // 检查 id='main-contents' 的标签
  241. main_container_element = document.getElementById('main-content');
  242. }
  243. if (main_container_element === null) { // 检查 id='content' 的标签
  244. main_container_element = document.getElementById('content');
  245. }
  246. if (main_container_element === null) { // 检查 id='contents' 的标签
  247. main_container_element = document.getElementById('contents');
  248. }
  249. if (main_container_element === null) { // 检查 class='main' 的标签
  250. let elements = document.getElementsByClassName('main');
  251. if (elements.length > 0) { main_container_element = elements[0]; }
  252. }
  253. if (main_container_element === null) { // 检查 class='main-content' 的标签
  254. let elements = document.getElementsByClassName('content');
  255. if (elements.length > 0) { main_container_element = elements[0]; }
  256. }
  257. if (main_container_element === null) { // 检查 class='main-contents' 的标签
  258. let elements = document.getElementsByClassName('content');
  259. if (elements.length > 0) { main_container_element = elements[0]; }
  260. }
  261. if (main_container_element === null) { // 检查 class='content' 的标签
  262. let elements = document.getElementsByClassName('content');
  263. if (elements.length > 0) { main_container_element = elements[0]; }
  264. }
  265. if (main_container_element === null) { // 检查 class='contents' 的标签
  266. let elements = document.getElementsByClassName('contents');
  267. if (elements.length > 0) { main_container_element = elements[0]; }
  268. }
  269. }
  270. return main_container_element;
  271. };
  272.  
  273. // 对抗延迟运行(即在此脚本执行后运行)的禁用程序和循环执行的禁用程序,
  274. executeWithInterval( // 每 0.2 秒执行一次。
  275. (function () {
  276. if (document) {
  277. try { allowElement(document); } catch (error) { } finally { }
  278. }
  279. }), 200
  280. );
  281. executeWithInterval( // 每 0.3 秒执行一次。
  282. (function () {
  283. if (document) {
  284. try { allowElement(document.body); } catch (error) { } finally { }
  285. }
  286. }), 300
  287. );
  288. executeWithInterval( // 每 2 秒执行一次。
  289. (function () {
  290. let mce = getMainContainerElement()
  291. if (document && mce) {
  292. try { allowElementRecursion(mce); } catch (error) { } finally { }
  293. }
  294. }), 2000
  295. );
  296.  
  297. // 对抗延迟运行(即在此脚本执行后运行)的混淆程序和循环执行的混淆程序,
  298. setTimeout(
  299. // 延迟 1 秒,有助于动态加载的内容的显示。
  300. function () {
  301. console.debug('Start scanning for hidden elements');
  302. executeWithInterval(
  303. // 每 2 秒执行一次。
  304. function () {
  305. if (document) {
  306. // 移除正文中的不可见元素
  307. try {
  308. let mce = getMainContainerElement()
  309. // 移除不可见元素
  310. if (mce) {
  311. removeHiddenElements(mce, true);
  312. }
  313. } catch (error) { } finally { }
  314. }
  315. }, 2000
  316. );
  317. }, 1000
  318. )
  319.  
  320. console.debug('Complete the installation of user-script/remove-limits');
  321. })();

QingJ © 2025

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