118 lines
3.6 KiB
JavaScript
118 lines
3.6 KiB
JavaScript
(() => {
|
|
function initTranslator(dialog) {
|
|
const openButton = document.querySelector("[data-translator-open]");
|
|
const swapButton = dialog.querySelector("[data-translator-swap]");
|
|
const submitButton = dialog.querySelector("[data-translator-submit]");
|
|
const input = dialog.querySelector("[data-translator-input]");
|
|
const sourceLabel = dialog.querySelector("[data-translator-source]");
|
|
const targetLabel = dialog.querySelector("[data-translator-target]");
|
|
const phraseButtons = dialog.querySelectorAll("[data-translator-phrase]");
|
|
|
|
if (!openButton || !swapButton || !submitButton || !input || !sourceLabel || !targetLabel) {
|
|
return;
|
|
}
|
|
|
|
let sourceLang = dialog.dataset.sourceLang === "en" ? "en" : "de";
|
|
const labels = {
|
|
de: sourceLang === "de" ? sourceLabel.textContent : targetLabel.textContent,
|
|
en: sourceLang === "en" ? sourceLabel.textContent : targetLabel.textContent,
|
|
};
|
|
|
|
const renderDirection = () => {
|
|
const targetLang = sourceLang === "de" ? "en" : "de";
|
|
sourceLabel.textContent = labels[sourceLang];
|
|
targetLabel.textContent = labels[targetLang];
|
|
};
|
|
|
|
const updateSubmit = () => {
|
|
submitButton.disabled = input.value.trim().length === 0;
|
|
};
|
|
|
|
let isClosing = false;
|
|
|
|
const close = () => {
|
|
if (!dialog.open || isClosing) {
|
|
return;
|
|
}
|
|
isClosing = true;
|
|
dialog.classList.remove("is-opening");
|
|
dialog.classList.add("is-closing");
|
|
|
|
const finishClose = () => {
|
|
if (!dialog.open) {
|
|
return;
|
|
}
|
|
dialog.classList.remove("is-closing");
|
|
dialog.close();
|
|
isClosing = false;
|
|
openButton.focus();
|
|
};
|
|
|
|
dialog.addEventListener("animationend", finishClose, { once: true });
|
|
window.setTimeout(
|
|
finishClose,
|
|
window.matchMedia("(prefers-reduced-motion: reduce)").matches ? 0 : 360,
|
|
);
|
|
};
|
|
|
|
openButton.addEventListener("click", () => {
|
|
dialog.showModal();
|
|
dialog.classList.remove("is-closing");
|
|
dialog.classList.add("is-opening");
|
|
window.requestAnimationFrame(() => input.focus());
|
|
});
|
|
|
|
dialog.addEventListener("click", (event) => {
|
|
if (event.target === dialog) {
|
|
close();
|
|
}
|
|
});
|
|
dialog.addEventListener("cancel", (event) => {
|
|
event.preventDefault();
|
|
close();
|
|
});
|
|
|
|
swapButton.addEventListener("click", () => {
|
|
sourceLang = sourceLang === "de" ? "en" : "de";
|
|
renderDirection();
|
|
phraseButtons.forEach((button) => {
|
|
input.value = input.value === button.dataset.de || input.value === button.dataset.en
|
|
? button.dataset[sourceLang]
|
|
: input.value;
|
|
});
|
|
updateSubmit();
|
|
input.focus();
|
|
});
|
|
|
|
phraseButtons.forEach((button) => {
|
|
button.addEventListener("click", () => {
|
|
input.value = button.dataset[sourceLang] || "";
|
|
updateSubmit();
|
|
input.focus();
|
|
});
|
|
});
|
|
|
|
input.addEventListener("input", updateSubmit);
|
|
submitButton.addEventListener("click", () => {
|
|
const text = input.value.trim();
|
|
if (!text) {
|
|
return;
|
|
}
|
|
const targetLang = sourceLang === "de" ? "en" : "de";
|
|
const url = `https://www.deepl.com/translator#${sourceLang}/${targetLang}/${encodeURIComponent(text)}`;
|
|
window.open(url, "_blank", "noopener,noreferrer");
|
|
close();
|
|
});
|
|
|
|
renderDirection();
|
|
updateSubmit();
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const dialog = document.querySelector("[data-translator-dialog]");
|
|
if (dialog) {
|
|
initTranslator(dialog);
|
|
}
|
|
});
|
|
})();
|