Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/menu/js/menuController.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function MenuController($mdMenu, $attrs, $element, $scope, $mdUtil, $timeout, $r
triggerElement.setAttribute('aria-expanded', 'false');

this.isInMenuBar = opts.isInMenuBar;
this.mdMenuBarCtrl = opts.mdMenuBarCtrl;
this.nestedMenus = $mdUtil.nodesToArray(menuContainer[0].querySelectorAll('.md-nested-menu'));

menuContainer.on('$mdInterimElementRemove', function() {
Expand Down
4 changes: 2 additions & 2 deletions src/components/menu/js/menuDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ function MenuDirective($mdUtil) {
function link(scope, element, attr, ctrls) {
var mdMenuCtrl = ctrls[0];
var isInMenuBar = !!ctrls[1];
var mdMenuBarCtrl = ctrls[1];
// Move everything into a md-menu-container and pass it to the controller
var menuContainer = angular.element('<div class="_md md-open-menu-container md-whiteframe-z2"></div>');
var menuContents = element.children()[1];
Expand All @@ -275,7 +276,6 @@ function MenuDirective($mdUtil) {

element.append(menuContainer);
menuContainer[0].style.display = 'none';
mdMenuCtrl.init(menuContainer, { isInMenuBar: isInMenuBar });

mdMenuCtrl.init(menuContainer, { isInMenuBar: isInMenuBar, mdMenuBarCtrl: mdMenuBarCtrl });
}
}
7 changes: 4 additions & 3 deletions src/components/menuBar/js/menuBarController.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,18 @@ MenuBarController.prototype.init = function() {
el[0].classList.remove('md-open');
}

if ($element[0].contains(el[0])) {
var ctrl = angular.element(el[0]).controller('mdMenu');
if (ctrl.isInMenuBar && ctrl.mdMenuBarCtrl === self) {
var parentMenu = el[0];
while (parentMenu && rootMenus.indexOf(parentMenu) == -1) {
parentMenu = $mdUtil.getClosest(parentMenu, 'MD-MENU', true);
}
if (parentMenu) {
if (!opts.skipFocus) parentMenu.querySelector('button:not([disabled])').focus();
self.currentlyOpenMenu = undefined;
self.disableOpenOnHover();
self.setKeyboardMode(true);
}
self.disableOpenOnHover();
self.setKeyboardMode(true);
}
}));

Expand Down
110 changes: 110 additions & 0 deletions src/components/menuBar/menu-bar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,116 @@ describe('material.components.menuBar', function() {
});
}));

it('should close when clicking on a menu item', inject(function($compile, $rootScope, $timeout, $material) {
var toolbar = $compile(
'<md-toolbar class="md-menu-toolbar">' +
'<md-menu-bar>' +
'<md-menu>' +
'<button ng-click="clicked=true">root</button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<md-button ng-click="subclicked=true">child</md-button>' +
'</md-menu-item>' +
'</md-menu-content>' +
'</md-menu>' +
'</md-menu-bar>' +
'</md-toolbar>'
)($rootScope);

$rootScope.$digest();
attachedMenuElements.push(toolbar); // ensure it gets cleaned up

var ctrl = toolbar.find('md-menu-bar').controller('mdMenuBar');
var rootMenu = toolbar[0].querySelector('md-menu');

angular.element(document.body).append(toolbar);

var menuCtrl = angular.element(rootMenu).controller('mdMenu');

menuCtrl.open();
waitForMenuOpen();

expect(toolbar).toHaveClass('md-has-open-menu');
spyOn(menuCtrl, 'close').and.callThrough();

var subMenu = getOpenSubMenu();
var childButton = subMenu[0].querySelector('md-button');
childButton.dispatchEvent(new MouseEvent('click'));
waitForMenuClose();

expect(toolbar).not.toHaveClass('md-has-open-menu');
expect(ctrl.getOpenMenuIndex()).toBe(-1);
expect(menuCtrl.close).toHaveBeenCalledWith(true, {
closeAll: true
});

function getOpenSubMenu() {
var containers = document.body.querySelectorAll('.md-open-menu-container.md-active');
var lastContainer = containers.item(containers.length - 1);

return angular.element(lastContainer.querySelector('md-menu-content'));
}
}));

it('should close when clicking on a nested menu item', inject(function($compile, $rootScope, $timeout, $material) {
var toolbar = $compile(
'<md-toolbar class="md-menu-toolbar">' +
'<md-menu-bar>' +
'<md-menu>' +
'<button>root</button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<md-menu>' +
'<md-button ng-click="$mdMenu.open()">child</md-button>' +
'<md-menu-content>' +
'<md-menu-item>' +
'<md-button>grandchild</md-button>' +
'</md-menu-item>' +
'</md-menu-content>' +
'</md-menu>' +
'</md-menu-item>' +
'</md-menu-content>' +
'</md-menu>' +
'</md-menu-bar>' +
'</md-toolbar>'
)($rootScope);

$rootScope.$digest();
attachedMenuElements.push(toolbar); // ensure it gets cleaned up

var ctrl = toolbar.find('md-menu-bar').controller('mdMenuBar');
var rootMenu = toolbar[0].querySelector('md-menu');

angular.element(document.body).append(toolbar);

var menuCtrl = angular.element(rootMenu).controller('mdMenu');

menuCtrl.open();
waitForMenuOpen();

expect(toolbar).toHaveClass('md-has-open-menu');

var subMenu = getLastOpenSubMenu();
var childButton = subMenu[0].querySelector('md-button');
childButton.dispatchEvent(new MouseEvent('click'));
waitForMenuOpen();

var nestedMenu = getLastOpenSubMenu();
var nestedButton = nestedMenu[0].querySelector('md-button');
nestedButton.dispatchEvent(new MouseEvent('click'));
waitForMenuClose();

expect(toolbar).not.toHaveClass('md-has-open-menu');
expect(ctrl.getOpenMenuIndex()).toBe(-1);

function getLastOpenSubMenu() {
var containers = document.body.querySelectorAll('.md-open-menu-container.md-active');
var lastContainer = containers.item(containers.length - 1);

return angular.element(lastContainer.querySelector('md-menu-content'));
}
}));

describe('ARIA', function() {

it('sets role="menubar" on the menubar', function() {
Expand Down