mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 16:44:23 +08:00
1 parent
b875b885f1
commit
75995cd8dc
3 files changed
+90
-40
No files matched your search
+14
-10
@@ -653,13 +653,15 @@ const el = {
|
|||||||
statusText: document.querySelector("#statusText"),
|
statusText: document.querySelector("#statusText"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let printDialog = null;
|
function createPrintDialog(tab) {
|
||||||
|
const panel = el.printPanel.cloneNode(true);
|
||||||
function createPrintDialog() {
|
el.printPanel.remove();
|
||||||
|
documentDialogs.register(panel, {shared:false});
|
||||||
return new PrintDialog({
|
return new PrintDialog({
|
||||||
|
panel,
|
||||||
nativeHost,
|
nativeHost,
|
||||||
show: panel => documentDialogs.showApplication(panel),
|
show: panel => documentDialogs.openFor(tab, panel),
|
||||||
download: downloadBytes,
|
download: (bytes, mime, name) => nativeHost ? nativeHost.download(bytes, mime, name) : downloadBytes(bytes, mime, name),
|
||||||
cancel: tab => {
|
cancel: tab => {
|
||||||
for (const [id, request] of wasmRequests) if (request.tab === tab && ["ofdgoPreparePrint", "ofdgoLayoutPrint", "ofdgoPrintSide", "ofdgoPrintPDF"].includes(request.name)) tab.worker?.postMessage({type:"cancel", id});
|
for (const [id, request] of wasmRequests) if (request.tab === tab && ["ofdgoPreparePrint", "ofdgoLayoutPrint", "ofdgoPrintSide", "ofdgoPrintPDF"].includes(request.name)) tab.worker?.postMessage({type:"cancel", id});
|
||||||
},
|
},
|
||||||
@@ -669,8 +671,8 @@ function createPrintDialog() {
|
|||||||
function openPrintPanel() {
|
function openPrintPanel() {
|
||||||
const tab = documentTab();
|
const tab = documentTab();
|
||||||
if (!tab.state.doc || !tab.state.ready || document.body.hasAttribute("data-busy") || formDialogOpen()) return;
|
if (!tab.state.doc || !tab.state.ready || document.body.hasAttribute("data-busy") || formDialogOpen()) return;
|
||||||
printDialog ||= createPrintDialog();
|
tab.print ||= createPrintDialog(tab);
|
||||||
printDialog.open({tab, document:documentEntryKey(tab.state.doc.documents?.[tab.state.doc.documentIndex || 0]), call:(name, ...args) => callTabWASM(tab, name, ...args), page:tab.state.pageIndex,
|
tab.print.open({tab, document:documentEntryKey(tab.state.doc.documents?.[tab.state.doc.documentIndex || 0]), call:(name, ...args) => callTabWASM(tab, name, ...args), page:tab.state.pageIndex,
|
||||||
selection:tab.state.pageSelection.size ? selectedPageIndexes() : [], annotations:tab.state.renderAnnotations,
|
selection:tab.state.pageSelection.size ? selectedPageIndexes() : [], annotations:tab.state.renderAnnotations,
|
||||||
name:tab.state.fileName || tab.state.doc.title || "OFDGo"});
|
name:tab.state.fileName || tab.state.doc.title || "OFDGo"});
|
||||||
}
|
}
|
||||||
@@ -1891,7 +1893,7 @@ function handleKeyDown(event) {
|
|||||||
}
|
}
|
||||||
if (nativeHost && (event.ctrlKey || event.metaKey) && (key === "Tab" || key.toLowerCase() === "w")) {
|
if (nativeHost && (event.ctrlKey || event.metaKey) && (key === "Tab" || key.toLowerCase() === "w")) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (document.body.hasAttribute("data-busy") || formDialogOpen()) return;
|
if (document.body.hasAttribute("data-busy") || formDialogOpen() && !documentTab().print?.context) return;
|
||||||
if (key.toLowerCase() === "w") closeTab(documentTab());
|
if (key.toLowerCase() === "w") closeTab(documentTab());
|
||||||
else {
|
else {
|
||||||
const count = workspace.tabs.length, index = workspace.tabs.indexOf(documentTab());
|
const count = workspace.tabs.length, index = workspace.tabs.indexOf(documentTab());
|
||||||
@@ -2008,7 +2010,7 @@ function handleKeyDown(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formDialogOpen() {
|
function formDialogOpen() {
|
||||||
if (el.printPanel.open) return true;
|
if (documentTab().print?.context) return true;
|
||||||
return Boolean(sealPreview || resourceManager.pick) || el.aboutPanel.open || el.closePanel.open || el.attachmentDialog.open || settingsElements.Panel.open || fontBindingElements.Panel.open || el.signPanel.open || el.verifyPanel.open || el.credentialsPanel.open || el.encryptionPanel.open || batchElements.Panel.open || el.exportPanel.open || el.createPanel.open || el.insertPanel.open || el.pagePanel.open || el.paragraphPanel.open || el.importPanel.open || el.infoPanel.open || el.documentPanel.open
|
return Boolean(sealPreview || resourceManager.pick) || el.aboutPanel.open || el.closePanel.open || el.attachmentDialog.open || settingsElements.Panel.open || fontBindingElements.Panel.open || el.signPanel.open || el.verifyPanel.open || el.credentialsPanel.open || el.encryptionPanel.open || batchElements.Panel.open || el.exportPanel.open || el.createPanel.open || el.insertPanel.open || el.pagePanel.open || el.paragraphPanel.open || el.importPanel.open || el.infoPanel.open || el.documentPanel.open
|
||||||
|| resourceElements.Panel.open || el.structureDialog.open || el.versionPanel.open || el.batchPagesPanel.open || el.objectStylePanel.open || el.outlinePanel.open || el.objectBoundsPanel.open || el.annotationNote.open || el.annotationCreate.open || el.objectPicker.open;
|
|| resourceElements.Panel.open || el.structureDialog.open || el.versionPanel.open || el.batchPagesPanel.open || el.objectStylePanel.open || el.outlinePanel.open || el.objectBoundsPanel.open || el.annotationNote.open || el.annotationCreate.open || el.objectPicker.open;
|
||||||
}
|
}
|
||||||
@@ -2868,6 +2870,8 @@ async function mountDocumentTab(tab) {
|
|||||||
async function releaseDocumentTab(tab) {
|
async function releaseDocumentTab(tab) {
|
||||||
if (tab.closed) return;
|
if (tab.closed) return;
|
||||||
tab.closed = true;
|
tab.closed = true;
|
||||||
|
tab.print?.destroy();
|
||||||
|
tab.print = null;
|
||||||
tab.opening?.controller.abort();
|
tab.opening?.controller.abort();
|
||||||
tab.opening = null;
|
tab.opening = null;
|
||||||
documentDialogs?.release(tab);
|
documentDialogs?.release(tab);
|
||||||
@@ -5043,7 +5047,7 @@ function resizeViewer() {
|
|||||||
async function boot() {
|
async function boot() {
|
||||||
documentDialogs = new DocumentDialogs({document, titlebar: el.documentTitleBar,
|
documentDialogs = new DocumentDialogs({document, titlebar: el.documentTitleBar,
|
||||||
targets: () => [...document.body.children].filter(node => node !== el.documentTitleBar)});
|
targets: () => [...document.body.children].filter(node => node !== el.documentTitleBar)});
|
||||||
for (const panel of document.querySelectorAll("dialog.form-dialog")) documentDialogs.register(panel);
|
for (const panel of document.querySelectorAll("dialog.form-dialog")) if (panel !== el.printPanel) documentDialogs.register(panel);
|
||||||
documentDialogs.setOwner(documentTab());
|
documentDialogs.setOwner(documentTab());
|
||||||
const openSeq = state.openSeq;
|
const openSeq = state.openSeq;
|
||||||
setBusy(true, "正在准备引擎", 8, STATUS.engine);
|
setBusy(true, "正在准备引擎", 8, STATUS.engine);
|
||||||
|
|||||||
+56
-21
@@ -1,7 +1,10 @@
|
|||||||
|
let printQueue = Promise.resolve();
|
||||||
|
|
||||||
export class PrintDialog {
|
export class PrintDialog {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
Object.assign(this, options);
|
Object.assign(this, options);
|
||||||
this.el = Object.fromEntries(["Panel", "Form", "Settings", "Printer", "Properties", "Copies", "Collation", "Duplex", "BackReverse", "BackRotate", "Contents", "Scope", "Range", "Parity", "Reverse", "Mode", "Paper", "Width", "Height", "Orientation", "Scaling", "Scale", "MarginTop", "MarginRight", "MarginBottom", "MarginLeft", "Grid", "PageOrder", "Gap", "Binding", "BookletSheets", "SheetFrom", "SheetTo", "Overlap", "Sides", "Rotate", "Grayscale", "Borders", "CropMarks", "Raster", "DPI", "DPIValue", "TileOnlyLarge", "Labels", "Preview", "Previous", "Next", "PreviewNumber", "PageControl", "PageCount", "Status", "Spinner", "ProgressTrack", "ProgressBar", "Cancel", "Submit"].map(name => [name, document.querySelector(`#print${name}`)]));
|
const panel = this.panel || document.querySelector("#printPanel");
|
||||||
|
this.el = Object.fromEntries(["Panel", "Form", "Settings", "Printer", "Properties", "Copies", "Collation", "Duplex", "BackReverse", "BackRotate", "Contents", "Scope", "Range", "Parity", "Reverse", "Mode", "Paper", "Width", "Height", "Orientation", "Scaling", "Scale", "MarginTop", "MarginRight", "MarginBottom", "MarginLeft", "Grid", "PageOrder", "Gap", "Binding", "BookletSheets", "SheetFrom", "SheetTo", "Overlap", "Sides", "Rotate", "Grayscale", "Borders", "CropMarks", "Raster", "DPI", "DPIValue", "TileOnlyLarge", "Labels", "Preview", "Previous", "Next", "PreviewNumber", "PageControl", "PageCount", "Status", "Spinner", "ProgressTrack", "ProgressBar", "Cancel", "Submit"].map(name => [name, name === "Panel" ? panel : panel.querySelector(`#print${name}`)]));
|
||||||
this.printerOptions = this.el.Printer.innerHTML;
|
this.printerOptions = this.el.Printer.innerHTML;
|
||||||
this.paperOptions = this.el.Paper.innerHTML;
|
this.paperOptions = this.el.Paper.innerHTML;
|
||||||
this.settings = new WeakMap();
|
this.settings = new WeakMap();
|
||||||
@@ -23,18 +26,23 @@ export class PrintDialog {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (!event.repeat) this.el.PreviewNumber.dispatchEvent(new Event("change"));
|
if (!event.repeat) this.el.PreviewNumber.dispatchEvent(new Event("change"));
|
||||||
});
|
});
|
||||||
new ResizeObserver(([entry]) => { this.previewSize = entry.contentRect; this.resize(); }).observe(this.el.Preview);
|
this.observer = new ResizeObserver(([entry]) => { this.previewSize = entry.contentRect; this.resize(); });
|
||||||
window.addEventListener("afterprint", () => { if (this.waiting === "browser") this.finishPrint(); });
|
this.observer.observe(this.el.Preview);
|
||||||
window.addEventListener("beforeprint", () => {
|
this.afterPrint = () => { if (this.waiting === "browser") this.finishPrint("打印窗口已关闭"); };
|
||||||
if (!this.root?.children.length) {
|
this.beforePrint = () => {
|
||||||
this.root ||= this.createRoot();
|
if (!this.context || !this.el.Panel.open) return;
|
||||||
|
const root = document.querySelector("#ofdgoPrintDocument");
|
||||||
|
if (!root?.children.length) {
|
||||||
|
this.root = root || this.createRoot();
|
||||||
this.root.textContent = "请先在OFDGo中打开打印预览,准备完整文档后打印。";
|
this.root.textContent = "请先在OFDGo中打开打印预览,准备完整文档后打印。";
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
window.addEventListener("afterprint", this.afterPrint);
|
||||||
|
window.addEventListener("beforeprint", this.beforePrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
open(context) {
|
open(context) {
|
||||||
if (this.el.Panel.open) return;
|
if (this.context) return;
|
||||||
const saved = this.settings.get(context.tab)?.get(context.document);
|
const saved = this.settings.get(context.tab)?.get(context.document);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.restoring = true;
|
this.restoring = true;
|
||||||
@@ -242,7 +250,11 @@ export class PrintDialog {
|
|||||||
if (!this.current(sequence)) return;
|
if (!this.current(sequence)) return;
|
||||||
const context = this.context;
|
const context = this.context;
|
||||||
try {
|
try {
|
||||||
if (!this.el.Form.reportValidity()) return;
|
if (!this.el.Form.checkValidity()) {
|
||||||
|
if (this.el.Panel.open) this.el.Form.reportValidity();
|
||||||
|
else this.status("请检查打印设置");
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.status("正在准备预览", true);
|
this.status("正在准备预览", true);
|
||||||
const deviceOptions = this.isDevice() ? this.deviceOptions() : null;
|
const deviceOptions = this.isDevice() ? this.deviceOptions() : null;
|
||||||
const profile = deviceOptions ? await this.nativeHost.call("print.query", deviceOptions) : null;
|
const profile = deviceOptions ? await this.nativeHost.call("print.query", deviceOptions) : null;
|
||||||
@@ -267,7 +279,7 @@ export class PrintDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current(sequence = this.sequence) { return this.el.Panel.open && sequence === this.sequence && this.context && !this.context.tab.closed; }
|
current(sequence = this.sequence) { return sequence === this.sequence && this.context && !this.context.tab.closed; }
|
||||||
|
|
||||||
async preview(index) {
|
async preview(index) {
|
||||||
if (!this.layout || this.running) return;
|
if (!this.layout || this.running) return;
|
||||||
@@ -359,8 +371,15 @@ export class PrintDialog {
|
|||||||
const job = this.job;
|
const job = this.job;
|
||||||
this.running = true;
|
this.running = true;
|
||||||
this.controls();
|
this.controls();
|
||||||
|
this.status("正在等待打印", true);
|
||||||
|
const previous = printQueue;
|
||||||
|
let release;
|
||||||
|
printQueue = new Promise(resolve => { release = resolve; });
|
||||||
|
await previous;
|
||||||
|
if (!this.current(sequence)) { release(); return; }
|
||||||
|
this.releasePrint = release;
|
||||||
try {
|
try {
|
||||||
this.root ||= this.createRoot();
|
this.root = document.querySelector("#ofdgoPrintDocument") || this.createRoot();
|
||||||
this.root.replaceChildren();
|
this.root.replaceChildren();
|
||||||
const style = document.createElement("style");
|
const style = document.createElement("style");
|
||||||
this.root.append(style);
|
this.root.append(style);
|
||||||
@@ -382,15 +401,17 @@ export class PrintDialog {
|
|||||||
}
|
}
|
||||||
await document.fonts.ready;
|
await document.fonts.ready;
|
||||||
if (!this.current(sequence)) throw new DOMException("打印已取消", "AbortError");
|
if (!this.current(sequence)) throw new DOMException("打印已取消", "AbortError");
|
||||||
|
if (this.el.Panel.open) {
|
||||||
this.previousTitle = document.title;
|
this.previousTitle = document.title;
|
||||||
document.title = context.name;
|
document.title = this.printTitle = context.name;
|
||||||
|
}
|
||||||
this.waiting = this.nativeHost ? "native" : "browser";
|
this.waiting = this.nativeHost ? "native" : "browser";
|
||||||
this.controls();
|
this.controls();
|
||||||
this.status(job.deviceOptions ? "正在提交打印" : "正在打开打印", true);
|
this.status(job.deviceOptions ? "正在提交打印" : "正在打开打印", true);
|
||||||
if (job.deviceOptions) {
|
if (job.deviceOptions) {
|
||||||
const result = await this.nativeHost.call("print", {...job.deviceOptions, fingerprint:job.fingerprint});
|
const result = await this.nativeHost.call("print", {...job.deviceOptions, fingerprint:job.fingerprint});
|
||||||
|
this.finishPrint(result?.submitted ? "打印已提交" : "打印作业未被接受");
|
||||||
if (this.current(sequence)) {
|
if (this.current(sequence)) {
|
||||||
this.finishPrint();
|
|
||||||
if (!result?.submitted) throw new Error("打印作业未被接受");
|
if (!result?.submitted) throw new Error("打印作业未被接受");
|
||||||
if (job.manual && job.sides === "front") {
|
if (job.manual && job.sides === "front") {
|
||||||
if (job.backContent) { this.el.Sides.value = "back"; this.schedule(); }
|
if (job.backContent) { this.el.Sides.value = "back"; this.schedule(); }
|
||||||
@@ -403,12 +424,12 @@ export class PrintDialog {
|
|||||||
if (!capabilities.systemDialog) throw new Error("当前运行时不支持系统打印");
|
if (!capabilities.systemDialog) throw new Error("当前运行时不支持系统打印");
|
||||||
if (!capabilities.dialogCompletion) this.waiting = "browser";
|
if (!capabilities.dialogCompletion) this.waiting = "browser";
|
||||||
await this.nativeHost.call("print.dialog", {kind:"system"});
|
await this.nativeHost.call("print.dialog", {kind:"system"});
|
||||||
if (this.current(sequence) && capabilities.dialogCompletion) this.finishPrint();
|
if (capabilities.dialogCompletion) this.finishPrint("打印窗口已关闭");
|
||||||
} else if (typeof window.print === "function") window.print();
|
} else if (typeof window.print === "function") window.print();
|
||||||
else throw new Error("当前浏览器不支持打印");
|
else throw new Error("当前浏览器不支持打印");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (this.releasePrint === release) this.finishPrint();
|
||||||
if (this.current(sequence)) {
|
if (this.current(sequence)) {
|
||||||
this.finishPrint();
|
|
||||||
this.status(error.name === "AbortError" ? "打印已取消" : error.message);
|
this.status(error.name === "AbortError" ? "打印已取消" : error.message);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -419,14 +440,20 @@ export class PrintDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finishPrint() {
|
finishPrint(message = "") {
|
||||||
if (this.previousTitle !== undefined) { document.title = this.previousTitle; delete this.previousTitle; }
|
if (this.previousTitle !== undefined) {
|
||||||
this.root?.replaceChildren();
|
if (document.title === this.printTitle) document.title = this.previousTitle;
|
||||||
|
delete this.previousTitle;
|
||||||
|
}
|
||||||
|
if (this.releasePrint) this.root?.replaceChildren();
|
||||||
for (const url of this.urls) URL.revokeObjectURL(url);
|
for (const url of this.urls) URL.revokeObjectURL(url);
|
||||||
this.urls = [];
|
this.urls = [];
|
||||||
this.status();
|
this.releasePrint?.();
|
||||||
|
this.releasePrint = null;
|
||||||
|
this.status(message);
|
||||||
this.waiting = this.running = false;
|
this.waiting = this.running = false;
|
||||||
this.controls();
|
this.controls();
|
||||||
|
if (this.destroyed) window.removeEventListener("afterprint", this.afterPrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
async pdf() {
|
async pdf() {
|
||||||
@@ -439,7 +466,7 @@ export class PrintDialog {
|
|||||||
const result = await context.call("ofdgoPrintPDF");
|
const result = await context.call("ofdgoPrintPDF");
|
||||||
if (this.current(sequence)) {
|
if (this.current(sequence)) {
|
||||||
await this.download(result.bytes, "application/pdf", `${context.name.replace(/\.[^.]+$/, "")}-打印.pdf`);
|
await this.download(result.bytes, "application/pdf", `${context.name.replace(/\.[^.]+$/, "")}-打印.pdf`);
|
||||||
if (this.current(sequence)) this.status();
|
if (this.current(sequence)) this.status("文件已生成");
|
||||||
}
|
}
|
||||||
} catch (error) { if (this.current(sequence)) this.status(error.message); }
|
} catch (error) { if (this.current(sequence)) this.status(error.message); }
|
||||||
finally { if (this.current(sequence)) { this.running = false; this.controls(); } }
|
finally { if (this.current(sequence)) { this.running = false; this.controls(); } }
|
||||||
@@ -451,11 +478,19 @@ export class PrintDialog {
|
|||||||
this.sequence++;
|
this.sequence++;
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
if (context) this.cancel(context.tab);
|
if (context) this.cancel(context.tab);
|
||||||
this.finishPrint();
|
if (!this.waiting) this.finishPrint();
|
||||||
if (this.previewURL) URL.revokeObjectURL(this.previewURL);
|
if (this.previewURL) URL.revokeObjectURL(this.previewURL);
|
||||||
this.previewURL = null;
|
this.previewURL = null;
|
||||||
this.el.Preview.replaceChildren();
|
this.el.Preview.replaceChildren();
|
||||||
this.context = null;
|
this.context = null;
|
||||||
this.queue = this.queue.catch(() => {}).then(() => context?.call("ofdgoDiscardPrint").catch(() => {}));
|
this.queue = this.queue.catch(() => {}).then(() => context?.call("ofdgoDiscardPrint").catch(() => {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.destroyed = true;
|
||||||
|
this.close();
|
||||||
|
this.observer.disconnect();
|
||||||
|
window.removeEventListener("beforeprint", this.beforePrint);
|
||||||
|
if (!this.waiting) window.removeEventListener("afterprint", this.afterPrint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -30,9 +30,9 @@ export class DocumentDialogs {
|
|||||||
root.defaultView.addEventListener("resize", () => this.paint());
|
root.defaultView.addEventListener("resize", () => this.paint());
|
||||||
}
|
}
|
||||||
|
|
||||||
register(panel) {
|
register(panel, { shared = true } = {}) {
|
||||||
if (this.records.has(panel)) return panel;
|
if (this.records.has(panel)) return panel;
|
||||||
const record = { show: panel.show.bind(panel), showModal: panel.showModal.bind(panel), close: panel.close.bind(panel), owner: null, application: false, clicks: new WeakMap(), initial: this.snapshot(panel) };
|
const record = { show: panel.show.bind(panel), showModal: panel.showModal.bind(panel), close: panel.close.bind(panel), owner: null, application: false, shared, clicks: new WeakMap(), initial: shared ? this.snapshot(panel) : null };
|
||||||
this.records.set(panel, record);
|
this.records.set(panel, record);
|
||||||
panel.showModal = panel.show = () => this.openFor(this.owner, panel);
|
panel.showModal = panel.show = () => this.openFor(this.owner, panel);
|
||||||
panel.close = value => {
|
panel.close = value => {
|
||||||
@@ -91,6 +91,7 @@ export class DocumentDialogs {
|
|||||||
this.unpaint();
|
this.unpaint();
|
||||||
this.records.get(panel).owner = tab;
|
this.records.get(panel).owner = tab;
|
||||||
this.prepare(entry, panel);
|
this.prepare(entry, panel);
|
||||||
|
if (!this.records.get(panel).shared) this.document.body.append(panel);
|
||||||
if (!panel.open) this.records.get(panel).show();
|
if (!panel.open) this.records.get(panel).show();
|
||||||
this.paint();
|
this.paint();
|
||||||
this.focus();
|
this.focus();
|
||||||
@@ -124,9 +125,9 @@ export class DocumentDialogs {
|
|||||||
this.unpaint();
|
this.unpaint();
|
||||||
if (value !== undefined) panel.returnValue = String(value);
|
if (value !== undefined) panel.returnValue = String(value);
|
||||||
panel.removeAttribute("open");
|
panel.removeAttribute("open");
|
||||||
entry.snapshot = this.snapshot(panel);
|
if (this.records.get(panel).shared) entry.snapshot = this.snapshot(panel);
|
||||||
}
|
}
|
||||||
const result = value === undefined ? visible ? panel.returnValue : entry.snapshot.returnValue : String(value);
|
const result = value === undefined ? visible ? panel.returnValue : entry.snapshot?.returnValue ?? panel.returnValue : String(value);
|
||||||
state.stack = state.stack.filter(value => value !== panel);
|
state.stack = state.stack.filter(value => value !== panel);
|
||||||
const resolve = entry.resolve;
|
const resolve = entry.resolve;
|
||||||
entry.resolve = entry.promise = null;
|
entry.resolve = entry.promise = null;
|
||||||
@@ -150,7 +151,11 @@ export class DocumentDialogs {
|
|||||||
for (const [panel, entry] of this.current(tab)?.entries || []) {
|
for (const [panel, entry] of this.current(tab)?.entries || []) {
|
||||||
const record = this.records.get(panel);
|
const record = this.records.get(panel);
|
||||||
if (record.application || record.owner !== tab) continue;
|
if (record.application || record.owner !== tab) continue;
|
||||||
entry.snapshot = this.snapshot(panel);
|
if (record.shared) entry.snapshot = this.snapshot(panel);
|
||||||
|
else {
|
||||||
|
entry.focus = panel.contains(this.document.activeElement) ? this.document.activeElement : null;
|
||||||
|
panel.remove();
|
||||||
|
}
|
||||||
panel.removeAttribute("open");
|
panel.removeAttribute("open");
|
||||||
}
|
}
|
||||||
this.owner = null;
|
this.owner = null;
|
||||||
@@ -167,7 +172,8 @@ export class DocumentDialogs {
|
|||||||
for (const [panel, entry] of state.entries) {
|
for (const [panel, entry] of state.entries) {
|
||||||
const record = this.records.get(panel);
|
const record = this.records.get(panel);
|
||||||
if (record.application) continue;
|
if (record.application) continue;
|
||||||
this.applySnapshot(entry.snapshot, panel);
|
if (record.shared) this.applySnapshot(entry.snapshot, panel);
|
||||||
|
else this.document.body.append(panel);
|
||||||
record.owner = tab;
|
record.owner = tab;
|
||||||
}
|
}
|
||||||
for (const [panel, entry] of state.entries) {
|
for (const [panel, entry] of state.entries) {
|
||||||
@@ -193,6 +199,11 @@ export class DocumentDialogs {
|
|||||||
for (const entry of state?.entries.values() || []) entry.resolve?.(null);
|
for (const entry of state?.entries.values() || []) entry.resolve?.(null);
|
||||||
for (const [panel] of state?.entries || []) {
|
for (const [panel] of state?.entries || []) {
|
||||||
const record = this.records.get(panel);
|
const record = this.records.get(panel);
|
||||||
|
if (!record.shared) {
|
||||||
|
panel.remove();
|
||||||
|
this.records.delete(panel);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (record.application || record.owner !== tab) continue;
|
if (record.application || record.owner !== tab) continue;
|
||||||
this.applySnapshot(record.initial, panel);
|
this.applySnapshot(record.initial, panel);
|
||||||
record.owner = null;
|
record.owner = null;
|
||||||
@@ -303,11 +314,11 @@ export class DocumentDialogs {
|
|||||||
focus(restore = false) {
|
focus(restore = false) {
|
||||||
const panel = this.current()?.stack.at(-1);
|
const panel = this.current()?.stack.at(-1);
|
||||||
if (!panel || this.applicationOpen()) return;
|
if (!panel || this.applicationOpen()) return;
|
||||||
const saved = restore ? this.current().entries.get(panel)?.snapshot.focus : null;
|
const saved = restore ? this.current().entries.get(panel)?.snapshot?.focus || this.current().entries.get(panel)?.focus : null;
|
||||||
const target = saved?.isConnected && panel.contains(saved) ? saved : panel.querySelector("[autofocus], button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]") || panel;
|
const target = saved?.isConnected && panel.contains(saved) ? saved : panel.querySelector("[autofocus], button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]") || panel;
|
||||||
if (restore || !panel.contains(this.document.activeElement)) target.focus({ preventScroll: true });
|
if (restore || !panel.contains(this.document.activeElement)) target.focus({ preventScroll: true });
|
||||||
const selection = restore && this.current().entries.get(panel)?.snapshot.selection;
|
const selection = restore && this.current().entries.get(panel)?.snapshot?.selection;
|
||||||
if (selection?.anchor?.isConnected && selection.focus?.isConnected) this.document.getSelection().setBaseAndExtent(selection.anchor, selection.start, selection.focus, selection.end);
|
if (selection?.anchor?.isConnected && selection.focus?.isConnected) this.document.getSelection().setBaseAndExtent(selection.anchor, selection.start, selection.focus, selection.end);
|
||||||
if (restore) for (const item of this.current().entries.get(panel)?.snapshot.nodes || []) { item.node.scrollTop = item.scrollTop; item.node.scrollLeft = item.scrollLeft; }
|
if (restore) for (const item of this.current().entries.get(panel)?.snapshot?.nodes || []) { item.node.scrollTop = item.scrollTop; item.node.scrollLeft = item.scrollLeft; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user