Skip to content

Commit 84f5328

Browse files
authored
fix(flame): failure when accessing visualViewport.visualViewport from within iFrame (#2502)
1 parent a6f98c3 commit 84f5328

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

packages/charts/src/chart_types/flame_chart/flame_chart.tsx

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ const NODE_TWEEN_DURATION_MS = 500;
6363
const unitRowPitch = (position: Float32Array) => (position.length >= 4 ? (position[1] ?? 0) - (position[3] ?? 0) : 1);
6464
const initialPixelRowPitch = () => 16;
6565
const specValueFormatter = (d: number) => d; // fixme use the formatter from the spec
66+
67+
/**
68+
* Returns top-level `window` when inside iframe
69+
*/
6670
const browserRootWindow = () => {
67-
let rootWindow = window; // we might be in an iframe, and visualViewport.scale is toplevel only
71+
let rootWindow = window;
6872
while (window.parent && window.parent.window !== rootWindow) rootWindow = rootWindow.parent.window;
6973
return rootWindow;
7074
};
@@ -182,7 +186,7 @@ class FlameComponent extends React.Component<FlameProps> {
182186

183187
// native browser pinch zoom handling
184188
private pinchZoomSetInterval: number = NaN;
185-
private pinchZoomScale: number;
189+
private pinchZoomScale: number = 1;
186190

187191
// mouse coordinates for the tooltip
188192
private pointerX: number = NaN;
@@ -258,8 +262,6 @@ class FlameComponent extends React.Component<FlameProps> {
258262
this.navigator = new NavButtonControlledZoomPanHistory({ ...this.getFocusOnRoot(), index: 0 });
259263

260264
// browser pinch zoom handling
261-
this.pinchZoomSetInterval = NaN;
262-
this.pinchZoomScale = browserRootWindow().visualViewport?.scale ?? 1;
263265
this.setupViewportScaleChangeListener();
264266

265267
// search
@@ -370,15 +372,26 @@ class FlameComponent extends React.Component<FlameProps> {
370372
);
371373
};
372374

375+
/**
376+
* Setup interval to update pinch zoom scale factor
377+
*/
373378
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);
380391
}
381-
}, PINCH_ZOOM_CHECK_INTERVAL_MS);
392+
} catch {
393+
// unable to access `window.visualViewport`
394+
}
382395
};
383396

384397
componentDidMount = () => {

0 commit comments

Comments
 (0)