stitch2 0.24.3 → 0.24.4

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.
Files changed (2) hide show
  1. package/dist/canvas.html +33 -1
  2. package/package.json +1 -1
package/dist/canvas.html CHANGED
@@ -654,6 +654,33 @@ function measure(f) {
654
654
  }
655
655
 
656
656
  const minHeight = (s) => (bigFrame(s) ? 800 : 844)
657
+ /** Whether two addresses are the same page: the same place, whatever their query or hash say. */
658
+ function samePage(a, b) {
659
+ try { const x = new URL(a), y = new URL(b); return x.origin === y.origin && x.pathname === y.pathname } catch { return false }
660
+ }
661
+ /**
662
+ * A page keeps growing after it loads: a table fetches its rows, an image arrives, a font swaps in. The measurements at load and in the first
663
+ * seconds catch what is there by then; this watches the page itself, so the frame is as tall as its page whenever the page changes size. The
664
+ * observer belongs to the loaded document and is replaced when the page reloads.
665
+ */
666
+ function watchSize(f, iframe) {
667
+ f.sizeWatch?.disconnect()
668
+ f.sizeWatch = null
669
+ try {
670
+ const doc = iframe.contentDocument
671
+ const Observer = iframe.contentWindow?.ResizeObserver
672
+ if (!doc || !Observer) return
673
+ let queued
674
+ const watch = new Observer(() => {
675
+ clearTimeout(queued)
676
+ // Wait for the page to settle: a table draws many rows in a few frames, and one measure after them is enough.
677
+ queued = setTimeout(() => { if (f.sizeWatch === watch && f.iframe === iframe) measure(f) }, 80)
678
+ })
679
+ watch.observe(doc.documentElement)
680
+ if (doc.body) watch.observe(doc.body)
681
+ f.sizeWatch = watch
682
+ } catch {}
683
+ }
657
684
  function setHeight(f, h) {
658
685
  h = Math.min(MAX_FRAME_HEIGHT, Math.max(minHeight(f.screen), h))
659
686
  HEIGHTS[`${f.screen.path}@${f.screen.width}`] = h
@@ -712,7 +739,9 @@ function mount(f) {
712
739
  // `load` also fires for the initial about:blank document. Compare the
713
740
  // loaded document itself with the current iframe target (which may have
714
741
  // changed for a language/theme reload while this mount was pending).
715
- return f.iframe === iframe && iframe.contentDocument === doc && doc.readyState === 'complete' && doc.location.href === iframe.src
742
+ // The address is compared without its query: a page may rewrite its own
743
+ // (a table that keeps its state there), and that is still the same page.
744
+ return f.iframe === iframe && iframe.contentDocument === doc && doc.readyState === 'complete' && samePage(doc.location.href, iframe.src)
716
745
  }
717
746
  iframe.addEventListener('load', () => {
718
747
  if (f.iframe !== iframe) return
@@ -731,6 +760,7 @@ function mount(f) {
731
760
  }, 350)
732
761
  setTimeout(() => { if (f.iframe === iframe) measure(f) }, 1200)
733
762
  setTimeout(() => { if (f.iframe === iframe) measure(f) }, 2500)
763
+ watchSize(f, iframe)
734
764
  })()
735
765
  })
736
766
  iframe.src = frameSrc(f.screen)
@@ -739,6 +769,8 @@ function mount(f) {
739
769
  function unmount(f) {
740
770
  if (!f.iframe) return
741
771
  clearTimeout(f.reveal)
772
+ f.sizeWatch?.disconnect()
773
+ f.sizeWatch = null
742
774
  // Cleared first: a page still loading can fire its load event as it's removed.
743
775
  const iframe = f.iframe
744
776
  f.iframe = null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitch2",
3
- "version": "0.24.3",
3
+ "version": "0.24.4",
4
4
  "description": "A design canvas, layout and type checks, component consistency and screen versioning for agent-built UI, on Google's DESIGN.md format.",
5
5
  "license": "MIT",
6
6
  "author": "ifokeev",