[fix] Dimensions.get() should not call change listeners

Fixes a bug introduced by 59af091fdb

Fix #2394
This commit is contained in:
Nicolas Gallagher
2022-11-02 11:26:24 -07:00
parent dee258ae02
commit 0f692f2c2b
2 changed files with 38 additions and 32 deletions
@@ -9,6 +9,8 @@ import Dimensions from '..';
describe('apis/Dimensions', () => { describe('apis/Dimensions', () => {
test('get', () => { test('get', () => {
const handler = jest.fn();
Dimensions.addEventListener('change', handler);
expect(Dimensions.get('screen')).toMatchInlineSnapshot(` expect(Dimensions.get('screen')).toMatchInlineSnapshot(`
{ {
"fontScale": 1, "fontScale": 1,
@@ -25,6 +27,7 @@ describe('apis/Dimensions', () => {
"width": 1024, "width": 1024,
} }
`); `);
expect(handler).toHaveBeenCalledTimes(0);
}); });
test('set', () => { test('set', () => {
@@ -34,21 +37,21 @@ describe('apis/Dimensions', () => {
test('addEventListener', () => { test('addEventListener', () => {
const handler = jest.fn(); const handler = jest.fn();
const subscription = Dimensions.addEventListener('change', handler); const subscription = Dimensions.addEventListener('change', handler);
Dimensions._update(); window.dispatchEvent(new Event('resize'));
expect(handler).toHaveBeenCalledTimes(1); expect(handler).toHaveBeenCalledTimes(1);
expect(handler).toHaveBeenLastCalledWith({ expect(handler).toHaveBeenLastCalledWith({
window: Dimensions.get('window'), window: Dimensions.get('window'),
screen: Dimensions.get('screen') screen: Dimensions.get('screen')
}); });
subscription.remove(); subscription.remove();
Dimensions._update(); window.dispatchEvent(new Event('resize'));
expect(handler).toHaveBeenCalledTimes(1); expect(handler).toHaveBeenCalledTimes(1);
}); });
test('removeEventListener', () => { test('removeEventListener', () => {
const handler = jest.fn(); const handler = jest.fn();
Dimensions.removeEventListener('change', handler); Dimensions.removeEventListener('change', handler);
Dimensions._update(); window.dispatchEvent(new Event('resize'));
expect(handler).toHaveBeenCalledTimes(0); expect(handler).toHaveBeenCalledTimes(0);
}); });
}); });
+32 -29
View File
@@ -46,11 +46,41 @@ const listeners = {};
let shouldInit = canUseDOM; let shouldInit = canUseDOM;
function update() {
if (!canUseDOM) {
return;
}
const win = window;
const docEl = win.document.documentElement;
dimensions.window = {
fontScale: 1,
height: docEl.clientHeight,
scale: win.devicePixelRatio || 1,
width: docEl.clientWidth
};
dimensions.screen = {
fontScale: 1,
height: win.screen.height,
scale: win.devicePixelRatio || 1,
width: win.screen.width
};
}
function handleResize() {
update();
if (Array.isArray(listeners['change'])) {
listeners['change'].forEach((handler) => handler(dimensions));
}
}
export default class Dimensions { export default class Dimensions {
static get(dimension: DimensionKey): DisplayMetrics { static get(dimension: DimensionKey): DisplayMetrics {
if (shouldInit) { if (shouldInit) {
shouldInit = false; shouldInit = false;
Dimensions._update(); update();
} }
invariant(dimensions[dimension], `No dimension set for key ${dimension}`); invariant(dimensions[dimension], `No dimension set for key ${dimension}`);
return dimensions[dimension]; return dimensions[dimension];
@@ -71,33 +101,6 @@ export default class Dimensions {
} }
} }
static _update() {
if (!canUseDOM) {
return;
}
const win = window;
const docEl = win.document.documentElement;
dimensions.window = {
fontScale: 1,
height: docEl.clientHeight,
scale: win.devicePixelRatio || 1,
width: docEl.clientWidth
};
dimensions.screen = {
fontScale: 1,
height: win.screen.height,
scale: win.devicePixelRatio || 1,
width: win.screen.width
};
if (Array.isArray(listeners['change'])) {
listeners['change'].forEach((handler) => handler(dimensions));
}
}
static addEventListener( static addEventListener(
type: DimensionEventListenerType, type: DimensionEventListenerType,
handler: (DimensionsValue) => void handler: (DimensionsValue) => void
@@ -125,5 +128,5 @@ export default class Dimensions {
} }
if (canUseDOM) { if (canUseDOM) {
window.addEventListener('resize', Dimensions._update, false); window.addEventListener('resize', handleResize, false);
} }