@@ -63,8 +63,12 @@ const NODE_TWEEN_DURATION_MS = 500;
63
63
const unitRowPitch = ( position : Float32Array ) => ( position . length >= 4 ? ( position [ 1 ] ?? 0 ) - ( position [ 3 ] ?? 0 ) : 1 ) ;
64
64
const initialPixelRowPitch = ( ) => 16 ;
65
65
const specValueFormatter = ( d : number ) => d ; // fixme use the formatter from the spec
66
+
67
+ /**
68
+ * Returns top-level `window` when inside iframe
69
+ */
66
70
const browserRootWindow = ( ) => {
67
- let rootWindow = window ; // we might be in an iframe, and visualViewport.scale is toplevel only
71
+ let rootWindow = window ;
68
72
while ( window . parent && window . parent . window !== rootWindow ) rootWindow = rootWindow . parent . window ;
69
73
return rootWindow ;
70
74
} ;
@@ -182,7 +186,7 @@ class FlameComponent extends React.Component<FlameProps> {
182
186
183
187
// native browser pinch zoom handling
184
188
private pinchZoomSetInterval : number = NaN ;
185
- private pinchZoomScale : number ;
189
+ private pinchZoomScale : number = 1 ;
186
190
187
191
// mouse coordinates for the tooltip
188
192
private pointerX : number = NaN ;
@@ -258,8 +262,6 @@ class FlameComponent extends React.Component<FlameProps> {
258
262
this . navigator = new NavButtonControlledZoomPanHistory ( { ...this . getFocusOnRoot ( ) , index : 0 } ) ;
259
263
260
264
// browser pinch zoom handling
261
- this . pinchZoomSetInterval = NaN ;
262
- this . pinchZoomScale = browserRootWindow ( ) . visualViewport ?. scale ?? 1 ;
263
265
this . setupViewportScaleChangeListener ( ) ;
264
266
265
267
// search
@@ -370,15 +372,26 @@ class FlameComponent extends React.Component<FlameProps> {
370
372
) ;
371
373
} ;
372
374
375
+ /**
376
+ * Setup interval to update pinch zoom scale factor
377
+ */
373
378
private setupViewportScaleChangeListener = ( ) => {
374
- window . clearInterval ( this . pinchZoomSetInterval ) ;
375
- this . pinchZoomSetInterval = window . setInterval ( ( ) => {
376
- const pinchZoomScale = browserRootWindow ( ) . visualViewport ?. scale ?? 1 ; // not cached, to avoid holding a reference to a `window` object
377
- if ( pinchZoomScale !== this . pinchZoomScale ) {
378
- this . pinchZoomScale = pinchZoomScale ;
379
- this . setState ( { } ) ;
379
+ try {
380
+ // if in an iframe we need the top-level `visualViewport`
381
+ if ( browserRootWindow ( ) . visualViewport ) {
382
+ // Only setup listener if access to `visualViewport` is allowed
383
+ window . clearInterval ( this . pinchZoomSetInterval ) ;
384
+ this . pinchZoomSetInterval = window . setInterval ( ( ) => {
385
+ const pinchZoomScale = browserRootWindow ( ) . visualViewport ?. scale ?? 1 ;
386
+ if ( pinchZoomScale !== this . pinchZoomScale ) {
387
+ this . pinchZoomScale = pinchZoomScale ;
388
+ this . setState ( { } ) ;
389
+ }
390
+ } , PINCH_ZOOM_CHECK_INTERVAL_MS ) ;
380
391
}
381
- } , PINCH_ZOOM_CHECK_INTERVAL_MS ) ;
392
+ } catch {
393
+ // unable to access `window.visualViewport`
394
+ }
382
395
} ;
383
396
384
397
componentDidMount = ( ) => {
0 commit comments