网页限制解除

通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。

目前为 2016-02-02 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @namespace https://www.github.com/Cat7373/
  3.  
  4. // @name 网页限制解除
  5. // @name:en Remove web limits
  6. // @name:zh 网页限制解除
  7. // @name:zh-CN 网页限制解除
  8. // @name:zh-TW 網頁限制解除
  9. // @name:ja ウェブの規制緩和
  10.  
  11. // @description 通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。
  12. // @description:en Pass to kill most of the site, you can lift the restrictions prohibited to copy, cut, select the text, right-click menu.
  13. // @description:zh 通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。
  14. // @description:zh-CN 通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。
  15. // @description:zh-TW 通殺大部分網站,可以解除禁止復制、剪切、選擇文本、右鍵菜單的限制。
  16. // @description:ja サイトのほとんどを殺すために渡し、あなたは、コピー切り取り、テキスト、右クリックメニューを選択することは禁止の制限を解除することができます。
  17.  
  18. // @homepageURL https://cat7373.github.io/remove-web-limits/
  19. // @supportURL https://github.com/Cat7373/remove-web-limits/issues/
  20.  
  21. // @author Cat73
  22. // @version 1.3
  23. // @license LGPLv3
  24.  
  25. // @compatible chrome Chrome_46.0.2490.86 + TamperMonkey + 脚本_1.3 测试通过
  26. // @compatible firefox Firefox_42.0 + GreaseMonkey + 脚本_1.2.1 测试通过
  27. // @compatible opera Opera_33.0.1990.115 + TamperMonkey + 脚本_1.1.3 测试通过
  28. // @compatible safari 未测试
  29.  
  30. // @match *://*/*
  31. // @grant none
  32. // @run-at document-start
  33. // ==/UserScript==
  34. 'use strict';
  35.  
  36. // 域名规则列表
  37. var rules = {
  38. black_rule: {
  39. name: "black",
  40. hook_eventNames: "",
  41. unhook_eventNames: ""
  42. },
  43. default_rule: {
  44. name: "default",
  45. hook_eventNames: "contextmenu|select|selectstart|copy|cut|dragstart",
  46. unhook_eventNames: "mousedown|mouseup|keydown|keyup",
  47. dom0: true,
  48. hook_addEventListener: true,
  49. hook_preventDefault: true,
  50. hook_set_returnValue: true,
  51. add_css: true
  52. }
  53. };
  54. // 域名列表
  55. var lists = {
  56. // 黑名单
  57. black_list: [
  58. /.*\.youtube\.com.*/,
  59. /.*\.wikipedia\.org.*/,
  60. /mail\.qq\.com.*/,
  61. /translate\.google\..*/
  62. ]
  63. };
  64.  
  65. // 要处理的 event 列表
  66. var hook_eventNames, unhook_eventNames, eventNames;
  67. // 储存名称
  68. var storageName = getRandStr('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM', parseInt(Math.random() * 12 + 8));
  69. // 储存被 Hook 的函数
  70. var EventTarget_addEventListener = EventTarget.prototype.addEventListener;
  71. var document_addEventListener = document.addEventListener;
  72. var Event_preventDefault = Event.prototype.preventDefault;
  73.  
  74. // Hook addEventListener proc
  75. function addEventListener(type, func, useCapture) {
  76. var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener;
  77. if(hook_eventNames.indexOf(type) >= 0) {
  78. _addEventListener.apply(this, [type, returnTrue, useCapture]);
  79. } else if(unhook_eventNames.indexOf(type) >= 0) {
  80. var funcsName = storageName + type + (useCapture ? 't' : 'f');
  81.  
  82. if(this[funcsName] === undefined) {
  83. this[funcsName] = [];
  84. _addEventListener.apply(this, [type, useCapture ? unhook_t : unhook_f, useCapture]);
  85. }
  86.  
  87. this[funcsName].push(func)
  88. } else {
  89. _addEventListener.apply(this, arguments);
  90. }
  91. }
  92.  
  93. // 清理循环
  94. function clearLoop() {
  95. var elements = getElements();
  96.  
  97. for(var i in elements) {
  98. for(var j in eventNames) {
  99. var name = 'on' + eventNames[j];
  100. if(elements[i][name] != null && elements[i][name] != onxxx) {
  101. if(unhook_eventNames.indexOf(eventNames[j]) >= 0) {
  102. elements[i][storageName + name] = elements[i][name];
  103. elements[i][name] = onxxx;
  104. } else {
  105. elements[i][name] = null;
  106. }
  107. }
  108. }
  109. }
  110. }
  111.  
  112. // 返回true的函数
  113. function returnTrue(e) {
  114. return true;
  115. }
  116. function unhook_t(e) {
  117. return unhook(e, this, storageName + e.type + 't');
  118. }
  119. function unhook_f(e) {
  120. return unhook(e, this, storageName + e.type + 'f');
  121. }
  122. function unhook(e, self, funcsName) {
  123. var list = self[funcsName];
  124. for(var i in list) {
  125. list[i](e);
  126. }
  127.  
  128. e.returnValue = true;
  129. return true;
  130. }
  131. function onxxx(e) {
  132. var name = storageName + 'on' + e.type;
  133. this[name](e);
  134.  
  135. e.returnValue = true;
  136. return true;
  137. }
  138.  
  139. // 获取随机字符串
  140. function getRandStr(chs, len) {
  141. var str = '';
  142.  
  143. while(len--) {
  144. str += chs[parseInt(Math.random() * chs.length)];
  145. }
  146.  
  147. return str;
  148. }
  149.  
  150. // 获取所有元素 包括document
  151. function getElements() {
  152. var elements = Array.prototype.slice.call(document.getElementsByTagName('*'));
  153. elements.push(document);
  154.  
  155. return elements;
  156. }
  157.  
  158. // 添加css
  159. function addStyle(css) {
  160. var style = document.createElement('style');
  161. style.innerHTML = css;
  162. document.head.appendChild(style);
  163. }
  164.  
  165. // 获取目标域名应该使用的规则
  166. function getRule(url) {
  167. function testUrl(list, url) {
  168. for(var i in list) {
  169. if(list[i].test(url)) {
  170. return true;
  171. }
  172. }
  173.  
  174. return false;
  175. }
  176.  
  177. if(testUrl(lists.black_list, url)) {
  178. return rules.black_rule;
  179. }
  180.  
  181. return rules.default_rule;
  182. }
  183.  
  184. // 初始化
  185. function init() {
  186. // 获取当前域名的规则
  187. var url = window.location.host + window.location.pathname;
  188. var rule = getRule(url);
  189.  
  190. // 设置 event 列表
  191. hook_eventNames = rule.hook_eventNames.split("|");
  192. // TODO Allowed to return value
  193. unhook_eventNames = rule.unhook_eventNames.split("|");
  194. eventNames = hook_eventNames.concat(unhook_eventNames);
  195.  
  196. // 调用清理 DOM0 event 方法的循环
  197. if(rule.dom0) {
  198. setInterval(clearLoop, 30 * 1000);
  199. setTimeout(clearLoop, 2500);
  200. window.addEventListener('load', clearLoop, true);
  201. clearLoop();
  202. }
  203.  
  204. // hook addEventListener
  205. if(rule.hook_addEventListener) {
  206. EventTarget.prototype.addEventListener = addEventListener;
  207. document.addEventListener = addEventListener;
  208. }
  209.  
  210. // hook preventDefault
  211. if(rule.hook_preventDefault) {
  212. Event.prototype.preventDefault = function() {
  213. if(eventNames.indexOf(this.type) < 0) {
  214. Event_preventDefault.apply(this, arguments);
  215. }
  216. };
  217. }
  218.  
  219. // Hook set returnValue
  220. if(rule.hook_set_returnValue) {
  221. Event.prototype.__defineSetter__('returnValue', function() {
  222. if(this.returnValue != true && eventNames.indexOf(this.type) >= 0) {
  223. this.returnValue = true;
  224. }
  225. });
  226. }
  227.  
  228. console.debug('url: ' + url, 'storageName:' + storageName, 'rule: ' + rule.name);
  229.  
  230. // 添加CSS
  231. if(rule.add_css) {
  232. addStyle('html, * {-webkit-user-select:text!important; -moz-user-select:text!important;}');
  233. }
  234. }
  235.  
  236. init();

QingJ © 2025

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