Skip to content

Instantly share code, notes, and snippets.

@Explosion-Scratch
Last active December 18, 2023 16:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Explosion-Scratch/32568b75ecee87a66234550f5f8cedbd to your computer and use it in GitHub Desktop.
Save Explosion-Scratch/32568b75ecee87a66234550f5f8cedbd to your computer and use it in GitHub Desktop.
Add a copy button to bard's responses
// ==UserScript==
// @name Bard copy button
// @namespace mailto:explosionscratch@gmail.com
// @version 0.1
// @description Add a copy button to Google Bard's response without clicking more
// @author Explosion-Scratch
// @match https://bard.google.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bard.google.com
// @grant none
// ==/UserScript==
(function () {
"use strict";
const style = `.gmat-mdc-tooltip,[mattooltip=More] {opacity: 0}`;
const s = document.createElement("style");
s.innerHTML = style;
document.head.appendChild(s);
observeMutations("body", () => {
[...document.querySelectorAll(".response-container")].forEach(
initContainer,
);
});
function initContainer(container) {
if (container.getAttribute("data-added-listeners")) {
return;
}
let button = document.createElement("button");
Object.entries({
class:
"mat-mdc-tooltip-trigger icon-button mdc-button mat-mdc-button gmat-mdc-button-with-prefix mat-unthemed mat-mdc-button-base gmat-mdc-button ng-star-inserted",
mattooltip: "Copy response",
"aria-label": "Copy response",
"mat-button": "",
style: 'border-radius: 1000px !important; color: var(--bard-color-on-surface-variant); min-height: 40px; min-width: 40px; border-radius: 50%; -webkit-flex-shrink: 0; -ms-flex-negative: 0;',
"mat-ripple-loader-class-name": "mat-mdc-button-ripple",
}).forEach(([k, v]) => button.setAttribute(k, v));
button.innerHTML = `<span class="mat-mdc-button-persistent-ripple mdc-button__ripple"></span
>
<span class="mat-mdc-button-persistent-ripple mdc-button__ripple"></span>
<mat-icon
role="img"
class="mat-icon notranslate icon-only-button-icon google-symbols mat-icon-no-color"
style="height: 20px; width: 20px; font-size: 20px;"
aria-hidden="true"
data-mat-icon-type="font"
data-mat-icon-name="content_copy"
>content_copy</mat-icon
><span class="mdc-button__label"></span
><span class="mat-mdc-focus-indicator"></span
><span class="mat-mdc-button-touch-target"></span
><span class="mat-ripple mat-mdc-button-ripple"></span>
`;
button.id = "copy_button";
button.onclick = async () => {
console.log('Clicked');
container.querySelector("[mattooltip=More]").click();
console.log('Clicked more');
await new Promise((r) => setTimeout(r, 10));
console.log('Clicked copy');
document.querySelector(".mat-mdc-menu-item[aria-label=Copy]").click();
console.log('Done');
await new Promise((r) => setTimeout(r, 10));
};
container.querySelector("[class*=buttons-container]").prepend(button);
container.setAttribute("data-added-listeners", "true");
}
function observeMutations(selector, callback = () => {}) {
const targetNode = document.querySelector(selector);
if (!targetNode) {
console.error("Invalid selector. Element not found.");
return;
}
const observerConfig = { attributes: true, childList: true, subtree: true };
const mutationCallback = (mutationsList, observer) => {
callback(mutationsList, observer);
};
const observer = new MutationObserver(mutationCallback);
observer.observe(targetNode, observerConfig);
const cancelFunction = () => {
observer.disconnect();
console.log("Mutation observation cancelled.");
};
return cancelFunction;
}
})();
@bonelifer
Copy link

Awesome,thanks for the help. After finding one for openai, chatgpt to put copy button on their UI, this means no more bad UX decisions for now in the two of them. Though I had to get chatgpt or bard can't remember to restyle it, as it was butt ugly. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment