diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-includes/blocks/navigation/view.js --- a/wp/wp-includes/blocks/navigation/view.js Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-includes/blocks/navigation/view.js Fri Sep 05 18:40:08 2025 +0200 @@ -1,93 +1,223 @@ -/******/ (function() { // webpackBootstrap -/******/ "use strict"; +import * as __WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__ from "@wordpress/interactivity"; +/******/ // The require scope +/******/ var __webpack_require__ = {}; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/************************************************************************/ var __webpack_exports__ = {}; -;// CONCATENATED MODULE: ./node_modules/micromodal/dist/micromodal.es.js -function e(e,t){for(var o=0;oe.length)&&(t=e.length);for(var o=0,n=new Array(t);o0&&this.registerTriggers.apply(this,t(a)),this.onClick=this.onClick.bind(this),this.onKeydown=this.onKeydown.bind(this)}var i,a,r;return i=o,(a=[{key:"registerTriggers",value:function(){for(var e=this,t=arguments.length,o=new Array(t),n=0;n0&&void 0!==arguments[0]?arguments[0]:null;if(this.activeElement=document.activeElement,this.modal.setAttribute("aria-hidden","false"),this.modal.classList.add(this.config.openClass),this.scrollBehaviour("disable"),this.addEventListeners(),this.config.awaitOpenAnimation){var o=function t(){e.modal.removeEventListener("animationend",t,!1),e.setFocusToFirstNode()};this.modal.addEventListener("animationend",o,!1)}else this.setFocusToFirstNode();this.config.onShow(this.modal,this.activeElement,t)}},{key:"closeModal",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=this.modal;if(this.modal.setAttribute("aria-hidden","true"),this.removeEventListeners(),this.scrollBehaviour("enable"),this.activeElement&&this.activeElement.focus&&this.activeElement.focus(),this.config.onClose(this.modal,this.activeElement,e),this.config.awaitCloseAnimation){var o=this.config.openClass;this.modal.addEventListener("animationend",(function e(){t.classList.remove(o),t.removeEventListener("animationend",e,!1)}),!1)}else t.classList.remove(this.config.openClass)}},{key:"closeModalById",value:function(e){this.modal=document.getElementById(e),this.modal&&this.closeModal()}},{key:"scrollBehaviour",value:function(e){if(this.config.disableScroll){var t=document.querySelector("body");switch(e){case"enable":Object.assign(t.style,{overflow:""});break;case"disable":Object.assign(t.style,{overflow:"hidden"})}}}},{key:"addEventListeners",value:function(){this.modal.addEventListener("touchstart",this.onClick),this.modal.addEventListener("click",this.onClick),document.addEventListener("keydown",this.onKeydown)}},{key:"removeEventListeners",value:function(){this.modal.removeEventListener("touchstart",this.onClick),this.modal.removeEventListener("click",this.onClick),document.removeEventListener("keydown",this.onKeydown)}},{key:"onClick",value:function(e){(e.target.hasAttribute(this.config.closeTrigger)||e.target.parentNode.hasAttribute(this.config.closeTrigger))&&(e.preventDefault(),e.stopPropagation(),this.closeModal(e))}},{key:"onKeydown",value:function(e){27===e.keyCode&&this.closeModal(e),9===e.keyCode&&this.retainFocus(e)}},{key:"getFocusableNodes",value:function(){var e=this.modal.querySelectorAll(n);return Array.apply(void 0,t(e))}},{key:"setFocusToFirstNode",value:function(){var e=this;if(!this.config.disableFocus){var t=this.getFocusableNodes();if(0!==t.length){var o=t.filter((function(t){return!t.hasAttribute(e.config.closeTrigger)}));o.length>0&&o[0].focus(),0===o.length&&t[0].focus()}}}},{key:"retainFocus",value:function(e){var t=this.getFocusableNodes();if(0!==t.length)if(t=t.filter((function(e){return null!==e.offsetParent})),this.modal.contains(document.activeElement)){var o=t.indexOf(document.activeElement);e.shiftKey&&0===o&&(t[t.length-1].focus(),e.preventDefault()),!e.shiftKey&&t.length>0&&o===t.length-1&&(t[0].focus(),e.preventDefault())}else t[0].focus()}}])&&e(i.prototype,a),r&&e(i,r),o}(),a=null,r=function(e){if(!document.getElementById(e))return console.warn("MicroModal: ❗Seems like you have missed %c'".concat(e,"'"),"background-color: #f8f9fa;color: #50596c;font-weight: bold;","ID somewhere in your code. Refer example below to resolve it."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",'')),!1},s=function(e,t){if(function(e){e.length<=0&&(console.warn("MicroModal: ❗Please specify at least one %c'micromodal-trigger'","background-color: #f8f9fa;color: #50596c;font-weight: bold;","data attribute."),console.warn("%cExample:","background-color: #f8f9fa;color: #50596c;font-weight: bold;",''))}(e),!t)return!0;for(var o in t)r(o);return!0},{init:function(e){var o=Object.assign({},{openTrigger:"data-micromodal-trigger"},e),n=t(document.querySelectorAll("[".concat(o.openTrigger,"]"))),r=function(e,t){var o=[];return e.forEach((function(e){var n=e.attributes[t].value;void 0===o[n]&&(o[n]=[]),o[n].push(e)})),o}(n,o.openTrigger);if(!0!==o.debugMode||!1!==s(n,r))for(var l in r){var c=r[l];o.targetModal=l,o.triggers=t(c),a=new i(o)}},show:function(e,t){var o=t||{};o.targetModal=e,!0===o.debugMode&&!1===r(e)||(a&&a.removeEventListeners(),(a=new i(o)).showModal())},close:function(e){e?a.closeModalById(e):a.closeModal()}});"undefined"!=typeof window&&(window.MicroModal=l);/* harmony default export */ var micromodal_es = (l); - +;// CONCATENATED MODULE: external "@wordpress/interactivity" +var x = (y) => { + var x = {}; __webpack_require__.d(x, y); return x +} +var y = (x) => (() => (x)) +const interactivity_namespaceObject = x({ ["getContext"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getContext), ["getElement"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getElement), ["store"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.store) }); ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-library/build-module/navigation/view.js /** - * External dependencies + * WordPress dependencies */ - // Responsive navigation toggle. - -function navigationToggleModal(modal) { - const dialogContainer = modal.querySelector(`.wp-block-navigation__responsive-dialog`); - const isHidden = 'true' === modal.getAttribute('aria-hidden'); - modal.classList.toggle('has-modal-open', !isHidden); - dialogContainer.toggleAttribute('aria-modal', !isHidden); - if (isHidden) { - dialogContainer.removeAttribute('role'); - dialogContainer.removeAttribute('aria-modal'); - } else { - dialogContainer.setAttribute('role', 'dialog'); - dialogContainer.setAttribute('aria-modal', 'true'); - } // Add a class to indicate the modal is open. - - - const htmlElement = document.documentElement; - htmlElement.classList.toggle('has-modal-open'); -} // Open on click functionality. - - -function closeSubmenus(element) { - element.querySelectorAll('[aria-expanded="true"]').forEach(function (toggle) { - toggle.setAttribute('aria-expanded', 'false'); - }); -} - -function toggleSubmenuOnClick(event) { - const buttonToggle = event.target.closest('[aria-expanded]'); - const isSubmenuOpen = buttonToggle.getAttribute('aria-expanded'); +const focusableSelectors = ['a[href]', 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', 'select:not([disabled]):not([aria-hidden])', 'textarea:not([disabled]):not([aria-hidden])', 'button:not([disabled]):not([aria-hidden])', '[contenteditable]', '[tabindex]:not([tabindex^="-"])']; - if (isSubmenuOpen === 'true') { - closeSubmenus(buttonToggle.closest('.wp-block-navigation-item')); - } else { - // Close all sibling submenus. - const parentElement = buttonToggle.closest('.wp-block-navigation-item'); - const navigationParent = buttonToggle.closest('.wp-block-navigation__submenu-container, .wp-block-navigation__container, .wp-block-page-list'); - navigationParent.querySelectorAll('.wp-block-navigation-item').forEach(function (child) { - if (child !== parentElement) { - closeSubmenus(child); +// This is a fix for Safari in iOS/iPadOS. Without it, Safari doesn't focus out +// when the user taps in the body. It can be removed once we add an overlay to +// capture the clicks, instead of relying on the focusout event. +document.addEventListener('click', () => {}); +const { + state, + actions +} = (0,interactivity_namespaceObject.store)('core/navigation', { + state: { + get roleAttribute() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + return ctx.type === 'overlay' && state.isMenuOpen ? 'dialog' : null; + }, + get ariaModal() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + return ctx.type === 'overlay' && state.isMenuOpen ? 'true' : null; + }, + get ariaLabel() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + return ctx.type === 'overlay' && state.isMenuOpen ? ctx.ariaLabel : null; + }, + get isMenuOpen() { + // The menu is opened if either `click`, `hover` or `focus` is true. + return Object.values(state.menuOpenedBy).filter(Boolean).length > 0; + }, + get menuOpenedBy() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + return ctx.type === 'overlay' ? ctx.overlayOpenedBy : ctx.submenuOpenedBy; + } + }, + actions: { + openMenuOnHover() { + const { + type, + overlayOpenedBy + } = (0,interactivity_namespaceObject.getContext)(); + if (type === 'submenu' && + // Only open on hover if the overlay is closed. + Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) { + actions.openMenu('hover'); } - }); // Open submenu. - - buttonToggle.setAttribute('aria-expanded', 'true'); - } -} // Necessary for some themes such as TT1 Blocks, where -// scripts could be loaded before the body. - + }, + closeMenuOnHover() { + const { + type, + overlayOpenedBy + } = (0,interactivity_namespaceObject.getContext)(); + if (type === 'submenu' && + // Only close on hover if the overlay is closed. + Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) { + actions.closeMenu('hover'); + } + }, + openMenuOnClick() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + const { + ref + } = (0,interactivity_namespaceObject.getElement)(); + ctx.previousFocus = ref; + actions.openMenu('click'); + }, + closeMenuOnClick() { + actions.closeMenu('click'); + actions.closeMenu('focus'); + }, + openMenuOnFocus() { + actions.openMenu('focus'); + }, + toggleMenuOnClick() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + const { + ref + } = (0,interactivity_namespaceObject.getElement)(); + // Safari won't send focus to the clicked element, so we need to manually place it: https://bugs.webkit.org/show_bug.cgi?id=22261 + if (window.document.activeElement !== ref) { + ref.focus(); + } + const { + menuOpenedBy + } = state; + if (menuOpenedBy.click || menuOpenedBy.focus) { + actions.closeMenu('click'); + actions.closeMenu('focus'); + } else { + ctx.previousFocus = ref; + actions.openMenu('click'); + } + }, + handleMenuKeydown(event) { + const { + type, + firstFocusableElement, + lastFocusableElement + } = (0,interactivity_namespaceObject.getContext)(); + if (state.menuOpenedBy.click) { + // If Escape close the menu. + if (event?.key === 'Escape') { + actions.closeMenu('click'); + actions.closeMenu('focus'); + return; + } -window.addEventListener('load', () => { - micromodal_es.init({ - onShow: navigationToggleModal, - onClose: navigationToggleModal, - openClass: 'is-menu-open' - }); - const submenuButtons = document.querySelectorAll('.wp-block-navigation-submenu__toggle'); - submenuButtons.forEach(function (button) { - button.addEventListener('click', toggleSubmenuOnClick); - }); // Close on click outside. + // Trap focus if it is an overlay (main menu). + if (type === 'overlay' && event.key === 'Tab') { + // If shift + tab it change the direction. + if (event.shiftKey && window.document.activeElement === firstFocusableElement) { + event.preventDefault(); + lastFocusableElement.focus(); + } else if (!event.shiftKey && window.document.activeElement === lastFocusableElement) { + event.preventDefault(); + firstFocusableElement.focus(); + } + } + } + }, + handleMenuFocusout(event) { + const { + modal, + type + } = (0,interactivity_namespaceObject.getContext)(); + // If focus is outside modal, and in the document, close menu + // event.target === The element losing focus + // event.relatedTarget === The element receiving focus (if any) + // When focusout is outside the document, + // `window.document.activeElement` doesn't change. - document.addEventListener('click', function (event) { - const navigationBlocks = document.querySelectorAll('.wp-block-navigation'); - navigationBlocks.forEach(function (block) { - if (!block.contains(event.target)) { - closeSubmenus(block); + // The event.relatedTarget is null when something outside the navigation menu is clicked. This is only necessary for Safari. + if (event.relatedTarget === null || !modal?.contains(event.relatedTarget) && event.target !== window.document.activeElement && type === 'submenu') { + actions.closeMenu('click'); + actions.closeMenu('focus'); + } + }, + openMenu(menuOpenedOn = 'click') { + const { + type + } = (0,interactivity_namespaceObject.getContext)(); + state.menuOpenedBy[menuOpenedOn] = true; + if (type === 'overlay') { + // Add a `has-modal-open` class to the root. + document.documentElement.classList.add('has-modal-open'); } - }); - }); // Close on focus outside. - - document.addEventListener('keyup', function (event) { - const submenuBlocks = document.querySelectorAll('.wp-block-navigation-item.has-child'); - submenuBlocks.forEach(function (block) { - if (!block.contains(event.target)) { - closeSubmenus(block); + }, + closeMenu(menuClosedOn = 'click') { + const ctx = (0,interactivity_namespaceObject.getContext)(); + state.menuOpenedBy[menuClosedOn] = false; + // Check if the menu is still open or not. + if (!state.isMenuOpen) { + if (ctx.modal?.contains(window.document.activeElement)) { + ctx.previousFocus?.focus(); + } + ctx.modal = null; + ctx.previousFocus = null; + if (ctx.type === 'overlay') { + document.documentElement.classList.remove('has-modal-open'); + } } - }); - }); + } + }, + callbacks: { + initMenu() { + const ctx = (0,interactivity_namespaceObject.getContext)(); + const { + ref + } = (0,interactivity_namespaceObject.getElement)(); + if (state.isMenuOpen) { + const focusableElements = ref.querySelectorAll(focusableSelectors); + ctx.modal = ref; + ctx.firstFocusableElement = focusableElements[0]; + ctx.lastFocusableElement = focusableElements[focusableElements.length - 1]; + } + }, + focusFirstElement() { + const { + ref + } = (0,interactivity_namespaceObject.getElement)(); + if (state.isMenuOpen) { + const focusableElements = ref.querySelectorAll(focusableSelectors); + focusableElements?.[0]?.focus(); + } + } + } +}, { + lock: true }); -/******/ })() -; \ No newline at end of file