63 lines
1.9 KiB
JavaScript
63 lines
1.9 KiB
JavaScript
(() => {
|
|
const announce = (component, message) => {
|
|
const status = component.querySelector("[data-share-status]");
|
|
if (!status) return;
|
|
status.textContent = "";
|
|
window.requestAnimationFrame(() => {
|
|
status.textContent = message;
|
|
});
|
|
};
|
|
|
|
const fallbackCopy = (url) => {
|
|
const field = document.createElement("textarea");
|
|
field.value = url;
|
|
field.setAttribute("readonly", "");
|
|
field.style.position = "fixed";
|
|
field.style.opacity = "0";
|
|
document.body.appendChild(field);
|
|
field.select();
|
|
const copied = document.execCommand("copy");
|
|
field.remove();
|
|
return copied;
|
|
};
|
|
|
|
const copyLink = async (component) => {
|
|
const url = component.dataset.shareUrl;
|
|
try {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
await navigator.clipboard.writeText(url);
|
|
} else if (!fallbackCopy(url)) {
|
|
throw new Error("Copy command unavailable");
|
|
}
|
|
announce(component, "Link copied.");
|
|
} catch (_error) {
|
|
window.prompt("Copy this link:", url);
|
|
announce(component, "Copy the link from the dialog.");
|
|
}
|
|
};
|
|
|
|
document.querySelectorAll("[data-share-component]").forEach((component) => {
|
|
component.querySelector("[data-share-native]")?.addEventListener("click", async (event) => {
|
|
event.preventDefault();
|
|
if (!navigator.share) {
|
|
await copyLink(component);
|
|
return;
|
|
}
|
|
try {
|
|
await navigator.share({
|
|
title: component.dataset.shareTitle,
|
|
text: component.dataset.shareDescription,
|
|
url: component.dataset.shareUrl,
|
|
});
|
|
} catch (error) {
|
|
if (error.name !== "AbortError") await copyLink(component);
|
|
}
|
|
});
|
|
|
|
component.querySelector("[data-share-copy]")?.addEventListener("click", async (event) => {
|
|
event.preventDefault();
|
|
await copyLink(component);
|
|
});
|
|
});
|
|
})();
|