stitch2 0.22.6 → 0.22.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas.html +36 -13
- package/package.json +1 -1
package/dist/canvas.html
CHANGED
|
@@ -300,9 +300,13 @@ let reports = { consistency: null, compare: null, states: null }
|
|
|
300
300
|
let selected = null
|
|
301
301
|
const frames = new Map() // path -> { el, device, img, iframe (while live), screen, height }
|
|
302
302
|
// Heights measured before, so the layout doesn't jump while pictures and pages load.
|
|
303
|
-
|
|
303
|
+
// Height semantics changed when live frames began loading at their authored
|
|
304
|
+
// viewport. Do not carry a pre-fix cache into this layout: one stale 20k page
|
|
305
|
+
// is enough to create a giant gap before its iframe is visited.
|
|
306
|
+
const HEIGHT_KEY = 'stitch2-heights-v3'
|
|
307
|
+
const HEIGHTS = JSON.parse(localStorage.getItem(HEIGHT_KEY) ?? '{}')
|
|
304
308
|
let heightsTimer
|
|
305
|
-
const saveHeights = () => { clearTimeout(heightsTimer); heightsTimer = setTimeout(() => localStorage.setItem(
|
|
309
|
+
const saveHeights = () => { clearTimeout(heightsTimer); heightsTimer = setTimeout(() => localStorage.setItem(HEIGHT_KEY, JSON.stringify(HEIGHTS)), 1000) }
|
|
306
310
|
let layoutQueued = false
|
|
307
311
|
/** Many frames measure themselves at once while loading: one layout per animation frame. */
|
|
308
312
|
const scheduleLayout = () => { if (!layoutQueued) { layoutQueued = true; requestAnimationFrame(() => { layoutQueued = false; layout() }) } }
|
|
@@ -630,21 +634,40 @@ function mount(f) {
|
|
|
630
634
|
const iframe = document.createElement('iframe')
|
|
631
635
|
iframe.setAttribute('scrolling', 'no')
|
|
632
636
|
f.iframe = iframe
|
|
637
|
+
// A remounted frame can still have a cached full-page height. Start the
|
|
638
|
+
// document at its authored viewport so vh/svh/dvh rules are evaluated
|
|
639
|
+
// against the screen, not against the previous page height.
|
|
633
640
|
size(f)
|
|
641
|
+
iframe.style.height = `${f.screen.viewportHeight ?? 844}px`
|
|
642
|
+
const waitForStyles = async () => {
|
|
643
|
+
const doc = iframe.contentDocument
|
|
644
|
+
if (!doc || doc.readyState !== 'complete') return false
|
|
645
|
+
try { await doc.fonts?.ready } catch {}
|
|
646
|
+
// Browser-built Tailwind and late stylesheet links can settle just after
|
|
647
|
+
// load. Do not measure or reveal the live page until that layout pass.
|
|
648
|
+
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)))
|
|
649
|
+
// `load` also fires for the initial about:blank document. Compare the
|
|
650
|
+
// loaded document itself with the current iframe target (which may have
|
|
651
|
+
// changed for a language/theme reload while this mount was pending).
|
|
652
|
+
return f.iframe === iframe && iframe.contentDocument === doc && doc.readyState === 'complete' && doc.location.href === iframe.src
|
|
653
|
+
}
|
|
634
654
|
iframe.addEventListener('load', () => {
|
|
635
655
|
if (f.iframe !== iframe) return
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
// Tailwind's browser build and the components settle just after load: the picture stays until then.
|
|
640
|
-
f.reveal = setTimeout(() => {
|
|
641
|
-
if (f.iframe !== iframe) return
|
|
656
|
+
void (async () => {
|
|
657
|
+
if (!(await waitForStyles()) || f.iframe !== iframe) return
|
|
658
|
+
applyTheme(f)
|
|
642
659
|
measure(f)
|
|
643
|
-
f.
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
660
|
+
clearTimeout(f.reveal)
|
|
661
|
+
// The picture stays until the complete, styled page has been measured.
|
|
662
|
+
f.reveal = setTimeout(() => {
|
|
663
|
+
if (f.iframe !== iframe) return
|
|
664
|
+
measure(f)
|
|
665
|
+
f.el.classList.add('ready')
|
|
666
|
+
for (const go of f.waiters.splice(0)) go()
|
|
667
|
+
}, 350)
|
|
668
|
+
setTimeout(() => { if (f.iframe === iframe) measure(f) }, 1200)
|
|
669
|
+
setTimeout(() => { if (f.iframe === iframe) measure(f) }, 2500)
|
|
670
|
+
})()
|
|
648
671
|
})
|
|
649
672
|
iframe.src = frameSrc(f.screen)
|
|
650
673
|
f.device.insertBefore(iframe, f.img.nextSibling)
|
package/package.json
CHANGED