解除网页限制,网站列表请看代码,也可以添加自定义网站

解除各种网页限制,网站列表请看代码,也可以添加自定义网站

安装此脚本?
作者推荐脚本

您可能也喜欢区分阿里巴巴广告

安装此脚本
  1. // ==UserScript==
  2. // @namespace ATGT
  3. // @name remove page limit
  4. // @name:zh-CN 解除网页限制,网站列表请看代码,也可以添加自定义网站
  5. // @description Remove various page limit, check the code for website list, or add other websites
  6. // quora.com: Remove login page
  7. // other domains: Remove copy or select limit
  8. // How to remove other web page's copy or select limit:
  9. // 1. Add domain to @match *://*.your.domain/*
  10. // 2. (Optional): Add your unlock handlers to variable `unlockPageHandlers' below
  11. // @description:zh-CN 解除各种网页限制,网站列表请看代码,也可以添加自定义网站
  12. // quora.com: 移除登录页面
  13. // 其它网站:解除选择和复制限制
  14. // 怎么移除其它网页的限制:
  15. // 1. 将域名加到 @match,格式如下:
  16. // // @match *://*.your.domain/*
  17. // 2. (可选):将解除限制的方法加到 `unlockPageHandlers' 这个数组
  18. //
  19. // @version 1.4.8
  20. // @match *://*.quora.com/*
  21. // @match *://*.360doc.com/*
  22. // @match *://*.baidu.com/*
  23. // @match *://*.sdifen.com/*
  24. // @match *://*.popbee.com/*
  25. // @match *://*.baikemy.com/*
  26. // @exclude *://pan.baidu.com/*
  27. // @exclude *://ditu.baidu.com/*
  28. // @exclude *://map.baidu.com/*
  29. // @exclude *://maps.baidu.com/*
  30. // @run-at document-start
  31. // ==/UserScript==
  32.  
  33. /*
  34. ChangeLog:
  35. v1.4.8:
  36. 5 Mar 2020, Delay before enable copy handler
  37. v1.4.7:
  38. 9 Nov 2019, Enable user select by css rules on '*' selector,
  39. Match baikemy.com
  40. v1.4.6:
  41. 16 Oct 2019, remove dead site, merge baidu handlers
  42. v1.4.5:
  43. 15 Oct 2019, skip hijack baidu login verify page
  44. v1.4.4:
  45. 18 Aug 2019, exclucde baidu map
  46. v1.4.3:
  47. 30 Jun 2019, Try remove all limit by default, may not work for all sites.
  48. v1.4:
  49. 27 Nov 2018, Add wenku.baidu.com
  50. v1.3:
  51. 29 Jan 2018, Added generic functions:
  52. 1. Intercept event handlers.
  53. 2. Wait for some node and do the unlock
  54. v1.1:
  55. someday, Enable user select.
  56. v1:
  57. someday, Remove quora login page.
  58.  
  59. */
  60.  
  61. console.log(`=== unlock-page ${location.href} ===`);
  62. (function () {
  63. var unlockPageHandlers = [
  64. /* !!! Need to add the global match to @include also */
  65. /* Formats:
  66. * [ /domain name regex/, [ selector-string or node-object, event-type, event-handler, delay-ms-before-run-event-handle, event-handler-parameter ] ]
  67. * -- or --
  68. * [ /domain name regex/, [ selector-string or node-object, event-type, event-handler, observed-object-to-be-added-dynamicly-before-run-event-handle, event-handler-parameter ] ]
  69. * -- or multiple handlers for the domain, syntax similar to previous ones --
  70. * [ /domain name regex/, [
  71. * [ selector-string or node-object, event-type, event-handler, delay or observed-object before run event handler, event-handler-parameter ],
  72. * [ selector-string or node-object, event-type, event-handler, delay or observed-object before run event handler, event-handler-parameter ], ]
  73. * ]
  74. * Notes:
  75. * 1. empty selector-string/node-object and event-type means run immediately/after-some-delay at document-start
  76. * 2. some event does not need a node to run on, e.g. DOMContentLoaded
  77. * 3. DOMContentLoaded is trigger before window's load event, since window's load event will trigger after external script/resource are loaded.
  78. */
  79. [
  80. /quora\.com/,
  81. [ /* not needed for event DOMContentLoaded */, 'DOMContentLoaded', quoraHandler, 0]
  82. ],
  83. [
  84. /360doc\.com/,
  85. [window, 'load', enableCopyHandler, 0]
  86. ],
  87. [
  88. /popbee\.com/,
  89. [window, 'load', enableCopyHandler, 0]
  90. ],
  91. [
  92. /wenku\.baidu\.com/,
  93. [
  94. [, , interceptJackEvent, 0], /* no selector/node and no event means run immediately at document-start */
  95. [window, 'load', enableCopyHandler, 0, '.bd.doc-reader'],
  96. ]
  97. ],
  98. [
  99. /^https?:\/\/([^/?&#%]*\.)?baidu\.com/, // <=> http*://*.baidu.com
  100. [
  101. [, , interceptJackEvent, 0, '.vcode-body'],
  102. [, 'DOMContentLoaded', enableUserSelect, 0, 'body'],
  103. [window, 'load', enableCopyHandler, 0],
  104. ]
  105. ],
  106. [
  107. /sdifen\.com/,
  108. [
  109. [, , interceptJackEvent, 0],
  110. [, 'DOMContentLoaded', enableUserSelect, 0, 'body'],
  111. [window, 'load', enableCopyHandler, 0],
  112. ]
  113. ],
  114. [
  115. /.*/,
  116. [
  117. [, , interceptJackEvent, 0],
  118. [, 'DOMContentLoaded', enableUserSelect, 0, 'body'],
  119. [window, 'load', enableCopyHandler, 1000],
  120. ]
  121. ],
  122. ];
  123.  
  124.  
  125. function quoraHandler() {
  126. console.log(new Date().toLocaleString(), ' ', arguments.callee.name);
  127. for (var d of document.body.childNodes) {
  128. if (/signup_wall_wrapper$/.test(d.id)) {
  129. d.remove();
  130. break;
  131. }
  132. }
  133. document.body.style.overflow = 'visible';
  134. }
  135. function replaceAddEventListener() {
  136. console.log('replaceAddEventListener');
  137. var r0_EventTargetRegFunc = EventTarget.prototype.addEventListener;
  138. //var r1_documentRegFunc = document.addEventListener;
  139. function dummyEvtRegFunc(type, listener, options) {
  140. //console.log('dummyEvtRegFunc', this, type, listener, options);
  141. var regFunc = r0_EventTargetRegFunc;
  142. if (window.ATGT_noHijackNodes) {
  143. let nhjk = document.querySelectorAll(window.ATGT_noHijackNodes);
  144. for (let n of nhjk) {
  145. if (n.contains(this)) {
  146. console.log('dummyEvtRegFunc skip hijack', this);
  147. regFunc.call(this, type, listener, options);
  148. return;
  149. }
  150. }
  151. }
  152. if (!this.ATGT_disabledEventHandlers)
  153. this.ATGT_disabledEventHandlers = {};
  154. if (!this.ATGT_enabledEventHandlers)
  155. this.ATGT_enabledEventHandlers = {};
  156. //console.log('window.ATGT_eventFilter', window.ATGT_eventFilter);
  157. if (window.ATGT_eventFilter && window.ATGT_eventFilter.test(type)) {
  158. console.log('dummyEvtRegFunc', this, type, listener, options);
  159. console.log('this event is %cdisabled.', 'color: red;');
  160. this.ATGT_disabledEventHandlers[type] = [listener, options];
  161. } else {
  162. //console.log('dummyEvtRegFunc', this, type, listener, options);
  163. //console.log('this event is %cregistered.', 'color: green;');
  164. this.ATGT_enabledEventHandlers[type] = [listener, options];
  165. regFunc.call(this, type, listener, options);
  166. }
  167. }
  168. EventTarget.prototype.addEventListener = dummyEvtRegFunc;
  169. if (document.addEventListener !== dummyEvtRegFunc)
  170. document.addEventListener = dummyEvtRegFunc;
  171. }
  172.  
  173. function injectFunction(func) {
  174. var script = document.createElement('script');
  175. //script.appendChild(document.createTextNode('('+ func +')();'));
  176. script.appendChild(document.createTextNode('(function (){' + '(' + func + ')();' + '})();'));
  177. (document.body || document.head || document.documentElement).appendChild(script);
  178. }
  179. //console.log(''+injectFunction);
  180. injectFunction(replaceAddEventListener);
  181.  
  182. function interceptJackEvent(noHijackNodes = '') {
  183. console.log(`interceptJackEvent noHijackNodes='${noHijackNodes}'`);
  184. var f = function setEventFilter() {
  185. var eventFilter = /copy|selectstart|mouseup|mousedown|contextmenu|keydown|keyup/;
  186. window.ATGT_eventFilter = eventFilter;
  187. window.ATGT_noHijackNodes = '__noHijackNodes__';
  188. };
  189. f = f.toString().replace('__noHijackNodes__', noHijackNodes);
  190. injectFunction(f);
  191. }
  192. function addStyleSheet(cssContent) {
  193. let cssid = `ATGT-remove-page-limit-css`;
  194. if (document.querySelector(`#${cssid}`))
  195. return;
  196. let style = document.createElement('STYLE');
  197. style.type = 'text/css';
  198. style.id = cssid;
  199. style.appendChild(document.createTextNode(cssContent));
  200. document.head.appendChild(style);
  201. }
  202. function enableUserSelect(sel) {
  203. console.log('enableUserSelect ', sel);
  204. var b = document.body;
  205. if (sel)
  206. b = document.querySelector(sel);
  207. var uselattrs = ['-webkit-touch-callout',
  208. '-webkit-user-select',
  209. '-khtml-user-select',
  210. '-moz-user-select',
  211. '-ms-user-select',
  212. 'user-select',
  213. ];
  214. for (var usel of uselattrs) {
  215. try {
  216. if (b && usel in b.style) {
  217. console.log('Found style user-select: ' + b.style[usel] + ', replace it.');
  218. b.style[usel] = 'text';
  219. }
  220. } catch (e) {
  221. console.log(e);
  222. }
  223. }
  224. console.log('add css rule to enable user select');
  225. addStyleSheet(`
  226. * {
  227. user-select: unset!important;
  228. }`);
  229. }
  230.  
  231. function enableCopyHandler(sel) {
  232. var body = document.body || document.querySelector('body');
  233. var doc = document;
  234. console.log('enableCopyHandler', new Date().toLocaleString(), ' ', arguments.callee.name, body.oncopy, doc.oncopy);
  235. function replaceUserHandlers(n) {
  236. if (!n)
  237. return;
  238. if (n.onclick)
  239. n.onclick = null;
  240. if (n.oncontextmenu)
  241. n.oncontextmenu = null;
  242. if (n.oncopy)
  243. n.oncopy = null;
  244. if (n.onmouseup)
  245. n.onmouseup = null;
  246. if (n.onmousedown)
  247. n.onmousedown = null;
  248. if (n.onselectstart)
  249. n.onselectstart = null;
  250. }
  251. //console.log('body', body);
  252. replaceUserHandlers(body);
  253. replaceUserHandlers(doc);
  254. var node = document.querySelector(sel);
  255. //for (var n of nodes)
  256. console.log('sel', sel, '=>', node);
  257. replaceUserHandlers(node);
  258. }
  259.  
  260. function waitForNode(targetSel, nodeFilter, nodeHandler, attrHandler) {
  261. console.log('waitForNode ', targetSel, nodeFilter, nodeHandler, attrHandler);
  262. // Select the node that will be observed for mutations
  263. var targetNode = document;
  264. if (typeof targetSel === 'object')
  265. targetNode = targetSel;
  266. else if (typeof targetSel === 'string')
  267. targetNode = document.querySelector(targetSel);
  268.  
  269. // console.log('targetNode', targetNode);
  270.  
  271. // Options for the observer (which mutations to observe)
  272. var config = {
  273. attributes: !!attrHandler,
  274. childList: !!nodeHandler,
  275. subtree: true,
  276. };
  277.  
  278. // Callback function to execute when mutations are observed
  279. var callback = function (mutationsList) {
  280. for (var mutation of mutationsList) {
  281. if (nodeHandler && mutation.type == 'childList') {
  282. //console.log('A child node has been added ', mutation.addedNodes, ' or removed.');
  283. for (var node of mutation.addedNodes) {
  284. if (node.querySelector instanceof Function && node.querySelector(nodeFilter) || node === node.parentNode.querySelector(nodeFilter)) {
  285. setTimeout(nodeHandler, 0);
  286. this.disconnect();
  287. break;
  288. }
  289. }
  290. } else if (attrHandler && mutation.type == 'attributes') {
  291. //console.log('The ' + mutation.attributeName + ' attribute was modified.');
  292. setTimeout(attrHandler, 0);
  293. }
  294. }
  295. };
  296.  
  297. // Create an observer instance linked to the callback function
  298. var observer = new MutationObserver(callback);
  299. // Start observing the target node for configured mutations
  300. observer.observe(targetNode, config);
  301. // Later, you can stop observing
  302. //observer.disconnect();
  303. }
  304.  
  305. function runHandler(url, info) {
  306. try {
  307. console.log(new Date().toLocaleString(), ' handle ', url, ' with ', info);
  308. var nodeSel = info[0];
  309. var evt = info[1];
  310. var func = info[2];
  311. var delay_or_observe = info[3];
  312. var param = info[4];
  313. var node = document;
  314. var handler;
  315. if (typeof delay_or_observe === 'number') {
  316. handler = function () {
  317. setTimeout(func, delay_or_observe, param);
  318. };
  319. } else {
  320. handler = function () {
  321. waitForNode(delay_or_observe, param, function () { func(param); });
  322. };
  323. }
  324. if (typeof nodeSel === 'object')
  325. node = nodeSel;
  326. else if (typeof nodeSel === 'string')
  327. node = document.querySelector(nodeSel);
  328. console.info('nodeSel', nodeSel, 'node', node);
  329. if (evt)
  330. node && node.addEventListener(evt, () => { handler(param); });
  331. else
  332. handler(param);
  333. } catch (e) {
  334. console.log('Error handling ', url, ' ', e);
  335. }
  336. }
  337.  
  338. for (var ph of unlockPageHandlers) {
  339. var url = ph[0];
  340. if (url.test(location.href)) {
  341. var info_list = ph[1];
  342. if (!(info_list[0] instanceof Array)) {
  343. try {
  344. runHandler(url, info_list);
  345. } catch (e) {
  346. console.log(e);
  347. }
  348. } else for (var info of info_list) {
  349. try {
  350. runHandler(url, info);
  351. } catch (e) {
  352. console.log(e);
  353. }
  354. }
  355.  
  356. // only one rule runs on one site
  357. break;
  358. }
  359. }
  360. })();
  361.  
  362. console.log(`=== /unlock-page ${location.href} ===`);