fix(keyboard): keyboard events now consistently fire on android (#21741)

fixes #21734
This commit is contained in:
Liam DeBeasi
2020-07-14 10:43:58 -04:00
committed by GitHub
parent 3cbf9e7c4c
commit 020f3cc56c
2 changed files with 14 additions and 54 deletions

View File

@ -5,9 +5,6 @@ const KEYBOARD_THRESHOLD = 150;
let previousVisualViewport: any = {}; let previousVisualViewport: any = {};
let currentVisualViewport: any = {}; let currentVisualViewport: any = {};
let previousLayoutViewport: any = {};
let currentLayoutViewport: any = {};
let keyboardOpen = false; let keyboardOpen = false;
/** /**
@ -16,8 +13,6 @@ let keyboardOpen = false;
export const resetKeyboardAssist = () => { export const resetKeyboardAssist = () => {
previousVisualViewport = {}; previousVisualViewport = {};
currentVisualViewport = {}; currentVisualViewport = {};
previousLayoutViewport = {};
currentLayoutViewport = {};
keyboardOpen = false; keyboardOpen = false;
}; };
@ -27,7 +22,6 @@ export const startKeyboardAssist = (win: Window) => {
if (!(win as any).visualViewport) { return; } if (!(win as any).visualViewport) { return; }
currentVisualViewport = copyVisualViewport((win as any).visualViewport); currentVisualViewport = copyVisualViewport((win as any).visualViewport);
currentLayoutViewport = copyLayoutViewport(win);
(win as any).visualViewport.onresize = () => { (win as any).visualViewport.onresize = () => {
trackViewportChanges(win); trackViewportChanges(win);
@ -67,7 +61,7 @@ export const setKeyboardClose = (win: Window) => {
* of the previous visual viewport height minus the current * of the previous visual viewport height minus the current
* visual viewport height is greater than KEYBOARD_THRESHOLD * visual viewport height is greater than KEYBOARD_THRESHOLD
* *
* We need to be able to accomodate users who have zooming * We need to be able to accommodate users who have zooming
* enabled in their browser (or have zoomed in manually) which * enabled in their browser (or have zoomed in manually) which
* is why we take into account the current visual viewport's * is why we take into account the current visual viewport's
* scale value. * scale value.
@ -77,8 +71,7 @@ export const keyboardDidOpen = (): boolean => {
return ( return (
!keyboardOpen && !keyboardOpen &&
previousVisualViewport.width === currentVisualViewport.width && previousVisualViewport.width === currentVisualViewport.width &&
scaledHeightDifference > KEYBOARD_THRESHOLD && scaledHeightDifference > KEYBOARD_THRESHOLD
!layoutViewportDidChange()
); );
}; };
@ -100,20 +93,6 @@ export const keyboardDidClose = (win: Window): boolean => {
return keyboardOpen && currentVisualViewport.height === win.innerHeight; return keyboardOpen && currentVisualViewport.height === win.innerHeight;
}; };
/**
* Determine if the layout viewport has
* changed since the last visual viewport change.
* It is rare that a layout viewport change is not
* associated with a visual viewport change so we
* want to make sure we don't get any false positives.
*/
const layoutViewportDidChange = (): boolean => {
return (
currentLayoutViewport.width !== previousLayoutViewport.width ||
currentLayoutViewport.height !== previousLayoutViewport.height
);
};
/** /**
* Dispatch a keyboard open event * Dispatch a keyboard open event
*/ */
@ -143,9 +122,6 @@ const fireKeyboardCloseEvent = (win: Window): void => {
export const trackViewportChanges = (win: Window) => { export const trackViewportChanges = (win: Window) => {
previousVisualViewport = { ...currentVisualViewport }; previousVisualViewport = { ...currentVisualViewport };
currentVisualViewport = copyVisualViewport((win as any).visualViewport); currentVisualViewport = copyVisualViewport((win as any).visualViewport);
previousLayoutViewport = { ...currentLayoutViewport };
currentLayoutViewport = copyLayoutViewport(win);
}; };
/** /**
@ -163,14 +139,3 @@ export const copyVisualViewport = (visualViewport: any): any => {
scale: visualViewport.scale scale: visualViewport.scale
}; };
}; };
/**
* Creates a deep copy of the layout viewport
* at a given state
*/
export const copyLayoutViewport = (win: Window): any => {
return {
width: win.innerWidth,
height: win.innerHeight
};
};

View File

@ -1,4 +1,4 @@
import { copyLayoutViewport, copyVisualViewport, setKeyboardClose, setKeyboardOpen, keyboardDidClose, keyboardDidOpen, keyboardDidResize, resetKeyboardAssist, startKeyboardAssist, trackViewportChanges, KEYBOARD_DID_OPEN, KEYBOARD_DID_CLOSE } from '../keyboard'; import { copyVisualViewport, setKeyboardClose, setKeyboardOpen, keyboardDidClose, keyboardDidOpen, keyboardDidResize, resetKeyboardAssist, startKeyboardAssist, trackViewportChanges, KEYBOARD_DID_OPEN, KEYBOARD_DID_CLOSE } from '../keyboard';
const mockVisualViewport = (win: Window, visualViewport: any = { width: 320, height: 568 }, layoutViewport = { innerWidth: 320, innerHeight: 568 }): any => { const mockVisualViewport = (win: Window, visualViewport: any = { width: 320, height: 568 }, layoutViewport = { innerWidth: 320, innerHeight: 568 }): any => {
win.visualViewport = { win.visualViewport = {
@ -32,23 +32,11 @@ const resizeVisualViewport = (win: Window, visualViewport: any = {}) => {
} }
} }
const resizeLayoutViewport = (win: Window, layoutViewport: any = {}) => {
win = Object.assign(win, { innerWidth: layoutViewport.width, innerHeight: layoutViewport.height });
}
describe('Keyboard Assist Tests', () => { describe('Keyboard Assist Tests', () => {
describe('copyLayoutViewport()', () => {
it('should properly copy the layout viewport', () => {
const win = {
innerWidth: 100,
innerHeight: 200
};
const copiedViewport = copyLayoutViewport(win);
win.innerWidth = 400;
win.innerHeight = 800;
expect(copiedViewport.width).toEqual(100);
expect(copiedViewport.height).toEqual(200);
});
});
describe('copyVisualViewport()', () => { describe('copyVisualViewport()', () => {
it('should properly copy the visual viewport', () => { it('should properly copy the visual viewport', () => {
@ -110,6 +98,13 @@ describe('Keyboard Assist Tests', () => {
expect(keyboardDidOpen(window)).toEqual(true); expect(keyboardDidOpen(window)).toEqual(true);
}); });
it('should return true if the layout and visual viewports resize', () => {
resizeLayoutViewport(window, { width: 320, height: 300 });
resizeVisualViewport(window, { width: 320, height: 300 });
expect(keyboardDidOpen(window)).toEqual(true);
});
it('should return false when visual viewport height < layout viewport heigh but does not meet the keyboard threshold', () => { it('should return false when visual viewport height < layout viewport heigh but does not meet the keyboard threshold', () => {
resizeVisualViewport(window, { height: 500 }); resizeVisualViewport(window, { height: 500 });