nexus site path corrected
[portal.git] / ecomp-portal-FE / client / bower_components / angular-material / modules / closure / dialog / dialog.js
1 /*!
2  * Angular Material Design
3  * https://github.com/angular/material
4  * @license MIT
5  * v0.9.8
6  */
7 goog.provide('ng.material.components.dialog');
8 goog.require('ng.material.components.backdrop');
9 goog.require('ng.material.core');
10 /**
11  * @ngdoc module
12  * @name material.components.dialog
13  */
14 angular.module('material.components.dialog', [
15   'material.core',
16   'material.components.backdrop'
17 ])
18   .directive('mdDialog', MdDialogDirective)
19   .provider('$mdDialog', MdDialogProvider);
20
21 function MdDialogDirective($$rAF, $mdTheming) {
22   return {
23     restrict: 'E',
24     link: function(scope, element, attr) {
25       $mdTheming(element);
26       $$rAF(function() {
27         var content = element[0].querySelector('md-dialog-content');
28         if (content && content.scrollHeight > content.clientHeight) {
29           element.addClass('md-content-overflow');
30         }
31       });
32     }
33   };
34 }
35 MdDialogDirective.$inject = ["$$rAF", "$mdTheming"];
36
37 /**
38  * @ngdoc service
39  * @name $mdDialog
40  * @module material.components.dialog
41  *
42  * @description
43  * `$mdDialog` opens a dialog over the app to inform users about critical information or require
44  *  them to make decisions. There are two approaches for setup: a simple promise API
45  *  and regular object syntax.
46  *
47  * ## Restrictions
48  *
49  * - The dialog is always given an isolate scope.
50  * - The dialog's template must have an outer `<md-dialog>` element.
51  *   Inside, use an `<md-dialog-content>` element for the dialog's content, and use
52  *   an element with class `md-actions` for the dialog's actions.
53  * - Dialogs must cover the entire application to keep interactions inside of them.
54  * Use the `parent` option to change where dialogs are appended.
55  *
56  * ## Sizing
57  * - Complex dialogs can be sized with `flex="percentage"`, i.e. `flex="66"`.
58  * - Default max-width is 80% of the `rootElement` or `parent`.
59  *
60  * @usage
61  * <hljs lang="html">
62  * <div  ng-app="demoApp" ng-controller="EmployeeController">
63  *   <div>
64  *     <md-button ng-click="showAlert()" class="md-raised md-warn">
65  *       Employee Alert!
66  *       </md-button>
67  *   </div>
68  *   <div>
69  *     <md-button ng-click="showDialog($event)" class="md-raised">
70  *       Custom Dialog
71  *       </md-button>
72  *   </div>
73  *   <div>
74  *     <md-button ng-click="closeAlert()" ng-disabled="!hasAlert()" class="md-raised">
75  *       Close Alert
76  *     </md-button>
77  *   </div>
78  *   <div>
79  *     <md-button ng-click="showGreeting($event)" class="md-raised md-primary" >
80  *       Greet Employee
81  *       </md-button>
82  *   </div>
83  * </div>
84  * </hljs>
85  *
86  * ### JavaScript: object syntax
87  * <hljs lang="js">
88  * (function(angular, undefined){
89  *   "use strict";
90  *
91  *   angular
92  *    .module('demoApp', ['ngMaterial'])
93  *    .controller('AppCtrl', AppController);
94  *
95  *   function AppController($scope, $mdDialog) {
96  *     var alert;
97  *     $scope.showAlert = showAlert;
98  *     $scope.showDialog = showDialog;
99  *     $scope.items = [1, 2, 3];
100  *
101  *     // Internal method
102  *     function showAlert() {
103  *       alert = $mdDialog.alert({
104  *         title: 'Attention',
105  *         content: 'This is an example of how easy dialogs can be!',
106  *         ok: 'Close'
107  *       });
108  *
109  *       $mdDialog
110  *         .show( alert )
111  *         .finally(function() {
112  *           alert = undefined;
113  *         });
114  *     }
115  *
116  *     function showDialog($event) {
117  *        var parentEl = angular.element(document.body);
118  *        $mdDialog.show({
119  *          parent: parentEl,
120  *          targetEvent: $event,
121  *          template:
122  *            '<md-dialog aria-label="List dialog">' +
123  *            '  <md-dialog-content>'+
124  *            '    <md-list>'+
125  *            '      <md-list-item ng-repeat="item in items">'+
126  *            '       <p>Number {{item}}</p>' +
127  *            '      </md-item>'+
128  *            '    </md-list>'+
129  *            '  </md-dialog-content>' +
130  *            '  <div class="md-actions">' +
131  *            '    <md-button ng-click="closeDialog()" class="md-primary">' +
132  *            '      Close Dialog' +
133  *            '    </md-button>' +
134  *            '  </div>' +
135  *            '</md-dialog>',
136  *          locals: {
137  *            items: $scope.items
138  *          },
139  *          controller: DialogController
140  *       });
141  *       function DialogController($scope, $mdDialog, items) {
142  *         $scope.items = items;
143  *         $scope.closeDialog = function() {
144  *           $mdDialog.hide();
145  *         }
146  *       }
147  *     }
148  *   }
149  * })(angular);
150  * </hljs>
151  *
152  * ### JavaScript: promise API syntax, custom dialog template
153  * <hljs lang="js">
154  * (function(angular, undefined){
155  *   "use strict";
156  *
157  *   angular
158  *     .module('demoApp', ['ngMaterial'])
159  *     .controller('EmployeeController', EmployeeEditor)
160  *     .controller('GreetingController', GreetingController);
161  *
162  *   // Fictitious Employee Editor to show how to use simple and complex dialogs.
163  *
164  *   function EmployeeEditor($scope, $mdDialog) {
165  *     var alert;
166  *
167  *     $scope.showAlert = showAlert;
168  *     $scope.closeAlert = closeAlert;
169  *     $scope.showGreeting = showCustomGreeting;
170  *
171  *     $scope.hasAlert = function() { return !!alert };
172  *     $scope.userName = $scope.userName || 'Bobby';
173  *
174  *     // Dialog #1 - Show simple alert dialog and cache
175  *     // reference to dialog instance
176  *
177  *     function showAlert() {
178  *       alert = $mdDialog.alert()
179  *         .title('Attention, ' + $scope.userName)
180  *         .content('This is an example of how easy dialogs can be!')
181  *         .ok('Close');
182  *
183  *       $mdDialog
184  *           .show( alert )
185  *           .finally(function() {
186  *             alert = undefined;
187  *           });
188  *     }
189  *
190  *     // Close the specified dialog instance and resolve with 'finished' flag
191  *     // Normally this is not needed, just use '$mdDialog.hide()' to close
192  *     // the most recent dialog popup.
193  *
194  *     function closeAlert() {
195  *       $mdDialog.hide( alert, "finished" );
196  *       alert = undefined;
197  *     }
198  *
199  *     // Dialog #2 - Demonstrate more complex dialogs construction and popup.
200  *
201  *     function showCustomGreeting($event) {
202  *         $mdDialog.show({
203  *           targetEvent: $event,
204  *           template:
205  *             '<md-dialog>' +
206  *
207  *             '  <md-dialog-content>Hello {{ employee }}!</md-dialog-content>' +
208  *
209  *             '  <div class="md-actions">' +
210  *             '    <md-button ng-click="closeDialog()" class="md-primary">' +
211  *             '      Close Greeting' +
212  *             '    </md-button>' +
213  *             '  </div>' +
214  *             '</md-dialog>',
215  *           controller: 'GreetingController',
216  *           onComplete: afterShowAnimation,
217  *           locals: { employee: $scope.userName }
218  *         });
219  *
220  *         // When the 'enter' animation finishes...
221  *
222  *         function afterShowAnimation(scope, element, options) {
223  *            // post-show code here: DOM element focus, etc.
224  *         }
225  *     }
226  *
227  *     // Dialog #3 - Demonstrate use of ControllerAs and passing $scope to dialog
228  *     //             Here we used ng-controller="GreetingController as vm" and
229  *     //             $scope.vm === <controller instance>
230  *
231  *     function showCustomGreeting() {
232  *
233  *        $mdDialog.show({
234  *           clickOutsideToClose: true,
235  *
236  *           scope: $scope,        // use parent scope in template
237  *           preserveScope: true,  // do not forget this if use parent scope
238
239  *           // Since GreetingController is instantiated with ControllerAs syntax
240  *           // AND we are passing the parent '$scope' to the dialog, we MUST
241  *           // use 'vm.<xxx>' in the template markup
242  *
243  *           template: '<md-dialog>' +
244  *                     '  <md-dialog-content>' +
245  *                     '     Hi There {{vm.employee}}' +
246  *                     '  </md-dialog-content>' +
247  *                     '</md-dialog>',
248  *
249  *           controller: function DialogController($scope, $mdDialog) {
250  *             $scope.closeDialog = function() {
251  *               $mdDialog.hide();
252  *             }
253  *           }
254  *        });
255  *     }
256  *
257  *   }
258  *
259  *   // Greeting controller used with the more complex 'showCustomGreeting()' custom dialog
260  *
261  *   function GreetingController($scope, $mdDialog, employee) {
262  *     // Assigned from construction <code>locals</code> options...
263  *     $scope.employee = employee;
264  *
265  *     $scope.closeDialog = function() {
266  *       // Easily hides most recent dialog shown...
267  *       // no specific instance reference is needed.
268  *       $mdDialog.hide();
269  *     };
270  *   }
271  *
272  * })(angular);
273  * </hljs>
274  */
275
276  /**
277  * @ngdoc method
278  * @name $mdDialog#alert
279  *
280  * @description
281  * Builds a preconfigured dialog with the specified message.
282  *
283  * @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
284  *
285  * - $mdDialogPreset#title(string) - sets title to string
286  * - $mdDialogPreset#content(string) - sets content / message to string
287  * - $mdDialogPreset#ok(string) - sets okay button text to string
288  * - $mdDialogPreset#theme(string) - sets the theme of the dialog
289  *
290  */
291
292  /**
293  * @ngdoc method
294  * @name $mdDialog#confirm
295  *
296  * @description
297  * Builds a preconfigured dialog with the specified message. You can call show and the promise returned
298  * will be resolved only if the user clicks the confirm action on the dialog.
299  *
300  * @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
301  *
302  * Additionally, it supports the following methods:
303  *
304  * - $mdDialogPreset#title(string) - sets title to string
305  * - $mdDialogPreset#content(string) - sets content / message to string
306  * - $mdDialogPreset#ok(string) - sets okay button text to string
307  * - $mdDialogPreset#cancel(string) - sets cancel button text to string
308  * - $mdDialogPreset#theme(string) - sets the theme of the dialog
309  *
310  */
311
312 /**
313  * @ngdoc method
314  * @name $mdDialog#show
315  *
316  * @description
317  * Show a dialog with the specified options.
318  *
319  * @param {object} optionsOrPreset Either provide an `$mdDialogPreset` returned from `alert()`, and
320  * `confirm()`, or an options object with the following properties:
321  *   - `templateUrl` - `{string=}`: The url of a template that will be used as the content
322  *   of the dialog.
323  *   - `template` - `{string=}`: Same as templateUrl, except this is an actual template string.
324  *   - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
325  *     the location of the click will be used as the starting point for the opening animation
326  *     of the the dialog.
327  *   - `scope` - `{object=}`: the scope to link the template / controller to. If none is specified,
328  *     it will create a new isolate scope.
329  *     This scope will be destroyed when the dialog is removed unless `preserveScope` is set to true.
330  *   - `preserveScope` - `{boolean=}`: whether to preserve the scope when the element is removed. Default is false
331  *   - `disableParentScroll` - `{boolean=}`: Whether to disable scrolling while the dialog is open.
332  *     Default true.
333  *   - `hasBackdrop` - `{boolean=}`: Whether there should be an opaque backdrop behind the dialog.
334  *     Default true.
335  *   - `clickOutsideToClose` - `{boolean=}`: Whether the user can click outside the dialog to
336  *     close it. Default false.
337  *   - `escapeToClose` - `{boolean=}`: Whether the user can press escape to close the dialog.
338  *     Default true.
339  *   - `focusOnOpen` - `{boolean=}`: An option to override focus behavior on open. Only disable if
340  *     focusing some other way, as focus management is required for dialogs to be accessible.
341  *     Defaults to true.
342  *   - `controller` - `{string=}`: The controller to associate with the dialog. The controller
343  *     will be injected with the local `$mdDialog`, which passes along a scope for the dialog.
344  *   - `locals` - `{object=}`: An object containing key/value pairs. The keys will be used as names
345  *     of values to inject into the controller. For example, `locals: {three: 3}` would inject
346  *     `three` into the controller, with the value 3. If `bindToController` is true, they will be
347  *     copied to the controller instead.
348  *   - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.
349  *     These values will not be available until after initialization.
350  *   - `resolve` - `{object=}`: Similar to locals, except it takes promises as values, and the
351  *     dialog will not open until all of the promises resolve.
352  *   - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
353  *   - `parent` - `{element=}`: The element to append the dialog to. Defaults to appending
354  *     to the root element of the application.
355  *   - `onComplete` `{function=}`: Callback function used to announce when the show() action is
356  *     finished.
357  *
358  * @returns {promise} A promise that can be resolved with `$mdDialog.hide()` or
359  * rejected with `$mdDialog.cancel()`.
360  */
361
362 /**
363  * @ngdoc method
364  * @name $mdDialog#hide
365  *
366  * @description
367  * Hide an existing dialog and resolve the promise returned from `$mdDialog.show()`.
368  *
369  * @param {*=} response An argument for the resolved promise.
370  *
371  * @returns {promise} A promise that is resolved when the dialog has been closed.
372  */
373
374 /**
375  * @ngdoc method
376  * @name $mdDialog#cancel
377  *
378  * @description
379  * Hide an existing dialog and reject the promise returned from `$mdDialog.show()`.
380  *
381  * @param {*=} response An argument for the rejected promise.
382  *
383  * @returns {promise} A promise that is resolved when the dialog has been closed.
384  */
385
386 function MdDialogProvider($$interimElementProvider) {
387
388   var alertDialogMethods = ['title', 'content', 'ariaLabel', 'ok'];
389
390   advancedDialogOptions.$inject = ["$mdDialog", "$mdTheming"];
391   dialogDefaultOptions.$inject = ["$mdAria", "$document", "$mdUtil", "$mdConstant", "$mdTheming", "$mdDialog", "$timeout", "$rootElement", "$animate", "$$rAF", "$q"];
392   return $$interimElementProvider('$mdDialog')
393     .setDefaults({
394       methods: ['disableParentScroll', 'hasBackdrop', 'clickOutsideToClose', 'escapeToClose', 'targetEvent', 'parent'],
395       options: dialogDefaultOptions
396     })
397     .addPreset('alert', {
398       methods: ['title', 'content', 'ariaLabel', 'ok', 'theme'],
399       options: advancedDialogOptions
400     })
401     .addPreset('confirm', {
402       methods: ['title', 'content', 'ariaLabel', 'ok', 'cancel', 'theme'],
403       options: advancedDialogOptions
404     });
405
406   /* ngInject */
407   function advancedDialogOptions($mdDialog, $mdTheming) {
408     return {
409       template: [
410         '<md-dialog md-theme="{{ dialog.theme }}" aria-label="{{ dialog.ariaLabel }}">',
411           '<md-dialog-content role="document" tabIndex="-1">',
412             '<h2 class="md-title">{{ dialog.title }}</h2>',
413             '<p>{{ dialog.content }}</p>',
414           '</md-dialog-content>',
415           '<div class="md-actions">',
416             '<md-button ng-if="dialog.$type == \'confirm\'"' +
417                       ' ng-click="dialog.abort()" class="md-primary">',
418               '{{ dialog.cancel }}',
419             '</md-button>',
420             '<md-button ng-click="dialog.hide()" class="md-primary">',
421               '{{ dialog.ok }}',
422             '</md-button>',
423           '</div>',
424         '</md-dialog>'
425       ].join(''),
426       controller: function mdDialogCtrl() {
427         this.hide = function() {
428           $mdDialog.hide(true);
429         };
430         this.abort = function() {
431           $mdDialog.cancel();
432         };
433       },
434       controllerAs: 'dialog',
435       bindToController: true,
436       theme: $mdTheming.defaultTheme()
437     };
438   }
439
440   /* ngInject */
441   function dialogDefaultOptions($mdAria, $document, $mdUtil, $mdConstant, $mdTheming, $mdDialog, $timeout, $rootElement, $animate, $$rAF, $q) {
442     return {
443       hasBackdrop: true,
444       isolateScope: true,
445       onShow: onShow,
446       onRemove: onRemove,
447       clickOutsideToClose: false,
448       escapeToClose: true,
449       targetEvent: null,
450       focusOnOpen: true,
451       disableParentScroll: true,
452       transformTemplate: function(template) {
453         return '<div class="md-dialog-container">' + template + '</div>';
454       }
455     };
456
457     function trapFocus(ev) {
458       var dialog = document.querySelector('md-dialog');
459
460       if (dialog && !dialog.contains(ev.target)) {
461         ev.stopImmediatePropagation();
462         dialog.focus();
463       }
464     }
465
466     // On show method for dialogs
467     function onShow(scope, element, options) {
468       angular.element($document[0].body).addClass('md-dialog-is-showing');
469       element = $mdUtil.extractElementByName(element, 'md-dialog');
470
471       // Incase the user provides a raw dom element, always wrap it in jqLite
472       options.parent = angular.element(options.parent);
473
474       options.popInTarget = angular.element((options.targetEvent || {}).target);
475       var closeButton = findCloseButton();
476
477       if (options.hasBackdrop) {
478         // Fix for IE 10
479         var computeFrom = (options.parent[0] == $document[0].body && $document[0].documentElement
480                            && $document[0].documentElement.scrollTop) ? angular.element($document[0].documentElement) : options.parent;
481         var parentOffset = computeFrom.prop('scrollTop');
482         options.backdrop = angular.element('<md-backdrop class="md-dialog-backdrop md-opaque">');
483         options.backdrop.css('top', parentOffset +'px');
484         $mdTheming.inherit(options.backdrop, options.parent);
485         $animate.enter(options.backdrop, options.parent);
486         element.css('top', parentOffset +'px');
487       }
488
489       var role = 'dialog',
490           elementToFocus = closeButton;
491
492       if (options.$type === 'alert') {
493         role = 'alertdialog';
494         elementToFocus = element.find('md-dialog-content');
495       }
496
497       configureAria(element.find('md-dialog'), role, options);
498
499       document.addEventListener('focus', trapFocus, true);
500
501       if (options.disableParentScroll) {
502         options.lastOverflow = options.parent.css('overflow');
503         options.parent.css('overflow', 'hidden');
504       }
505
506       return dialogPopIn(
507         element,
508         options.parent,
509         options.popInTarget && options.popInTarget.length && options.popInTarget
510       )
511       .then(function() {
512
513         applyAriaToSiblings(element, true);
514
515         if (options.escapeToClose) {
516           options.rootElementKeyupCallback = function(e) {
517             if (e.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
518               $timeout($mdDialog.cancel);
519             }
520           };
521           $rootElement.on('keyup', options.rootElementKeyupCallback);
522         }
523
524         if (options.clickOutsideToClose) {
525           options.dialogClickOutsideCallback = function(ev) {
526             // Only close if we click the flex container outside the backdrop
527             if (ev.target === element[0]) {
528               $timeout($mdDialog.cancel);
529             }
530           };
531           element.on('click', options.dialogClickOutsideCallback);
532         }
533
534         if (options.focusOnOpen) {
535           elementToFocus.focus();
536         }
537       });
538
539
540       function findCloseButton() {
541         //If no element with class dialog-close, try to find the last
542         //button child in md-actions and assume it is a close button
543         var closeButton = element[0].querySelector('.dialog-close');
544         if (!closeButton) {
545           var actionButtons = element[0].querySelectorAll('.md-actions button');
546           closeButton = actionButtons[ actionButtons.length - 1 ];
547         }
548         return angular.element(closeButton);
549       }
550
551     }
552
553     // On remove function for all dialogs
554     function onRemove(scope, element, options) {
555       angular.element($document[0].body).removeClass('md-dialog-is-showing');
556
557       if (options.backdrop) {
558         $animate.leave(options.backdrop);
559       }
560       if (options.disableParentScroll) {
561         options.parent.css('overflow', options.lastOverflow);
562         delete options.lastOverflow;
563       }
564       if (options.escapeToClose) {
565         $rootElement.off('keyup', options.rootElementKeyupCallback);
566       }
567       if (options.clickOutsideToClose) {
568         element.off('click', options.dialogClickOutsideCallback);
569       }
570
571       applyAriaToSiblings(element, false);
572
573       document.removeEventListener('focus', trapFocus, true);
574
575       return dialogPopOut(
576         element,
577         options.parent,
578         options.popInTarget && options.popInTarget.length && options.popInTarget
579       ).then(function() {
580         element.remove();
581         options.popInTarget && options.popInTarget.focus();
582       });
583
584     }
585
586     /**
587      * Inject ARIA-specific attributes appropriate for Dialogs
588      */
589     function configureAria(element, role, options) {
590
591       element.attr({
592         'role': role,
593         'tabIndex': '-1'
594       });
595
596       var dialogContent = element.find('md-dialog-content');
597       if (dialogContent.length === 0){
598         dialogContent = element;
599       }
600
601       var dialogId = element.attr('id') || ('dialog_' + $mdUtil.nextUid());
602       dialogContent.attr('id', dialogId);
603       element.attr('aria-describedby', dialogId);
604
605       if (options.ariaLabel) {
606         $mdAria.expect(element, 'aria-label', options.ariaLabel);
607       }
608       else {
609         $mdAria.expectAsync(element, 'aria-label', function() {
610           var words = dialogContent.text().split(/\s+/);
611           if (words.length > 3) words = words.slice(0,3).concat('...');
612           return words.join(' ');
613         });
614       }
615     }
616     /**
617      * Utility function to filter out raw DOM nodes
618      */
619     function isNodeOneOf(elem, nodeTypeArray) {
620       if (nodeTypeArray.indexOf(elem.nodeName) !== -1) {
621         return true;
622       }
623     }
624     /**
625      * Walk DOM to apply or remove aria-hidden on sibling nodes
626      * and parent sibling nodes
627      *
628      * Prevents screen reader interaction behind modal window
629      * on swipe interfaces
630      */
631     function applyAriaToSiblings(element, value) {
632       var attribute = 'aria-hidden';
633
634       // get raw DOM node
635       element = element[0];
636
637       function walkDOM(element) {
638         while (element.parentNode) {
639           if (element === document.body) {
640             return;
641           }
642           var children = element.parentNode.children;
643           for (var i = 0; i < children.length; i++) {
644             // skip over child if it is an ascendant of the dialog
645             // or a script or style tag
646             if (element !== children[i] && !isNodeOneOf(children[i], ['SCRIPT', 'STYLE'])) {
647               children[i].setAttribute(attribute, value);
648             }
649           }
650
651           walkDOM(element = element.parentNode);
652         }
653       }
654       walkDOM(element);
655     }
656
657     function dialogPopIn(container, parentElement, clickElement) {
658       var dialogEl = container.find('md-dialog');
659
660       parentElement.append(container);
661       transformToClickElement(dialogEl, clickElement);
662
663       $$rAF(function() {
664         dialogEl.addClass('transition-in')
665           .css($mdConstant.CSS.TRANSFORM, '');
666       });
667
668       return $mdUtil.transitionEndPromise(dialogEl);
669     }
670
671     function dialogPopOut(container, parentElement, clickElement) {
672       var dialogEl = container.find('md-dialog');
673
674       dialogEl.addClass('transition-out').removeClass('transition-in');
675       transformToClickElement(dialogEl, clickElement);
676
677       return $mdUtil.transitionEndPromise(dialogEl);
678     }
679
680     function transformToClickElement(dialogEl, clickElement) {
681       if (clickElement) {
682         var clickRect = clickElement[0].getBoundingClientRect();
683         var dialogRect = dialogEl[0].getBoundingClientRect();
684
685         var scaleX = Math.min(0.5, clickRect.width / dialogRect.width);
686         var scaleY = Math.min(0.5, clickRect.height / dialogRect.height);
687
688         dialogEl.css($mdConstant.CSS.TRANSFORM, 'translate3d(' +
689           (-dialogRect.left + clickRect.left + clickRect.width/2 - dialogRect.width/2) + 'px,' +
690           (-dialogRect.top + clickRect.top + clickRect.height/2 - dialogRect.height/2) + 'px,' +
691           '0) scale(' + scaleX + ',' + scaleY + ')'
692         );
693       }
694     }
695
696     function dialogTransitionEnd(dialogEl) {
697       var deferred = $q.defer();
698       dialogEl.on($mdConstant.CSS.TRANSITIONEND, finished);
699       function finished(ev) {
700         //Make sure this transitionend didn't bubble up from a child
701         if (ev.target === dialogEl[0]) {
702           dialogEl.off($mdConstant.CSS.TRANSITIONEND, finished);
703           deferred.resolve();
704         }
705       }
706       return deferred.promise;
707     }
708
709   }
710 }
711 MdDialogProvider.$inject = ["$$interimElementProvider"];
712
713 ng.material.components.dialog = angular.module("material.components.dialog");