diff options
Diffstat (limited to 'vnfmarket/common/thirdparty/angular-material/modules/js/menu')
7 files changed, 1292 insertions, 0 deletions
diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/bower.json b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/bower.json new file mode 100644 index 00000000..3b5a37a4 --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/bower.json @@ -0,0 +1,8 @@ +{ + "name": "angular-material-menu", + "version": "1.1.2-master-a9ba340", + "dependencies": { + "angular-material-core": "1.1.2-master-a9ba340", + "angular-material-backdrop": "1.1.2-master-a9ba340" + } +}
\ No newline at end of file diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu-default-theme.css b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu-default-theme.css new file mode 100644 index 00000000..448d20d3 --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu-default-theme.css @@ -0,0 +1,18 @@ +/*! + * Angular Material Design + * https://github.com/angular/material + * @license MIT + * v1.1.3 + */ +md-menu-content.md-THEME_NAME-theme { + background-color: '{{background-A100}}'; } + md-menu-content.md-THEME_NAME-theme md-menu-item { + color: '{{background-A200-0.87}}'; } + md-menu-content.md-THEME_NAME-theme md-menu-item md-icon { + color: '{{background-A200-0.54}}'; } + md-menu-content.md-THEME_NAME-theme md-menu-item .md-button[disabled] { + color: '{{background-A200-0.25}}'; } + md-menu-content.md-THEME_NAME-theme md-menu-item .md-button[disabled] md-icon { + color: '{{background-A200-0.25}}'; } + md-menu-content.md-THEME_NAME-theme md-menu-divider { + background-color: '{{background-A200-0.11}}'; } diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu-default-theme.min.css b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu-default-theme.min.css new file mode 100644 index 00000000..b87f42a7 --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu-default-theme.min.css @@ -0,0 +1,6 @@ +/*! + * Angular Material Design + * https://github.com/angular/material + * @license MIT + * v1.1.2-master-a9ba340 + */md-menu-content.md-THEME_NAME-theme{background-color:"{{background-A100}}"}md-menu-content.md-THEME_NAME-theme md-menu-item{color:"{{background-A200-0.87}}"}md-menu-content.md-THEME_NAME-theme md-menu-item md-icon{color:"{{background-A200-0.54}}"}md-menu-content.md-THEME_NAME-theme md-menu-item .md-button[disabled],md-menu-content.md-THEME_NAME-theme md-menu-item .md-button[disabled] md-icon{color:"{{background-A200-0.25}}"}md-menu-content.md-THEME_NAME-theme md-menu-divider{background-color:"{{background-A200-0.11}}"}
\ No newline at end of file diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.css b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.css new file mode 100644 index 00000000..2ca057c3 --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.css @@ -0,0 +1,151 @@ +/*! + * Angular Material Design + * https://github.com/angular/material + * @license MIT + * v1.1.3 + */ +.md-open-menu-container { + position: fixed; + left: 0; + top: 0; + z-index: 100; + opacity: 0; + border-radius: 2px; } + .md-open-menu-container md-menu-divider { + margin-top: 4px; + margin-bottom: 4px; + height: 1px; + min-height: 1px; + max-height: 1px; + width: 100%; } + .md-open-menu-container md-menu-content > * { + opacity: 0; } + .md-open-menu-container:not(.md-clickable) { + pointer-events: none; } + .md-open-menu-container.md-active { + opacity: 1; + -webkit-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); + transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); + -webkit-transition-duration: 200ms; + transition-duration: 200ms; } + .md-open-menu-container.md-active > md-menu-content > * { + opacity: 1; + -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); + transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); + -webkit-transition-duration: 200ms; + transition-duration: 200ms; + -webkit-transition-delay: 100ms; + transition-delay: 100ms; } + .md-open-menu-container.md-leave { + opacity: 0; + -webkit-transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); + transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); + -webkit-transition-duration: 250ms; + transition-duration: 250ms; } + +md-menu-content { + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + flex-direction: column; + padding: 8px 0; + max-height: 304px; + overflow-y: auto; } + md-menu-content.md-dense { + max-height: 208px; } + md-menu-content.md-dense md-menu-item { + height: 32px; + min-height: 0px; } + +md-menu-item { + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + flex-direction: row; + min-height: 48px; + height: 48px; + -webkit-align-content: center; + align-content: center; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + /* + * We cannot use flex on <button> elements due to a bug in Firefox, so we also can't use it on + * <a> elements. Add some top padding to fix alignment since buttons automatically align their + * text vertically. + */ } + md-menu-item > * { + width: 100%; + margin: auto 0; + padding-left: 16px; + padding-right: 16px; } + md-menu-item > a.md-button { + padding-top: 5px; } + md-menu-item > .md-button { + text-align: left; + display: inline-block; + border-radius: 0; + margin: auto 0; + font-size: 15px; + text-transform: none; + font-weight: 400; + height: 100%; + padding-left: 16px; + padding-right: 16px; + width: 100%; } + md-menu-item > .md-button::-moz-focus-inner { + padding: 0; + border: 0; } + [dir=rtl] md-menu-item > .md-button { + text-align: right; } + md-menu-item > .md-button md-icon { + margin: auto 16px auto 0; } + [dir=rtl] md-menu-item > .md-button md-icon { + margin: auto 0 auto 16px; } + md-menu-item > .md-button p { + display: inline-block; + margin: auto; } + md-menu-item > .md-button span { + margin-top: auto; + margin-bottom: auto; } + md-menu-item > .md-button .md-ripple-container { + border-radius: inherit; } + +md-toolbar .md-menu { + height: auto; + margin: auto; + padding: 0; } + +@media (max-width: 959px) { + md-menu-content { + min-width: 112px; } + md-menu-content[width="3"] { + min-width: 168px; } + md-menu-content[width="4"] { + min-width: 224px; } + md-menu-content[width="5"] { + min-width: 280px; } + md-menu-content[width="6"] { + min-width: 336px; } + md-menu-content[width="7"] { + min-width: 392px; } } + +@media (min-width: 960px) { + md-menu-content { + min-width: 96px; } + md-menu-content[width="3"] { + min-width: 192px; } + md-menu-content[width="4"] { + min-width: 256px; } + md-menu-content[width="5"] { + min-width: 320px; } + md-menu-content[width="6"] { + min-width: 384px; } + md-menu-content[width="7"] { + min-width: 448px; } } diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.js b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.js new file mode 100644 index 00000000..e1574156 --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.js @@ -0,0 +1,1096 @@ +/*! + * Angular Material Design + * https://github.com/angular/material + * @license MIT + * v1.1.3 + */ +(function( window, angular, undefined ){ +"use strict"; + +/** + * @ngdoc module + * @name material.components.menu + */ + +angular.module('material.components.menu', [ + 'material.core', + 'material.components.backdrop' +]); + + + +MenuController['$inject'] = ["$mdMenu", "$attrs", "$element", "$scope", "$mdUtil", "$timeout", "$rootScope", "$q", "$log"]; +angular + .module('material.components.menu') + .controller('mdMenuCtrl', MenuController); + +/** + * ngInject + */ +function MenuController($mdMenu, $attrs, $element, $scope, $mdUtil, $timeout, $rootScope, $q, $log) { + + var prefixer = $mdUtil.prefixer(); + var menuContainer; + var self = this; + var triggerElement; + + this.nestLevel = parseInt($attrs.mdNestLevel, 10) || 0; + + /** + * Called by our linking fn to provide access to the menu-content + * element removed during link + */ + this.init = function init(setMenuContainer, opts) { + opts = opts || {}; + menuContainer = setMenuContainer; + + // Default element for ARIA attributes has the ngClick or ngMouseenter expression + triggerElement = $element[0].querySelector(prefixer.buildSelector(['ng-click', 'ng-mouseenter'])); + triggerElement.setAttribute('aria-expanded', 'false'); + + this.isInMenuBar = opts.isInMenuBar; + this.nestedMenus = $mdUtil.nodesToArray(menuContainer[0].querySelectorAll('.md-nested-menu')); + + menuContainer.on('$mdInterimElementRemove', function() { + self.isOpen = false; + $mdUtil.nextTick(function(){ self.onIsOpenChanged(self.isOpen);}); + }); + $mdUtil.nextTick(function(){ self.onIsOpenChanged(self.isOpen);}); + + var menuContainerId = 'menu_container_' + $mdUtil.nextUid(); + menuContainer.attr('id', menuContainerId); + angular.element(triggerElement).attr({ + 'aria-owns': menuContainerId, + 'aria-haspopup': 'true' + }); + + $scope.$on('$destroy', angular.bind(this, function() { + this.disableHoverListener(); + $mdMenu.destroy(); + })); + + menuContainer.on('$destroy', function() { + $mdMenu.destroy(); + }); + }; + + var openMenuTimeout, menuItems, deregisterScopeListeners = []; + this.enableHoverListener = function() { + deregisterScopeListeners.push($rootScope.$on('$mdMenuOpen', function(event, el) { + if (menuContainer[0].contains(el[0])) { + self.currentlyOpenMenu = el.controller('mdMenu'); + self.isAlreadyOpening = false; + self.currentlyOpenMenu.registerContainerProxy(self.triggerContainerProxy.bind(self)); + } + })); + deregisterScopeListeners.push($rootScope.$on('$mdMenuClose', function(event, el) { + if (menuContainer[0].contains(el[0])) { + self.currentlyOpenMenu = undefined; + } + })); + menuItems = angular.element($mdUtil.nodesToArray(menuContainer[0].children[0].children)); + menuItems.on('mouseenter', self.handleMenuItemHover); + menuItems.on('mouseleave', self.handleMenuItemMouseLeave); + }; + + this.disableHoverListener = function() { + while (deregisterScopeListeners.length) { + deregisterScopeListeners.shift()(); + } + menuItems && menuItems.off('mouseenter', self.handleMenuItemHover); + menuItems && menuItems.off('mouseleave', self.handleMenuItemMouseLeave); + }; + + this.handleMenuItemHover = function(event) { + if (self.isAlreadyOpening) return; + var nestedMenu = ( + event.target.querySelector('md-menu') + || $mdUtil.getClosest(event.target, 'MD-MENU') + ); + openMenuTimeout = $timeout(function() { + if (nestedMenu) { + nestedMenu = angular.element(nestedMenu).controller('mdMenu'); + } + + if (self.currentlyOpenMenu && self.currentlyOpenMenu != nestedMenu) { + var closeTo = self.nestLevel + 1; + self.currentlyOpenMenu.close(true, { closeTo: closeTo }); + self.isAlreadyOpening = !!nestedMenu; + nestedMenu && nestedMenu.open(); + } else if (nestedMenu && !nestedMenu.isOpen && nestedMenu.open) { + self.isAlreadyOpening = !!nestedMenu; + nestedMenu && nestedMenu.open(); + } + }, nestedMenu ? 100 : 250); + var focusableTarget = event.currentTarget.querySelector('.md-button:not([disabled])'); + focusableTarget && focusableTarget.focus(); + }; + + this.handleMenuItemMouseLeave = function() { + if (openMenuTimeout) { + $timeout.cancel(openMenuTimeout); + openMenuTimeout = undefined; + } + }; + + + /** + * Uses the $mdMenu interim element service to open the menu contents + */ + this.open = function openMenu(ev) { + ev && ev.stopPropagation(); + ev && ev.preventDefault(); + if (self.isOpen) return; + self.enableHoverListener(); + self.isOpen = true; + $mdUtil.nextTick(function(){ self.onIsOpenChanged(self.isOpen);}); + triggerElement = triggerElement || (ev ? ev.target : $element[0]); + triggerElement.setAttribute('aria-expanded', 'true'); + $scope.$emit('$mdMenuOpen', $element); + $mdMenu.show({ + scope: $scope, + mdMenuCtrl: self, + nestLevel: self.nestLevel, + element: menuContainer, + target: triggerElement, + preserveElement: true, + parent: 'body' + }).finally(function() { + triggerElement.setAttribute('aria-expanded', 'false'); + self.disableHoverListener(); + }); + }; + + this.onIsOpenChanged = function(isOpen) { + if (isOpen) { + menuContainer.attr('aria-hidden', 'false'); + $element[0].classList.add('md-open'); + angular.forEach(self.nestedMenus, function(el) { + el.classList.remove('md-open'); + }); + } else { + menuContainer.attr('aria-hidden', 'true'); + $element[0].classList.remove('md-open'); + } + $scope.$mdMenuIsOpen = self.isOpen; + }; + + this.focusMenuContainer = function focusMenuContainer() { + var focusTarget = menuContainer[0] + .querySelector(prefixer.buildSelector(['md-menu-focus-target', 'md-autofocus'])); + + if (!focusTarget) focusTarget = menuContainer[0].querySelector('.md-button:not([disabled])'); + focusTarget.focus(); + }; + + this.registerContainerProxy = function registerContainerProxy(handler) { + this.containerProxy = handler; + }; + + this.triggerContainerProxy = function triggerContainerProxy(ev) { + this.containerProxy && this.containerProxy(ev); + }; + + this.destroy = function() { + return self.isOpen ? $mdMenu.destroy() : $q.when(false); + }; + + // Use the $mdMenu interim element service to close the menu contents + this.close = function closeMenu(skipFocus, closeOpts) { + if ( !self.isOpen ) return; + self.isOpen = false; + $mdUtil.nextTick(function(){ self.onIsOpenChanged(self.isOpen);}); + + var eventDetails = angular.extend({}, closeOpts, { skipFocus: skipFocus }); + $scope.$emit('$mdMenuClose', $element, eventDetails); + $mdMenu.hide(null, closeOpts); + + if (!skipFocus) { + var el = self.restoreFocusTo || $element.find('button')[0]; + if (el instanceof angular.element) el = el[0]; + if (el) el.focus(); + } + }; + + /** + * Build a nice object out of our string attribute which specifies the + * target mode for left and top positioning + */ + this.positionMode = function positionMode() { + var attachment = ($attrs.mdPositionMode || 'target').split(' '); + + // If attachment is a single item, duplicate it for our second value. + // ie. 'target' -> 'target target' + if (attachment.length == 1) { + attachment.push(attachment[0]); + } + + return { + left: attachment[0], + top: attachment[1] + }; + }; + + /** + * Build a nice object out of our string attribute which specifies + * the offset of top and left in pixels. + */ + this.offsets = function offsets() { + var position = ($attrs.mdOffset || '0 0').split(' ').map(parseFloat); + if (position.length == 2) { + return { + left: position[0], + top: position[1] + }; + } else if (position.length == 1) { + return { + top: position[0], + left: position[0] + }; + } else { + throw Error('Invalid offsets specified. Please follow format <x, y> or <n>'); + } + }; + + // Functionality that is exposed in the view. + $scope.$mdMenu = { + open: this.open, + close: this.close + }; + + // Deprecated APIs + $scope.$mdOpenMenu = angular.bind(this, function() { + $log.warn('mdMenu: The $mdOpenMenu method is deprecated. Please use `$mdMenu.open`.'); + return this.open.apply(this, arguments); + }); +} + +/** + * @ngdoc directive + * @name mdMenu + * @module material.components.menu + * @restrict E + * @description + * + * Menus are elements that open when clicked. They are useful for displaying + * additional options within the context of an action. + * + * Every `md-menu` must specify exactly two child elements. The first element is what is + * left in the DOM and is used to open the menu. This element is called the trigger element. + * The trigger element's scope has access to `$mdMenu.open($event)` + * which it may call to open the menu. By passing $event as argument, the + * corresponding event is stopped from propagating up the DOM-tree. Similarly, `$mdMenu.close()` + * can be used to close the menu. + * + * The second element is the `md-menu-content` element which represents the + * contents of the menu when it is open. Typically this will contain `md-menu-item`s, + * but you can do custom content as well. + * + * <hljs lang="html"> + * <md-menu> + * <!-- Trigger element is a md-button with an icon --> + * <md-button ng-click="$mdMenu.open($event)" class="md-icon-button" aria-label="Open sample menu"> + * <md-icon md-svg-icon="call:phone"></md-icon> + * </md-button> + * <md-menu-content> + * <md-menu-item><md-button ng-click="doSomething()">Do Something</md-button></md-menu-item> + * </md-menu-content> + * </md-menu> + * </hljs> + + * ## Sizing Menus + * + * The width of the menu when it is open may be specified by specifying a `width` + * attribute on the `md-menu-content` element. + * See the [Material Design Spec](https://material.google.com/components/menus.html#menus-simple-menus) + * for more information. + * + * + * ## Aligning Menus + * + * When a menu opens, it is important that the content aligns with the trigger element. + * Failure to align menus can result in jarring experiences for users as content + * suddenly shifts. To help with this, `md-menu` provides serveral APIs to help + * with alignment. + * + * ### Target Mode + * + * By default, `md-menu` will attempt to align the `md-menu-content` by aligning + * designated child elements in both the trigger and the menu content. + * + * To specify the alignment element in the `trigger` you can use the `md-menu-origin` + * attribute on a child element. If no `md-menu-origin` is specified, the `md-menu` + * will be used as the origin element. + * + * Similarly, the `md-menu-content` may specify a `md-menu-align-target` for a + * `md-menu-item` to specify the node that it should try and align with. + * + * In this example code, we specify an icon to be our origin element, and an + * icon in our menu content to be our alignment target. This ensures that both + * icons are aligned when the menu opens. + * + * <hljs lang="html"> + * <md-menu> + * <md-button ng-click="$mdMenu.open($event)" class="md-icon-button" aria-label="Open some menu"> + * <md-icon md-menu-origin md-svg-icon="call:phone"></md-icon> + * </md-button> + * <md-menu-content> + * <md-menu-item> + * <md-button ng-click="doSomething()" aria-label="Do something"> + * <md-icon md-menu-align-target md-svg-icon="call:phone"></md-icon> + * Do Something + * </md-button> + * </md-menu-item> + * </md-menu-content> + * </md-menu> + * </hljs> + * + * Sometimes we want to specify alignment on the right side of an element, for example + * if we have a menu on the right side a toolbar, we want to right align our menu content. + * + * We can specify the origin by using the `md-position-mode` attribute on both + * the `x` and `y` axis. Right now only the `x-axis` has more than one option. + * You may specify the default mode of `target target` or + * `target-right target` to specify a right-oriented alignment target. See the + * position section of the demos for more examples. + * + * ### Menu Offsets + * + * It is sometimes unavoidable to need to have a deeper level of control for + * the positioning of a menu to ensure perfect alignment. `md-menu` provides + * the `md-offset` attribute to allow pixel level specificty of adjusting the + * exact positioning. + * + * This offset is provided in the format of `x y` or `n` where `n` will be used + * in both the `x` and `y` axis. + * + * For example, to move a menu by `2px` down from the top, we can use: + * <hljs lang="html"> + * <md-menu md-offset="0 2"> + * <!-- menu-content --> + * </md-menu> + * </hljs> + * + * ### Auto Focus + * By default, when a menu opens, `md-menu` focuses the first button in the menu content. + * + * But sometimes you would like to focus another specific menu item instead of the first.<br/> + * This can be done by applying the `md-autofocus` directive on the given element. + * + * <hljs lang="html"> + * <md-menu-item> + * <md-button md-autofocus ng-click="doSomething()"> + * Auto Focus + * </md-button> + * </md-menu-item> + * </hljs> + * + * + * ### Preventing close + * + * Sometimes you would like to be able to click on a menu item without having the menu + * close. To do this, ngMaterial exposes the `md-prevent-menu-close` attribute which + * can be added to a button inside a menu to stop the menu from automatically closing. + * You can then close the menu either by using `$mdMenu.close()` in the template, + * or programatically by injecting `$mdMenu` and calling `$mdMenu.hide()`. + * + * <hljs lang="html"> + * <md-menu-content ng-mouseleave="$mdMenu.close()"> + * <md-menu-item> + * <md-button ng-click="doSomething()" aria-label="Do something" md-prevent-menu-close="md-prevent-menu-close"> + * <md-icon md-menu-align-target md-svg-icon="call:phone"></md-icon> + * Do Something + * </md-button> + * </md-menu-item> + * </md-menu-content> + * </hljs> + * + * @usage + * <hljs lang="html"> + * <md-menu> + * <md-button ng-click="$mdMenu.open($event)" class="md-icon-button"> + * <md-icon md-svg-icon="call:phone"></md-icon> + * </md-button> + * <md-menu-content> + * <md-menu-item><md-button ng-click="doSomething()">Do Something</md-button></md-menu-item> + * </md-menu-content> + * </md-menu> + * </hljs> + * + * @param {string} md-position-mode The position mode in the form of + * `x`, `y`. Default value is `target`,`target`. Right now the `x` axis + * also supports `target-right`. + * @param {string} md-offset An offset to apply to the dropdown after positioning + * `x`, `y`. Default value is `0`,`0`. + * + */ + +MenuDirective['$inject'] = ["$mdUtil"]; +angular + .module('material.components.menu') + .directive('mdMenu', MenuDirective); + +/** + * ngInject + */ +function MenuDirective($mdUtil) { + var INVALID_PREFIX = 'Invalid HTML for md-menu: '; + return { + restrict: 'E', + require: ['mdMenu', '?^mdMenuBar'], + controller: 'mdMenuCtrl', // empty function to be built by link + scope: true, + compile: compile + }; + + function compile(templateElement) { + templateElement.addClass('md-menu'); + + var triggerEl = templateElement.children()[0]; + var contentEl = templateElement.children()[1]; + + var prefixer = $mdUtil.prefixer(); + + if (!prefixer.hasAttribute(triggerEl, 'ng-click')) { + triggerEl = triggerEl + .querySelector(prefixer.buildSelector(['ng-click', 'ng-mouseenter'])) || triggerEl; + } + + var isButtonTrigger = triggerEl.nodeName === 'MD-BUTTON' || triggerEl.nodeName === 'BUTTON'; + + if (triggerEl && isButtonTrigger && !triggerEl.hasAttribute('type')) { + triggerEl.setAttribute('type', 'button'); + } + + if (!triggerEl) { + throw Error(INVALID_PREFIX + 'Expected the menu to have a trigger element.'); + } + + if (!contentEl || contentEl.nodeName !== 'MD-MENU-CONTENT') { + throw Error(INVALID_PREFIX + 'Expected the menu to contain a `md-menu-content` element.'); + } + + // Default element for ARIA attributes has the ngClick or ngMouseenter expression + triggerEl && triggerEl.setAttribute('aria-haspopup', 'true'); + + var nestedMenus = templateElement[0].querySelectorAll('md-menu'); + var nestingDepth = parseInt(templateElement[0].getAttribute('md-nest-level'), 10) || 0; + if (nestedMenus) { + angular.forEach($mdUtil.nodesToArray(nestedMenus), function(menuEl) { + if (!menuEl.hasAttribute('md-position-mode')) { + menuEl.setAttribute('md-position-mode', 'cascade'); + } + menuEl.classList.add('_md-nested-menu'); + menuEl.setAttribute('md-nest-level', nestingDepth + 1); + }); + } + return link; + } + + function link(scope, element, attr, ctrls) { + var mdMenuCtrl = ctrls[0]; + var isInMenuBar = !!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]; + + element.addClass('_md'); // private md component indicator for styling + + if (!menuContents.hasAttribute('role')) { + menuContents.setAttribute('role', 'menu'); + } + menuContainer.append(menuContents); + + element.on('$destroy', function() { + menuContainer.remove(); + }); + + element.append(menuContainer); + menuContainer[0].style.display = 'none'; + mdMenuCtrl.init(menuContainer, { isInMenuBar: isInMenuBar }); + + } +} + + +MenuProvider['$inject'] = ["$$interimElementProvider"];angular + .module('material.components.menu') + .provider('$mdMenu', MenuProvider); + +/* + * Interim element provider for the menu. + * Handles behavior for a menu while it is open, including: + * - handling animating the menu opening/closing + * - handling key/mouse events on the menu element + * - handling enabling/disabling scroll while the menu is open + * - handling redrawing during resizes and orientation changes + * + */ + +function MenuProvider($$interimElementProvider) { + menuDefaultOptions['$inject'] = ["$mdUtil", "$mdTheming", "$mdConstant", "$document", "$window", "$q", "$$rAF", "$animateCss", "$animate", "$log"]; + var MENU_EDGE_MARGIN = 8; + + return $$interimElementProvider('$mdMenu') + .setDefaults({ + methods: ['target'], + options: menuDefaultOptions + }); + + /* ngInject */ + function menuDefaultOptions($mdUtil, $mdTheming, $mdConstant, $document, $window, $q, $$rAF, + $animateCss, $animate, $log) { + + var prefixer = $mdUtil.prefixer(); + var animator = $mdUtil.dom.animator; + + return { + parent: 'body', + onShow: onShow, + onRemove: onRemove, + hasBackdrop: true, + disableParentScroll: true, + skipCompile: true, + preserveScope: true, + multiple: true, + themable: true + }; + + /** + * Show modal backdrop element... + * @returns {function(): void} A function that removes this backdrop + */ + function showBackdrop(scope, element, options) { + if (options.nestLevel) return angular.noop; + + // If we are not within a dialog... + if (options.disableParentScroll && !$mdUtil.getClosest(options.target, 'MD-DIALOG')) { + // !! DO this before creating the backdrop; since disableScrollAround() + // configures the scroll offset; which is used by mdBackDrop postLink() + options.restoreScroll = $mdUtil.disableScrollAround(options.element, options.parent); + } else { + options.disableParentScroll = false; + } + + if (options.hasBackdrop) { + options.backdrop = $mdUtil.createBackdrop(scope, "md-menu-backdrop md-click-catcher"); + + $animate.enter(options.backdrop, $document[0].body); + } + + /** + * Hide and destroys the backdrop created by showBackdrop() + */ + return function hideBackdrop() { + if (options.backdrop) options.backdrop.remove(); + if (options.disableParentScroll) options.restoreScroll(); + }; + } + + /** + * Removing the menu element from the DOM and remove all associated event listeners + * and backdrop + */ + function onRemove(scope, element, opts) { + opts.cleanupInteraction(); + opts.cleanupBackdrop(); + opts.cleanupResizing(); + opts.hideBackdrop(); + + // Before the menu is closing remove the clickable class. + element.removeClass('md-clickable'); + + // For navigation $destroy events, do a quick, non-animated removal, + // but for normal closes (from clicks, etc) animate the removal + + return (opts.$destroy === true) ? detachAndClean() : animateRemoval().then( detachAndClean ); + + /** + * For normal closes, animate the removal. + * For forced closes (like $destroy events), skip the animations + */ + function animateRemoval() { + return $animateCss(element, {addClass: 'md-leave'}).start(); + } + + /** + * Detach the element + */ + function detachAndClean() { + element.removeClass('md-active'); + detachElement(element, opts); + opts.alreadyOpen = false; + } + + } + + /** + * Inserts and configures the staged Menu element into the DOM, positioning it, + * and wiring up various interaction events + */ + function onShow(scope, element, opts) { + sanitizeAndConfigure(opts); + + if (opts.menuContentEl[0]) { + // Inherit the theme from the target element. + $mdTheming.inherit(opts.menuContentEl, opts.target); + } else { + $log.warn( + '$mdMenu: Menu elements should always contain a `md-menu-content` element,' + + 'otherwise interactivity features will not work properly.', + element + ); + } + + // Register various listeners to move menu on resize/orientation change + opts.cleanupResizing = startRepositioningOnResize(); + opts.hideBackdrop = showBackdrop(scope, element, opts); + + // Return the promise for when our menu is done animating in + return showMenu() + .then(function(response) { + opts.alreadyOpen = true; + opts.cleanupInteraction = activateInteraction(); + opts.cleanupBackdrop = setupBackdrop(); + + // Since the menu finished its animation, mark the menu as clickable. + element.addClass('md-clickable'); + + return response; + }); + + /** + * Place the menu into the DOM and call positioning related functions + */ + function showMenu() { + opts.parent.append(element); + element[0].style.display = ''; + + return $q(function(resolve) { + var position = calculateMenuPosition(element, opts); + + element.removeClass('md-leave'); + + // Animate the menu scaling, and opacity [from its position origin (default == top-left)] + // to normal scale. + $animateCss(element, { + addClass: 'md-active', + from: animator.toCss(position), + to: animator.toCss({transform: ''}) + }) + .start() + .then(resolve); + + }); + } + + /** + * Check for valid opts and set some sane defaults + */ + function sanitizeAndConfigure() { + if (!opts.target) { + throw Error( + '$mdMenu.show() expected a target to animate from in options.target' + ); + } + angular.extend(opts, { + alreadyOpen: false, + isRemoved: false, + target: angular.element(opts.target), //make sure it's not a naked dom node + parent: angular.element(opts.parent), + menuContentEl: angular.element(element[0].querySelector('md-menu-content')) + }); + } + + /** + * Configure various resize listeners for screen changes + */ + function startRepositioningOnResize() { + + var repositionMenu = (function(target, options) { + return $$rAF.throttle(function() { + if (opts.isRemoved) return; + var position = calculateMenuPosition(target, options); + + target.css(animator.toCss(position)); + }); + })(element, opts); + + $window.addEventListener('resize', repositionMenu); + $window.addEventListener('orientationchange', repositionMenu); + + return function stopRepositioningOnResize() { + + // Disable resizing handlers + $window.removeEventListener('resize', repositionMenu); + $window.removeEventListener('orientationchange', repositionMenu); + + }; + } + + /** + * Sets up the backdrop and listens for click elements. + * Once the backdrop will be clicked, the menu will automatically close. + * @returns {!Function} Function to remove the backdrop. + */ + function setupBackdrop() { + if (!opts.backdrop) return angular.noop; + + opts.backdrop.on('click', onBackdropClick); + + return function() { + opts.backdrop.off('click', onBackdropClick); + } + } + + /** + * Function to be called whenever the backdrop is clicked. + * @param {!MouseEvent} event + */ + function onBackdropClick(event) { + event.preventDefault(); + event.stopPropagation(); + + scope.$apply(function() { + opts.mdMenuCtrl.close(true, { closeAll: true }); + }); + } + + /** + * Activate interaction on the menu. Resolves the focus target and closes the menu on + * escape or option click. + * @returns {!Function} Function to deactivate the interaction listeners. + */ + function activateInteraction() { + if (!opts.menuContentEl[0]) return angular.noop; + + // Wire up keyboard listeners. + // - Close on escape, + // - focus next item on down arrow, + // - focus prev item on up + opts.menuContentEl.on('keydown', onMenuKeyDown); + opts.menuContentEl[0].addEventListener('click', captureClickListener, true); + + // kick off initial focus in the menu on the first enabled element + var focusTarget = opts.menuContentEl[0] + .querySelector(prefixer.buildSelector(['md-menu-focus-target', 'md-autofocus'])); + + if ( !focusTarget ) { + var childrenLen = opts.menuContentEl[0].children.length; + for(var childIndex = 0; childIndex < childrenLen; childIndex++) { + var child = opts.menuContentEl[0].children[childIndex]; + focusTarget = child.querySelector('.md-button:not([disabled])'); + if (focusTarget) { + break; + } + if (child.firstElementChild && !child.firstElementChild.disabled) { + focusTarget = child.firstElementChild; + break; + } + } + } + + focusTarget && focusTarget.focus(); + + return function cleanupInteraction() { + opts.menuContentEl.off('keydown', onMenuKeyDown); + opts.menuContentEl[0].removeEventListener('click', captureClickListener, true); + }; + + // ************************************ + // internal functions + // ************************************ + + function onMenuKeyDown(ev) { + var handled; + switch (ev.keyCode) { + case $mdConstant.KEY_CODE.ESCAPE: + opts.mdMenuCtrl.close(false, { closeAll: true }); + handled = true; + break; + case $mdConstant.KEY_CODE.UP_ARROW: + if (!focusMenuItem(ev, opts.menuContentEl, opts, -1) && !opts.nestLevel) { + opts.mdMenuCtrl.triggerContainerProxy(ev); + } + handled = true; + break; + case $mdConstant.KEY_CODE.DOWN_ARROW: + if (!focusMenuItem(ev, opts.menuContentEl, opts, 1) && !opts.nestLevel) { + opts.mdMenuCtrl.triggerContainerProxy(ev); + } + handled = true; + break; + case $mdConstant.KEY_CODE.LEFT_ARROW: + if (opts.nestLevel) { + opts.mdMenuCtrl.close(); + } else { + opts.mdMenuCtrl.triggerContainerProxy(ev); + } + handled = true; + break; + case $mdConstant.KEY_CODE.RIGHT_ARROW: + var parentMenu = $mdUtil.getClosest(ev.target, 'MD-MENU'); + if (parentMenu && parentMenu != opts.parent[0]) { + ev.target.click(); + } else { + opts.mdMenuCtrl.triggerContainerProxy(ev); + } + handled = true; + break; + } + if (handled) { + ev.preventDefault(); + ev.stopImmediatePropagation(); + } + } + + function onBackdropClick(e) { + e.preventDefault(); + e.stopPropagation(); + scope.$apply(function() { + opts.mdMenuCtrl.close(true, { closeAll: true }); + }); + } + + // Close menu on menu item click, if said menu-item is not disabled + function captureClickListener(e) { + var target = e.target; + // Traverse up the event until we get to the menuContentEl to see if + // there is an ng-click and that the ng-click is not disabled + do { + if (target == opts.menuContentEl[0]) return; + if ((hasAnyAttribute(target, ['ng-click', 'ng-href', 'ui-sref']) || + target.nodeName == 'BUTTON' || target.nodeName == 'MD-BUTTON') && !hasAnyAttribute(target, ['md-prevent-menu-close'])) { + var closestMenu = $mdUtil.getClosest(target, 'MD-MENU'); + if (!target.hasAttribute('disabled') && (!closestMenu || closestMenu == opts.parent[0])) { + close(); + } + break; + } + } while (target = target.parentNode); + + function close() { + scope.$apply(function() { + opts.mdMenuCtrl.close(true, { closeAll: true }); + }); + } + + function hasAnyAttribute(target, attrs) { + if (!target) return false; + + for (var i = 0, attr; attr = attrs[i]; ++i) { + if (prefixer.hasAttribute(target, attr)) { + return true; + } + } + + return false; + } + } + + } + } + + /** + * Takes a keypress event and focuses the next/previous menu + * item from the emitting element + * @param {event} e - The origin keypress event + * @param {angular.element} menuEl - The menu element + * @param {object} opts - The interim element options for the mdMenu + * @param {number} direction - The direction to move in (+1 = next, -1 = prev) + */ + function focusMenuItem(e, menuEl, opts, direction) { + var currentItem = $mdUtil.getClosest(e.target, 'MD-MENU-ITEM'); + + var items = $mdUtil.nodesToArray(menuEl[0].children); + var currentIndex = items.indexOf(currentItem); + + // Traverse through our elements in the specified direction (+/-1) and try to + // focus them until we find one that accepts focus + var didFocus; + for (var i = currentIndex + direction; i >= 0 && i < items.length; i = i + direction) { + var focusTarget = items[i].querySelector('.md-button'); + didFocus = attemptFocus(focusTarget); + if (didFocus) { + break; + } + } + return didFocus; + } + + /** + * Attempts to focus an element. Checks whether that element is the currently + * focused element after attempting. + * @param {HTMLElement} el - the element to attempt focus on + * @returns {bool} - whether the element was successfully focused + */ + function attemptFocus(el) { + if (el && el.getAttribute('tabindex') != -1) { + el.focus(); + return ($document[0].activeElement == el); + } + } + + /** + * Use browser to remove this element without triggering a $destroy event + */ + function detachElement(element, opts) { + if (!opts.preserveElement) { + if (toNode(element).parentNode === toNode(opts.parent)) { + toNode(opts.parent).removeChild(toNode(element)); + } + } else { + toNode(element).style.display = 'none'; + } + } + + /** + * Computes menu position and sets the style on the menu container + * @param {HTMLElement} el - the menu container element + * @param {object} opts - the interim element options object + */ + function calculateMenuPosition(el, opts) { + + var containerNode = el[0], + openMenuNode = el[0].firstElementChild, + openMenuNodeRect = openMenuNode.getBoundingClientRect(), + boundryNode = $document[0].body, + boundryNodeRect = boundryNode.getBoundingClientRect(); + + var menuStyle = $window.getComputedStyle(openMenuNode); + + var originNode = opts.target[0].querySelector(prefixer.buildSelector('md-menu-origin')) || opts.target[0], + originNodeRect = originNode.getBoundingClientRect(); + + var bounds = { + left: boundryNodeRect.left + MENU_EDGE_MARGIN, + top: Math.max(boundryNodeRect.top, 0) + MENU_EDGE_MARGIN, + bottom: Math.max(boundryNodeRect.bottom, Math.max(boundryNodeRect.top, 0) + boundryNodeRect.height) - MENU_EDGE_MARGIN, + right: boundryNodeRect.right - MENU_EDGE_MARGIN + }; + + var alignTarget, alignTargetRect = { top:0, left : 0, right:0, bottom:0 }, existingOffsets = { top:0, left : 0, right:0, bottom:0 }; + var positionMode = opts.mdMenuCtrl.positionMode(); + + if (positionMode.top == 'target' || positionMode.left == 'target' || positionMode.left == 'target-right') { + alignTarget = firstVisibleChild(); + if ( alignTarget ) { + // TODO: Allow centering on an arbitrary node, for now center on first menu-item's child + alignTarget = alignTarget.firstElementChild || alignTarget; + alignTarget = alignTarget.querySelector(prefixer.buildSelector('md-menu-align-target')) || alignTarget; + alignTargetRect = alignTarget.getBoundingClientRect(); + + existingOffsets = { + top: parseFloat(containerNode.style.top || 0), + left: parseFloat(containerNode.style.left || 0) + }; + } + } + + var position = {}; + var transformOrigin = 'top '; + + switch (positionMode.top) { + case 'target': + position.top = existingOffsets.top + originNodeRect.top - alignTargetRect.top; + break; + case 'cascade': + position.top = originNodeRect.top - parseFloat(menuStyle.paddingTop) - originNode.style.top; + break; + case 'bottom': + position.top = originNodeRect.top + originNodeRect.height; + break; + default: + throw new Error('Invalid target mode "' + positionMode.top + '" specified for md-menu on Y axis.'); + } + + var rtl = ($mdUtil.bidi() == 'rtl'); + + switch (positionMode.left) { + case 'target': + position.left = existingOffsets.left + originNodeRect.left - alignTargetRect.left; + transformOrigin += rtl ? 'right' : 'left'; + break; + case 'target-left': + position.left = originNodeRect.left; + transformOrigin += 'left'; + break; + case 'target-right': + position.left = originNodeRect.right - openMenuNodeRect.width + (openMenuNodeRect.right - alignTargetRect.right); + transformOrigin += 'right'; + break; + case 'cascade': + var willFitRight = rtl ? (originNodeRect.left - openMenuNodeRect.width) < bounds.left : (originNodeRect.right + openMenuNodeRect.width) < bounds.right; + position.left = willFitRight ? originNodeRect.right - originNode.style.left : originNodeRect.left - originNode.style.left - openMenuNodeRect.width; + transformOrigin += willFitRight ? 'left' : 'right'; + break; + case 'right': + if (rtl) { + position.left = originNodeRect.right - originNodeRect.width; + transformOrigin += 'left'; + } else { + position.left = originNodeRect.right - openMenuNodeRect.width; + transformOrigin += 'right'; + } + break; + case 'left': + if (rtl) { + position.left = originNodeRect.right - openMenuNodeRect.width; + transformOrigin += 'right'; + } else { + position.left = originNodeRect.left; + transformOrigin += 'left'; + } + break; + default: + throw new Error('Invalid target mode "' + positionMode.left + '" specified for md-menu on X axis.'); + } + + var offsets = opts.mdMenuCtrl.offsets(); + position.top += offsets.top; + position.left += offsets.left; + + clamp(position); + + var scaleX = Math.round(100 * Math.min(originNodeRect.width / containerNode.offsetWidth, 1.0)) / 100; + var scaleY = Math.round(100 * Math.min(originNodeRect.height / containerNode.offsetHeight, 1.0)) / 100; + + return { + top: Math.round(position.top), + left: Math.round(position.left), + // Animate a scale out if we aren't just repositioning + transform: !opts.alreadyOpen ? $mdUtil.supplant('scale({0},{1})', [scaleX, scaleY]) : undefined, + transformOrigin: transformOrigin + }; + + /** + * Clamps the repositioning of the menu within the confines of + * bounding element (often the screen/body) + */ + function clamp(pos) { + pos.top = Math.max(Math.min(pos.top, bounds.bottom - containerNode.offsetHeight), bounds.top); + pos.left = Math.max(Math.min(pos.left, bounds.right - containerNode.offsetWidth), bounds.left); + } + + /** + * Gets the first visible child in the openMenuNode + * Necessary incase menu nodes are being dynamically hidden + */ + function firstVisibleChild() { + for (var i = 0; i < openMenuNode.children.length; ++i) { + if ($window.getComputedStyle(openMenuNode.children[i]).display != 'none') { + return openMenuNode.children[i]; + } + } + } + } + } + function toNode(el) { + if (el instanceof angular.element) { + el = el[0]; + } + return el; + } +} + +})(window, window.angular);
\ No newline at end of file diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.min.css b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.min.css new file mode 100644 index 00000000..5add9f3c --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.min.css @@ -0,0 +1,6 @@ +/*! + * Angular Material Design + * https://github.com/angular/material + * @license MIT + * v1.1.2-master-a9ba340 + */.md-open-menu-container{position:fixed;left:0;top:0;z-index:100;opacity:0;border-radius:2px}.md-open-menu-container md-menu-divider{margin-top:4px;margin-bottom:4px;height:1px;min-height:1px;max-height:1px;width:100%}.md-open-menu-container md-menu-content>*{opacity:0}.md-open-menu-container:not(.md-clickable){pointer-events:none}.md-open-menu-container.md-active{opacity:1;-webkit-transition:all .4s cubic-bezier(.25,.8,.25,1);transition:all .4s cubic-bezier(.25,.8,.25,1);-webkit-transition-duration:.2s;transition-duration:.2s}.md-open-menu-container.md-active>md-menu-content>*{opacity:1;-webkit-transition:all .3s cubic-bezier(.55,0,.55,.2);transition:all .3s cubic-bezier(.55,0,.55,.2);-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-delay:.1s;transition-delay:.1s}.md-open-menu-container.md-leave{opacity:0;-webkit-transition:all .3s cubic-bezier(.55,0,.55,.2);transition:all .3s cubic-bezier(.55,0,.55,.2);-webkit-transition-duration:.25s;transition-duration:.25s}md-menu-content{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;padding:8px 0;max-height:304px;overflow-y:auto}md-menu-content.md-dense{max-height:208px}md-menu-content.md-dense md-menu-item{height:32px;min-height:0}md-menu-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row;min-height:48px;height:48px;-webkit-align-content:center;align-content:center;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}md-menu-item>*{width:100%;margin:auto 0;padding-left:16px;padding-right:16px}md-menu-item>a.md-button{padding-top:5px}md-menu-item>.md-button{text-align:left;display:inline-block;border-radius:0;margin:auto 0;font-size:15px;text-transform:none;font-weight:400;height:100%;padding-left:16px;padding-right:16px;width:100%}md-menu-item>.md-button::-moz-focus-inner{padding:0;border:0}[dir=rtl] md-menu-item>.md-button{text-align:right}md-menu-item>.md-button md-icon{margin:auto 16px auto 0}[dir=rtl] md-menu-item>.md-button md-icon{margin:auto 0 auto 16px}md-menu-item>.md-button p{display:inline-block;margin:auto}md-menu-item>.md-button span{margin-top:auto;margin-bottom:auto}md-menu-item>.md-button .md-ripple-container{border-radius:inherit}md-toolbar .md-menu{height:auto;margin:auto;padding:0}@media (max-width:959px){md-menu-content{min-width:112px}md-menu-content[width="3"]{min-width:168px}md-menu-content[width="4"]{min-width:224px}md-menu-content[width="5"]{min-width:280px}md-menu-content[width="6"]{min-width:336px}md-menu-content[width="7"]{min-width:392px}}@media (min-width:960px){md-menu-content{min-width:96px}md-menu-content[width="3"]{min-width:192px}md-menu-content[width="4"]{min-width:256px}md-menu-content[width="5"]{min-width:320px}md-menu-content[width="6"]{min-width:384px}md-menu-content[width="7"]{min-width:448px}}
\ No newline at end of file diff --git a/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.min.js b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.min.js new file mode 100644 index 00000000..64bae9a5 --- /dev/null +++ b/vnfmarket/common/thirdparty/angular-material/modules/js/menu/menu.min.js @@ -0,0 +1,7 @@ +/*! + * Angular Material Design + * https://github.com/angular/material + * @license MIT + * v1.1.2-master-a9ba340 + */ +!function(e,t,n){"use strict";function r(e,r,o,i,a,l,s,u,d){var c,m,f=a.prefixer(),p=this;this.nestLevel=parseInt(r.mdNestLevel,10)||0,this.init=function(n,r){r=r||{},c=n,m=o[0].querySelector(f.buildSelector(["ng-click","ng-mouseenter"])),m.setAttribute("aria-expanded","false"),this.isInMenuBar=r.isInMenuBar,this.nestedMenus=a.nodesToArray(c[0].querySelectorAll(".md-nested-menu")),c.on("$mdInterimElementRemove",function(){p.isOpen=!1,a.nextTick(function(){p.onIsOpenChanged(p.isOpen)})}),a.nextTick(function(){p.onIsOpenChanged(p.isOpen)});var l="menu_container_"+a.nextUid();c.attr("id",l),t.element(m).attr({"aria-owns":l,"aria-haspopup":"true"}),i.$on("$destroy",t.bind(this,function(){this.disableHoverListener(),e.destroy()})),c.on("$destroy",function(){e.destroy()})};var h,g,v=[];this.enableHoverListener=function(){v.push(s.$on("$mdMenuOpen",function(e,t){c[0].contains(t[0])&&(p.currentlyOpenMenu=t.controller("mdMenu"),p.isAlreadyOpening=!1,p.currentlyOpenMenu.registerContainerProxy(p.triggerContainerProxy.bind(p)))})),v.push(s.$on("$mdMenuClose",function(e,t){c[0].contains(t[0])&&(p.currentlyOpenMenu=n)})),g=t.element(a.nodesToArray(c[0].children[0].children)),g.on("mouseenter",p.handleMenuItemHover),g.on("mouseleave",p.handleMenuItemMouseLeave)},this.disableHoverListener=function(){for(;v.length;)v.shift()();g&&g.off("mouseenter",p.handleMenuItemHover),g&&g.off("mouseleave",p.handleMenuItemMouseLeave)},this.handleMenuItemHover=function(e){if(!p.isAlreadyOpening){var n=e.target.querySelector("md-menu")||a.getClosest(e.target,"MD-MENU");h=l(function(){if(n&&(n=t.element(n).controller("mdMenu")),p.currentlyOpenMenu&&p.currentlyOpenMenu!=n){var e=p.nestLevel+1;p.currentlyOpenMenu.close(!0,{closeTo:e}),p.isAlreadyOpening=!!n,n&&n.open()}else n&&!n.isOpen&&n.open&&(p.isAlreadyOpening=!!n,n&&n.open())},n?100:250);var r=e.currentTarget.querySelector(".md-button:not([disabled])");r&&r.focus()}},this.handleMenuItemMouseLeave=function(){h&&(l.cancel(h),h=n)},this.open=function(t){t&&t.stopPropagation(),t&&t.preventDefault(),p.isOpen||(p.enableHoverListener(),p.isOpen=!0,a.nextTick(function(){p.onIsOpenChanged(p.isOpen)}),m=m||(t?t.target:o[0]),m.setAttribute("aria-expanded","true"),i.$emit("$mdMenuOpen",o),e.show({scope:i,mdMenuCtrl:p,nestLevel:p.nestLevel,element:c,target:m,preserveElement:!0,parent:"body"})["finally"](function(){m.setAttribute("aria-expanded","false"),p.disableHoverListener()}))},this.onIsOpenChanged=function(e){e?(c.attr("aria-hidden","false"),o[0].classList.add("md-open"),t.forEach(p.nestedMenus,function(e){e.classList.remove("md-open")})):(c.attr("aria-hidden","true"),o[0].classList.remove("md-open")),i.$mdMenuIsOpen=p.isOpen},this.focusMenuContainer=function(){var e=c[0].querySelector(f.buildSelector(["md-menu-focus-target","md-autofocus"]));e||(e=c[0].querySelector(".md-button:not([disabled])")),e.focus()},this.registerContainerProxy=function(e){this.containerProxy=e},this.triggerContainerProxy=function(e){this.containerProxy&&this.containerProxy(e)},this.destroy=function(){return p.isOpen?e.destroy():u.when(!1)},this.close=function(n,r){if(p.isOpen){p.isOpen=!1,a.nextTick(function(){p.onIsOpenChanged(p.isOpen)});var l=t.extend({},r,{skipFocus:n});if(i.$emit("$mdMenuClose",o,l),e.hide(null,r),!n){var s=p.restoreFocusTo||o.find("button")[0];s instanceof t.element&&(s=s[0]),s&&s.focus()}}},this.positionMode=function(){var e=(r.mdPositionMode||"target").split(" ");return 1==e.length&&e.push(e[0]),{left:e[0],top:e[1]}},this.offsets=function(){var e=(r.mdOffset||"0 0").split(" ").map(parseFloat);if(2==e.length)return{left:e[0],top:e[1]};if(1==e.length)return{top:e[0],left:e[0]};throw Error("Invalid offsets specified. Please follow format <x, y> or <n>")},i.$mdMenu={open:this.open,close:this.close},i.$mdOpenMenu=t.bind(this,function(){return d.warn("mdMenu: The $mdOpenMenu method is deprecated. Please use `$mdMenu.open`."),this.open.apply(this,arguments)})}function o(e){function n(n){n.addClass("md-menu");var i=n.children()[0],a=n.children()[1],l=e.prefixer();l.hasAttribute(i,"ng-click")||(i=i.querySelector(l.buildSelector(["ng-click","ng-mouseenter"]))||i);var s="MD-BUTTON"===i.nodeName||"BUTTON"===i.nodeName;if(i&&s&&!i.hasAttribute("type")&&i.setAttribute("type","button"),!i)throw Error(o+"Expected the menu to have a trigger element.");if(!a||"MD-MENU-CONTENT"!==a.nodeName)throw Error(o+"Expected the menu to contain a `md-menu-content` element.");i&&i.setAttribute("aria-haspopup","true");var u=n[0].querySelectorAll("md-menu"),d=parseInt(n[0].getAttribute("md-nest-level"),10)||0;return u&&t.forEach(e.nodesToArray(u),function(e){e.hasAttribute("md-position-mode")||e.setAttribute("md-position-mode","cascade"),e.classList.add("_md-nested-menu"),e.setAttribute("md-nest-level",d+1)}),r}function r(e,n,r,o){var i=o[0],a=!!o[1],l=t.element('<div class="_md md-open-menu-container md-whiteframe-z2"></div>'),s=n.children()[1];n.addClass("_md"),s.hasAttribute("role")||s.setAttribute("role","menu"),l.append(s),n.on("$destroy",function(){l.remove()}),n.append(l),l[0].style.display="none",i.init(l,{isInMenuBar:a})}var o="Invalid HTML for md-menu: ";return{restrict:"E",require:["mdMenu","?^mdMenuBar"],controller:"mdMenuCtrl",scope:!0,compile:n}}function i(e){function r(e,r,a,l,s,u,d,c,m,f){function p(n,r,o){return o.nestLevel?t.noop:(o.disableParentScroll&&!e.getClosest(o.target,"MD-DIALOG")?o.restoreScroll=e.disableScrollAround(o.element,o.parent):o.disableParentScroll=!1,o.hasBackdrop&&(o.backdrop=e.createBackdrop(n,"md-menu-backdrop md-click-catcher"),m.enter(o.backdrop,l[0].body)),function(){o.backdrop&&o.backdrop.remove(),o.disableParentScroll&&o.restoreScroll()})}function h(e,t,n){function r(){return c(t,{addClass:"md-leave"}).start()}function o(){t.removeClass("md-active"),M(t,n),n.alreadyOpen=!1}return n.cleanupInteraction(),n.cleanupBackdrop(),n.cleanupResizing(),n.hideBackdrop(),t.removeClass("md-clickable"),n.$destroy===!0?o():r().then(o)}function g(n,o,i){function l(){return i.parent.append(o),o[0].style.display="",u(function(e){var t=y(o,i);o.removeClass("md-leave"),c(o,{addClass:"md-active",from:E.toCss(t),to:E.toCss({transform:""})}).start().then(e)})}function m(){if(!i.target)throw Error("$mdMenu.show() expected a target to animate from in options.target");t.extend(i,{alreadyOpen:!1,isRemoved:!1,target:t.element(i.target),parent:t.element(i.parent),menuContentEl:t.element(o[0].querySelector("md-menu-content"))})}function h(){var e=function(e,t){return d.throttle(function(){if(!i.isRemoved){var n=y(e,t);e.css(E.toCss(n))}})}(o,i);return s.addEventListener("resize",e),s.addEventListener("orientationchange",e),function(){s.removeEventListener("resize",e),s.removeEventListener("orientationchange",e)}}function g(){return i.backdrop?(i.backdrop.on("click",b),function(){i.backdrop.off("click",b)}):t.noop}function b(e){e.preventDefault(),e.stopPropagation(),n.$apply(function(){i.mdMenuCtrl.close(!0,{closeAll:!0})})}function M(){function r(t){var n;switch(t.keyCode){case a.KEY_CODE.ESCAPE:i.mdMenuCtrl.close(!1,{closeAll:!0}),n=!0;break;case a.KEY_CODE.UP_ARROW:v(t,i.menuContentEl,i,-1)||i.nestLevel||i.mdMenuCtrl.triggerContainerProxy(t),n=!0;break;case a.KEY_CODE.DOWN_ARROW:v(t,i.menuContentEl,i,1)||i.nestLevel||i.mdMenuCtrl.triggerContainerProxy(t),n=!0;break;case a.KEY_CODE.LEFT_ARROW:i.nestLevel?i.mdMenuCtrl.close():i.mdMenuCtrl.triggerContainerProxy(t),n=!0;break;case a.KEY_CODE.RIGHT_ARROW:var r=e.getClosest(t.target,"MD-MENU");r&&r!=i.parent[0]?t.target.click():i.mdMenuCtrl.triggerContainerProxy(t),n=!0}n&&(t.preventDefault(),t.stopImmediatePropagation())}function o(t){function r(){n.$apply(function(){i.mdMenuCtrl.close(!0,{closeAll:!0})})}function o(e,t){if(!e)return!1;for(var n,r=0;n=t[r];++r)if(C.hasAttribute(e,n))return!0;return!1}var a=t.target;do{if(a==i.menuContentEl[0])return;if((o(a,["ng-click","ng-href","ui-sref"])||"BUTTON"==a.nodeName||"MD-BUTTON"==a.nodeName)&&!o(a,["md-prevent-menu-close"])){var l=e.getClosest(a,"MD-MENU");a.hasAttribute("disabled")||l&&l!=i.parent[0]||r();break}}while(a=a.parentNode)}if(!i.menuContentEl[0])return t.noop;i.menuContentEl.on("keydown",r),i.menuContentEl[0].addEventListener("click",o,!0);var l=i.menuContentEl[0].querySelector(C.buildSelector(["md-menu-focus-target","md-autofocus"]));if(!l)for(var s=i.menuContentEl[0].children.length,u=0;u<s;u++){var d=i.menuContentEl[0].children[u];if(l=d.querySelector(".md-button:not([disabled])"))break;if(d.firstElementChild&&!d.firstElementChild.disabled){l=d.firstElementChild;break}}return l&&l.focus(),function(){i.menuContentEl.off("keydown",r),i.menuContentEl[0].removeEventListener("click",o,!0)}}return m(i),i.menuContentEl[0]?r.inherit(i.menuContentEl,i.target):f.warn("$mdMenu: Menu elements should always contain a `md-menu-content` element,otherwise interactivity features will not work properly.",o),i.cleanupResizing=h(),i.hideBackdrop=p(n,o,i),l().then(function(e){return i.alreadyOpen=!0,i.cleanupInteraction=M(),i.cleanupBackdrop=g(),o.addClass("md-clickable"),e})}function v(t,n,r,o){for(var i,a=e.getClosest(t.target,"MD-MENU-ITEM"),l=e.nodesToArray(n[0].children),s=l.indexOf(a),u=s+o;u>=0&&u<l.length;u+=o){var d=l[u].querySelector(".md-button");if(i=b(d))break}return i}function b(e){if(e&&e.getAttribute("tabindex")!=-1)return e.focus(),l[0].activeElement==e}function M(e,t){t.preserveElement?o(e).style.display="none":o(e).parentNode===o(t.parent)&&o(t.parent).removeChild(o(e))}function y(t,r){function o(e){e.top=Math.max(Math.min(e.top,b.bottom-d.offsetHeight),b.top),e.left=Math.max(Math.min(e.left,b.right-d.offsetWidth),b.left)}function a(){for(var e=0;e<c.children.length;++e)if("none"!=s.getComputedStyle(c.children[e]).display)return c.children[e]}var u,d=t[0],c=t[0].firstElementChild,m=c.getBoundingClientRect(),f=l[0].body,p=f.getBoundingClientRect(),h=s.getComputedStyle(c),g=r.target[0].querySelector(C.buildSelector("md-menu-origin"))||r.target[0],v=g.getBoundingClientRect(),b={left:p.left+i,top:Math.max(p.top,0)+i,bottom:Math.max(p.bottom,Math.max(p.top,0)+p.height)-i,right:p.right-i},M={top:0,left:0,right:0,bottom:0},y={top:0,left:0,right:0,bottom:0},E=r.mdMenuCtrl.positionMode();"target"!=E.top&&"target"!=E.left&&"target-right"!=E.left||(u=a(),u&&(u=u.firstElementChild||u,u=u.querySelector(C.buildSelector("md-menu-align-target"))||u,M=u.getBoundingClientRect(),y={top:parseFloat(d.style.top||0),left:parseFloat(d.style.left||0)}));var k={},O="top ";switch(E.top){case"target":k.top=y.top+v.top-M.top;break;case"cascade":k.top=v.top-parseFloat(h.paddingTop)-g.style.top;break;case"bottom":k.top=v.top+v.height;break;default:throw new Error('Invalid target mode "'+E.top+'" specified for md-menu on Y axis.')}var $="rtl"==e.bidi();switch(E.left){case"target":k.left=y.left+v.left-M.left,O+=$?"right":"left";break;case"target-left":k.left=v.left,O+="left";break;case"target-right":k.left=v.right-m.width+(m.right-M.right),O+="right";break;case"cascade":var w=$?v.left-m.width<b.left:v.right+m.width<b.right;k.left=w?v.right-g.style.left:v.left-g.style.left-m.width,O+=w?"left":"right";break;case"right":$?(k.left=v.right-v.width,O+="left"):(k.left=v.right-m.width,O+="right");break;case"left":$?(k.left=v.right-m.width,O+="right"):(k.left=v.left,O+="left");break;default:throw new Error('Invalid target mode "'+E.left+'" specified for md-menu on X axis.')}var x=r.mdMenuCtrl.offsets();k.top+=x.top,k.left+=x.left,o(k);var A=Math.round(100*Math.min(v.width/d.offsetWidth,1))/100,S=Math.round(100*Math.min(v.height/d.offsetHeight,1))/100;return{top:Math.round(k.top),left:Math.round(k.left),transform:r.alreadyOpen?n:e.supplant("scale({0},{1})",[A,S]),transformOrigin:O}}var C=e.prefixer(),E=e.dom.animator;return{parent:"body",onShow:g,onRemove:h,hasBackdrop:!0,disableParentScroll:!0,skipCompile:!0,preserveScope:!0,multiple:!0,themable:!0}}function o(e){return e instanceof t.element&&(e=e[0]),e}r.$inject=["$mdUtil","$mdTheming","$mdConstant","$document","$window","$q","$$rAF","$animateCss","$animate","$log"];var i=8;return e("$mdMenu").setDefaults({methods:["target"],options:r})}t.module("material.components.menu",["material.core","material.components.backdrop"]),r.$inject=["$mdMenu","$attrs","$element","$scope","$mdUtil","$timeout","$rootScope","$q","$log"],t.module("material.components.menu").controller("mdMenuCtrl",r),o.$inject=["$mdUtil"],t.module("material.components.menu").directive("mdMenu",o),i.$inject=["$$interimElementProvider"],t.module("material.components.menu").provider("$mdMenu",i)}(window,window.angular);
\ No newline at end of file |