Selection and Copying Restorer

Unlock right-click, remove restrictions on copy, cut, select text, right-click menu, text copying, text selection, image right-click

当前为 2024-05-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Selection and Copying Restorer
  3. // @version 0.4
  4. // @description Unlock right-click, remove restrictions on copy, cut, select text, right-click menu, text copying, text selection, image right-click
  5. // @namespace https://greasyfork.org/users/1300060
  6. // @author AstralRift
  7. // @run-at document-end
  8. // @match *://*/*
  9. // @grant GM_registerMenuCommand
  10. // @grant GM_unregisterMenuCommand
  11. // @grant GM.setValue
  12. // @grant GM.getValue
  13. // @grant GM_addValueChangeListener
  14. // @grant unsafeWindow
  15. // @license MIT
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. 'use strict';
  20.  
  21. function unlockTextSelection() {
  22. const style = document.createElement('style');
  23. style.textContent = `
  24. * {
  25. user-select: text !important;
  26. -webkit-user-select: text !important;
  27. -moz-user-select: text !important;
  28. }
  29. `;
  30. document.head.appendChild(style);
  31. }
  32.  
  33. function hasCopyRestrictions() {
  34. const testElement = document.createElement('div');
  35. testElement.style.userSelect = 'none';
  36. document.body.appendChild(testElement);
  37. const userSelect = getComputedStyle(testElement).userSelect;
  38. document.body.removeChild(testElement);
  39.  
  40. if (userSelect === 'none') return true;
  41.  
  42. const events = ['contextmenu', 'copy', 'cut', 'selectstart'];
  43. const isBlocked = events.some(event => {
  44. let blocked = false;
  45. document.addEventListener(event, function tempListener(e) {
  46. e.stopImmediatePropagation();
  47. blocked = true;
  48. document.removeEventListener(event, tempListener, true);
  49. }, true);
  50.  
  51. const evt = new Event(event, { bubbles: true, cancelable: true });
  52. document.dispatchEvent(evt);
  53. return blocked;
  54. });
  55.  
  56. return isBlocked;
  57. }
  58.  
  59. function stopEventPropagation(event) {
  60. event.stopPropagation();
  61. }
  62.  
  63. function stopEventDefault(event) {
  64. event.preventDefault();
  65. }
  66.  
  67. function toggleEnabled() {
  68. GM.getValue('enabled', true).then(enabled => {
  69. enabled = !enabled;
  70. GM.setValue('enabled', enabled).then(() => {
  71. location.reload();
  72. });
  73. });
  74. }
  75.  
  76. GM_registerMenuCommand('Toggle Selection and Copying Restorer', toggleEnabled);
  77.  
  78. GM.getValue('enabled', true).then(enabled => {
  79. if (enabled && hasCopyRestrictions()) {
  80. unlockTextSelection();
  81.  
  82. const eventOptions = { capture: true, passive: true };
  83. const eventOptionsNoPassive = { capture: true };
  84.  
  85. document.addEventListener('contextmenu', stopEventPropagation, eventOptions);
  86. document.addEventListener('copy', stopEventDefault, eventOptionsNoPassive);
  87. document.addEventListener('cut', stopEventDefault, eventOptionsNoPassive);
  88. }
  89. });
  90. })();