arnaucube
arnaucube/commonroutesAppPublic Self-hosted repository
commonroutesApp/www/lib/angular-material/modules/js/dialog/dialog.js
www/lib/angular-material/modules/js/dialog/dialog.jsRaw
   1/*!
   2 * Angular Material Design
   3 * https://github.com/angular/material
   4 * @license MIT
   5 * v1.1.1
   6 */
   7(function( window, angular, undefined ){
   8"use strict";
   9
  10/**
  11 * @ngdoc module
  12 * @name material.components.dialog
  13 */
  14MdDialogDirective.$inject = ["$$rAF", "$mdTheming", "$mdDialog"];
  15MdDialogProvider.$inject = ["$$interimElementProvider"];
  16angular
  17  .module('material.components.dialog', [
  18    'material.core',
  19    'material.components.backdrop'
  20  ])
  21  .directive('mdDialog', MdDialogDirective)
  22  .provider('$mdDialog', MdDialogProvider);
  23
  24/**
  25 * @ngdoc directive
  26 * @name mdDialog
  27 * @module material.components.dialog
  28 *
  29 * @restrict E
  30 *
  31 * @description
  32 * `<md-dialog>` - The dialog's template must be inside this element.
  33 *
  34 * Inside, use an `<md-dialog-content>` element for the dialog's content, and use
  35 * an `<md-dialog-actions>` element for the dialog's actions.
  36 *
  37 * ## CSS
  38 * - `.md-dialog-content` - class that sets the padding on the content as the spec file
  39 *
  40 * ## Notes
  41 * - If you specify an `id` for the `<md-dialog>`, the `<md-dialog-content>` will have the same `id`
  42 * prefixed with `dialogContent_`.
  43 *
  44 * @usage
  45 * ### Dialog template
  46 * <hljs lang="html">
  47 * <md-dialog aria-label="List dialog">
  48 *   <md-dialog-content>
  49 *     <md-list>
  50 *       <md-list-item ng-repeat="item in items">
  51 *         <p>Number {{item}}</p>
  52 *       </md-list-item>
  53 *     </md-list>
  54 *   </md-dialog-content>
  55 *   <md-dialog-actions>
  56 *     <md-button ng-click="closeDialog()" class="md-primary">Close Dialog</md-button>
  57 *   </md-dialog-actions>
  58 * </md-dialog>
  59 * </hljs>
  60 */
  61function MdDialogDirective($$rAF, $mdTheming, $mdDialog) {
  62  return {
  63    restrict: 'E',
  64    link: function(scope, element) {
  65      element.addClass('_md');     // private md component indicator for styling
  66
  67      $mdTheming(element);
  68      $$rAF(function() {
  69        var images;
  70        var content = element[0].querySelector('md-dialog-content');
  71
  72        if (content) {
  73          images = content.getElementsByTagName('img');
  74          addOverflowClass();
  75          //-- delayed image loading may impact scroll height, check after images are loaded
  76          angular.element(images).on('load', addOverflowClass);
  77        }
  78
  79        scope.$on('$destroy', function() {
  80          $mdDialog.destroy(element);
  81        });
  82
  83        /**
  84         *
  85         */
  86        function addOverflowClass() {
  87          element.toggleClass('md-content-overflow', content.scrollHeight > content.clientHeight);
  88        }
  89
  90
  91      });
  92    }
  93  };
  94}
  95
  96/**
  97 * @ngdoc service
  98 * @name $mdDialog
  99 * @module material.components.dialog
 100 *
 101 * @description
 102 * `$mdDialog` opens a dialog over the app to inform users about critical information or require
 103 *  them to make decisions. There are two approaches for setup: a simple promise API
 104 *  and regular object syntax.
 105 *
 106 * ## Restrictions
 107 *
 108 * - The dialog is always given an isolate scope.
 109 * - The dialog's template must have an outer `<md-dialog>` element.
 110 *   Inside, use an `<md-dialog-content>` element for the dialog's content, and use
 111 *   an `<md-dialog-actions>` element for the dialog's actions.
 112 * - Dialogs must cover the entire application to keep interactions inside of them.
 113 * Use the `parent` option to change where dialogs are appended.
 114 *
 115 * ## Sizing
 116 * - Complex dialogs can be sized with `flex="percentage"`, i.e. `flex="66"`.
 117 * - Default max-width is 80% of the `rootElement` or `parent`.
 118 *
 119 * ## CSS
 120 * - `.md-dialog-content` - class that sets the padding on the content as the spec file
 121 *
 122 * @usage
 123 * <hljs lang="html">
 124 * <div  ng-app="demoApp" ng-controller="EmployeeController">
 125 *   <div>
 126 *     <md-button ng-click="showAlert()" class="md-raised md-warn">
 127 *       Employee Alert!
 128 *       </md-button>
 129 *   </div>
 130 *   <div>
 131 *     <md-button ng-click="showDialog($event)" class="md-raised">
 132 *       Custom Dialog
 133 *       </md-button>
 134 *   </div>
 135 *   <div>
 136 *     <md-button ng-click="closeAlert()" ng-disabled="!hasAlert()" class="md-raised">
 137 *       Close Alert
 138 *     </md-button>
 139 *   </div>
 140 *   <div>
 141 *     <md-button ng-click="showGreeting($event)" class="md-raised md-primary" >
 142 *       Greet Employee
 143 *       </md-button>
 144 *   </div>
 145 * </div>
 146 * </hljs>
 147 *
 148 * ### JavaScript: object syntax
 149 * <hljs lang="js">
 150 * (function(angular, undefined){
 151 *   "use strict";
 152 *
 153 *   angular
 154 *    .module('demoApp', ['ngMaterial'])
 155 *    .controller('AppCtrl', AppController);
 156 *
 157 *   function AppController($scope, $mdDialog) {
 158 *     var alert;
 159 *     $scope.showAlert = showAlert;
 160 *     $scope.showDialog = showDialog;
 161 *     $scope.items = [1, 2, 3];
 162 *
 163 *     // Internal method
 164 *     function showAlert() {
 165 *       alert = $mdDialog.alert({
 166 *         title: 'Attention',
 167 *         textContent: 'This is an example of how easy dialogs can be!',
 168 *         ok: 'Close'
 169 *       });
 170 *
 171 *       $mdDialog
 172 *         .show( alert )
 173 *         .finally(function() {
 174 *           alert = undefined;
 175 *         });
 176 *     }
 177 *
 178 *     function showDialog($event) {
 179 *        var parentEl = angular.element(document.body);
 180 *        $mdDialog.show({
 181 *          parent: parentEl,
 182 *          targetEvent: $event,
 183 *          template:
 184 *            '<md-dialog aria-label="List dialog">' +
 185 *            '  <md-dialog-content>'+
 186 *            '    <md-list>'+
 187 *            '      <md-list-item ng-repeat="item in items">'+
 188 *            '       <p>Number {{item}}</p>' +
 189 *            '      </md-item>'+
 190 *            '    </md-list>'+
 191 *            '  </md-dialog-content>' +
 192 *            '  <md-dialog-actions>' +
 193 *            '    <md-button ng-click="closeDialog()" class="md-primary">' +
 194 *            '      Close Dialog' +
 195 *            '    </md-button>' +
 196 *            '  </md-dialog-actions>' +
 197 *            '</md-dialog>',
 198 *          locals: {
 199 *            items: $scope.items
 200 *          },
 201 *          controller: DialogController
 202 *       });
 203 *       function DialogController($scope, $mdDialog, items) {
 204 *         $scope.items = items;
 205 *         $scope.closeDialog = function() {
 206 *           $mdDialog.hide();
 207 *         }
 208 *       }
 209 *     }
 210 *   }
 211 * })(angular);
 212 * </hljs>
 213 *
 214 * ### Pre-Rendered Dialogs
 215 * By using the `contentElement` option, it is possible to use an already existing element in the DOM.
 216 *
 217 * <hljs lang="js">
 218 *   $scope.showPrerenderedDialog = function() {
 219 *     $mdDialog.show({
 220 *       contentElement: '#myStaticDialog',
 221 *       parent: angular.element(document.body)
 222 *     });
 223 *   };
 224 * </hljs>
 225 *
 226 * When using a string as value, `$mdDialog` will automatically query the DOM for the specified CSS selector.
 227 *
 228 * <hljs lang="html">
 229 *   <div style="visibility: hidden">
 230 *     <div class="md-dialog-container" id="myStaticDialog">
 231 *       <md-dialog>
 232 *         This is a pre-rendered dialog.
 233 *       </md-dialog>
 234 *     </div>
 235 *   </div>
 236 * </hljs>
 237 *
 238 * **Notice**: It is important, to use the `.md-dialog-container` as the content element, otherwise the dialog
 239 * will not show up.
 240 *
 241 * It also possible to use a DOM element for the `contentElement` option.
 242 * - `contentElement: document.querySelector('#myStaticDialog')`
 243 * - `contentElement: angular.element(TEMPLATE)`
 244 *
 245 * When using a `template` as content element, it will be not compiled upon open.
 246 * This allows you to compile the element yourself and use it each time the dialog opens.
 247 *
 248 * ### Custom Presets
 249 * Developers are also able to create their own preset, which can be easily used without repeating
 250 * their options each time.
 251 *
 252 * <hljs lang="js">
 253 *   $mdDialogProvider.addPreset('testPreset', {
 254 *     options: function() {
 255 *       return {
 256 *         template:
 257 *           '<md-dialog>' +
 258 *             'This is a custom preset' +
 259 *           '</md-dialog>',
 260 *         controllerAs: 'dialog',
 261 *         bindToController: true,
 262 *         clickOutsideToClose: true,
 263 *         escapeToClose: true
 264 *       };
 265 *     }
 266 *   });
 267 * </hljs>
 268 *
 269 * After you created your preset at config phase, you can easily access it.
 270 *
 271 * <hljs lang="js">
 272 *   $mdDialog.show(
 273 *     $mdDialog.testPreset()
 274 *   );
 275 * </hljs>
 276 *
 277 * ### JavaScript: promise API syntax, custom dialog template
 278 * <hljs lang="js">
 279 * (function(angular, undefined){
 280 *   "use strict";
 281 *
 282 *   angular
 283 *     .module('demoApp', ['ngMaterial'])
 284 *     .controller('EmployeeController', EmployeeEditor)
 285 *     .controller('GreetingController', GreetingController);
 286 *
 287 *   // Fictitious Employee Editor to show how to use simple and complex dialogs.
 288 *
 289 *   function EmployeeEditor($scope, $mdDialog) {
 290 *     var alert;
 291 *
 292 *     $scope.showAlert = showAlert;
 293 *     $scope.closeAlert = closeAlert;
 294 *     $scope.showGreeting = showCustomGreeting;
 295 *
 296 *     $scope.hasAlert = function() { return !!alert };
 297 *     $scope.userName = $scope.userName || 'Bobby';
 298 *
 299 *     // Dialog #1 - Show simple alert dialog and cache
 300 *     // reference to dialog instance
 301 *
 302 *     function showAlert() {
 303 *       alert = $mdDialog.alert()
 304 *         .title('Attention, ' + $scope.userName)
 305 *         .textContent('This is an example of how easy dialogs can be!')
 306 *         .ok('Close');
 307 *
 308 *       $mdDialog
 309 *           .show( alert )
 310 *           .finally(function() {
 311 *             alert = undefined;
 312 *           });
 313 *     }
 314 *
 315 *     // Close the specified dialog instance and resolve with 'finished' flag
 316 *     // Normally this is not needed, just use '$mdDialog.hide()' to close
 317 *     // the most recent dialog popup.
 318 *
 319 *     function closeAlert() {
 320 *       $mdDialog.hide( alert, "finished" );
 321 *       alert = undefined;
 322 *     }
 323 *
 324 *     // Dialog #2 - Demonstrate more complex dialogs construction and popup.
 325 *
 326 *     function showCustomGreeting($event) {
 327 *         $mdDialog.show({
 328 *           targetEvent: $event,
 329 *           template:
 330 *             '<md-dialog>' +
 331 *
 332 *             '  <md-dialog-content>Hello {{ employee }}!</md-dialog-content>' +
 333 *
 334 *             '  <md-dialog-actions>' +
 335 *             '    <md-button ng-click="closeDialog()" class="md-primary">' +
 336 *             '      Close Greeting' +
 337 *             '    </md-button>' +
 338 *             '  </md-dialog-actions>' +
 339 *             '</md-dialog>',
 340 *           controller: 'GreetingController',
 341 *           onComplete: afterShowAnimation,
 342 *           locals: { employee: $scope.userName }
 343 *         });
 344 *
 345 *         // When the 'enter' animation finishes...
 346 *
 347 *         function afterShowAnimation(scope, element, options) {
 348 *            // post-show code here: DOM element focus, etc.
 349 *         }
 350 *     }
 351 *
 352 *     // Dialog #3 - Demonstrate use of ControllerAs and passing $scope to dialog
 353 *     //             Here we used ng-controller="GreetingController as vm" and
 354 *     //             $scope.vm === <controller instance>
 355 *
 356 *     function showCustomGreeting() {
 357 *
 358 *        $mdDialog.show({
 359 *           clickOutsideToClose: true,
 360 *
 361 *           scope: $scope,        // use parent scope in template
 362 *           preserveScope: true,  // do not forget this if use parent scope
 363
 364 *           // Since GreetingController is instantiated with ControllerAs syntax
 365 *           // AND we are passing the parent '$scope' to the dialog, we MUST
 366 *           // use 'vm.<xxx>' in the template markup
 367 *
 368 *           template: '<md-dialog>' +
 369 *                     '  <md-dialog-content>' +
 370 *                     '     Hi There {{vm.employee}}' +
 371 *                     '  </md-dialog-content>' +
 372 *                     '</md-dialog>',
 373 *
 374 *           controller: function DialogController($scope, $mdDialog) {
 375 *             $scope.closeDialog = function() {
 376 *               $mdDialog.hide();
 377 *             }
 378 *           }
 379 *        });
 380 *     }
 381 *
 382 *   }
 383 *
 384 *   // Greeting controller used with the more complex 'showCustomGreeting()' custom dialog
 385 *
 386 *   function GreetingController($scope, $mdDialog, employee) {
 387 *     // Assigned from construction <code>locals</code> options...
 388 *     $scope.employee = employee;
 389 *
 390 *     $scope.closeDialog = function() {
 391 *       // Easily hides most recent dialog shown...
 392 *       // no specific instance reference is needed.
 393 *       $mdDialog.hide();
 394 *     };
 395 *   }
 396 *
 397 * })(angular);
 398 * </hljs>
 399 */
 400
 401/**
 402 * @ngdoc method
 403 * @name $mdDialog#alert
 404 *
 405 * @description
 406 * Builds a preconfigured dialog with the specified message.
 407 *
 408 * @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
 409 *
 410 * - $mdDialogPreset#title(string) - Sets the alert title.
 411 * - $mdDialogPreset#textContent(string) - Sets the alert message.
 412 * - $mdDialogPreset#htmlContent(string) - Sets the alert message as HTML. Requires ngSanitize
 413 *     module to be loaded. HTML is not run through Angular's compiler.
 414 * - $mdDialogPreset#ok(string) - Sets the alert "Okay" button text.
 415 * - $mdDialogPreset#theme(string) - Sets the theme of the alert dialog.
 416 * - $mdDialogPreset#targetEvent(DOMClickEvent=) - A click's event object. When passed in as an option,
 417 *     the location of the click will be used as the starting point for the opening animation
 418 *     of the the dialog.
 419 *
 420 */
 421
 422/**
 423 * @ngdoc method
 424 * @name $mdDialog#confirm
 425 *
 426 * @description
 427 * Builds a preconfigured dialog with the specified message. You can call show and the promise returned
 428 * will be resolved only if the user clicks the confirm action on the dialog.
 429 *
 430 * @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
 431 *
 432 * Additionally, it supports the following methods:
 433 *
 434 * - $mdDialogPreset#title(string) - Sets the confirm title.
 435 * - $mdDialogPreset#textContent(string) - Sets the confirm message.
 436 * - $mdDialogPreset#htmlContent(string) - Sets the confirm message as HTML. Requires ngSanitize
 437 *     module to be loaded. HTML is not run through Angular's compiler.
 438 * - $mdDialogPreset#ok(string) - Sets the confirm "Okay" button text.
 439 * - $mdDialogPreset#cancel(string) - Sets the confirm "Cancel" button text.
 440 * - $mdDialogPreset#theme(string) - Sets the theme of the confirm dialog.
 441 * - $mdDialogPreset#targetEvent(DOMClickEvent=) - A click's event object. When passed in as an option,
 442 *     the location of the click will be used as the starting point for the opening animation
 443 *     of the the dialog.
 444 *
 445 */
 446
 447/**
 448 * @ngdoc method
 449 * @name $mdDialog#prompt
 450 *
 451 * @description
 452 * Builds a preconfigured dialog with the specified message and input box. You can call show and the promise returned
 453 * will be resolved only if the user clicks the prompt action on the dialog, passing the input value as the first argument.
 454 *
 455 * @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
 456 *
 457 * Additionally, it supports the following methods:
 458 *
 459 * - $mdDialogPreset#title(string) - Sets the prompt title.
 460 * - $mdDialogPreset#textContent(string) - Sets the prompt message.
 461 * - $mdDialogPreset#htmlContent(string) - Sets the prompt message as HTML. Requires ngSanitize
 462 *     module to be loaded. HTML is not run through Angular's compiler.
 463 * - $mdDialogPreset#placeholder(string) - Sets the placeholder text for the input.
 464 * - $mdDialogPreset#initialValue(string) - Sets the initial value for the prompt input.
 465 * - $mdDialogPreset#ok(string) - Sets the prompt "Okay" button text.
 466 * - $mdDialogPreset#cancel(string) - Sets the prompt "Cancel" button text.
 467 * - $mdDialogPreset#theme(string) - Sets the theme of the prompt dialog.
 468 * - $mdDialogPreset#targetEvent(DOMClickEvent=) - A click's event object. When passed in as an option,
 469 *     the location of the click will be used as the starting point for the opening animation
 470 *     of the the dialog.
 471 *
 472 */
 473
 474/**
 475 * @ngdoc method
 476 * @name $mdDialog#show
 477 *
 478 * @description
 479 * Show a dialog with the specified options.
 480 *
 481 * @param {object} optionsOrPreset Either provide an `$mdDialogPreset` returned from `alert()`, and
 482 * `confirm()`, or an options object with the following properties:
 483 *   - `templateUrl` - `{string=}`: The url of a template that will be used as the content
 484 *   of the dialog.
 485 *   - `template` - `{string=}`: HTML template to show in the dialog. This **must** be trusted HTML
 486 *      with respect to Angular's [$sce service](https://docs.angularjs.org/api/ng/service/$sce).
 487 *      This template should **never** be constructed with any kind of user input or user data.
 488 *   - `contentElement` - `{string|Element}`: Instead of using a template, which will be compiled each time a
 489 *     dialog opens, you can also use a DOM element.<br/>
 490 *     * When specifying an element, which is present on the DOM, `$mdDialog` will temporary fetch the element into
 491 *       the dialog and restores it at the old DOM position upon close.
 492 *     * When specifying a string, the string be used as a CSS selector, to lookup for the element in the DOM.
 493 *   - `autoWrap` - `{boolean=}`: Whether or not to automatically wrap the template with a
 494 *     `<md-dialog>` tag if one is not provided. Defaults to true. Can be disabled if you provide a
 495 *     custom dialog directive.
 496 *   - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
 497 *     the location of the click will be used as the starting point for the opening animation
 498 *     of the the dialog.
 499 *   - `openFrom` - `{string|Element|object}`: The query selector, DOM element or the Rect object
 500 *     that is used to determine the bounds (top, left, height, width) from which the Dialog will
 501 *     originate.
 502 *   - `closeTo` - `{string|Element|object}`: The query selector, DOM element or the Rect object
 503 *     that is used to determine the bounds (top, left, height, width) to which the Dialog will
 504 *     target.
 505 *   - `scope` - `{object=}`: the scope to link the template / controller to. If none is specified,
 506 *     it will create a new isolate scope.
 507 *     This scope will be destroyed when the dialog is removed unless `preserveScope` is set to true.
 508 *   - `preserveScope` - `{boolean=}`: whether to preserve the scope when the element is removed. Default is false
 509 *   - `disableParentScroll` - `{boolean=}`: Whether to disable scrolling while the dialog is open.
 510 *     Default true.
 511 *   - `hasBackdrop` - `{boolean=}`: Whether there should be an opaque backdrop behind the dialog.
 512 *     Default true.
 513 *   - `clickOutsideToClose` - `{boolean=}`: Whether the user can click outside the dialog to
 514 *     close it. Default false.
 515 *   - `escapeToClose` - `{boolean=}`: Whether the user can press escape to close the dialog.
 516 *     Default true.
 517 *   - `focusOnOpen` - `{boolean=}`: An option to override focus behavior on open. Only disable if
 518 *     focusing some other way, as focus management is required for dialogs to be accessible.
 519 *     Defaults to true.
 520 *   - `controller` - `{function|string=}`: The controller to associate with the dialog. The controller
 521 *     will be injected with the local `$mdDialog`, which passes along a scope for the dialog.
 522 *   - `locals` - `{object=}`: An object containing key/value pairs. The keys will be used as names
 523 *     of values to inject into the controller. For example, `locals: {three: 3}` would inject
 524 *     `three` into the controller, with the value 3. If `bindToController` is true, they will be
 525 *     copied to the controller instead.
 526 *   - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.
 527 *   - `resolve` - `{object=}`: Similar to locals, except it takes promises as values, and the
 528 *     dialog will not open until all of the promises resolve.
 529 *   - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
 530 *   - `parent` - `{element=}`: The element to append the dialog to. Defaults to appending
 531 *     to the root element of the application.
 532 *   - `onShowing` - `function(scope, element)`: Callback function used to announce the show() action is
 533 *     starting.
 534 *   - `onComplete` - `function(scope, element)`: Callback function used to announce when the show() action is
 535 *     finished.
 536 *   - `onRemoving` - `function(element, removePromise)`: Callback function used to announce the
 537 *      close/hide() action is starting. This allows developers to run custom animations
 538 *      in parallel the close animations.
 539 *   - `fullscreen` `{boolean=}`: An option to toggle whether the dialog should show in fullscreen
 540 *      or not. Defaults to `false`.
 541 * @returns {promise} A promise that can be resolved with `$mdDialog.hide()` or
 542 * rejected with `$mdDialog.cancel()`.
 543 */
 544
 545/**
 546 * @ngdoc method
 547 * @name $mdDialog#hide
 548 *
 549 * @description
 550 * Hide an existing dialog and resolve the promise returned from `$mdDialog.show()`.
 551 *
 552 * @param {*=} response An argument for the resolved promise.
 553 *
 554 * @returns {promise} A promise that is resolved when the dialog has been closed.
 555 */
 556
 557/**
 558 * @ngdoc method
 559 * @name $mdDialog#cancel
 560 *
 561 * @description
 562 * Hide an existing dialog and reject the promise returned from `$mdDialog.show()`.
 563 *
 564 * @param {*=} response An argument for the rejected promise.
 565 *
 566 * @returns {promise} A promise that is resolved when the dialog has been closed.
 567 */
 568
 569function MdDialogProvider($$interimElementProvider) {
 570  // Elements to capture and redirect focus when the user presses tab at the dialog boundary.
 571  advancedDialogOptions.$inject = ["$mdDialog", "$mdConstant"];
 572  dialogDefaultOptions.$inject = ["$mdDialog", "$mdAria", "$mdUtil", "$mdConstant", "$animate", "$document", "$window", "$rootElement", "$log", "$injector", "$mdTheming"];
 573  var topFocusTrap, bottomFocusTrap;
 574
 575  return $$interimElementProvider('$mdDialog')
 576    .setDefaults({
 577      methods: ['disableParentScroll', 'hasBackdrop', 'clickOutsideToClose', 'escapeToClose',
 578          'targetEvent', 'closeTo', 'openFrom', 'parent', 'fullscreen', 'contentElement'],
 579      options: dialogDefaultOptions
 580    })
 581    .addPreset('alert', {
 582      methods: ['title', 'htmlContent', 'textContent', 'content', 'ariaLabel', 'ok', 'theme',
 583          'css'],
 584      options: advancedDialogOptions
 585    })
 586    .addPreset('confirm', {
 587      methods: ['title', 'htmlContent', 'textContent', 'content', 'ariaLabel', 'ok', 'cancel',
 588          'theme', 'css'],
 589      options: advancedDialogOptions
 590    })
 591    .addPreset('prompt', {
 592      methods: ['title', 'htmlContent', 'textContent', 'initialValue', 'content', 'placeholder', 'ariaLabel',
 593          'ok', 'cancel', 'theme', 'css'],
 594      options: advancedDialogOptions
 595    });
 596
 597  /* ngInject */
 598  function advancedDialogOptions($mdDialog, $mdConstant) {
 599    return {
 600      template: [
 601        '<md-dialog md-theme="{{ dialog.theme }}" aria-label="{{ dialog.ariaLabel }}" ng-class="dialog.css">',
 602        '  <md-dialog-content class="md-dialog-content" role="document" tabIndex="-1">',
 603        '    <h2 class="md-title">{{ dialog.title }}</h2>',
 604        '    <div ng-if="::dialog.mdHtmlContent" class="md-dialog-content-body" ',
 605        '        ng-bind-html="::dialog.mdHtmlContent"></div>',
 606        '    <div ng-if="::!dialog.mdHtmlContent" class="md-dialog-content-body">',
 607        '      <p>{{::dialog.mdTextContent}}</p>',
 608        '    </div>',
 609        '    <md-input-container md-no-float ng-if="::dialog.$type == \'prompt\'" class="md-prompt-input-container">',
 610        '      <input ng-keypress="dialog.keypress($event)" md-autofocus ng-model="dialog.result" ' +
 611        '             placeholder="{{::dialog.placeholder}}">',
 612        '    </md-input-container>',
 613        '  </md-dialog-content>',
 614        '  <md-dialog-actions>',
 615        '    <md-button ng-if="dialog.$type === \'confirm\' || dialog.$type === \'prompt\'"' +
 616        '               ng-click="dialog.abort()" class="md-primary md-cancel-button">',
 617        '      {{ dialog.cancel }}',
 618        '    </md-button>',
 619        '    <md-button ng-click="dialog.hide()" class="md-primary md-confirm-button" md-autofocus="dialog.$type===\'alert\'">',
 620        '      {{ dialog.ok }}',
 621        '    </md-button>',
 622        '  </md-dialog-actions>',
 623        '</md-dialog>'
 624      ].join('').replace(/\s\s+/g, ''),
 625      controller: function mdDialogCtrl() {
 626        var isPrompt = this.$type == 'prompt';
 627
 628        if (isPrompt && this.initialValue) {
 629          this.result = this.initialValue;
 630        }
 631
 632        this.hide = function() {
 633          $mdDialog.hide(isPrompt ? this.result : true);
 634        };
 635        this.abort = function() {
 636          $mdDialog.cancel();
 637        };
 638        this.keypress = function($event) {
 639          if ($event.keyCode === $mdConstant.KEY_CODE.ENTER) {
 640            $mdDialog.hide(this.result);
 641          }
 642        };
 643      },
 644      controllerAs: 'dialog',
 645      bindToController: true,
 646    };
 647  }
 648
 649  /* ngInject */
 650  function dialogDefaultOptions($mdDialog, $mdAria, $mdUtil, $mdConstant, $animate, $document, $window, $rootElement,
 651                                $log, $injector, $mdTheming) {
 652
 653    return {
 654      hasBackdrop: true,
 655      isolateScope: true,
 656      onCompiling: beforeCompile,
 657      onShow: onShow,
 658      onShowing: beforeShow,
 659      onRemove: onRemove,
 660      clickOutsideToClose: false,
 661      escapeToClose: true,
 662      targetEvent: null,
 663      contentElement: null,
 664      closeTo: null,
 665      openFrom: null,
 666      focusOnOpen: true,
 667      disableParentScroll: true,
 668      autoWrap: true,
 669      fullscreen: false,
 670      transformTemplate: function(template, options) {
 671        // Make the dialog container focusable, because otherwise the focus will be always redirected to
 672        // an element outside of the container, and the focus trap won't work probably..
 673        // Also the tabindex is needed for the `escapeToClose` functionality, because
 674        // the keyDown event can't be triggered when the focus is outside of the container.
 675        return '<div class="md-dialog-container" tabindex="-1">' + validatedTemplate(template) + '</div>';
 676
 677        /**
 678         * The specified template should contain a <md-dialog> wrapper element....
 679         */
 680        function validatedTemplate(template) {
 681          if (options.autoWrap && !/<\/md-dialog>/g.test(template)) {
 682            return '<md-dialog>' + (template || '') + '</md-dialog>';
 683          } else {
 684            return template || '';
 685          }
 686        }
 687      }
 688    };
 689
 690    function beforeCompile(options) {
 691      // Automatically apply the theme, if the user didn't specify a theme explicitly.
 692      // Those option changes need to be done, before the compilation has started, because otherwise
 693      // the option changes will be not available in the $mdCompilers locales.
 694      detectTheming(options);
 695
 696      if (options.contentElement) {
 697        options.restoreContentElement = installContentElement(options);
 698      }
 699    }
 700
 701    function beforeShow(scope, element, options, controller) {
 702
 703      if (controller) {
 704        controller.mdHtmlContent = controller.htmlContent || options.htmlContent || '';
 705        controller.mdTextContent = controller.textContent || options.textContent ||
 706            controller.content || options.content || '';
 707
 708        if (controller.mdHtmlContent && !$injector.has('$sanitize')) {
 709          throw Error('The ngSanitize module must be loaded in order to use htmlContent.');
 710        }
 711
 712        if (controller.mdHtmlContent && controller.mdTextContent) {
 713          throw Error('md-dialog cannot have both `htmlContent` and `textContent`');
 714        }
 715      }
 716    }
 717
 718    /** Show method for dialogs */
 719    function onShow(scope, element, options, controller) {
 720      angular.element($document[0].body).addClass('md-dialog-is-showing');
 721
 722      var dialogElement = element.find('md-dialog');
 723
 724      // Once a dialog has `ng-cloak` applied on his template the dialog animation will not work properly.
 725      // This is a very common problem, so we have to notify the developer about this.
 726      if (dialogElement.hasClass('ng-cloak')) {
 727        var message = '$mdDialog: using `<md-dialog ng-cloak >` will affect the dialog opening animations.';
 728        $log.warn( message, element[0] );
 729      }
 730
 731      captureParentAndFromToElements(options);
 732      configureAria(dialogElement, options);
 733      showBackdrop(scope, element, options);
 734      activateListeners(element, options);
 735
 736      return dialogPopIn(element, options)
 737        .then(function() {
 738          lockScreenReader(element, options);
 739          warnDeprecatedActions();
 740          focusOnOpen();
 741        });
 742
 743      /**
 744       * Check to see if they used the deprecated .md-actions class and log a warning
 745       */
 746      function warnDeprecatedActions() {
 747        if (element[0].querySelector('.md-actions')) {
 748          $log.warn('Using a class of md-actions is deprecated, please use <md-dialog-actions>.');
 749        }
 750      }
 751
 752      /**
 753       * For alerts, focus on content... otherwise focus on
 754       * the close button (or equivalent)
 755       */
 756      function focusOnOpen() {
 757        if (options.focusOnOpen) {
 758          var target = $mdUtil.findFocusTarget(element) || findCloseButton() || dialogElement;
 759          target.focus();
 760        }
 761
 762        /**
 763         * If no element with class dialog-close, try to find the last
 764         * button child in md-actions and assume it is a close button.
 765         *
 766         * If we find no actions at all, log a warning to the console.
 767         */
 768        function findCloseButton() {
 769          var closeButton = element[0].querySelector('.dialog-close');
 770
 771          if (!closeButton) {
 772            var actionButtons = element[0].querySelectorAll('.md-actions button, md-dialog-actions button');
 773            closeButton = actionButtons[actionButtons.length - 1];
 774          }
 775
 776          return closeButton;
 777        }
 778      }
 779    }
 780
 781    /**
 782     * Remove function for all dialogs
 783     */
 784    function onRemove(scope, element, options) {
 785      options.deactivateListeners();
 786      options.unlockScreenReader();
 787      options.hideBackdrop(options.$destroy);
 788
 789      // Remove the focus traps that we added earlier for keeping focus within the dialog.
 790      if (topFocusTrap && topFocusTrap.parentNode) {
 791        topFocusTrap.parentNode.removeChild(topFocusTrap);
 792      }
 793
 794      if (bottomFocusTrap && bottomFocusTrap.parentNode) {
 795        bottomFocusTrap.parentNode.removeChild(bottomFocusTrap);
 796      }
 797
 798      // For navigation $destroy events, do a quick, non-animated removal,
 799      // but for normal closes (from clicks, etc) animate the removal
 800      return !!options.$destroy ? detachAndClean() : animateRemoval().then( detachAndClean );
 801
 802      /**
 803       * For normal closes, animate the removal.
 804       * For forced closes (like $destroy events), skip the animations
 805       */
 806      function animateRemoval() {
 807        return dialogPopOut(element, options);
 808      }
 809
 810      /**
 811       * Detach the element
 812       */
 813      function detachAndClean() {
 814        angular.element($document[0].body).removeClass('md-dialog-is-showing');
 815        // Only remove the element, if it's not provided through the contentElement option.
 816        if (!options.contentElement) {
 817          element.remove();
 818        } else {
 819          options.reverseContainerStretch();
 820          options.restoreContentElement();
 821        }
 822
 823        if (!options.$destroy) options.origin.focus();
 824      }
 825    }
 826
 827    function detectTheming(options) {
 828      // Only detect the theming, if the developer didn't specify the theme specifically.
 829      if (options.theme) return;
 830
 831      options.theme = $mdTheming.defaultTheme();
 832
 833      if (options.targetEvent && options.targetEvent.target) {
 834        var targetEl = angular.element(options.targetEvent.target);
 835
 836        // Once the user specifies a targetEvent, we will automatically try to find the correct
 837        // nested theme.
 838        options.theme = (targetEl.controller('mdTheme') || {}).$mdTheme || options.theme;
 839      }
 840
 841    }
 842
 843    /**
 844     * Installs a content element to the current $$interimElement provider options.
 845     * @returns {Function} Function to restore the content element at its old DOM location.
 846     */
 847    function installContentElement(options) {
 848      var contentEl = options.contentElement;
 849      var restoreFn = null;
 850
 851      if (angular.isString(contentEl)) {
 852        contentEl = document.querySelector(contentEl);
 853        restoreFn = createRestoreFn(contentEl);
 854      } else {
 855        contentEl = contentEl[0] || contentEl;
 856
 857        // When the element is visible in the DOM, then we restore it at close of the dialog.
 858        // Otherwise it will be removed from the DOM after close.
 859        if (document.contains(contentEl)) {
 860          restoreFn = createRestoreFn(contentEl);
 861        } else {
 862          restoreFn = function() {
 863            contentEl.parentNode.removeChild(contentEl);
 864          }
 865        }
 866      }
 867
 868      // Overwrite the options to use the content element.
 869      options.element = angular.element(contentEl);
 870      options.skipCompile = true;
 871
 872      return restoreFn;
 873
 874      function createRestoreFn(element) {
 875        var parent = element.parentNode;
 876        var nextSibling = element.nextElementSibling;
 877
 878        return function() {
 879          if (!nextSibling) {
 880            // When the element didn't had any sibling, then it can be simply appended to the
 881            // parent, because it plays no role, which index it had before.
 882            parent.appendChild(element);
 883          } else {
 884            // When the element had a sibling, which marks the previous position of the element
 885            // in the DOM, we insert it correctly before the sibling, to have the same index as
 886            // before.
 887            parent.insertBefore(element, nextSibling);
 888          }
 889        }
 890      }
 891    }
 892
 893    /**
 894     * Capture originator/trigger/from/to element information (if available)
 895     * and the parent container for the dialog; defaults to the $rootElement
 896     * unless overridden in the options.parent
 897     */
 898    function captureParentAndFromToElements(options) {
 899          options.origin = angular.extend({
 900            element: null,
 901            bounds: null,
 902            focus: angular.noop
 903          }, options.origin || {});
 904
 905          options.parent   = getDomElement(options.parent, $rootElement);
 906          options.closeTo  = getBoundingClientRect(getDomElement(options.closeTo));
 907          options.openFrom = getBoundingClientRect(getDomElement(options.openFrom));
 908
 909          if ( options.targetEvent ) {
 910            options.origin   = getBoundingClientRect(options.targetEvent.target, options.origin);
 911          }
 912
 913
 914          /**
 915           * Identify the bounding RECT for the target element
 916           *
 917           */
 918          function getBoundingClientRect (element, orig) {
 919            var source = angular.element((element || {}));
 920            if (source && source.length) {
 921              // Compute and save the target element's bounding rect, so that if the
 922              // element is hidden when the dialog closes, we can shrink the dialog
 923              // back to the same position it expanded from.
 924              //
 925              // Checking if the source is a rect object or a DOM element
 926              var bounds = {top:0,left:0,height:0,width:0};
 927              var hasFn = angular.isFunction(source[0].getBoundingClientRect);
 928
 929              return angular.extend(orig || {}, {
 930                  element : hasFn ? source : undefined,
 931                  bounds  : hasFn ? source[0].getBoundingClientRect() : angular.extend({}, bounds, source[0]),
 932                  focus   : angular.bind(source, source.focus),
 933              });
 934            }
 935          }
 936
 937          /**
 938           * If the specifier is a simple string selector, then query for
 939           * the DOM element.
 940           */
 941          function getDomElement(element, defaultElement) {
 942            if (angular.isString(element)) {
 943              element = $document[0].querySelector(element);
 944            }
 945
 946            // If we have a reference to a raw dom element, always wrap it in jqLite
 947            return angular.element(element || defaultElement);
 948          }
 949
 950        }
 951
 952    /**
 953     * Listen for escape keys and outside clicks to auto close
 954     */
 955    function activateListeners(element, options) {
 956      var window = angular.element($window);
 957      var onWindowResize = $mdUtil.debounce(function() {
 958        stretchDialogContainerToViewport(element, options);
 959      }, 60);
 960
 961      var removeListeners = [];
 962      var smartClose = function() {
 963        // Only 'confirm' dialogs have a cancel button... escape/clickOutside will
 964        // cancel or fallback to hide.
 965        var closeFn = ( options.$type == 'alert' ) ? $mdDialog.hide : $mdDialog.cancel;
 966        $mdUtil.nextTick(closeFn, true);
 967      };
 968
 969      if (options.escapeToClose) {
 970        var parentTarget = options.parent;
 971        var keyHandlerFn = function(ev) {
 972          if (ev.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
 973            ev.stopPropagation();
 974            ev.preventDefault();
 975
 976            smartClose();
 977          }
 978        };
 979
 980        // Add keydown listeners
 981        element.on('keydown', keyHandlerFn);
 982        parentTarget.on('keydown', keyHandlerFn);
 983
 984        // Queue remove listeners function
 985        removeListeners.push(function() {
 986
 987          element.off('keydown', keyHandlerFn);
 988          parentTarget.off('keydown', keyHandlerFn);
 989
 990        });
 991      }
 992
 993      // Register listener to update dialog on window resize
 994      window.on('resize', onWindowResize);
 995
 996      removeListeners.push(function() {
 997        window.off('resize', onWindowResize);
 998      });
 999
1000      if (options.clickOutsideToClose) {
1001        var target = element;
1002        var sourceElem;
1003
1004        // Keep track of the element on which the mouse originally went down
1005        // so that we can only close the backdrop when the 'click' started on it.
1006        // A simple 'click' handler does not work,
1007        // it sets the target object as the element the mouse went down on.
1008        var mousedownHandler = function(ev) {
1009          sourceElem = ev.target;
1010        };
1011
1012        // We check if our original element and the target is the backdrop
1013        // because if the original was the backdrop and the target was inside the dialog
1014        // we don't want to dialog to close.
1015        var mouseupHandler = function(ev) {
1016          if (sourceElem === target[0] && ev.target === target[0]) {
1017            ev.stopPropagation();
1018            ev.preventDefault();
1019
1020            smartClose();
1021          }
1022        };
1023
1024        // Add listeners
1025        target.on('mousedown', mousedownHandler);
1026        target.on('mouseup', mouseupHandler);
1027
1028        // Queue remove listeners function
1029        removeListeners.push(function() {
1030          target.off('mousedown', mousedownHandler);
1031          target.off('mouseup', mouseupHandler);
1032        });
1033      }
1034
1035      // Attach specific `remove` listener handler
1036      options.deactivateListeners = function() {
1037        removeListeners.forEach(function(removeFn) {
1038          removeFn();
1039        });
1040        options.deactivateListeners = null;
1041      };
1042    }
1043
1044    /**
1045     * Show modal backdrop element...
1046     */
1047    function showBackdrop(scope, element, options) {
1048
1049      if (options.disableParentScroll) {
1050        // !! DO this before creating the backdrop; since disableScrollAround()
1051        //    configures the scroll offset; which is used by mdBackDrop postLink()
1052        options.restoreScroll = $mdUtil.disableScrollAround(element, options.parent);
1053      }
1054
1055      if (options.hasBackdrop) {
1056        options.backdrop = $mdUtil.createBackdrop(scope, "md-dialog-backdrop md-opaque");
1057        $animate.enter(options.backdrop, options.parent);
1058      }
1059
1060      /**
1061       * Hide modal backdrop element...
1062       */
1063      options.hideBackdrop = function hideBackdrop($destroy) {
1064        if (options.backdrop) {
1065          if ( !!$destroy ) options.backdrop.remove();
1066          else              $animate.leave(options.backdrop);
1067        }
1068
1069
1070        if (options.disableParentScroll) {
1071          options.restoreScroll();
1072          delete options.restoreScroll;
1073        }
1074
1075        options.hideBackdrop = null;
1076      };
1077    }
1078
1079    /**
1080     * Inject ARIA-specific attributes appropriate for Dialogs
1081     */
1082    function configureAria(element, options) {
1083
1084      var role = (options.$type === 'alert') ? 'alertdialog' : 'dialog';
1085      var dialogContent = element.find('md-dialog-content');
1086      var existingDialogId = element.attr('id');
1087      var dialogContentId = 'dialogContent_' + (existingDialogId || $mdUtil.nextUid());
1088
1089      element.attr({
1090        'role': role,
1091        'tabIndex': '-1'
1092      });
1093
1094      if (dialogContent.length === 0) {
1095        dialogContent = element;
1096        // If the dialog element already had an ID, don't clobber it.
1097        if (existingDialogId) {
1098          dialogContentId = existingDialogId;
1099        }
1100      }
1101
1102      dialogContent.attr('id', dialogContentId);
1103      element.attr('aria-describedby', dialogContentId);
1104
1105      if (options.ariaLabel) {
1106        $mdAria.expect(element, 'aria-label', options.ariaLabel);
1107      }
1108      else {
1109        $mdAria.expectAsync(element, 'aria-label', function() {
1110          var words = dialogContent.text().split(/\s+/);
1111          if (words.length > 3) words = words.slice(0, 3).concat('...');
1112          return words.join(' ');
1113        });
1114      }
1115
1116      // Set up elements before and after the dialog content to capture focus and
1117      // redirect back into the dialog.
1118      topFocusTrap = document.createElement('div');
1119      topFocusTrap.classList.add('md-dialog-focus-trap');
1120      topFocusTrap.tabIndex = 0;
1121
1122      bottomFocusTrap = topFocusTrap.cloneNode(false);
1123
1124      // When focus is about to move out of the dialog, we want to intercept it and redirect it
1125      // back to the dialog element.
1126      var focusHandler = function() {
1127        element.focus();
1128      };
1129      topFocusTrap.addEventListener('focus', focusHandler);
1130      bottomFocusTrap.addEventListener('focus', focusHandler);
1131
1132      // The top focus trap inserted immeidately before the md-dialog element (as a sibling).
1133      // The bottom focus trap is inserted at the very end of the md-dialog element (as a child).
1134      element[0].parentNode.insertBefore(topFocusTrap, element[0]);
1135      element.after(bottomFocusTrap);
1136    }
1137
1138    /**
1139     * Prevents screen reader interaction behind modal window
1140     * on swipe interfaces
1141     */
1142    function lockScreenReader(element, options) {
1143      var isHidden = true;
1144
1145      // get raw DOM node
1146      walkDOM(element[0]);
1147
1148      options.unlockScreenReader = function() {
1149        isHidden = false;
1150        walkDOM(element[0]);
1151
1152        options.unlockScreenReader = null;
1153      };
1154
1155      /**
1156       * Walk DOM to apply or remove aria-hidden on sibling nodes
1157       * and parent sibling nodes
1158       *
1159       */
1160      function walkDOM(element) {
1161        while (element.parentNode) {
1162          if (element === document.body) {
1163            return;
1164          }
1165          var children = element.parentNode.children;
1166          for (var i = 0; i < children.length; i++) {
1167            // skip over child if it is an ascendant of the dialog
1168            // or a script or style tag
1169            if (element !== children[i] && !isNodeOneOf(children[i], ['SCRIPT', 'STYLE'])) {
1170              children[i].setAttribute('aria-hidden', isHidden);
1171            }
1172          }
1173
1174          walkDOM(element = element.parentNode);
1175        }
1176      }
1177    }
1178
1179    /**
1180     * Ensure the dialog container fill-stretches to the viewport
1181     */
1182    function stretchDialogContainerToViewport(container, options) {
1183      var isFixed = $window.getComputedStyle($document[0].body).position == 'fixed';
1184      var backdrop = options.backdrop ? $window.getComputedStyle(options.backdrop[0]) : null;
1185      var height = backdrop ? Math.min($document[0].body.clientHeight, Math.ceil(Math.abs(parseInt(backdrop.height, 10)))) : 0;
1186
1187      var previousStyles = {
1188        top: container.css('top'),
1189        height: container.css('height')
1190      };
1191
1192      container.css({
1193        top: (isFixed ? $mdUtil.scrollTop(options.parent) : 0) + 'px',
1194        height: height ? height + 'px' : '100%'
1195      });
1196
1197      return function() {
1198        // Reverts the modified styles back to the previous values.
1199        // This is needed for contentElements, which should have the same styles after close
1200        // as before.
1201        container.css(previousStyles);
1202      };
1203    }
1204
1205    /**
1206     *  Dialog open and pop-in animation
1207     */
1208    function dialogPopIn(container, options) {
1209      // Add the `md-dialog-container` to the DOM
1210      options.parent.append(container);
1211      options.reverseContainerStretch = stretchDialogContainerToViewport(container, options);
1212
1213      var dialogEl = container.find('md-dialog');
1214      var animator = $mdUtil.dom.animator;
1215      var buildTranslateToOrigin = animator.calculateZoomToOrigin;
1216      var translateOptions = {transitionInClass: 'md-transition-in', transitionOutClass: 'md-transition-out'};
1217      var from = animator.toTransformCss(buildTranslateToOrigin(dialogEl, options.openFrom || options.origin));
1218      var to = animator.toTransformCss("");  // defaults to center display (or parent or $rootElement)
1219
1220      dialogEl.toggleClass('md-dialog-fullscreen', !!options.fullscreen);
1221
1222      return animator
1223        .translate3d(dialogEl, from, to, translateOptions)
1224        .then(function(animateReversal) {
1225
1226          // Build a reversal translate function synced to this translation...
1227          options.reverseAnimate = function() {
1228            delete options.reverseAnimate;
1229
1230            if (options.closeTo) {
1231              // Using the opposite classes to create a close animation to the closeTo element
1232              translateOptions = {transitionInClass: 'md-transition-out', transitionOutClass: 'md-transition-in'};
1233              from = to;
1234              to = animator.toTransformCss(buildTranslateToOrigin(dialogEl, options.closeTo));
1235
1236              return animator
1237                .translate3d(dialogEl, from, to,translateOptions);
1238            }
1239
1240            return animateReversal(
1241              to = animator.toTransformCss(
1242                // in case the origin element has moved or is hidden,
1243                // let's recalculate the translateCSS
1244                buildTranslateToOrigin(dialogEl, options.origin)
1245              )
1246            );
1247
1248          };
1249
1250          // Function to revert the generated animation styles on the dialog element.
1251          // Useful when using a contentElement instead of a template.
1252          options.clearAnimate = function() {
1253            delete options.clearAnimate;
1254
1255            // Remove the transition classes, added from $animateCSS, since those can't be removed
1256            // by reversely running the animator.
1257            dialogEl.removeClass([
1258              translateOptions.transitionOutClass,
1259              translateOptions.transitionInClass
1260            ].join(' '));
1261
1262            // Run the animation reversely to remove the previous added animation styles.
1263            return animator.translate3d(dialogEl, to, animator.toTransformCss(''), {});
1264          };
1265
1266          return true;
1267        });
1268    }
1269
1270    /**
1271     * Dialog close and pop-out animation
1272     */
1273    function dialogPopOut(container, options) {
1274      return options.reverseAnimate().then(function() {
1275        if (options.contentElement) {
1276          // When we use a contentElement, we want the element to be the same as before.
1277          // That means, that we have to clear all the animation properties, like transform.
1278          options.clearAnimate();
1279        }
1280      });
1281    }
1282
1283    /**
1284     * Utility function to filter out raw DOM nodes
1285     */
1286    function isNodeOneOf(elem, nodeTypeArray) {
1287      if (nodeTypeArray.indexOf(elem.nodeName) !== -1) {
1288        return true;
1289      }
1290    }
1291
1292  }
1293}
1294
1295})(window, window.angular);