1 line
8 KiB
Plaintext
1 line
8 KiB
Plaintext
{"version":3,"sources":["webpack:///./node_modules/arrow-key-navigation/dist-web/index.js"],"names":["focusablesQuery","textInputTypes","checkboxRadioInputTypes","focusTrapTest","undefined","getFocusableElements","activeElement","res","elements","element","parent","parentElement","getFocusTrapParent","document","querySelectorAll","len","length","i","disabled","test","getAttribute","hasAttribute","offsetWidth","offsetHeight","push","focusNextOrPrevious","event","key","selectionStart","selectionEnd","tagName","isTextarea","isTextInput","indexOf","toLowerCase","isContentEditable","selection","getSelection","anchorOffset","focusOffset","textContent","value","shouldIgnoreEvent","focusableElements","index","focus","preventDefault","keyListener","altKey","metaKey","ctrlKey","click","handleEnter","register","addEventListener","unregister","removeEventListener","setFocusTrapTest"],"mappings":"0FAAA,4IAQA,IAAIA,EAAkB,wJAKlBC,EAAiB,CAAC,OAAQ,SAAU,MAAO,WAAY,OACvDC,EAA0B,CAAC,WAAY,SACvCC,OAAgBC,EAEpB,SAASC,EAAqBC,GAQ5B,IANA,IAEIC,EAAM,GACNC,GAeN,SAA4BC,GAC1B,IAAKN,EACH,OAGF,IAAIO,EAASD,EAAQE,cAErB,KAAOD,GAAQ,CACb,GAAIP,EAAcO,GAChB,OAAOA,EAGTA,EAASA,EAAOC,eA9BCC,CAAmBN,IACXO,UAEPC,iBAAiBd,GACjCe,EAAMP,EAASQ,OAEVC,EAAI,EAAGA,EAAIF,EAAKE,IAAK,CAC5B,IAAIR,EAAUD,EAASS,GAEnBR,IAAYH,IAAkBG,EAAQS,UAAa,KAAKC,KAAKV,EAAQW,aAAa,aAAe,KAAQX,EAAQY,aAAa,YAClIZ,EAAQa,YAAc,GAAKb,EAAQc,aAAe,KAChDhB,EAAIiB,KAAKf,GAIb,OAAOF,EAuDT,SAASkB,EAAoBC,EAAOC,GAClC,IAAIrB,EAAgBO,SAASP,cAE7B,IAvCF,SAA2BA,EAAeqB,GACxC,IASIC,EACAC,EACAd,EAXAe,EAAUxB,EAAcwB,QACxBC,EAAyB,aAAZD,EACbE,EAA0B,UAAZF,IAAqG,IAA9E7B,EAAegC,QAAQ3B,EAAcc,aAAa,QAAQc,eAC/FC,EAAoB7B,EAAce,aAAa,mBAEnD,IAAKU,IAAeC,IAAgBG,EAClC,OAAO,EAOT,GAAIA,EAAmB,CACrB,IAAIC,EAAYC,eAChBT,EAAiBQ,EAAUE,aAC3BT,EAAeO,EAAUG,YACzBxB,EAAMT,EAAckC,YAAYxB,YAEhCY,EAAiBtB,EAAcsB,eAC/BC,EAAevB,EAAcuB,aAC7Bd,EAAMT,EAAcmC,MAAMzB,OAK5B,OAAY,cAARW,GAAuBC,IAAmBC,GAAmC,IAAnBD,KAE3C,eAARD,GAAwBC,IAAmBC,GAAgBD,IAAmBb,GAUrF2B,CAAkBpC,EAAeqB,GAArC,CAIA,IAAIgB,EAAoBtC,EAAqBC,GAE7C,GAAKqC,EAAkB3B,OAAvB,CAIA,IAAI4B,EAAQD,EAAkBV,QAAQ3B,IAG1B,cAARqB,EACQgB,EAAkBC,EAAQ,IAAMD,EAAkB,GAGlDA,EAAkBC,EAAQ,IAAMD,EAAkBA,EAAkB3B,OAAS,IAGjF6B,QACRnB,EAAMoB,mBAaR,SAASC,EAAYrB,GACnB,KAAIA,EAAMsB,QAAUtB,EAAMuB,SAAWvB,EAAMwB,SAA3C,CAIA,IAAIvB,EAAMD,EAAMC,IAEhB,OAAQA,GACN,IAAK,YACL,IAAK,aAEDF,EAAoBC,EAAOC,GAC3B,MAGJ,IAAK,SAzBT,SAAqBD,GACnB,IAAIpB,EAAgBO,SAASP,cAEC,UAA1BA,EAAcwB,UAA8G,IAAvF5B,EAAwB+B,QAAQ3B,EAAcc,aAAa,QAAQc,iBAE1G5B,EAAc6C,QACdzB,EAAMoB,kBAqBFM,CAAY1B,KAUpB,SAAS2B,IACPC,iBAAiB,UAAWP,GAO9B,SAASQ,IACPC,oBAAoB,UAAWT,GAUjC,SAASU,EAAiBtC,GACxBhB,EAAgBgB","file":"arrow-key-navigation.js","sourcesContent":["/**\n * Makes it so the left and right arrows change focus, ala Tab/Shift+Tab. This is mostly designed\n * for KaiOS devices.\n */\n\n/* global document, addEventListener, removeEventListener, getSelection */\n// This query is adapted from a11y-dialog\n// https://github.com/edenspiekermann/a11y-dialog/blob/cf4ed81/a11y-dialog.js#L6-L18\nvar focusablesQuery = 'a[href], area[href], input, select, textarea, ' + 'button, iframe, object, embed, [contenteditable], [tabindex], ' + 'video[controls], audio[controls], summary'; // TODO: email/number types are a special type, in that they return selectionStart/selectionEnd as null\n// As far as I can tell, there is no way to actually get the caret position from these inputs. So we\n// don't do the proper caret handling for those inputs, unfortunately.\n// https://html.spec.whatwg.org/multipage/input.html#do-not-apply\n\nvar textInputTypes = ['text', 'search', 'url', 'password', 'tel'];\nvar checkboxRadioInputTypes = ['checkbox', 'radio'];\nvar focusTrapTest = undefined;\n\nfunction getFocusableElements(activeElement) {\n // Respect focus trap inside of dialogs\n var dialogParent = getFocusTrapParent(activeElement);\n var root = dialogParent || document;\n var res = [];\n var elements = root.querySelectorAll(focusablesQuery);\n var len = elements.length;\n\n for (var i = 0; i < len; i++) {\n var element = elements[i];\n\n if (element === activeElement || !element.disabled && !/^-/.test(element.getAttribute('tabindex') || '') && !element.hasAttribute('inert') && ( // see https://github.com/GoogleChrome/inert-polyfill\n element.offsetWidth > 0 || element.offsetHeight > 0)) {\n res.push(element);\n }\n }\n\n return res;\n}\n\nfunction getFocusTrapParent(element) {\n if (!focusTrapTest) {\n return;\n }\n\n var parent = element.parentElement;\n\n while (parent) {\n if (focusTrapTest(parent)) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n}\n\nfunction shouldIgnoreEvent(activeElement, key) {\n var tagName = activeElement.tagName;\n var isTextarea = tagName === 'TEXTAREA';\n var isTextInput = tagName === 'INPUT' && textInputTypes.indexOf(activeElement.getAttribute('type').toLowerCase()) !== -1;\n var isContentEditable = activeElement.hasAttribute('contenteditable');\n\n if (!isTextarea && !isTextInput && !isContentEditable) {\n return false;\n }\n\n var selectionStart;\n var selectionEnd;\n var len;\n\n if (isContentEditable) {\n var selection = getSelection();\n selectionStart = selection.anchorOffset;\n selectionEnd = selection.focusOffset;\n len = activeElement.textContent.length;\n } else {\n selectionStart = activeElement.selectionStart;\n selectionEnd = activeElement.selectionEnd;\n len = activeElement.value.length;\n } // if the cursor is inside of a textarea/input, then don't focus to the next/previous element\n // unless the cursor is at the beginning or the end\n\n\n if (key === 'ArrowLeft' && selectionStart === selectionEnd && selectionStart === 0) {\n return false;\n } else if (key === 'ArrowRight' && selectionStart === selectionEnd && selectionStart === len) {\n return false;\n }\n\n return true;\n}\n\nfunction focusNextOrPrevious(event, key) {\n var activeElement = document.activeElement;\n\n if (shouldIgnoreEvent(activeElement, key)) {\n return;\n }\n\n var focusableElements = getFocusableElements(activeElement);\n\n if (!focusableElements.length) {\n return;\n }\n\n var index = focusableElements.indexOf(activeElement);\n var element;\n\n if (key === 'ArrowLeft') {\n element = focusableElements[index - 1] || focusableElements[0];\n } else {\n // ArrowRight\n element = focusableElements[index + 1] || focusableElements[focusableElements.length - 1];\n }\n\n element.focus();\n event.preventDefault();\n}\n\nfunction handleEnter(event) {\n var activeElement = document.activeElement;\n\n if (activeElement.tagName === 'INPUT' && checkboxRadioInputTypes.indexOf(activeElement.getAttribute('type').toLowerCase()) !== -1) {\n // Explicitly override \"enter\" on an input and make it fire the checkbox/radio\n activeElement.click();\n event.preventDefault();\n }\n}\n\nfunction keyListener(event) {\n if (event.altKey || event.metaKey || event.ctrlKey) {\n return; // ignore e.g. Alt-Left and Ctrl-Right, which are used to switch browser tabs or navigate back/forward\n }\n\n var key = event.key;\n\n switch (key) {\n case 'ArrowLeft':\n case 'ArrowRight':\n {\n focusNextOrPrevious(event, key);\n break;\n }\n\n case 'Enter':\n {\n handleEnter(event);\n break;\n }\n }\n}\n/**\n * Start listening for keyboard events. Attaches a listener to the window.\n */\n\n\nfunction register() {\n addEventListener('keydown', keyListener);\n}\n/**\n * Stop listening for keyboard events. Unattaches a listener to the window.\n */\n\n\nfunction unregister() {\n removeEventListener('keydown', keyListener);\n}\n/**\n * Set a focus trap test to identify any focus traps in the DOM, i.e. a top-level DOM node that indicates the root\n * of a focus trap. Once this is set, if focus changes within the focus trap, then will not leave the focus trap.\n * @param test: the test function\n * @see https://w3c.github.io/aria-practices/examples/dialog-modal/dialog.html\n */\n\n\nfunction setFocusTrapTest(test) {\n focusTrapTest = test;\n}\n\nexport { register, setFocusTrapTest, unregister };"],"sourceRoot":""} |