Auto Copy Selected Text

Automatically copy selected text to clipboard and keep the selection

目前为 2024-09-16 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Auto Copy Selected Text
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.4
  5. // @description Automatically copy selected text to clipboard and keep the selection
  6. // @author liuweiqing
  7. // @match *://*/*
  8. // @grant none
  9. // @license MIT
  10. // @icon https://icons.iconarchive.com/icons/gartoon-team/gartoon-places/256/user-desktop-icon.png
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. ("use strict");
  15.  
  16. // 监听鼠标松开的事件
  17. document.addEventListener("mouseup", () => {
  18. const selection = window.getSelection();
  19. const selectedText = selection.toString();
  20.  
  21. if (selectedText) {
  22. const range = selection.getRangeAt(0);
  23. if (navigator.clipboard) {
  24. navigator.clipboard
  25. .writeText(selectedText)
  26. .then(() => {
  27. console.log("Text copied to clipboard:", selectedText);
  28. })
  29. .catch((err) => {
  30. console.error("Failed to copy text to clipboard", err);
  31. });
  32. } else {
  33. const tempElement = document.createElement("textarea");
  34. tempElement.value = selectedText;
  35. document.body.appendChild(tempElement);
  36. tempElement.select();
  37. try {
  38. document.execCommand("copy");
  39. console.log("Text copied to clipboard:", selectedText);
  40. } catch (err) {
  41. console.error("Failed to copy text to clipboard", err);
  42. }
  43. document.body.removeChild(tempElement);
  44. }
  45. selection.removeAllRanges();
  46. selection.addRange(range);
  47. }
  48. });
  49.  
  50. // 监听鼠标中键点击事件,粘贴剪贴板内容
  51. document.addEventListener("mousedown", async (event) => {
  52. if (event.button === 1) {
  53. // 中键点击
  54. event.preventDefault();
  55. event.stopPropagation();
  56.  
  57. try {
  58. const text = await navigator.clipboard.readText();
  59.  
  60. // 获取点击位置的元素
  61. const targetElement = document.elementFromPoint(
  62. event.clientX,
  63. event.clientY
  64. );
  65. if (targetElement && isEditable(targetElement)) {
  66. // 设置焦点并模拟正常输入
  67. forceFocus(targetElement);
  68. pasteIntoInput(targetElement, text);
  69. } else {
  70. // 如果不是输入框,则尝试插入到其他可编辑区域
  71. document.execCommand("insertText", false, text);
  72. }
  73. } catch (err) {
  74. console.error("Failed to read clipboard contents: ", err);
  75. }
  76. }
  77. });
  78.  
  79. // 检查元素是否可编辑
  80. function isEditable(element) {
  81. return (
  82. element.tagName === "INPUT" ||
  83. element.tagName === "TEXTAREA" ||
  84. element.isContentEditable
  85. );
  86. }
  87.  
  88. // 尝试强制获得焦点
  89. function forceFocus(element) {
  90. try {
  91. element.focus(); // 尝试直接聚焦
  92. // 如果还没有焦点,再尝试更强制的方式
  93. if (document.activeElement !== element) {
  94. const focusEvent = new FocusEvent("focus", {
  95. bubbles: true,
  96. cancelable: true,
  97. });
  98. element.dispatchEvent(focusEvent);
  99. }
  100. } catch (e) {
  101. console.error("Failed to focus on element: ", e);
  102. }
  103. }
  104.  
  105. // 模拟正常输入
  106. function pasteIntoInput(element, text) {
  107. // 如果支持 `execCommand`
  108. if (document.execCommand) {
  109. element.focus();
  110. document.execCommand("insertText", false, text);
  111. } else {
  112. // 如果不支持 `execCommand`,直接使用事件
  113. const inputEvent = new InputEvent("input", {
  114. bubbles: true,
  115. cancelable: true,
  116. data: text,
  117. inputType: "insertText",
  118. });
  119. element.dispatchEvent(inputEvent);
  120. }
  121. }
  122. })();