translate: add open-in-tab button, move controls above preview, fix blob lifetime
This commit is contained in:
parent
bd30ee1fab
commit
21edbe7d81
3 changed files with 67 additions and 21 deletions
|
|
@ -518,12 +518,20 @@ ${samplePreserved}`;
|
|||
htmlWithBase = `<!DOCTYPE html>\n<html><head><base href="${baseUrl}">${scriptTag}</head><body>${translatedText}</body></html>`;
|
||||
}
|
||||
|
||||
// Revoke any blob URL kept alive from a previous translation
|
||||
if (resultArea._translateBlobUrl) {
|
||||
URL.revokeObjectURL(resultArea._translateBlobUrl);
|
||||
}
|
||||
|
||||
// Render inline via iframe with blob URL (no popup)
|
||||
const blob = new Blob([htmlWithBase], { type: "text/html" });
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
|
||||
resultArea.innerHTML = "";
|
||||
resultArea.className = "translate-result-area";
|
||||
// Keep the blob URL alive so the iframe and the
|
||||
// open-in-tab link both stay valid until the next render.
|
||||
resultArea._translateBlobUrl = blobUrl;
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = blobUrl;
|
||||
|
|
@ -542,36 +550,46 @@ ${samplePreserved}`;
|
|||
}
|
||||
iframe.title = iframeTitle;
|
||||
|
||||
// Clean up blob URL when iframe loads
|
||||
iframe.addEventListener("load", () => URL.revokeObjectURL(blobUrl));
|
||||
// Controls bar above the preview
|
||||
const controls = document.createElement("div");
|
||||
controls.className = "translate-result-controls";
|
||||
|
||||
const toggleContainer = document.createElement("div");
|
||||
toggleContainer.style.marginBottom = "12px";
|
||||
|
||||
const toggleBtn = document.createElement("button");
|
||||
toggleBtn.className = "translate-raw-toggle-btn";
|
||||
toggleBtn.textContent = "Show Raw HTML";
|
||||
toggleBtn.onclick = () => {
|
||||
const raw = toggleContainer.querySelector(".translate-raw-html");
|
||||
if (raw.style.display === "none") {
|
||||
raw.style.display = "block";
|
||||
toggleBtn.textContent = "Hide Raw HTML";
|
||||
} else {
|
||||
raw.style.display = "none";
|
||||
toggleBtn.textContent = "Show Raw HTML";
|
||||
}
|
||||
};
|
||||
// Open the translated page in a real browser tab. A user
|
||||
// click on an anchor is a genuine gesture, so it is not
|
||||
// blocked like the automatic window.open popups we replaced.
|
||||
const openTabLink = document.createElement("a");
|
||||
openTabLink.className =
|
||||
"translate-raw-toggle-btn translate-open-tab-btn";
|
||||
openTabLink.href = blobUrl;
|
||||
openTabLink.target = "_blank";
|
||||
openTabLink.rel = "noopener";
|
||||
openTabLink.textContent = "Open full page ↗";
|
||||
openTabLink.title = iframeTitle;
|
||||
|
||||
const rawHtml = document.createElement("div");
|
||||
rawHtml.className = "translate-raw-html";
|
||||
rawHtml.style.display = "none";
|
||||
rawHtml.textContent = translatedText;
|
||||
|
||||
toggleContainer.appendChild(toggleBtn);
|
||||
toggleContainer.appendChild(rawHtml);
|
||||
const toggleBtn = document.createElement("button");
|
||||
toggleBtn.className = "translate-raw-toggle-btn";
|
||||
toggleBtn.textContent = "Show Raw HTML";
|
||||
toggleBtn.onclick = () => {
|
||||
if (rawHtml.style.display === "none") {
|
||||
rawHtml.style.display = "block";
|
||||
toggleBtn.textContent = "Hide Raw HTML";
|
||||
} else {
|
||||
rawHtml.style.display = "none";
|
||||
toggleBtn.textContent = "Show Raw HTML";
|
||||
}
|
||||
};
|
||||
|
||||
controls.appendChild(openTabLink);
|
||||
controls.appendChild(toggleBtn);
|
||||
|
||||
resultArea.appendChild(controls);
|
||||
resultArea.appendChild(iframe);
|
||||
resultArea.appendChild(toggleContainer);
|
||||
resultArea.appendChild(rawHtml);
|
||||
} else {
|
||||
resultArea.textContent = translatedText;
|
||||
resultArea.className = "translate-result-area pre-wrap";
|
||||
|
|
|
|||
|
|
@ -451,6 +451,20 @@ dialog#translate-modal > article > .translate-btn {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.translate-result-controls {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: start;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.translate-open-tab-btn {
|
||||
background: #0b7285;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.translate-result-area {
|
||||
white-space: normal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -500,6 +500,20 @@ dialog#translate-modal > article > .translate-btn {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.translate-result-controls {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: start;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.translate-open-tab-btn {
|
||||
background: #0b7285;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.translate-result-area {
|
||||
white-space: normal;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue