Thêm nút Sao chép vào tin nhắn trò chuyện trên trang web Github Copilot

Thêm nút "Sao chép" vào các phần tử tin nhắn trò chuyện để dễ dàng sao chép nội dung của chúng.

  1. // ==UserScript==
  2. // @name Add Copy Button to Chat Messages on Github Copilot web page
  3. // @name:ar إضافة زر نسخ إلى رسائل الدردشة في صفحة Github Copilot
  4. // @name:bg Добавяне на бутон за копиране към чат съобщенията на уеб страницата на Github Copilot
  5. // @name:cs Přidat tlačítko Kopírovat ke zprávám chatu na webové stránce Github Copilot
  6. // @name:da Tilføj Kopier-knap til chatbeskeder på Github Copilot webside
  7. // @name:de Kopier-Button zu Chatnachrichten auf der Github Copilot Webseite hinzufügen
  8. // @name:el Προσθήκη κουμπιού αντιγραφής στα μηνύματα συνομιλίας στην ιστοσελίδα Github Copilot
  9. // @name:en Add Copy Button to Chat Messages on Github Copilot web page
  10. // @name:eo Aldoni Kopian Butonon al Babilaj Mesaĝoj sur Github Copilot retpaĝo
  11. // @name:es Añadir botón de copiar a los mensajes de chat en la página web de Github Copilot
  12. // @name:fi Lisää kopiointipainike Github Copilotin verkkosivun chattiviesteihin
  13. // @name:fr Ajouter un bouton de copie aux messages de chat sur la page web Github Copilot
  14. // @name:fr-CA Ajouter un bouton de copie aux messages de chat sur la page web Github Copilot (Canada)
  15. // @name:he הוספת כפתור העתקה להודעות צ'אט בדף האינטרנט של Github Copilot
  16. // @name:hr Dodaj gumb za kopiranje porukama chata na web stranici Github Copilot
  17. // @name:hu Másolás gomb hozzáadása a csevegő üzenetekhez a Github Copilot weboldalán
  18. // @name:id Tambahkan Tombol Salin ke Pesan Obrolan di Halaman Web Github Copilot
  19. // @name:it Aggiungi pulsante Copia ai messaggi di chat sulla pagina web di Github Copilot
  20. // @name:ja Github Copilot Web ページのチャットメッセージにコピーボタンを追加
  21. // @name:ka დაამატეთ კოპირების ღილაკი Github Copilot-ის ვებ გვერდზე ჩეთის შეტყობინებებს
  22. // @name:ko Github Copilot 웹 페이지의 채팅 메시지에 복사 버튼 추가
  23. // @name:nb Legg til Kopier-knapp til chatmeldinger på Github Copilot-websiden
  24. // @name:nl Kopieerknop toevoegen aan chatberichten op Github Copilot webpagina
  25. // @name:pl Dodaj przycisk Kopiuj do wiadomości na czacie na stronie Github Copilot
  26. // @name:pt-BR Adicionar botão de copiar às mensagens de chat na página web do Github Copilot
  27. // @name:ro Adaugă butonul Copiază la mesajele chat de pe pagina web Github Copilot
  28. // @name:ru Добавить кнопку "Копировать" к сообщениям чата на веб-странице Github Copilot
  29. // @name:sk Pridať tlačidlo Kopírovať k chatovým správam na webovej stránke Github Copilot
  30. // @name:sr Додај дугме Копирај порукама ћаскања на веб страници Github Copilot
  31. // @name:sv Lägg till Kopiera-knapp till chattmeddelanden på Github Copilot-webbsidan
  32. // @name:th เพิ่มปุ่มคัดลอกไปยังข้อความแชทบนหน้าเว็บ Github Copilot
  33. // @name:tr Github Copilot web sayfasındaki sohbet mesajlarına Kopyala düğmesi ekle
  34. // @name:ug Github Copilot تور بېتىدىكى پاراڭلىشىش ئۇچۇرلىرىغا كۆچۈرۈش كۇنۇپكىسى قوشۇش
  35. // @name:uk Додати кнопку "Копіювати" до повідомлень чату на веб-сторінці Github Copilot
  36. // @name:vi Thêm nút Sao chép vào tin nhắn trò chuyện trên trang web Github Copilot
  37. // @name:zh 在 Github Copilot 网页的聊天消息中添加复制按钮
  38. // @name:zh-CN 在 Github Copilot 网页的聊天消息中添加复制按钮
  39. // @name:zh-HK 在 Github Copilot 網頁的聊天訊息中新增複製按鈕
  40. // @name:zh-SG 在 Github Copilot 网页的聊天消息中添加复制按钮
  41. // @name:zh-TW 在 Github Copilot 網頁的聊天訊息中新增複製按鈕
  42. // @description Adds a "Copy" button to chat message elements to easily copy their content.
  43. // @description:ar يضيف زر "نسخ" إلى عناصر رسائل الدردشة لنسخ محتواها بسهولة.
  44. // @description:bg Добавя бутон "Копиране" към елементите на чат съобщенията, за да можете лесно да копирате съдържанието им.
  45. // @description:cs Přidá tlačítko "Kopírovat" k prvkům zpráv chatu pro snadné kopírování jejich obsahu.
  46. // @description:da Tilføjer en "Kopier"-knap til chatbeskedelementer for nemt at kopiere deres indhold.
  47. // @description:de Fügt einen "Kopieren"-Button zu Chatnachrichtenelementen hinzu, um deren Inhalt einfach zu kopieren.
  48. // @description:el Προσθέτει ένα κουμπί "Αντιγραφή" στα στοιχεία μηνυμάτων συνομιλίας για εύκολη αντιγραφή του περιεχομένου τους.
  49. // @description:en Adds a "Copy" button to chat message elements to easily copy their content.
  50. // @description:eo Aldonas "Kopi" butonon al la babilejmesaĝaj elementoj por facile kopii ilian enhavon.
  51. // @description:es Añade un botón de "Copiar" a los elementos de los mensajes de chat para copiar fácilmente su contenido.
  52. // @description:fi Lisää "Kopioi"-painikkeen chattiviestielementteihin, jotta niiden sisällön kopioiminen olisi helppoa.
  53. // @description:fr Ajoute un bouton "Copier" aux éléments de message de chat pour copier facilement leur contenu.
  54. // @description:fr-CA Ajoute un bouton "Copier" aux éléments de message de chat pour copier facilement leur contenu.
  55. // @description:he מוסיף כפתור "העתקה" לרכיבי הודעות צ'אט כדי להעתיק בקלות את התוכן שלהם.
  56. // @description:hr Dodaje gumb "Kopiraj" elementima poruka chata za jednostavno kopiranje njihovog sadržaja.
  57. // @description:hu Hozzáad egy "Másolás" gombot a csevegő üzenetelemekhez, hogy könnyen másolható legyen a tartalmuk.
  58. // @description:id Menambahkan tombol "Salin" ke elemen pesan obrolan untuk menyalin kontennya dengan mudah.
  59. // @description:it Aggiunge un pulsante "Copia" agli elementi dei messaggi di chat per copiare facilmente il loro contenuto.
  60. // @description:ja チャットメッセージ要素に「コピー」ボタンを追加して、コンテンツを簡単にコピーできるようにします。
  61. // @description:ka ამატებს "კოპირების" ღილაკს ჩეთის შეტყობინების ელემენტებს, რათა მარტივად დააკოპიროთ მათი შინაარსი.
  62. // @description:ko 채팅 메시지 요소에 "복사" 버튼을 추가하여 해당 콘텐츠를 쉽게 복사할 수 있습니다.
  63. // @description:nb Legger til en "Kopier"-knapp til chatmeldingselementer for å enkelt kopiere innholdet deres.
  64. // @description:nl Voegt een "Kopieer"-knop toe aan chatberichtelementen om de inhoud ervan gemakkelijk te kopiëren.
  65. // @description:pl Dodaje przycisk "Kopiuj" do elementów wiadomości na czacie, aby łatwo kopiować ich zawartość.
  66. // @description:pt-BR Adiciona um botão "Copiar" aos elementos de mensagens de chat para copiar facilmente seu conteúdo.
  67. // @description:ro Adaugă un buton "Copiază" elementelor mesajelor chat pentru a copia cu ușurință conținutul acestora.
  68. // @description:ru Добавляет кнопку "Копировать" к элементам сообщений чата для удобного копирования их содержимого.
  69. // @description:sk Pridá tlačidlo "Kopírovať" k elementom chatových správ pre jednoduché kopírovanie ich obsahu.
  70. // @description:sr Додаје дугме "Копирај" елементима порука ћаскања ради лакшег копирања њиховог садржаја.
  71. // @description:sv Lägger till en "Kopiera"-knapp till chattmeddelandeelement för att enkelt kopiera deras innehåll.
  72. // @description:th เพิ่มปุ่ม "คัดลอก" ไปยังองค์ประกอบข้อความแชทเพื่อให้คัดลอกเนื้อหาได้ง่าย
  73. // @description:tr Sohbet mesajı öğelerine içeriklerini kolayca kopyalamak için bir "Kopyala" düğmesi ekler.
  74. // @description:ug پاراڭلىشىش ئۇچۇر ئېلېمېنتلىرىغا «كۆچۈرۈش» كۇنۇپكىسى قوشۇپ ئۇلارنىڭ مەزمۇنىنى ئاسان كۆچۈرۈشكە قۇلايلىق يارىتىدۇ.
  75. // @description:uk Додає кнопку "Копіювати" до елементів повідомлень чату для легкого копіювання їх вмісту.
  76. // @description:vi Thêm nút "Sao chép" vào các phần tử tin nhắn trò chuyện để dễ dàng sao chép nội dung của chúng.
  77. // @description:zh 在聊天消息元素中添加一个“复制”按钮,以便轻松复制其内容。
  78. // @description:zh-CN 在聊天消息元素中添加一个“复制”按钮,以便轻松复制其内容。
  79. // @description:zh-HK 在聊天訊息元素中新增一個「複製」按鈕,以便輕鬆複製其內容。
  80. // @description:zh-SG 在聊天消息元素中添加一个“复制”按钮,以便轻松复制其内容。
  81. // @description:zh-TW 在聊天訊息元素中新增一個「複製」按鈕,以便輕鬆複製其內容。
  82. // @namespace http://tampermonkey.net/
  83. // @version 1.2.1
  84. // @author aspen138
  85. // @match *://github.com/copilot/c/*
  86. // @match *://github.com/copilot/
  87. // @match *://github.com/copilot/*
  88. // @grant none
  89. // @run-at document-end
  90. // @icon https://github.com/favicons/favicon-copilot.svg
  91. // @license MIT
  92. // ==/UserScript==
  93.  
  94.  
  95.  
  96.  
  97.  
  98. (function() {
  99. 'use strict';
  100.  
  101. // Update these if class names change
  102. const MESSAGE_CONTENT_CLASS = 'UserMessage-module__container--cAvvK';
  103. const CHAT_MESSAGE_CONTENT_CLASS = 'ChatMessage-module__content--MYneF';
  104.  
  105. /**
  106. * Creates and returns a copy button element.
  107. */
  108. function createCopyButton() {
  109. const button = document.createElement('button');
  110. button.innerText = 'Copy';
  111. button.classList.add('copy-button');
  112.  
  113. // Use sticky positioning to keep it visible while the element is in view
  114. button.style.position = 'sticky';
  115. button.style.top = '10px';
  116. button.style.right = '10px';
  117. button.style.backgroundColor = '#4CAF50';
  118. button.style.color = '#fff';
  119. button.style.border = 'none';
  120. button.style.borderRadius = '4px';
  121. button.style.padding = '5px 10px';
  122. button.style.cursor = 'pointer';
  123. button.style.fontSize = '0.9em';
  124. button.style.zIndex = '1000';
  125. button.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)';
  126. button.style.marginLeft = 'auto';
  127. button.style.float = 'right';
  128. button.style.display = 'inline-block';
  129. // Ensure parent or relevant ancestor allows sticky to function
  130. // For sticky to work, the ancestor should have no overflow constraints that break it.
  131.  
  132. button.addEventListener('mouseenter', () => {
  133. button.style.backgroundColor = '#45a049';
  134. });
  135. button.addEventListener('mouseleave', () => {
  136. button.style.backgroundColor = '#4CAF50';
  137. });
  138.  
  139. return button;
  140. }
  141.  
  142. /**
  143. * Adds a copy button to a chat message element.
  144. * @param {HTMLElement} messageElement
  145. */
  146. function addCopyButton(messageElement) {
  147. // Prevent adding multiple buttons
  148. if (messageElement.querySelector('.copy-button')) return;
  149.  
  150. const messageContent = messageElement.querySelector(`.${MESSAGE_CONTENT_CLASS}`);
  151. if (!messageContent) return;
  152.  
  153. // Ensure the parent is a block-level container that supports sticky
  154. messageElement.style.position = 'relative';
  155. messageElement.style.display = 'block';
  156.  
  157. const copyButton = createCopyButton();
  158.  
  159. copyButton.addEventListener('click', () => {
  160. const textToCopy = messageContent.innerText.trim();
  161. navigator.clipboard.writeText(textToCopy).then(() => {
  162. copyButton.innerText = 'Copied!';
  163. copyButton.style.backgroundColor = '#388E3C';
  164. setTimeout(() => {
  165. copyButton.innerText = 'Copy';
  166. copyButton.style.backgroundColor = '#4CAF50';
  167. }, 2000);
  168. }).catch(err => {
  169. console.error('Failed to copy text: ', err);
  170. });
  171. });
  172.  
  173. messageElement.appendChild(copyButton);
  174. }
  175.  
  176. /**
  177. * Processes all existing chat messages on page load.
  178. */
  179. function processExistingMessages() {
  180. const messageElements = document.querySelectorAll(`.${CHAT_MESSAGE_CONTENT_CLASS}`);
  181. messageElements.forEach(messageElement => addCopyButton(messageElement));
  182. }
  183.  
  184. /**
  185. * Observes newly added messages dynamically.
  186. */
  187. function observeNewMessages() {
  188. const targetNode = document.body;
  189. const config = { childList: true, subtree: true };
  190.  
  191. const callback = (mutationsList) => {
  192. for (const mutation of mutationsList) {
  193. if (mutation.type === 'childList') {
  194. mutation.addedNodes.forEach(node => {
  195. if (node.nodeType === Node.ELEMENT_NODE) {
  196. if (node.classList && node.classList.contains(CHAT_MESSAGE_CONTENT_CLASS)) {
  197. addCopyButton(node);
  198. }
  199. const nestedMessages = node.querySelectorAll(`.${CHAT_MESSAGE_CONTENT_CLASS}`);
  200. nestedMessages.forEach(nestedNode => addCopyButton(nestedNode));
  201. }
  202. });
  203. }
  204. }
  205. };
  206.  
  207. const observer = new MutationObserver(callback);
  208. observer.observe(targetNode, config);
  209. }
  210.  
  211. function init() {
  212. processExistingMessages();
  213. observeNewMessages();
  214. }
  215.  
  216. if (document.readyState === 'loading') {
  217. document.addEventListener('DOMContentLoaded', init);
  218. } else {
  219. init();
  220. }
  221.  
  222. })();
  223.  
  224.