14 lines
4.9 KiB
JavaScript
14 lines
4.9 KiB
JavaScript
/*
|
|
* This file is part of the TYPO3 CMS project.
|
|
*
|
|
* It is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License, either version 2
|
|
* of the License, or any later version.
|
|
*
|
|
* For the full copyright and license information, please read the
|
|
* LICENSE.txt file that was distributed with this source code.
|
|
*
|
|
* The TYPO3 project - inspiring people to share!
|
|
*/
|
|
import p from"@typo3/core/document-service.js";class m{constructor(){this.handleFocusout=e=>{const t=e.currentTarget,r=e.relatedTarget;if(r===null||t.contains(r))return;const o=r.closest(".dropdown-menu[popover]");if(o){const n=o.id;if(n&&t.querySelector(`[popovertarget="${n}"]`))return}t.hidePopover()},this.handleKeydown=e=>{const t=e.currentTarget,r=document.activeElement;if(r&&r.closest(".dropdown-menu")!==t)return;const o=this.getFocusableItems(t);if(o.length===0)return;const n=o.findIndex(s=>s===r),u=this.isRtl(t),i=e.key==="ArrowRight"&&!u||e.key==="ArrowLeft"&&u,l=e.key==="ArrowLeft"&&!u||e.key==="ArrowRight"&&u;switch(e.key){case"ArrowDown":e.preventDefault(),o[(n+1)%o.length].focus();break;case"ArrowUp":e.preventDefault(),o[(n-1+o.length)%o.length].focus();break;case"ArrowRight":case"ArrowLeft":if(i){if(r?.hasAttribute("popovertarget")){e.preventDefault(),e.stopPropagation();const s=r.getAttribute("popovertarget"),a=s?document.getElementById(s):null;if(a?.matches("[popover]")){a.showPopover();const d=this.getFocusableItems(a);d.length>0&&d[0].focus()}}}else if(l){const s=document.querySelector(`[popovertarget="${t.id}"]`);s?.closest(".dropdown-menu")&&(e.preventDefault(),e.stopPropagation(),t.hidePopover(),s.focus())}break;case"Escape":{e.preventDefault(),e.stopPropagation();const s=document.querySelector(`[popovertarget="${t.id}"]`);t.hidePopover(),s?.focus();break}case"Home":e.preventDefault(),o[0].focus();break;case"End":e.preventDefault(),o[o.length-1].focus();break;default:break}},document.addEventListener("toggle",e=>{const t=e.target;t.matches(".dropdown-menu[popover]")&&(e.newState==="open"?(t.addEventListener("keydown",this.handleKeydown),t.addEventListener("focusout",this.handleFocusout)):(t.removeEventListener("keydown",this.handleKeydown),t.removeEventListener("focusout",this.handleFocusout)))},!0),document.addEventListener("keydown",e=>{const t=e.target?.closest(".dropdown-toggle[popovertarget]");if(t&&!t.closest(".dropdown-menu")&&(e.key==="ArrowDown"||e.key==="ArrowUp")){const r=t.getAttribute("popovertarget"),o=r?document.getElementById(r):null;if(!o?.matches("[popover]"))return;e.preventDefault(),o.showPopover();const n=this.getFocusableItems(o);n.length>0&&(e.key==="ArrowDown"?n[0].focus():n[n.length-1].focus())}}),window.addEventListener("blur",()=>{document.querySelectorAll(".dropdown-menu[popover]:popover-open").forEach(e=>{e.hidePopover()})}),document.addEventListener("click",e=>{const r=e.target.closest(".dropdown-item");if(!r||r.hasAttribute("popovertarget"))return;let o=r.closest(".dropdown-menu[popover]");for(;o;)o.hidePopover(),o=o.closest(".dropdown-menu[popover]:popover-open")})}getFocusableItems(e){return Array.from(e.querySelectorAll(".dropdown-item:not(:disabled):not(.disabled)")).filter(t=>t.closest(".dropdown-menu")===e)}isRtl(e){return getComputedStyle(e).direction==="rtl"}}new m;class f{constructor(){this.dropdownIdCounter=0,document.addEventListener("click",e=>{const t=e.target?.closest('[data-bs-toggle="dropdown"]');if(t){e.preventDefault();const r=this.getMenu(t);this.convert(t),r?.togglePopover()}}),p.ready().then(()=>this.convertAll())}convertAnchorToButton(e){const t=document.createElement("button");t.type="button";for(const r of e.attributes)if(r.name==="href"){const o=r.value;o.startsWith("#")&&!e.hasAttribute("data-bs-target")&&t.setAttribute("data-bs-target",o)}else t.setAttribute(r.name,r.value);return t.innerHTML=e.innerHTML,e.replaceWith(t),t}getMenu(e){const t=e.dataset.bsTarget;if(t){const o=t.startsWith("#")?t:"#"+t;return document.querySelector(o)}const r=e.getAttribute("href");return r?.startsWith("#")?document.querySelector(r):e.nextElementSibling?.matches(".dropdown-menu")?e.nextElementSibling:e.closest(".dropdown")?.querySelector(".dropdown-menu")??null}convert(e){if(e.hasAttribute("popovertarget"))return null;const t=this.getMenu(e);return t?(t.id||(t.id="dropdown-menu-"+this.dropdownIdCounter++),t.setAttribute("popover",""),e.tagName==="A"&&(e=this.convertAnchorToButton(e)),e.closest(".dropdown")||e.parentElement?.classList.add("dropdown"),e.setAttribute("popovertarget",t.id),e.removeAttribute("data-bs-toggle"),e.removeAttribute("data-bs-target"),e.removeAttribute("data-bs-offset"),e.removeAttribute("data-bs-auto-close"),e.removeAttribute("data-bs-reference"),e.removeAttribute("data-bs-display"),e.removeAttribute("data-bs-boundary"),e.removeAttribute("aria-haspopup"),e.removeAttribute("aria-expanded"),e):null}convertAll(){document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(e=>this.convert(e))}}new f;
|