Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix copy button invalid & copy button (invisible) duplication bug in chatbot #4350

Merged
merged 10 commits into from
Jun 1, 2023
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ No changes to highlight.

## Bug Fixes:

No changes to highlight.
- Fixed Copy Button bugs in the Chatbot component (Copy Button duplication & Copy Button ineffectiveness via non-localhost http access) by [@binary-husky](https://github.com/binary-husky) in [PR 4350](https://github.com/gradio-app/gradio/pull/4350).

## Other Changes:

Expand Down
43 changes: 28 additions & 15 deletions js/chatbot/src/ChatBot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,35 @@
}
div.querySelectorAll("pre > code").forEach((n) => {
let code_node = n as HTMLElement;
const copy_div = document.createElement("div");
new Copy({
target: copy_div,
props: {
value: code_node.innerText.trimEnd()
// check whether copy button is already in there
let copy_div_exist = false;
if (code_node.parentElement) {
let buttonElement = code_node.parentElement.querySelector("button");
if (buttonElement) {
// button element is already inside code_node
copy_div_exist = true;
}
});
let node = n.parentElement as HTMLElement;
copy_div.style.position = "absolute";
copy_div.style.right = "0";
copy_div.style.top = "0";
copy_div.style.zIndex = "1";
copy_div.style.padding = "var(--spacing-md)";
copy_div.style.borderBottomLeftRadius = "var(--radius-sm)";
node.style.position = "relative";
node.appendChild(copy_div);
}
if (copy_div_exist) {
return;
} else {
const copy_div = document.createElement("div");
new Copy({
target: copy_div,
props: {
value: code_node.innerText.trimEnd()
}
});
let node = n.parentElement as HTMLElement;
copy_div.style.position = "absolute";
copy_div.style.right = "0";
copy_div.style.top = "0";
copy_div.style.zIndex = "1";
copy_div.style.padding = "var(--spacing-md)";
copy_div.style.borderBottomLeftRadius = "var(--radius-sm)";
node.style.position = "relative";
node.appendChild(copy_div);
}
});

render_math_in_element(div, {
Expand Down
21 changes: 21 additions & 0 deletions js/chatbot/src/Copy.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,30 @@
}

async function handle_copy() {
// Navigator clipboard api needs a secure context (https)
if ("clipboard" in navigator) {
await navigator.clipboard.writeText(value);
copy_feedback();
} else {
// Use the 'out of viewport hidden text area' trick
const textArea = document.createElement("textarea");
textArea.value = value;

// Move textarea out of the viewport so it's not visible
textArea.style.position = "absolute";
textArea.style.left = "-999999px";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about

textArea.style.display = "none";

I was just about to fix the issue of duplicated buttons. Lucky to see this pr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😄


document.body.prepend(textArea);
textArea.select();

try {
document.execCommand("copy");
copy_feedback();
} catch (error) {
console.error(error);
} finally {
textArea.remove();
}
}
}

Expand Down