Gemini Copy Text Button

特定の要素からテキストをコピーするボタンを追加します。

目前为 2024-06-23 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Gemini Copy Text Button
  3. // @namespace https://qestir.hatenablog.com/entry/2024/06/23/153328
  4. // @match https://gemini.google.com/*
  5. // @grant none
  6. // @version 1.2
  7. // @description 特定の要素からテキストをコピーするボタンを追加します。
  8. // @author Qestir
  9. // @license GPL-3.0-or-later
  10. //
  11. // ==/UserScript==
  12. // スクリプトを実行する関数
  13. (function() {
  14. // テキストをコピーする関数
  15. function copyTextToClipboard(text) {
  16. // 一時的なテキストエリアを作成
  17. var textArea = document.createElement("textarea");
  18. textArea.value = text;
  19.  
  20. // テキストエリアをドキュメントに追加
  21. document.body.appendChild(textArea);
  22.  
  23. // テキストを選択
  24. textArea.select();
  25.  
  26. try {
  27. // クリップボードにコピー
  28. var successful = document.execCommand('copy');
  29. var msg = successful ? '成功' : '失敗';
  30. console.log('テキストのコピーに' + msg + 'しました');
  31. } catch (err) {
  32. console.error('テキストのコピーに失敗しました', err);
  33. }
  34.  
  35. // テキストエリアをドキュメントから削除
  36. document.body.removeChild(textArea);
  37. }
  38.  
  39. // テキストをコピーするボタンを作成する関数
  40. function createCopyButton(targetElement) {
  41. // コピー用ボタンを作成
  42. var button = document.createElement("button");
  43. button.textContent = "コピー";
  44. button.style.marginLeft = "10px";
  45. button.style.padding = "5px 10px";
  46. button.style.backgroundColor = "#4CAF50";
  47. button.style.color = "white";
  48. button.style.border = "none";
  49. button.style.borderRadius = "5px";
  50. button.style.cursor = "pointer";
  51.  
  52. // ボタンにホバースタイルを追加
  53. button.addEventListener("mouseover", function() {
  54. button.style.backgroundColor = "#45a049";
  55. });
  56. button.addEventListener("mouseout", function() {
  57. button.style.backgroundColor = "#4CAF50";
  58. });
  59.  
  60. // ボタンがクリックされた時の処理
  61. button.addEventListener("click", function() {
  62. // query-textクラスのテキストのみを取得
  63. var textElement = targetElement.querySelector(".query-text");
  64. if (textElement) {
  65. var text = textElement.textContent;
  66. copyTextToClipboard(text);
  67. }
  68. });
  69.  
  70. // 対象の要素にボタンを追加
  71. targetElement.appendChild(button);
  72. }
  73.  
  74. // 特定のクラス名の要素にボタンを追加する関数
  75. function addCopyButtons() {
  76. var userQueryElements = document.querySelectorAll("user-query");
  77. userQueryElements.forEach(function(element) {
  78. if (!element.querySelector("button")) {
  79. createCopyButton(element);
  80. }
  81. });
  82. }
  83.  
  84. // MutationObserverの設定
  85. var observer = new MutationObserver(function(mutations) {
  86. mutations.forEach(function(mutation) {
  87. mutation.addedNodes.forEach(function(node) {
  88. if (node.nodeType === 1) { // 要素ノードの場合
  89. var userQueryElements = node.querySelectorAll("user-query");
  90. userQueryElements.forEach(function(element) {
  91. createCopyButton(element);
  92. });
  93. }
  94. });
  95. });
  96. });
  97.  
  98. // 監視を開始
  99. observer.observe(document.body, { childList: true, subtree: true });
  100.  
  101. // 初回実行
  102. addCopyButtons();
  103. })();