A Universal Script to Re-Enable the Selection and Copying

Enables select, right-click, copy and drag on pages that disable them.

当前为 2021-06-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name A Universal Script to Re-Enable the Selection and Copying
  3. // @version 1.2.9
  4. // @description Enables select, right-click, copy and drag on pages that disable them.
  5. // @include /^https?\:\/\//
  6. // @grant none
  7. // @run-at document-start
  8. // @namespace https://greasyfork.org/users/371179
  9. // ==/UserScript==
  10. "use strict";
  11. (function() {
  12. var wasRun = false;
  13.  
  14. var cssStyle = '*, body *, div, span, body *::before, body *::after, *:hover, *:link, *:visited, *:active , *[style], *[class]{' +
  15. '-webkit-touch-callout: text !important; -webkit-user-select: text !important; ' +
  16. '-khtml-user-select: text !important; -moz-user-select: text !important; ' +
  17. '-ms-user-select: text !important; user-select: text !important;}' +
  18. 'html body *:hover>img[class][src], html body *:hover>img[style][src]{' +
  19. 'pointer-events:auto;' +
  20. '}';
  21.  
  22. function enableSelectClickCopy() {
  23.  
  24. var mKey = 'dqzadwpujtct';
  25. var enabledSCC = '___enabledSCC_' + mKey + '___';
  26. var nonFalseFunc = '___nff_' + mKey + '___';
  27. var rvSCC = '___returnValue_' + mKey + '___';
  28.  
  29. if (window[enabledSCC]) return;
  30. window[enabledSCC] = true;
  31.  
  32. Event.prototype.preventDefault = (function(f) {
  33. var eys = ['copy', 'contextmenu', 'select', 'selectstart', 'dragstart', 'beforecopy'];
  34. return function() {
  35. if (eys.indexOf(this.type) >= 0) return;
  36. return f.apply(this);
  37. }
  38. })(Event.prototype.preventDefault);
  39.  
  40. var exs = ['copy', 'contextmenu', 'select', 'selectstart', 'dragstart', 'beforecopy'];
  41. Object.defineProperty(Event.prototype, "returnValue", {
  42.  
  43. get() {
  44. return rvSCC in this ? this[rvSCC] : true;
  45. },
  46. set(newValue) {
  47. if (exs.indexOf(this.type) < 0 && newValue === false) this.preventDefault();
  48. this[rvSCC] = newValue;
  49. },
  50. enumerable: true,
  51. configurable: true
  52. });
  53.  
  54. var ezs = ['copy', 'contextmenu', 'select', 'selectstart', 'dragstart', 'beforecopy'];
  55. var eventsCount = ezs.length;
  56.  
  57. function universaler(originalFunc) {
  58. return function wrapFunction(ev) {
  59. var pName = 'on' + ev.type;
  60. var func = this[pName];
  61. if (typeof func == 'function' && func.name == 'wrapFunction') {
  62. var res = originalFunc.apply(this, arguments);
  63. if (res !== false) {
  64. originalFunc[nonFalseFunc] = true;
  65. this[pName] = originalFunc;
  66. return res;
  67. }
  68. }
  69. }
  70. }
  71.  
  72. function disableAll(event) {
  73. var elmNode = event.target
  74. while (elmNode && elmNode.nodeType > 0) {
  75. var pName = 'on' + event.type
  76. var f = elmNode[pName];
  77. if (f && f[nonFalseFunc] !== true) {
  78. var nf = universaler(f);
  79. nf[nonFalseFunc] = true;
  80. elmNode[pName] = nf;
  81. }
  82. elmNode = elmNode.parentNode;
  83. }
  84. }
  85.  
  86.  
  87. for (var i = 0; i < eventsCount; i++) {
  88. var event = ezs[i];
  89. document.addEventListener(event, disableAll, true);
  90. }
  91.  
  92.  
  93. }
  94.  
  95. function loadedHandler() {
  96. if (wasRun) return;
  97. wasRun = true;
  98. console.log("Select-click-copy Enabler");
  99. try {
  100. document.removeEventListener('beforescriptexecute', loadedHandler, true);
  101. document.removeEventListener('beforeload', loadedHandler, true);
  102. document.removeEventListener('DOMContentLoaded', loadedHandler, true);
  103. } catch (e) {}
  104. appendScript(document);
  105.  
  106. }
  107.  
  108. function isDocumentObj(x) {
  109. return x && x.nodeType == 9
  110. }
  111.  
  112.  
  113. function isHTMLElementObj(x) {
  114. return x && x.nodeType == 1
  115. }
  116.  
  117. function makeScriptElm(documentObject) {
  118. if (!isDocumentObj(documentObject)) return null;
  119. var s = documentObject.createElement('script');
  120. s.type = 'text/javascript';
  121. s.innerHTML = '(' + enableSelectClickCopy.toString() + ')()';
  122. return s
  123. }
  124.  
  125. function appendScript(documentObject) {
  126. try {
  127. if (!isDocumentObj(documentObject)) return;
  128. var container = documentObject.head || documentObject.body;
  129. if (container) container.appendChild(makeScriptElm(documentObject));
  130. } catch (e) {}
  131. }
  132.  
  133.  
  134. function appendCssEnabler(container) {
  135. if (!isHTMLElementObj(container)) return;
  136. try {
  137. var css = document.createElement('style');
  138. css.type = 'text/css';
  139. css.innerHTML = cssStyle;
  140. container.appendChild(css);
  141. } catch (e) {}
  142. }
  143.  
  144. wasRun = false;
  145.  
  146. if (document != null) {
  147.  
  148. try {
  149. enableSelectClickCopy(); //try direct call
  150. } catch (e) {}
  151.  
  152. try {
  153. if ('onbeforescriptexecute' in document) {
  154. //for firefox
  155. document.addEventListener('beforescriptexecute', loadedHandler, true);
  156. } else {
  157. //for chrome and opera
  158. document.addEventListener('beforeload', loadedHandler, true);
  159. }
  160.  
  161. } catch (e) {}
  162.  
  163. function onReady() {
  164.  
  165. //in case all previous efforts fail
  166. try {
  167. loadedHandler();
  168. } catch (e) {}
  169.  
  170. appendCssEnabler(document.documentElement || document.body);
  171. }
  172.  
  173. if (document.readyState !== 'loading') {
  174. onReady();
  175. } else {
  176. document.addEventListener('DOMContentLoaded', onReady);
  177. }
  178.  
  179.  
  180. }
  181. })();