|
122 | 122 | } |
123 | 123 | } |
124 | 124 |
|
| 125 | + function isExportPreviewShellReady(previewWindow, targetUrl) { |
| 126 | + if (!previewWindow || previewWindow.closed) return false; |
| 127 | + try { |
| 128 | + var href = previewWindow.location && previewWindow.location.href; |
| 129 | + if (!href || href === 'about:blank') return false; |
| 130 | + var current = new URL(href, window.location.href); |
| 131 | + var target = new URL(targetUrl, window.location.href); |
| 132 | + if (current.origin !== target.origin || current.pathname !== target.pathname) { |
| 133 | + return false; |
| 134 | + } |
| 135 | + var doc = previewWindow.document; |
| 136 | + return !!(doc && (doc.readyState === 'interactive' || doc.readyState === 'complete')); |
| 137 | + } catch (_) { |
| 138 | + return false; |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + function hasExportPreviewWindowControlApi(previewWindow) { |
| 143 | + if (!previewWindow || previewWindow.closed) return false; |
| 144 | + try { |
| 145 | + var api = previewWindow.nekoWindowControl; |
| 146 | + return !!(api && typeof api.minimize === 'function' && typeof api.maximize === 'function'); |
| 147 | + } catch (_) { |
| 148 | + return false; |
| 149 | + } |
| 150 | + } |
| 151 | + |
| 152 | + function waitForExportPreviewShell(previewWindow, targetUrl, timeoutMs) { |
| 153 | + return new Promise(function (resolve) { |
| 154 | + if (!previewWindow || previewWindow.closed) { |
| 155 | + resolve(false); |
| 156 | + return; |
| 157 | + } |
| 158 | + |
| 159 | + var waitMs = Number(timeoutMs); |
| 160 | + if (!Number.isFinite(waitMs) || waitMs <= 0) waitMs = 1500; |
| 161 | + var settled = false; |
| 162 | + var pollTimer = null; |
| 163 | + var timeoutTimer = null; |
| 164 | + |
| 165 | + function cleanup() { |
| 166 | + if (pollTimer) { |
| 167 | + window.clearInterval(pollTimer); |
| 168 | + pollTimer = null; |
| 169 | + } |
| 170 | + if (timeoutTimer) { |
| 171 | + window.clearTimeout(timeoutTimer); |
| 172 | + timeoutTimer = null; |
| 173 | + } |
| 174 | + try { |
| 175 | + previewWindow.removeEventListener('load', checkReady); |
| 176 | + } catch (_) {} |
| 177 | + } |
| 178 | + |
| 179 | + function finish(ok) { |
| 180 | + if (settled) return; |
| 181 | + settled = true; |
| 182 | + cleanup(); |
| 183 | + resolve(!!ok); |
| 184 | + } |
| 185 | + |
| 186 | + function checkReady() { |
| 187 | + if (!previewWindow || previewWindow.closed) { |
| 188 | + finish(false); |
| 189 | + return; |
| 190 | + } |
| 191 | + if (isExportPreviewShellReady(previewWindow, targetUrl)) { |
| 192 | + finish(true); |
| 193 | + } |
| 194 | + } |
| 195 | + |
| 196 | + try { |
| 197 | + previewWindow.addEventListener('load', checkReady); |
| 198 | + } catch (_) {} |
| 199 | + pollTimer = window.setInterval(checkReady, 40); |
| 200 | + timeoutTimer = window.setTimeout(function () { finish(false); }, waitMs); |
| 201 | + checkReady(); |
| 202 | + }); |
| 203 | + } |
| 204 | + |
| 205 | + async function waitForExportPreviewRewriteGate(previewWindow, targetUrl) { |
| 206 | + var shellReady = await waitForExportPreviewShell(previewWindow, targetUrl, 1500); |
| 207 | + if (shellReady || hasExportPreviewWindowControlApi(previewWindow)) return true; |
| 208 | + shellReady = await waitForExportPreviewShell(previewWindow, targetUrl, 6500); |
| 209 | + return !!(shellReady || hasExportPreviewWindowControlApi(previewWindow)); |
| 210 | + } |
| 211 | + |
125 | 212 | function showToast(key, fallback, duration) { |
126 | 213 | if (typeof window.showStatusToast !== 'function') return; |
127 | 214 | window.showStatusToast(translateLabel(key, fallback), duration || 3000); |
|
2465 | 2552 | if (isExistingWindow) { |
2466 | 2553 | disposePreviewModal(false); |
2467 | 2554 | } |
| 2555 | + state.previewWindow = previewWindow; |
| 2556 | + if (!isExistingWindow) { |
| 2557 | + var canRewritePreview = await waitForExportPreviewRewriteGate(previewWindow, getExportPreviewShellUrl()); |
| 2558 | + if (!previewWindow || previewWindow.closed) return null; |
| 2559 | + if (!canRewritePreview) { |
| 2560 | + if (state.previewWindow === previewWindow) state.previewWindow = null; |
| 2561 | + try { |
| 2562 | + previewWindow.close(); |
| 2563 | + } catch (_) {} |
| 2564 | + return null; |
| 2565 | + } |
| 2566 | + } |
2468 | 2567 | try { |
2469 | 2568 | if (typeof previewWindow.stop === 'function') previewWindow.stop(); |
2470 | 2569 | } catch (_) {} |
2471 | | - state.previewWindow = previewWindow; |
2472 | 2570 | var doc = previewWindow.document; |
2473 | 2571 | doc.open(); |
2474 | 2572 | doc.write('<!DOCTYPE html><html lang="' + escapeHtml(document.documentElement.lang || 'en') + '"' + getPreviewThemeAttributesHtml() + '><head><meta charset="utf-8">' |
|
0 commit comments