mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 18:54:11 +08:00
fix(keyboard): keyboard events now consistently fire on android (#21741)
fixes #21734
This commit is contained in:
@ -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
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
@ -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 });
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user