70 lines
1.8 KiB
JavaScript
70 lines
1.8 KiB
JavaScript
export function ifstyle(condition, then) {
|
|
return condition ? " " + then : "";
|
|
}
|
|
export function b64e(str) {
|
|
return btoa(
|
|
encodeURIComponent(str).replace(
|
|
/%([0-9A-F]{2})/g,
|
|
function toSolidBytes(match, p1) {
|
|
return String.fromCharCode("0x" + p1);
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
export function b64d(str) {
|
|
return decodeURIComponent(
|
|
atob(str)
|
|
.split("")
|
|
.map(function (c) {
|
|
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
})
|
|
.join("")
|
|
);
|
|
}
|
|
|
|
|
|
/** by claude
|
|
* Universal copy-to-clipboard function
|
|
* Works with modern Clipboard API and falls back to legacy methods
|
|
* @param {string} text - The text to copy to clipboard
|
|
* @returns {Promise<boolean>} - Returns true if successful, false otherwise
|
|
*/
|
|
export async function copyToClipboard(text) {
|
|
// Method 1: Modern Clipboard API (preferred)
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
try {
|
|
await navigator.clipboard.writeText(text);
|
|
return true;
|
|
} catch (err) {
|
|
console.warn('Clipboard API failed, trying fallback:', err);
|
|
}
|
|
}
|
|
|
|
// Method 2: Fallback for older browsers or non-secure contexts
|
|
try {
|
|
const textarea = document.createElement('textarea');
|
|
textarea.value = text;
|
|
|
|
// Make it invisible and non-intrusive
|
|
textarea.style.position = 'fixed';
|
|
textarea.style.left = '-999999px';
|
|
textarea.style.top = '-999999px';
|
|
textarea.style.opacity = '0';
|
|
textarea.setAttribute('readonly', '');
|
|
|
|
document.body.appendChild(textarea);
|
|
|
|
// Select and copy
|
|
textarea.select();
|
|
textarea.setSelectionRange(0, text.length);
|
|
|
|
const success = document.execCommand('copy');
|
|
document.body.removeChild(textarea);
|
|
|
|
return success;
|
|
} catch (err) {
|
|
console.error('All copy methods failed:', err);
|
|
return false;
|
|
}
|
|
} |