You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

0 lines
5.7 KiB

8 months ago
  1. {"version":3,"file":"focustrap.js","sources":["../../src/util/focustrap.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n}\n\nconst DefaultType = {\n autofocus: 'boolean',\n trapElement: 'element'\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isActive = false\n this._lastTabNavDirection = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return\n }\n\n if (this._config.autofocus) {\n this._config.trapElement.focus()\n }\n\n EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))\n\n this._isActive = true\n }\n\n deactivate() {\n if (!this._isActive) {\n return\n }\n\n this._isActive = false\n EventHandler.off(document, EVENT_KEY)\n }\n\n // Private\n _handleFocusin(event) {\n const { trapElement } = this._config\n\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return\n }\n\n const elements = SelectorEngine.focusableChildren(trapElement)\n\n if (elements.length === 0) {\n trapElement.focus()\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus()\n } else {\n elements[0].focus()\n }\n }\n\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return\n }\n\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n }\n}\n\nexport default FocusTrap\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_FOCUSIN","EVENT_KEYDOWN_TAB","TAB_KEY","TAB_NAV_FORWARD","TAB_NAV_BACKWARD","Default","autofocus","trapElement","DefaultType","FocusTrap","Config","constructor","config","_config","_getConfig","_isActive","_lastTabNavDirection","activate","focus","EventHandler","off","document","on","event","_handleFocusin","_handleKeydown","deactivate","target","contains","elements","SelectorEngine","focusableChildren","length","key","shiftKey"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAMA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,WAAW,CAAA;EACxB,MAAMC,QAAQ,GAAG,cAAc,CAAA;EAC/B,MAAMC,SAAS,GAAI,CAAGD,CAAAA,EAAAA,QAAS,CAAC,CAAA,CAAA;EAChC,MAAME,aAAa,GAAI,CAASD,OAAAA,EAAAA,SAAU,CAAC,CAAA,CAAA;EAC3C,MAAME,iBAAiB,GAAI,CAAaF,WAAAA,EAAAA,SAAU,CAAC,CAAA,CAAA;EAEnD,MAAMG,OAAO,GAAG,KAAK,CAAA;EACrB,MAAMC,eAAe,GAAG,SAAS,CAAA;EACjC,MAAMC,gBAAgB,GAAG,UAAU,CAAA;EAEnC,MAAMC,OAAO,GAAG;EACdC,EAAAA,SAAS,EAAE,IAAI;IACfC,WAAW,EAAE,IAAI;EACnB,CAAC,CAAA;EAED,MAAMC,WAAW,GAAG;EAClBF,EAAAA,SAAS,EAAE,SAAS;EACpBC,EAAAA,WAAW,EAAE,SAAA;EACf,CAAC,CAAA;;EAED;EACA;EACA;;EAEA,MAAME,SAAS,SAASC,MAAM,CAAC;IAC7BC,WAAWA,CAACC,MAAM,EAAE;EAClB,IAAA,KAAK,EAAE,CAAA;MACP,IAAI,CAACC,OAAO,GAAG,IAAI,CAACC,UAAU,CAACF,MAAM,CAAC,CAAA;MACtC,IAAI,CAACG,SAAS,GAAG,KAAK,CAAA;MACtB,IAAI,CAACC,oBAAoB,GAAG,IAAI,CAAA;EAClC,GAAA;;EAEA;IACA,WAAWX,OAAOA,GAAG;EACnB,IAA