diff --git a/UI/WebServerResources/js/vendor/angular-material.js b/UI/WebServerResources/js/vendor/angular-material.js index a59b0f465..c91b34ac0 100644 --- a/UI/WebServerResources/js/vendor/angular-material.js +++ b/UI/WebServerResources/js/vendor/angular-material.js @@ -2,7 +2,7 @@ * Angular Material Design * https://github.com/angular/material * @license MIT - * v1.0.0-rc5-master-fd33d41 + * v1.0.0-rc7-master-2ab3075 */ (function( window, angular, undefined ){ "use strict"; @@ -27,7 +27,25 @@ angular 'material.core.gestures', 'material.core.theming' ]) - .config(MdCoreConfigure); + .config(MdCoreConfigure) + .run(DetectNgTouch); + + +/** + * Detect if the ng-Touch module is also being used. + * Warn if detected. + */ +function DetectNgTouch($log, $injector) { + if ( $injector.has('$swipe') ) { + var msg = "" + + "You are using the ngTouch module. \n" + + "Angular Material already has mobile click, tap, and swipe support... \n" + + "ngTouch is not supported with Angular Material!"; + $log.warn(msg); + } +} +DetectNgTouch.$inject = ["$log", "$injector"]; + function MdCoreConfigure($provide, $mdThemingProvider) { @@ -36,7 +54,7 @@ function MdCoreConfigure($provide, $mdThemingProvider) { $mdThemingProvider.theme('default') .primaryPalette('indigo') .accentPalette('pink') - .warnPalette('red') + .warnPalette('deep-orange') .backgroundPalette('grey'); } MdCoreConfigure.$inject = ["$provide", "$mdThemingProvider"]; @@ -1125,6 +1143,7 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in * * @param el Element to start walking the DOM from * @param tagName Tag name to find closest to el, such as 'form' + * @param onlyParent Only start checking from the parent element, not `el`. */ getClosest: function getClosest(el, tagName, onlyParent) { if (el instanceof angular.element) el = el[0]; @@ -2993,22 +3012,21 @@ function InterimElementProvider() { (function() { 'use strict'; - var $mdUtil, $interpolate; + var $mdUtil, $interpolate, $log; var SUFFIXES = /(-gt)?-(sm|md|lg)/g; var WHITESPACE = /\s+/g; - var FLEX_OPTIONS = ['grow', 'initial', 'auto', 'none']; + var FLEX_OPTIONS = ['grow', 'initial', 'auto', 'none', 'noshrink']; var LAYOUT_OPTIONS = ['row', 'column']; var ALIGNMENT_MAIN_AXIS= [ "", "start", "center", "end", "stretch", "space-around", "space-between" ]; var ALIGNMENT_CROSS_AXIS= [ "", "start", "center", "end", "stretch" ]; - var config = { /** * Enable directive attribute-to-class conversions * Developers can use `` to quickly - * disable the Layout directivees and prohibit the injection of Layout classnames + * disable the Layout directives and prohibit the injection of Layout classNames */ enabled: true, @@ -3023,7 +3041,11 @@ function InterimElementProvider() { breakpoints: [] }; + registerLayoutAPI( angular.module('material.core.layout', ['ng']) ); + /** + * registerLayoutAPI() + * * The original ngMaterial Layout solution used attribute selectors and CSS. * * ```html @@ -3032,12 +3054,12 @@ function InterimElementProvider() { * * ```css * [layout] { - * box-sizing: border-box; - * display:flex; - * } + * box-sizing: border-box; + * display:flex; + * } * [layout=column] { - * flex-direction : column - * } + * flex-direction : column + * } * ``` * * Use of attribute selectors creates significant performance impacts in some @@ -3053,117 +3075,83 @@ function InterimElementProvider() { * * ```css * .layout { - * box-sizing: border-box; - * display:flex; - * } + * box-sizing: border-box; + * display:flex; + * } * .layout-column { - * flex-direction : column - * } + * flex-direction : column + * } * ``` */ - angular.module('material.core.layout', ['ng']) + function registerLayoutAPI(module){ + var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i; + var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g; - .directive('mdLayoutCss', disableLayoutDirective ) + // NOTE: these are also defined in constants::MEDIA_PRIORITY and constants::MEDIA + var BREAKPOINTS = [ "", "xs", "gt-xs", "sm", "gt-sm", "md", "gt-md", "lg", "gt-lg", "xl" ]; + var API_WITH_VALUES = [ "layout", "flex", "flex-order", "flex-offset", "layout-align" ]; + var API_NO_VALUES = [ "show", "hide", "layout-padding", "layout-margin" ]; - .directive('layout', attributeWithObserve('layout')) - .directive('layoutSm', attributeWithObserve('layout-sm')) - .directive('layoutGtSm', attributeWithObserve('layout-gt-sm')) - .directive('layoutMd', attributeWithObserve('layout-md')) - .directive('layoutGtMd', attributeWithObserve('layout-gt-md')) - .directive('layoutLg', attributeWithObserve('layout-lg')) - .directive('layoutGtLg', attributeWithObserve('layout-gt-lg')) - .directive('flex', attributeWithObserve('flex')) - .directive('flexSm', attributeWithObserve('flex-sm')) - .directive('flexGtSm', attributeWithObserve('flex-gt-sm')) - .directive('flexMd', attributeWithObserve('flex-md')) - .directive('flexGtMd', attributeWithObserve('flex-gt-md')) - .directive('flexLg', attributeWithObserve('flex-lg')) - .directive('flexGtLg', attributeWithObserve('flex-gt-lg')) + // Build directive registration functions for the standard Layout API... for all breakpoints. + angular.forEach(BREAKPOINTS, function(mqb) { - .directive('flexOrder', attributeWithObserve('flex-order')) - .directive('flexOrderSm', attributeWithObserve('flex-order-sm')) - .directive('flexOrderGtSm', attributeWithObserve('flex-order-gt-sm')) - .directive('flexOrderMd', attributeWithObserve('flex-order-md')) - .directive('flexOrderGtMd', attributeWithObserve('flex-order-gt-md')) - .directive('flexOrderLg', attributeWithObserve('flex-order-lg')) - .directive('flexOrderGtLg', attributeWithObserve('flex-order-gt-lg')) + // Attribute directives with expected, observable value(s) + angular.forEach( API_WITH_VALUES, function(name){ + var fullName = mqb ? name + "-" + mqb : name; + module.directive( directiveNormalize(fullName), attributeWithObserve(fullName)); + }); - .directive('flexOffset', attributeWithObserve('flex-offset')) - .directive('flexOffsetSm', attributeWithObserve('flex-offset-sm')) - .directive('flexOffsetGtSm', attributeWithObserve('flex-offset-gt-sm')) - .directive('flexOffsetMd', attributeWithObserve('flex-offset-md')) - .directive('flexOffsetGtMd', attributeWithObserve('flex-offset-gt-md')) - .directive('flexOffsetLg', attributeWithObserve('flex-offset-lg')) - .directive('flexOffsetGtLg', attributeWithObserve('flex-offset-gt-lg')) + // Attribute directives with no expected value(s) + angular.forEach( API_NO_VALUES, function(name){ + var fullName = mqb ? name + "-" + mqb : name; + module.directive( directiveNormalize(fullName), attributeWithoutValue(fullName)); + }); - .directive('layoutAlign', attributeWithObserve('layout-align')) - .directive('layoutAlignSm', attributeWithObserve('layout-align-sm')) - .directive('layoutAlignGtSm', attributeWithObserve('layout-align-gt-sm')) - .directive('layoutAlignMd', attributeWithObserve('layout-align-md')) - .directive('layoutAlignGtMd', attributeWithObserve('layout-align-gt-md')) - .directive('layoutAlignLg', attributeWithObserve('layout-align-lg')) - .directive('layoutAlignGtLg', attributeWithObserve('layout-align-gt-lg')) + }); - // Attribute directives with no value(s) + // Register other, special directive functions for the Layout features: + module + .directive('mdLayoutCss' , disableLayoutDirective ) + .directive('ngCloak' , buildCloakInterceptor('ng-cloak')) - .directive('hide', attributeWithoutValue('hide')) - .directive('hideSm', attributeWithoutValue('hide-sm')) - .directive('hideGtSm', attributeWithoutValue('hide-gt-sm')) - .directive('hideMd', attributeWithoutValue('hide-md')) - .directive('hideGtMd', attributeWithoutValue('hide-gt-md')) - .directive('hideLg', attributeWithoutValue('hide-lg')) - .directive('hideGtLg', attributeWithoutValue('hide-gt-lg')) - .directive('show', attributeWithoutValue('show')) - .directive('showSm', attributeWithoutValue('show-sm')) - .directive('showGtSm', attributeWithoutValue('show-gt-sm')) - .directive('showMd', attributeWithoutValue('show-md')) - .directive('showGtMd', attributeWithoutValue('show-gt-md')) - .directive('showLg', attributeWithoutValue('show-lg')) - .directive('showGtLg', attributeWithoutValue('show-gt-lg')) + .directive('layoutWrap' , attributeWithoutValue('layout-wrap')) + .directive('layoutNoWrap' , attributeWithoutValue('layout-no-wrap')) + .directive('layoutFill' , attributeWithoutValue('layout-fill')) - // Attribute directives with no value(s) and NO breakpoints + // !! Deprecated attributes: use the `-lt` (aka less-than) notations - .directive('layoutPadding', attributeWithoutValue('layout-padding')) - .directive('layoutPaddingSm', attributeWithoutValue('layout-padding-sm')) - .directive('layoutPaddingGtSm', attributeWithoutValue('layout-padding-gt-sm')) - .directive('layoutPaddingMd', attributeWithoutValue('layout-padding-md')) - .directive('layoutPaddingGtMd', attributeWithoutValue('layout-padding-gt-md')) - .directive('layoutPaddingLg', attributeWithoutValue('layout-padding-lg')) - .directive('layoutPaddingGtLg', attributeWithoutValue('layout-padding-gt-lg')) - - .directive('layoutMargin', attributeWithoutValue('layout-margin')) - .directive('layoutMarginSm', attributeWithoutValue('layout-margin-sm')) - .directive('layoutMarginGtSm', attributeWithoutValue('layout-margin-gt-sm')) - .directive('layoutMarginMd', attributeWithoutValue('layout-margin-md')) - .directive('layoutMarginGtMd', attributeWithoutValue('layout-margin-gt-md')) - .directive('layoutMarginLg', attributeWithoutValue('layout-margin-lg')) - .directive('layoutMarginGtLg', attributeWithoutValue('layout-margin-gt-lg')) + .directive('layoutLtMd' , warnAttrNotSupported('layout-lt-md', true)) + .directive('layoutLtLg' , warnAttrNotSupported('layout-lt-lg', true)) + .directive('flexLtMd' , warnAttrNotSupported('flex-lt-md', true)) + .directive('flexLtLg' , warnAttrNotSupported('flex-lt-lg', true)) - .directive('layoutWrap', attributeWithoutValue('layout-wrap')) - .directive('layoutNoWrap', attributeWithoutValue('layout-no-wrap')) - .directive('layoutFill', attributeWithoutValue('layout-fill')) + .directive('layoutAlignLtMd', warnAttrNotSupported('layout-align-lt-md')) + .directive('layoutAlignLtLg', warnAttrNotSupported('layout-align-lt-lg')) + .directive('flexOrderLtMd' , warnAttrNotSupported('flex-order-lt-md')) + .directive('flexOrderLtLg' , warnAttrNotSupported('flex-order-lt-lg')) + .directive('offsetLtMd' , warnAttrNotSupported('flex-offset-lt-md')) + .directive('offsetLtLg' , warnAttrNotSupported('flex-offset-lt-lg')) - // !! Deprecated attributes: use the `-lt` (aka less-than) notations + .directive('hideLtMd' , warnAttrNotSupported('hide-lt-md')) + .directive('hideLtLg' , warnAttrNotSupported('hide-lt-lg')) + .directive('showLtMd' , warnAttrNotSupported('show-lt-md')) + .directive('showLtLg' , warnAttrNotSupported('show-lt-lg')); - .directive('layoutLtMd', warnAttrNotSupported('layout-lt-md', true)) - .directive('layoutLtLg', warnAttrNotSupported('layout-lt-lg', true)) - .directive('flexLtMd', warnAttrNotSupported('flex-lt-md', true)) - .directive('flexLtLg', warnAttrNotSupported('flex-lt-lg', true)) + /** + * Converts snake_case to camelCase. + * Also there is special case for Moz prefix starting with upper case letter. + * @param name Name to normalize + */ + function directiveNormalize(name) { + return name + .replace(PREFIX_REGEXP, '') + .replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { + return offset ? letter.toUpperCase() : letter; + }); + } - .directive('layoutAlignLtMd', warnAttrNotSupported('layout-align-lt-md')) - .directive('layoutAlignLtLg', warnAttrNotSupported('layout-align-lt-lg')) - .directive('flexOrderLtMd', warnAttrNotSupported('flex-order-lt-md')) - .directive('flexOrderLtLg', warnAttrNotSupported('flex-order-lt-lg')) - .directive('offsetLtMd', warnAttrNotSupported('flex-offset-lt-md')) - .directive('offsetLtLg', warnAttrNotSupported('flex-offset-lt-lg')) - - .directive('hideLtMd', warnAttrNotSupported('hide-lt-md')) - .directive('hideLtLg', warnAttrNotSupported('hide-lt-lg')) - .directive('showLtMd', warnAttrNotSupported('show-lt-md')) - .directive('showLtLg', warnAttrNotSupported('show-lt-lg')) - - .directive('ngCloak', buildCloakInterceptor('ng-cloak')); + } /** * Special directive that will disable ALL Layout conversions of layout @@ -3196,15 +3184,6 @@ function InterimElementProvider() { }; } - // ********************************************************************************* - // - // These functions create registration functions for ngMaterial Layout attribute directives - // This provides easy translation to switch ngMaterial attribute selectors to - // CLASS selectors and directives; which has huge performance implications - // for IE Browsers - // - // ********************************************************************************* - /** * Tail-hook ngCloak to delay the uncloaking while Layout transformers * finish processing. Eliminates flicker with Material.Layoouts @@ -3233,6 +3212,16 @@ function InterimElementProvider() { }]; } + + // ********************************************************************************* + // + // These functions create registration functions for ngMaterial Layout attribute directives + // This provides easy translation to switch ngMaterial attribute selectors to + // CLASS selectors and directives; which has huge performance implications + // for IE Browsers + // + // ********************************************************************************* + /** * Creates a directive registration function where a possible dynamic attribute * value will be observed/watched. @@ -3240,9 +3229,10 @@ function InterimElementProvider() { */ function attributeWithObserve(className) { - return ['$mdUtil', '$interpolate', function(_$mdUtil_, _$interpolate_) { + return ['$mdUtil', '$interpolate', "$log", function(_$mdUtil_, _$interpolate_, _$log_) { $mdUtil = _$mdUtil_; $interpolate = _$interpolate_; + $log = _$log_; return { restrict: 'A', @@ -3251,6 +3241,8 @@ function InterimElementProvider() { if (config.enabled) { // immediately replace static (non-interpolated) invalid values... + validateAttributeUsage(className, attr, element, $log); + validateAttributeValue( className, getNormalizedAttrValue(className, attr, ""), buildUpdateFn(element, className, attr) @@ -3284,8 +3276,10 @@ function InterimElementProvider() { * any attribute value */ function attributeWithoutValue(className) { - return ['$interpolate', function(_$interpolate_) { + return ['$mdUtil', '$interpolate', "$log", function(_$mdUtil_, _$interpolate_, _$log_) { + $mdUtil = _$mdUtil_; $interpolate = _$interpolate_; + $log = _$log_; return { restrict: 'A', @@ -3360,6 +3354,30 @@ function InterimElementProvider() { }]; } + /** + * Centralize warnings for known flexbox issues (especially IE-related issues) + */ + function validateAttributeUsage(className, attr, element, $log){ + var message, usage, url; + var nodeName = element[0].nodeName.toLowerCase(); + + switch(className.replace(SUFFIXES,"")) { + case "flex": + if ((nodeName == "md-button") || (nodeName == "fieldset")){ + // @see https://github.com/philipwalton/flexbugs#9-some-html-elements-cant-be-flex-containers + // Use
wrapper inside (preferred) or outside + + usage = "<" + nodeName + " " + className + ">"; + url = "https://github.com/philipwalton/flexbugs#9-some-html-elements-cant-be-flex-containers"; + message = "Markup '{0}' may not work as expected in IE Browsers. Consult '{1}' for details."; + + $log.warn( $mdUtil.supplant(message, [usage, url]) ); + } + } + + } + + /** * For the Layout attribute value, validate or replace with default * fallback value @@ -3450,14 +3468,22 @@ function InterimElementProvider() { return found; } - function extractAlignAxis(value) { + function extractAlignAxis(attrValue) { var axis = { main : "start", cross: "stretch" - }; + }, values; - var values = (value || "").replace(WHITESPACE, "-").split("-"); - if ( values.length == 3 ) { + attrValue = (attrValue || ""); + + if ( attrValue.indexOf("-") == 0 || attrValue.indexOf(" ") == 0) { + // For missing main-axis values + attrValue = "none" + attrValue; + } + + values = attrValue.toLowerCase().trim().replace(WHITESPACE, "-").split("-"); + if ( values.length && (values[0] === "space") ) { + // for main-axis values of "space-around" or "space-between" values = [ values[0]+"-"+values[1],values[2] ]; } @@ -3470,6 +3496,7 @@ function InterimElementProvider() { return axis; } + })(); })(); @@ -3751,9 +3778,9 @@ var DURATION = 450; * @module material.core.ripple * * @description - * The `md-ripple-ink` directive allows you to specify the ripple color or id a ripple is allowed. + * The `md-ink-ripple` directive allows you to specify the ripple color or id a ripple is allowed. * - * @param {string|boolean} md-ripple-ink A color string `#FF0000` or boolean (`false` or `0`) for preventing ripple + * @param {string|boolean} md-ink-ripple A color string `#FF0000` or boolean (`false` or `0`) for preventing ripple * * @usage * ### String values @@ -3994,7 +4021,17 @@ InkRippleCtrl.prototype.handleMousedown = function (event) { if (this.options.center) { this.createRipple(this.container.prop('clientWidth') / 2, this.container.prop('clientWidth') / 2); } else { - this.createRipple(event.offsetX, event.offsetY); + + // We need to calculate the relative coordinates if the target is a sublayer of the ripple element + if (event.srcElement !== this.$element[0]) { + var layerRect = this.$element[0].getBoundingClientRect(); + var layerX = event.clientX - layerRect.left; + var layerY = event.clientY - layerRect.top; + + this.createRipple(layerX, layerY); + } else { + this.createRipple(event.offsetX, event.offsetY); + } } }; @@ -8799,6 +8836,39 @@ angular .directive('mdDialog', MdDialogDirective) .provider('$mdDialog', MdDialogProvider); +/** + * @ngdoc directive + * @name mdDialog + * @module material.components.dialog + * + * @restrict E + * + * @description + * `` - The dialog's template must be inside this element. + * + * Inside, use an `` element for the dialog's content, and use + * an `` element for the dialog's actions. + * + * * ## CSS + * - `.md-dialog-content` - class that sets the padding on the content as the spec file + * + * @usage + * ### Dialog template + * + * + * + * + * + *

Number {{item}}

+ *
+ *
+ *
+ * + * Close Dialog + * + *
+ *
+ */ function MdDialogDirective($$rAF, $mdTheming, $mdDialog) { return { restrict: 'E', @@ -8856,7 +8926,7 @@ MdDialogDirective.$inject = ["$$rAF", "$mdTheming", "$mdDialog"]; * - Complex dialogs can be sized with `flex="percentage"`, i.e. `flex="66"`. * - Default max-width is 80% of the `rootElement` or `parent`. * - * ## Css + * ## CSS * - `.md-dialog-content` - class that sets the padding on the content as the spec file * * @usage @@ -8904,7 +8974,7 @@ MdDialogDirective.$inject = ["$$rAF", "$mdTheming", "$mdDialog"]; * function showAlert() { * alert = $mdDialog.alert({ * title: 'Attention', - * content: 'This is an example of how easy dialogs can be!', + * textContent: 'This is an example of how easy dialogs can be!', * ok: 'Close' * }); * @@ -9162,7 +9232,7 @@ MdDialogDirective.$inject = ["$$rAF", "$mdTheming", "$mdDialog"]; * - `focusOnOpen` - `{boolean=}`: An option to override focus behavior on open. Only disable if * focusing some other way, as focus management is required for dialogs to be accessible. * Defaults to true. - * - `controller` - `{string=}`: The controller to associate with the dialog. The controller + * - `controller` - `{function|string=}`: The controller to associate with the dialog. The controller * will be injected with the local `$mdDialog`, which passes along a scope for the dialog. * - `locals` - `{object=}`: An object containing key/value pairs. The keys will be used as names * of values to inject into the controller. For example, `locals: {three: 3}` would inject @@ -11420,15 +11490,21 @@ angular.module('material.components.icon', [ */ angular.module('material.components.input', [ - 'material.core' -]) + 'material.core' + ]) .directive('mdInputContainer', mdInputContainerDirective) .directive('label', labelDirective) .directive('input', inputTextareaDirective) .directive('textarea', inputTextareaDirective) .directive('mdMaxlength', mdMaxlengthDirective) .directive('placeholder', placeholderDirective) - .directive('ngMessages', ngMessagesDirective); + .directive('ngMessages', ngMessagesDirective) + .directive('ngMessage', ngMessageDirective) + .directive('ngMessageExp', ngMessageDirective) + + .animation('.md-input-invalid', mdInputInvalidMessagesAnimation) + .animation('.md-input-messages-animation', ngMessagesAnimation) + .animation('.md-input-message-animation', ngMessageAnimation); /** * @ngdoc directive @@ -11464,7 +11540,7 @@ angular.module('material.components.input', [ * */ function mdInputContainerDirective($mdTheming, $parse) { - ContainerCtrl.$inject = ["$scope", "$element", "$attrs"]; + ContainerCtrl.$inject = ["$scope", "$element", "$attrs", "$animate"]; return { restrict: 'E', link: postLink, @@ -11476,7 +11552,7 @@ function mdInputContainerDirective($mdTheming, $parse) { if (element.find('md-icon').length) element.addClass('md-has-icon'); } - function ContainerCtrl($scope, $element, $attrs) { + function ContainerCtrl($scope, $element, $attrs, $animate) { var self = this; self.isErrorGetter = $attrs.mdIsError && $parse($attrs.mdIsError); @@ -11491,14 +11567,15 @@ function mdInputContainerDirective($mdTheming, $parse) { self.setHasValue = function(hasValue) { $element.toggleClass('md-input-has-value', !!hasValue); }; - self.setHasMessages = function(hasMessages) { - $element.toggleClass('md-input-has-messages', !!hasMessages); - }; self.setHasPlaceholder = function(hasPlaceholder) { $element.toggleClass('md-input-has-placeholder', !!hasPlaceholder); }; self.setInvalid = function(isInvalid) { - $element.toggleClass('md-input-invalid', !!isInvalid); + if (isInvalid) { + $animate.addClass($element, 'md-input-invalid'); + } else { + $animate.removeClass($element, 'md-input-invalid'); + } }; $scope.$watch(function() { return self.label && self.input; @@ -11533,7 +11610,8 @@ function labelDirective() { * @module material.components.input * * @description - * Use the `` or the `