UNPKG

on-screen-keyboard-detector

Version:

Detects presence of the On-Screen-Keyboard in mobile browsers

126 lines (96 loc) 4.75 kB
[![NPM Version](https://img.shields.io/npm/v/on-screen-keyboard-detector.svg?style=flat-square)](https://www.npmjs.com/package/on-screen-keyboard-detector) [![Dependencies](https://img.shields.io/david/semmel/on-screen-keyboard-detector.svg?style=flat-square)](https://david-dm.org/semmel/on-screen-keyboard-detector) [![Reactive Programming](https://img.shields.io/badge/code%20style-reactive%2C%20functional-blue?color=b7178c)](http://reactivex.io) On-screen keyboard detector ============================= > Indirect detection of the presence of the on-screen keyboard (OSK) shown by mobile browsers when the user interacts with input controls on a webpage. Background ---------- This approach employs the browsers layout and visual viewports ([Explainer][5], [MDN][1], [Demo][2]) to observe the appearance of the virtual keyboard. Simplified, since it's introduction - *Mobile Safari* excludes the keyboard from the visual viewport, while - *Chrome for Android* the keyboard is excluded from both the visual and the layout viewport. ![Browser Viewports](./doc/browser_viewports.png) *Chrome's* behaviour makes it necessary to also observe `focusin`, `focusout`, `resize` and `visibilitychange` events. Limitations ------ The indirect detection relying on viewport and window DOM events brings some limitations: - `hidden` and `visible` events are dispatched with a approximate 1 second delay. - On *Chrome for Android* the keyboard must be *initially hidden* when subscribing to the detector. - On *iOS* requires *Safari* v. ≥ 13 - On iPad the predictive text bar, which is shown when an *external keyboard* is used, is *not* detected as `visible` keyboard. ![iPad Predictive Text Bar](./doc/predictive-text-bar-ipad.png) Because of these caveats, the straight-forward way of detecting `blur` and `focus` events on inputs should be explored before falling back on this project. Install ------- `npm install on-screen-keyboard-detector` Usage ----- ### Basic ```javascript import { subscribe, isSupported } from 'on-screen-keyboard-detector'; if (isSupported()) { const unsubscribe = subscribe(visibility => { if (visibility === "hidden") { // ... } else { // visibility === "visible" // ... } }); // After calling unsubscribe() the callback will no longer be invoked. unsubscribe(); } ``` API --- ### subscribe(listenerCallback): unsubscribe Begins to observe browser events and invokes the provided callback function when a change in the keyboard visibility is detected. | Parameter | Type | Description | |-----------|------|-------------| | callback |`function(String)`| user-defined handler which receives the keyboard visibility changes | #### Return value `function(): void` : Unsubscribes to receive updates ### isSupported() Returns `true` if the browser runtime supports oskd. Advanced Usage -------------- ### Multiple Subscriptions (PubSub) PubSub is not part of this module and needs additional tools, e.g. [emittery][3]. See [`demo/pubsub.html`](./demo/pubsub.html) ```javascript import {subscribe} from 'on-screen-keyboard-detector'; import Emitter from 'emittery'; const emitter = new Emitter(); subscribe(visibility => emitter.emit(visibility)); emitter.on('hidden', function() { /* ... */ }); emitter.on('visible', function() { /* ... */ }); ``` Tests ----- #### Requirements (not listed in `package.json`) - mocha :coffee: - chai :tea: - selenium-webdriver - a Mac for Mobile Safari tests - running a local webserver (see `TEST_SERVER` in `package.json`), E.g. run [http-server](https://github.com/http-party/http-server) in the project root folder `http-server . --port 8081` ### Android For real devices make sure - the adb server is running (`adb start-server`), and - a device is connected via USB or Wifi (`adb devices -l`) - ggf. `adb tcpip 5555` and `adb connect <test phone ip address>` (see `"setup_test"` in `package.json`) Then run `npm run test:chrome`. ### iOS Connect a device where `Remote Automatation` is enabled for Safari (see the [Webkit blog][4]). Then run `npm run test:ios` **iOS tests should be performed manually (see the [demo](./demo) folder), because Webdriver controlled Mobile Safari does not show the virtual keyboard** Dependencies ----------- [Ramda](https://ramdajs.com), and [Most](https://github.com/mostjs/core) for the reactive functional infrastructure. Changelog (See changelog.md) --------- [1]: https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API [2]: http://bokand.github.io/viewport/index.html [3]: https://github.com/sindresorhus/emittery [4]: https://webkit.org/blog/9395/webdriver-is-coming-to-safari-in-ios-13/ [5]: https://github.com/bokand/bokand.github.io/blob/master/web_viewports_explainer.md