+
✅ Preview Opened in New Window
+
The translated HTML page has opened in a new window with full AI functionality!
+ ${previewWindow ? "" : '
Note: Please allow popups for preview window
'}
+
+ `;
+ resultArea.style.whiteSpace = "normal";
+ } else {
+ resultArea.textContent = translatedText;
+ resultArea.style.whiteSpace = "pre-wrap";
+ }
+
+ resultContainer.style.display = "block";
+
+ // Complete progress bar
+ clearInterval(progressInterval);
+ progressFill.style.width = "100%";
+ etaText.textContent = "Translation completed!";
+ statusText.textContent = "✅ Ready to preview";
+
+ // Hide progress after a moment
+ setTimeout(() => {
+ if (progressContainer.parentNode) {
+ progressContainer.parentNode.removeChild(progressContainer);
+ }
+ }, 2000);
+
+ // Scroll to result
+ resultContainer.scrollIntoView({ behavior: "smooth", block: "nearest" });
+ } catch (error) {
+ // Clean up progress on error
+ if (typeof progressInterval !== "undefined") {
+ clearInterval(progressInterval);
+ }
+ const progressContainer = document.querySelector(
+ '[style*="border: 2px solid #4CAF50"]',
+ );
+ if (progressContainer && progressContainer.parentNode) {
+ progressContainer.parentNode.removeChild(progressContainer);
+ }
+ alert(`Translation failed: ${error.message}`);
+ } finally {
+ translateButton.textContent = isPageMode
+ ? "🌐 Translate Page"
+ : "🌐 Translate Text";
+ translateButton.disabled = false;
+ }
+ };
+
+ document.body.appendChild(modal);
+
+ // Use showModal() for proper mobile support and backdrop
+ modal.showModal();
+
+ // Close modal when clicking backdrop
+ modal.addEventListener("click", (e) => {
+ if (e.target === modal) {
+ modal.close();
+ document.body.removeChild(modal);
+ }
+ });
+}
diff --git a/src/tts-modal.js b/src/tts-modal.js
new file mode 100644
index 0000000..b9a34b4
--- /dev/null
+++ b/src/tts-modal.js
@@ -0,0 +1,335 @@
+// TTS Modal functionality
+import { initializeChunkFiveFont } from "./ui-themes.js";
+import { getUIText } from "./ui-translations.js";
+import { handleTTS, downloadAudio } from "./tts.js";
+
+// Get USE_CUSTOM_STYLING from window or default
+const USE_CUSTOM_STYLING = window.UNCLOSEAI_CUSTOM_STYLING !== false;
+
+export function openTTSModal() {
+ // Ensure ChunkFive font is loaded
+ initializeChunkFiveFont();
+
+ // Check if Hermes modal is open to set appropriate z-index
+ const hermesModal = document.getElementById("uncloseai-embedded-modal");
+ const zIndex = hermesModal ? "2001" : "1001";
+
+ const modal = document.createElement("dialog");
+ modal.style.zIndex = zIndex;
+ modal.style.position = "fixed";
+
+ if (USE_CUSTOM_STYLING) {
+ modal.style.cssText += `
+ width: 95vw;
+ max-width: 800px;
+ max-height: 95vh;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ padding: 0;
+ overflow: hidden;
+ `;
+ } else {
+ modal.style.cssText += `
+ position: fixed;
+ inset: 0;
+ max-width: 100%;
+ max-height: 100%;
+ height: 100%;
+ width: 100%;
+ border: 0;
+ padding: 0;
+ background: var(--background-color);
+ color: var(--color);
+ `;
+ }
+
+ document.body.appendChild(modal);
+
+ const article = document.createElement("article");
+ if (USE_CUSTOM_STYLING) {
+ article.style.cssText = `
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+ `;
+ }
+
+ const header = document.createElement("header");
+ if (USE_CUSTOM_STYLING) {
+ header.style.cssText = `
+ background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ padding: 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ `;
+ }
+
+ const h1 = document.createElement("h1");
+ h1.innerHTML = `