|  | /** | 
|  | * | 
|  | * Angular-Material-Mocks | 
|  | * | 
|  | * Developers interested in running their own custom unit tests WITH angular-material.js loaded... | 
|  | * must also include this *mocks* file. Similar to `angular-mocks.js`, `angular-material-mocks.js` | 
|  | * will override and disable specific Angular Material performance settings: | 
|  | * | 
|  | *  - Disabled Theme CSS rule generations | 
|  | *  - Forces $mdAria.expectWithText() to be synchronous | 
|  | *  - Mocks $$rAF.throttle() | 
|  | *  - Captures flush exceptions from $$rAF | 
|  | * | 
|  | */ | 
|  | (function(window, angular, undefined) { | 
|  |  | 
|  | 'use strict'; | 
|  |  | 
|  | /** | 
|  | * @ngdoc module | 
|  | * @name ngMaterial-mock | 
|  | * @packageName angular-material-mocks | 
|  | * | 
|  | * @description | 
|  | * | 
|  | * The `ngMaterial-mock` module provides support | 
|  | * | 
|  | */ | 
|  | angular.module('ngMaterial-mock', [ | 
|  | 'ngMock', | 
|  | 'ngAnimateMock', | 
|  | 'material.core' | 
|  | ]) | 
|  | .config(['$provide', function($provide) { | 
|  |  | 
|  | $provide.factory('$material', ['$animate', '$timeout', function($animate, $timeout) { | 
|  | return { | 
|  | flushOutstandingAnimations: function() { | 
|  | // this code is placed in a try-catch statement | 
|  | // since 1.3 and 1.4 handle their animations differently | 
|  | // and there may be situations where follow-up animations | 
|  | // are run in one version and not the other | 
|  | try { $animate.flush(); } catch(e) {} | 
|  | }, | 
|  | flushInterimElement: function() { | 
|  | this.flushOutstandingAnimations(); | 
|  | $timeout.flush(); | 
|  | this.flushOutstandingAnimations(); | 
|  | $timeout.flush(); | 
|  | this.flushOutstandingAnimations(); | 
|  | $timeout.flush(); | 
|  | } | 
|  | }; | 
|  | }]); | 
|  |  | 
|  | /** | 
|  | * Angular Material dynamically generates Style tags | 
|  | * based on themes and palletes; for each ng-app. | 
|  | * | 
|  | * For testing, we want to disable generation and | 
|  | * <style> DOM injections. So we clear the huge THEME | 
|  | * styles while testing... | 
|  | */ | 
|  | $provide.constant('$MD_THEME_CSS', '/**/'); | 
|  |  | 
|  | /** | 
|  | * Intercept to make .expectWithText() to be synchronous | 
|  | */ | 
|  | $provide.decorator('$mdAria', function($delegate){ | 
|  |  | 
|  | $delegate.expectWithText = function(element, attrName){ | 
|  | $delegate.expect(element, attrName, element.text().trim()); | 
|  | }; | 
|  |  | 
|  | return $delegate; | 
|  | }); | 
|  |  | 
|  | /** | 
|  | * Add throttle() and wrap .flush() to catch `no callbacks present` | 
|  | * errors | 
|  | */ | 
|  | $provide.decorator('$$rAF', function throttleInjector($delegate){ | 
|  |  | 
|  | $delegate.throttle = function(cb) { | 
|  | return function() { | 
|  | cb.apply(this, arguments); | 
|  | }; | 
|  | }; | 
|  |  | 
|  | var ngFlush = $delegate.flush; | 
|  | $delegate.flush = function() { | 
|  | try      { ngFlush();  } | 
|  | catch(e) { ;           } | 
|  | }; | 
|  |  | 
|  | return $delegate; | 
|  | }); | 
|  |  | 
|  | /** | 
|  | * Capture $timeout.flush() errors: "No deferred tasks to be flushed" | 
|  | * errors | 
|  | */ | 
|  | $provide.decorator('$timeout', function throttleInjector($delegate){ | 
|  |  | 
|  | var ngFlush = $delegate.flush; | 
|  | $delegate.flush = function() { | 
|  | var args = Array.prototype.slice.call(arguments); | 
|  | try      { ngFlush.apply($delegate, args);  } | 
|  | catch(e) { ;           } | 
|  | }; | 
|  |  | 
|  | return $delegate; | 
|  | }); | 
|  |  | 
|  | }]) | 
|  |  | 
|  | /** | 
|  | * Stylesheet Mocks used by `animateCss.spec.js` | 
|  | */ | 
|  | window.createMockStyleSheet = function createMockStyleSheet(doc, wind) { | 
|  | doc = doc ? doc[0] : window.document; | 
|  | wind = wind || window; | 
|  |  | 
|  | var node = doc.createElement('style'); | 
|  | var head = doc.getElementsByTagName('head')[0]; | 
|  | head.appendChild(node); | 
|  |  | 
|  | var ss = doc.styleSheets[doc.styleSheets.length - 1]; | 
|  |  | 
|  | return { | 
|  | addRule: function(selector, styles) { | 
|  | styles = addVendorPrefix(styles); | 
|  |  | 
|  | try { | 
|  | ss.insertRule(selector + '{ ' + styles + '}', 0); | 
|  | } | 
|  | catch (e) { | 
|  | try { | 
|  | ss.addRule(selector, styles); | 
|  | } | 
|  | catch (e2) {} | 
|  | } | 
|  | }, | 
|  |  | 
|  | destroy: function() { | 
|  | head.removeChild(node); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Decompose styles, attached specific vendor prefixes | 
|  | * and recompose... | 
|  | * e.g. | 
|  | *    'transition:0.5s linear all; font-size:100px;' | 
|  | * becomes | 
|  | *    '-webkit-transition:0.5s linear all; transition:0.5s linear all; font-size:100px;' | 
|  | */ | 
|  | function addVendorPrefix(styles) { | 
|  | var cache = { }; | 
|  |  | 
|  | // Decompose into cache registry | 
|  | styles | 
|  | .match(/([\-A-Za-z]*)\w\:\w*([A-Za-z0-9\.\-\s]*)/gi) | 
|  | .forEach(function(style){ | 
|  | var pair = style.split(":"); | 
|  | var key = pair[0]; | 
|  |  | 
|  | switch(key) { | 
|  | case 'transition': | 
|  | case 'transform': | 
|  | case 'animation': | 
|  | case 'transition-duration': | 
|  | case 'animation-duration': | 
|  | cache[key] = cache['-webkit-' + key] = pair[1]; | 
|  | break; | 
|  | default: | 
|  | cache[key] = pair[1]; | 
|  | } | 
|  | }); | 
|  |  | 
|  | // Recompose full style object (as string) | 
|  | styles = ""; | 
|  | angular.forEach(cache, function(value, key) { | 
|  | styles = styles + key + ":" + value + "; "; | 
|  | }); | 
|  |  | 
|  | return styles; | 
|  | } | 
|  |  | 
|  | }; | 
|  |  | 
|  | })(window, window.angular); |