MDL-71680 navigation: Update templates/js to force nodes into more menu
- Part of: MDL-69588
This commit is contained in:
committed by
Mathew May
parent
e3f35a2f22
commit
1c017ad8fb
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core/moremenu",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c={regions:{moredropdown:"[data-region=\"moredropdown\"]",morebutton:"[data-region=\"morebutton\"]"},classes:{dropdownitem:"dropdown-item",dropdownmoremenu:"dropdownmoremenu",dropdowntoggle:"dropdown-toggle",hidden:"d-none",active:"active",nav:"nav",navlink:"nav-link",observed:"observed"},attributes:{menu:"[role=\"menu\"]"}},d=6,e=function(a){var b=a.parentNode.offsetHeight+1,f=a.querySelector(c.regions.moredropdown),g=a.querySelector(c.regions.morebutton),h=a.querySelector("."+c.classes.dropdowntoggle);if(a.offsetHeight>b||a.children.length>d){g.classList.remove(c.classes.hidden);var i=Array.from(a.children).reverse();i.forEach(function(e){if(!e.classList.contains(c.classes.dropdownmoremenu)){if(a.offsetHeight>b||a.children.length>d){var g=a.removeChild(e),i=g.querySelector("."+c.classes.navlink);if(i&&!i.hasAttribute("role")){i.setAttribute("role","menuitem")}if(i.classList.contains(c.classes.active)){h.classList.add(c.classes.active)}i.classList.remove(c.classes.navlink);i.classList.add(c.classes.dropdownitem);f.prepend(g)}}})}else{if("children"in f){var j=Array.from(f.children);j.forEach(function(e){if(a.offsetHeight<b&&a.children.length<d){var i=f.removeChild(e),j=i.querySelector("."+c.classes.dropdownitem);if(j){var k=j.getAttribute("role");if("menuitem"===k){j.removeAttribute("role")}}if(j.classList.contains(c.classes.active)){h.classList.remove(c.classes.active)}j.classList.remove(c.classes.dropdownitem);j.classList.add(c.classes.navlink);a.insertBefore(i,g)}});if(0===j.length){g.classList.add(c.classes.hidden)}}if(a.offsetHeight>b){e(a)}}a.parentNode.classList.add(c.classes.observed)},f=function(a){e(a);window.addEventListener("resize",function(){e(a)});var d=function(a){var b=a.target.parentNode.querySelector(c.attributes.menu);if(b){b.classList.toggle("show")}a.stopPropagation()};(0,b.default)("."+c.classes.dropdownmoremenu).on("show.bs.dropdown",function(){var b=a.querySelector(c.regions.moredropdown);b.querySelectorAll(".dropdown").forEach(function(a){a.removeEventListener("click",d,!0);a.addEventListener("click",d,!0)})})};a.default=f;return a.default});
|
||||
define ("core/moremenu",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c={regions:{moredropdown:"[data-region=\"moredropdown\"]",morebutton:"[data-region=\"morebutton\"]"},classes:{dropdownitem:"dropdown-item",dropdownmoremenu:"dropdownmoremenu",dropdowntoggle:"dropdown-toggle",hidden:"d-none",active:"active",nav:"nav",navlink:"nav-link",observed:"observed"},attributes:{menu:"[role=\"menu\"]"}},d=function(a){var b=a.parentNode.offsetHeight+1,g=a.querySelector(c.regions.moredropdown),h=a.querySelector(c.regions.morebutton);if(a.offsetHeight>b){h.classList.remove(c.classes.hidden);var i=Array.from(a.children).reverse();i.forEach(function(d){if(!d.classList.contains(c.classes.dropdownmoremenu)){if(a.offsetHeight>b){var f=a.removeChild(d);e(a,f,!0)}}})}else{if("children"in g){var j=Array.from(g.children);j.forEach(function(c){if(a.offsetHeight<b&&"true"!==c.dataset.forceintomoremenu){var d=g.removeChild(c);f(a,d)}});if(0===j.length){h.classList.add(c.classes.hidden)}}if(a.offsetHeight>b){d(a)}}a.parentNode.classList.add(c.classes.observed)},e=function(a,b){var d=2<arguments.length&&arguments[2]!==void 0?arguments[2]:!1,e=a.querySelector(c.regions.moredropdown),f=a.querySelector("."+c.classes.dropdowntoggle),g=b.querySelector("."+c.classes.navlink);if(g&&!g.hasAttribute("role")){g.setAttribute("role","menuitem")}if(g.classList.contains(c.classes.active)){f.classList.add(c.classes.active)}g.classList.remove(c.classes.navlink);g.classList.add(c.classes.dropdownitem);if(d){e.prepend(b)}else{e.append(b)}},f=function(a,b){var d=a.querySelector(c.regions.morebutton),e=a.querySelector("."+c.classes.dropdowntoggle),f=b.querySelector("."+c.classes.dropdownitem);if(f){var g=f.getAttribute("role");if("menuitem"===g){f.removeAttribute("role")}}if(f.classList.contains(c.classes.active)){e.classList.remove(c.classes.active)}f.classList.remove(c.classes.dropdownitem);f.classList.add(c.classes.navlink);a.insertBefore(b,d)},g=function(a){if("children"in a){var f=a.querySelector(c.regions.morebutton),g=Array.from(a.children);g.forEach(function(b){if(!b.classList.contains(c.classes.dropdownmoremenu)&&"true"===b.dataset.forceintomoremenu){e(a,b,!1);if(f.classList.contains(c.classes.hidden)){f.classList.remove(c.classes.hidden)}}})}d(a);window.addEventListener("resize",function(){d(a)});var h=function(a){var b=a.target.parentNode.querySelector(c.attributes.menu);if(b){b.classList.toggle("show")}a.stopPropagation()};(0,b.default)("."+c.classes.dropdownmoremenu).on("show.bs.dropdown",function(){var b=a.querySelector(c.regions.moredropdown);b.querySelectorAll(".dropdown").forEach(function(a){a.removeEventListener("click",h,!0);a.addEventListener("click",h,!0)})})};a.default=g;return a.default});
|
||||
//# sourceMappingURL=moremenu.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+101
-50
@@ -47,7 +47,6 @@ const Selectors = {
|
||||
}
|
||||
};
|
||||
|
||||
const maxMenuItems = 6;
|
||||
/**
|
||||
* Auto Collapse navigation items that wrap into a dropdown menu.
|
||||
*
|
||||
@@ -60,70 +59,36 @@ const autoCollapse = menu => {
|
||||
const moreDropdown = menu.querySelector(Selectors.regions.moredropdown);
|
||||
const moreButton = menu.querySelector(Selectors.regions.morebutton);
|
||||
|
||||
const dropdownToggle = menu.querySelector('.' + Selectors.classes.dropdowntoggle);
|
||||
|
||||
// If the menuitems wrap and the menu height is larger than the height of the
|
||||
// parent. Or if the number if menuitems is larger than the maximum menu items
|
||||
// allowed then start pushing navlinks into the moreDropdown.
|
||||
if (menu.offsetHeight > maxHeight || menu.children.length > maxMenuItems) {
|
||||
// If the menu items wrap and the menu height is larger than the height of the
|
||||
// parent then start pushing navlinks into the moreDropdown.
|
||||
if (menu.offsetHeight > maxHeight) {
|
||||
|
||||
moreButton.classList.remove(Selectors.classes.hidden);
|
||||
|
||||
const menuNodes = Array.from(menu.children).reverse();
|
||||
menuNodes.forEach(item => {
|
||||
if (!item.classList.contains(Selectors.classes.dropdownmoremenu)) {
|
||||
// After moving the menuitems into the moreDropdown check again
|
||||
// if the menuheight is still larger then the height of the parent or if the
|
||||
// menu still has more items than maxMenuItems.
|
||||
if (menu.offsetHeight > maxHeight || menu.children.length > maxMenuItems) {
|
||||
// After moving the menu items into the moreDropdown check again
|
||||
// if the menu height is still larger then the height of the parent.
|
||||
if (menu.offsetHeight > maxHeight) {
|
||||
const lastNode = menu.removeChild(item);
|
||||
const navLink = lastNode.querySelector('.' + Selectors.classes.navlink);
|
||||
if (navLink && !navLink.hasAttribute('role')) {
|
||||
// Adding the menuitem role so the dropdown includes the
|
||||
// Accessibility improvements from theme/boost/amd/src/aria.js
|
||||
navLink.setAttribute('role', 'menuitem');
|
||||
}
|
||||
|
||||
// If there are navLinks that contain an active link in the moreDropdown
|
||||
// make the dropdownToggle in the moreButton active.
|
||||
if (navLink.classList.contains(Selectors.classes.active)) {
|
||||
dropdownToggle.classList.add(Selectors.classes.active);
|
||||
}
|
||||
|
||||
// Change the styling of the navLink to a dropdownitem and push it into
|
||||
// the moreDropdown.
|
||||
navLink.classList.remove(Selectors.classes.navlink);
|
||||
navLink.classList.add(Selectors.classes.dropdownitem);
|
||||
moreDropdown.prepend(lastNode);
|
||||
// Move this node into the more dropdown menu.
|
||||
moveIntoMoreDropdown(menu, lastNode, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If the the menu height is smaller than the height of the parent and there are
|
||||
// less than the maximum items in the menu, then try returning navlinks to the menu.
|
||||
// If the menu height is smaller than the height of the parent, then try returning navlinks to the menu.
|
||||
|
||||
if ('children' in moreDropdown) {
|
||||
const menuNodes = Array.from(moreDropdown.children);
|
||||
menuNodes.forEach(item => {
|
||||
|
||||
if (menu.offsetHeight < maxHeight && menu.children.length < maxMenuItems) {
|
||||
// Don't move the node to the more menu if it is explicitly defined that
|
||||
// this node should be displayed in the more dropdown menu at all times.
|
||||
if (menu.offsetHeight < maxHeight && item.dataset.forceintomoremenu !== 'true') {
|
||||
const lastNode = moreDropdown.removeChild(item);
|
||||
const navLink = lastNode.querySelector('.' + Selectors.classes.dropdownitem);
|
||||
if (navLink) {
|
||||
const currentAttribute = navLink.getAttribute('role');
|
||||
if (currentAttribute === 'menuitem') {
|
||||
navLink.removeAttribute('role');
|
||||
}
|
||||
}
|
||||
|
||||
// Stop displaying the active state on the dropdownToggle if
|
||||
// the active navlink is removed.
|
||||
if (navLink.classList.contains(Selectors.classes.active)) {
|
||||
dropdownToggle.classList.remove(Selectors.classes.active);
|
||||
}
|
||||
navLink.classList.remove(Selectors.classes.dropdownitem);
|
||||
navLink.classList.add(Selectors.classes.navlink);
|
||||
menu.insertBefore(lastNode, moreButton);
|
||||
// Move this node from the more dropdown menu into the main section of the menu.
|
||||
moveOutOfMoreDropdown(menu, lastNode);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -140,12 +105,98 @@ const autoCollapse = menu => {
|
||||
menu.parentNode.classList.add(Selectors.classes.observed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a node into the "more" dropdown menu.
|
||||
*
|
||||
* This method forces a given navigation node to be added and displayed within the "more" dropdown menu.
|
||||
*
|
||||
* @param {HTMLElement} menu The navbar moremenu.
|
||||
* @param {HTMLElement} navNode The navigation node.
|
||||
* @param {boolean} prepend Whether to prepend or append the node to the content in the more dropdown menu.
|
||||
*/
|
||||
const moveIntoMoreDropdown = (menu, navNode, prepend = false) => {
|
||||
const moreDropdown = menu.querySelector(Selectors.regions.moredropdown);
|
||||
const dropdownToggle = menu.querySelector('.' + Selectors.classes.dropdowntoggle);
|
||||
|
||||
const navLink = navNode.querySelector('.' + Selectors.classes.navlink);
|
||||
if (navLink && !navLink.hasAttribute('role')) {
|
||||
// Adding the menuitem role so the dropdown includes the
|
||||
// accessibility improvements from theme/boost/amd/src/aria.js
|
||||
navLink.setAttribute('role', 'menuitem');
|
||||
}
|
||||
|
||||
// If there are navLinks that contain an active link in the moreDropdown
|
||||
// make the dropdownToggle in the moreButton active.
|
||||
if (navLink.classList.contains(Selectors.classes.active)) {
|
||||
dropdownToggle.classList.add(Selectors.classes.active);
|
||||
}
|
||||
|
||||
// Change the styling of the navLink to a dropdownitem and push it into
|
||||
// the moreDropdown.
|
||||
navLink.classList.remove(Selectors.classes.navlink);
|
||||
navLink.classList.add(Selectors.classes.dropdownitem);
|
||||
if (prepend) {
|
||||
moreDropdown.prepend(navNode);
|
||||
} else {
|
||||
moreDropdown.append(navNode);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a node out of the "more" dropdown menu.
|
||||
*
|
||||
* This method forces a given node from the "more" dropdown menu to be displayed in the main section of the menu.
|
||||
*
|
||||
* @param {HTMLElement} menu The navbar moremenu.
|
||||
* @param {HTMLElement} navNode The navigation node.
|
||||
*/
|
||||
const moveOutOfMoreDropdown = (menu, navNode) => {
|
||||
const moreButton = menu.querySelector(Selectors.regions.morebutton);
|
||||
const dropdownToggle = menu.querySelector('.' + Selectors.classes.dropdowntoggle);
|
||||
const navLink = navNode.querySelector('.' + Selectors.classes.dropdownitem);
|
||||
|
||||
if (navLink) {
|
||||
const currentAttribute = navLink.getAttribute('role');
|
||||
if (currentAttribute === 'menuitem') {
|
||||
navLink.removeAttribute('role');
|
||||
}
|
||||
}
|
||||
|
||||
// Stop displaying the active state on the dropdownToggle if
|
||||
// the active navlink is removed.
|
||||
if (navLink.classList.contains(Selectors.classes.active)) {
|
||||
dropdownToggle.classList.remove(Selectors.classes.active);
|
||||
}
|
||||
navLink.classList.remove(Selectors.classes.dropdownitem);
|
||||
navLink.classList.add(Selectors.classes.navlink);
|
||||
menu.insertBefore(navNode, moreButton);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the more menus.
|
||||
*
|
||||
* @param {HTMLElement} menu The navbar moremenu.
|
||||
*/
|
||||
export default menu => {
|
||||
// Pre-populate the "more" dropdown menu with navigation nodes which are set to be displayed in this menu
|
||||
// by default at all times.
|
||||
if ('children' in menu) {
|
||||
const moreButton = menu.querySelector(Selectors.regions.morebutton);
|
||||
const menuNodes = Array.from(menu.children);
|
||||
menuNodes.forEach((item) => {
|
||||
if (!item.classList.contains(Selectors.classes.dropdownmoremenu) &&
|
||||
item.dataset.forceintomoremenu === 'true') {
|
||||
// Append this node into the more dropdown menu.
|
||||
moveIntoMoreDropdown(menu, item, false);
|
||||
// After adding the node into the more dropdown menu, make sure that the more dropdown menu button
|
||||
// is displayed.
|
||||
if (moreButton.classList.contains(Selectors.classes.hidden)) {
|
||||
moreButton.classList.remove(Selectors.classes.hidden);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Populate the more dropdown menu with additional nodes if necessary, depending on the current screen size.
|
||||
autoCollapse(menu);
|
||||
|
||||
// When the screen size changes make sure the menu still fits.
|
||||
@@ -162,7 +213,7 @@ export default menu => {
|
||||
};
|
||||
|
||||
// If there are dropdowns in the MoreMenu, add a new
|
||||
// eventlistener to show the contents on click and prevent the
|
||||
// event listener to show the contents on click and prevent the
|
||||
// moreMenu from closing.
|
||||
$('.' + Selectors.classes.dropdownmoremenu).on('show.bs.dropdown', function() {
|
||||
const moreDropdown = menu.querySelector(Selectors.regions.moredropdown);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
}
|
||||
}}
|
||||
{{#haschildren}}
|
||||
<li class="dropdown nav-item">
|
||||
<li class="dropdown nav-item" data-forceintomoremenu="{{#forceintomoremenu}}true{{/forceintomoremenu}}{{^forceintomoremenu}}false{{/forceintomoremenu}}">
|
||||
<a class="dropdown-toggle nav-link" id="drop-down-{{uniqid}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#" {{#title}}title="{{{title}}}"{{/title}} aria-controls="drop-down-menu-{{uniqid}}">
|
||||
{{{text}}}
|
||||
</a>
|
||||
@@ -48,7 +48,7 @@
|
||||
</li>
|
||||
{{/haschildren}}
|
||||
{{^haschildren}}
|
||||
<li class="nav-item">
|
||||
<li class="nav-item" data-forceintomoremenu="{{#forceintomoremenu}}true{{/forceintomoremenu}}{{^forceintomoremenu}}false{{/forceintomoremenu}}">
|
||||
{{#tab}}
|
||||
<a class="nav-link {{#isactive}}active{{/isactive}} {{#classes}}{{.}} {{/classes}}" href="{{tab}}" role="tab" data-toggle="tab" aria-selected="false" tabindex="-1">{{{text}}}
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user