Refactor copy logic to remove deprecated execCommand

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-17 04:55:45 +00:00
1 parent 84e7f50f96
commit 6d0bd25067
3 files changed
+112 -17

No files matched your search

+3 -13
View File
@@ -399,6 +399,7 @@ export class EmbedVideoModal {
return;
}
// Attempt to copy using the Clipboard API
if (navigator?.clipboard?.writeText) {
try {
await navigator.clipboard.writeText(snippet);
@@ -409,24 +410,13 @@ export class EmbedVideoModal {
}
}
// Fallback: Select the text so the user can copy manually
const textarea = this.snippetTextarea;
textarea.focus();
textarea.select();
textarea.setSelectionRange(0, textarea.value.length);
let succeeded = false;
try {
succeeded = this.document.execCommand("copy");
} catch (error) {
logger.user.warn("Embed modal copy fallback failed.", error);
succeeded = false;
}
if (succeeded) {
this.callbacks.showSuccess("Embed code copied to clipboard!");
} else {
this.callbacks.showError("Unable to copy embed code. Please copy it manually.");
}
this.callbacks.showError("Unable to copy embed code. Please copy it manually.");
}
async open({ video, triggerElement } = {}) {
+1 -4
View File
@@ -1550,11 +1550,8 @@ export default class LoginModalController {
if (!copied && handshakeInput.select) {
try {
handshakeInput.select();
if (this.document?.execCommand) {
copied = this.document.execCommand("copy");
}
} catch (error) {
copied = false;
// no-op
}
}
if (copied) {
+108
View File
@@ -0,0 +1,108 @@
import test from "node:test";
import assert from "node:assert/strict";
// Mock globals
if (!globalThis.window) {
globalThis.window = {
location: { origin: "http://localhost" },
NostrTools: { nip19: { naddrEncode: () => "naddr...", neventEncode: () => "nevent..." } }
};
}
if (!globalThis.document) {
globalThis.document = {
createElement: (tag) => {
return {
tagName: tag.toUpperCase(),
innerHTML: "",
firstChild: null,
querySelector: () => null,
classList: { add: () => {}, remove: () => {}, contains: () => false },
addEventListener: () => {},
setAttribute: () => {},
appendChild: () => {},
disabled: false,
checked: false,
value: ""
};
},
createDocumentFragment: () => ({ appendChild: () => {} }),
getElementById: () => null,
body: { appendChild: () => {} },
execCommand: () => {}
};
}
if (!globalThis.navigator) {
globalThis.navigator = {
userAgent: "node",
};
}
if (!globalThis.navigator.clipboard) {
globalThis.navigator.clipboard = {
writeText: async () => {},
};
}
import { EmbedVideoModal } from "../../../js/ui/components/EmbedVideoModal.js";
test("EmbedVideoModal handleCopy uses navigator.clipboard", async (t) => {
let clipboardText = "";
const originalWriteText = globalThis.navigator.clipboard.writeText;
globalThis.navigator.clipboard.writeText = async (text) => {
clipboardText = text;
};
let successMsg = "";
const callbacks = {
showSuccess: (msg) => { successMsg = msg; },
showError: () => {}
};
const modal = new EmbedVideoModal({ callbacks });
modal.snippetTextarea = { value: "<iframe></iframe>", select: () => {}, setSelectionRange: () => {}, focus: () => {} };
await modal.handleCopy();
assert.equal(clipboardText, "<iframe></iframe>");
assert.equal(successMsg, "Embed code copied to clipboard!");
globalThis.navigator.clipboard.writeText = originalWriteText;
});
test("EmbedVideoModal handleCopy handles clipboard failure without execCommand", async (t) => {
// Simulate clipboard failure
const originalWriteText = globalThis.navigator.clipboard.writeText;
globalThis.navigator.clipboard.writeText = async () => { throw new Error("Clipboard error"); };
let errorMsg = "";
const callbacks = {
showSuccess: () => {},
showError: (msg) => { errorMsg = msg; }
};
// Mock document.execCommand to track calls
let execCommandCalled = false;
const originalExecCommand = globalThis.document.execCommand;
globalThis.document.execCommand = () => { execCommandCalled = true; return false; };
const modal = new EmbedVideoModal({ callbacks });
// Ensure modal uses our mocked document
modal.document = globalThis.document;
let selectCalled = false;
modal.snippetTextarea = {
value: "<iframe></iframe>",
select: () => { selectCalled = true; },
setSelectionRange: () => {},
focus: () => {}
};
await modal.handleCopy();
assert.equal(execCommandCalled, false, "execCommand should not be called");
assert.equal(selectCalled, true, "Text should be selected for manual copy");
assert.ok(errorMsg.toLowerCase().includes("manual"), "Error message should mention manual copy");
// Restore
globalThis.document.execCommand = originalExecCommand;
globalThis.navigator.clipboard.writeText = originalWriteText;
});