UNPKG

photoswipe

Version:
147 lines (128 loc) 3.69 kB
import { specialKeyUsed } from './util/util.js'; /** @typedef {import('./photoswipe.js').default} PhotoSwipe */ /** * @template T * @typedef {import('./types.js').Methods<T>} Methods<T> */ /** * - Manages keyboard shortcuts. * - Heps trap focus within photoswipe. */ class Keyboard { /** * @param {PhotoSwipe} pswp */ constructor(pswp) { this.pswp = pswp; pswp.on('bindEvents', () => { // Dialog was likely opened by keyboard if initial point is not defined if (!pswp.options.initialPointerPos) { // focus causes layout, // which causes lag during the animation, // that's why we delay it until the opener transition ends this._focusRoot(); } pswp.events.add(document, 'focusin', this._onFocusIn.bind(this)); pswp.events.add(document, 'keydown', this._onKeyDown.bind(this)); }); const lastActiveElement = /** @type {HTMLElement} */ (document.activeElement); pswp.on('destroy', () => { if (pswp.options.returnFocus && lastActiveElement && this._wasFocused) { lastActiveElement.focus(); } }); } _focusRoot() { if (!this._wasFocused) { this.pswp.element.focus(); this._wasFocused = true; } } /** * @param {KeyboardEvent} e */ _onKeyDown(e) { const { pswp } = this; if (pswp.dispatch('keydown', { originalEvent: e }).defaultPrevented) { return; } if (specialKeyUsed(e)) { // don't do anything if special key pressed // to prevent from overriding default browser actions // for example, in Chrome on Mac cmd+arrow-left returns to previous page return; } /** @type {Methods<PhotoSwipe>} */ let keydownAction; /** @type {'x' | 'y'} */ let axis; let isForward; switch (e.keyCode) { case 27: // esc if (pswp.options.escKey) { keydownAction = 'close'; } break; case 90: // z key keydownAction = 'toggleZoom'; break; case 37: // left axis = 'x'; break; case 38: // top axis = 'y'; break; case 39: // right axis = 'x'; isForward = true; break; case 40: // bottom isForward = true; axis = 'y'; break; case 9: // tab this._focusRoot(); break; default: } // if left/right/top/bottom key if (axis) { // prevent page scroll e.preventDefault(); const { currSlide } = pswp; if (pswp.options.arrowKeys && axis === 'x' && pswp.getNumItems() > 1) { keydownAction = isForward ? 'next' : 'prev'; } else if (currSlide && currSlide.currZoomLevel > currSlide.zoomLevels.fit) { // up/down arrow keys pan the image vertically // left/right arrow keys pan horizontally. // Unless there is only one image, // or arrowKeys option is disabled currSlide.pan[axis] += isForward ? -80 : 80; currSlide.panTo(currSlide.pan.x, currSlide.pan.y); } } if (keydownAction) { e.preventDefault(); pswp[keydownAction](); } } /** * Trap focus inside photoswipe * * @param {FocusEvent} e */ _onFocusIn(e) { const { template } = this.pswp; if (document !== e.target && template !== e.target && !template.contains(/** @type {Node} */ (e.target))) { // focus root element template.focus(); } } } export default Keyboard;