arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
socketioMEANseed/www/bower_components/angular-material/modules/js/toast/toast.js
www/bower_components/angular-material/modules/js/toast/toast.jsRaw
  1/*!
  2 * Angular Material Design
  3 * https://github.com/angular/material
  4 * @license MIT
  5 * v1.1.3
  6 */
  7(function( window, angular, undefined ){
  8"use strict";
  9
 10/**
 11  * @ngdoc module
 12  * @name material.components.toast
 13  * @description
 14  * Toast
 15  */
 16MdToastDirective['$inject'] = ["$mdToast"];
 17MdToastProvider['$inject'] = ["$$interimElementProvider"];
 18angular.module('material.components.toast', [
 19  'material.core',
 20  'material.components.button'
 21])
 22  .directive('mdToast', MdToastDirective)
 23  .provider('$mdToast', MdToastProvider);
 24
 25/* ngInject */
 26function MdToastDirective($mdToast) {
 27  return {
 28    restrict: 'E',
 29    link: function postLink(scope, element) {
 30      element.addClass('_md');     // private md component indicator for styling
 31      
 32      // When navigation force destroys an interimElement, then
 33      // listen and $destroy() that interim instance...
 34      scope.$on('$destroy', function() {
 35        $mdToast.destroy();
 36      });
 37    }
 38  };
 39}
 40
 41/**
 42  * @ngdoc service
 43  * @name $mdToast
 44  * @module material.components.toast
 45  *
 46  * @description
 47  * `$mdToast` is a service to build a toast notification on any position
 48  * on the screen with an optional duration, and provides a simple promise API.
 49  *
 50  * The toast will be always positioned at the `bottom`, when the screen size is
 51  * between `600px` and `959px` (`sm` breakpoint)
 52  *
 53  * ## Restrictions on custom toasts
 54  * - The toast's template must have an outer `<md-toast>` element.
 55  * - For a toast action, use element with class `md-action`.
 56  * - Add the class `md-capsule` for curved corners.
 57  *
 58  * ### Custom Presets
 59  * Developers are also able to create their own preset, which can be easily used without repeating
 60  * their options each time.
 61  *
 62  * <hljs lang="js">
 63  *   $mdToastProvider.addPreset('testPreset', {
 64  *     options: function() {
 65  *       return {
 66  *         template:
 67  *           '<md-toast>' +
 68  *             '<div class="md-toast-content">' +
 69  *               'This is a custom preset' +
 70  *             '</div>' +
 71  *           '</md-toast>',
 72  *         controllerAs: 'toast',
 73  *         bindToController: true
 74  *       };
 75  *     }
 76  *   });
 77  * </hljs>
 78  *
 79  * After you created your preset at config phase, you can easily access it.
 80  *
 81  * <hljs lang="js">
 82  *   $mdToast.show(
 83  *     $mdToast.testPreset()
 84  *   );
 85  * </hljs>
 86  *
 87  * ## Parent container notes
 88  *
 89  * The toast is positioned using absolute positioning relative to its first non-static parent
 90  * container. Thus, if the requested parent container uses static positioning, we will temporarily
 91  * set its positioning to `relative` while the toast is visible and reset it when the toast is
 92  * hidden.
 93  *
 94  * Because of this, it is usually best to ensure that the parent container has a fixed height and
 95  * prevents scrolling by setting the `overflow: hidden;` style. Since the position is based off of
 96  * the parent's height, the toast may be mispositioned if you allow the parent to scroll.
 97  *
 98  * You can, however, have a scrollable element inside of the container; just make sure the
 99  * container itself does not scroll.
100  *
101  * <hljs lang="html">
102  * <div layout-fill id="toast-container">
103  *   <md-content>
104  *     I can have lots of content and scroll!
105  *   </md-content>
106  * </div>
107  * </hljs>
108  *
109  * @usage
110  * <hljs lang="html">
111  * <div ng-controller="MyController">
112  *   <md-button ng-click="openToast()">
113  *     Open a Toast!
114  *   </md-button>
115  * </div>
116  * </hljs>
117  *
118  * <hljs lang="js">
119  * var app = angular.module('app', ['ngMaterial']);
120  * app.controller('MyController', function($scope, $mdToast) {
121  *   $scope.openToast = function($event) {
122  *     $mdToast.show($mdToast.simple().textContent('Hello!'));
123  *     // Could also do $mdToast.showSimple('Hello');
124  *   };
125  * });
126  * </hljs>
127  */
128
129/**
130 * @ngdoc method
131 * @name $mdToast#showSimple
132 * 
133 * @param {string} message The message to display inside the toast
134 * @description
135 * Convenience method which builds and shows a simple toast.
136 *
137 * @returns {promise} A promise that can be resolved with `$mdToast.hide()` or
138 * rejected with `$mdToast.cancel()`.
139 *
140 */
141
142 /**
143  * @ngdoc method
144  * @name $mdToast#simple
145  *
146  * @description
147  * Builds a preconfigured toast.
148  *
149  * @returns {obj} a `$mdToastPreset` with the following chainable configuration methods.
150  *
151  * _**Note:** These configuration methods are provided in addition to the methods provided by
152  * the `build()` and `show()` methods below._
153  *
154  * <table class="md-api-table methods">
155  *    <thead>
156  *      <tr>
157  *        <th>Method</th>
158  *        <th>Description</th>
159  *      </tr>
160  *    </thead>
161  *    <tbody>
162  *      <tr>
163  *        <td>`.textContent(string)`</td>
164  *        <td>Sets the toast content to the specified string</td>
165  *      </tr>
166  *      <tr>
167  *        <td>`.action(string)`</td>
168  *        <td>
169  *          Adds an action button. <br/>
170  *          If clicked, the promise (returned from `show()`)
171  *          will resolve with the value `'ok'`; otherwise, it is resolved with `true` after a `hideDelay`
172  *          timeout
173  *        </td>
174  *      </tr>
175  *      <tr>
176  *        <td>`.highlightAction(boolean)`</td>
177  *        <td>
178  *          Whether or not the action button will have an additional highlight class.<br/>
179  *          By default the `accent` color will be applied to the action button.
180  *        </td>
181  *      </tr>
182  *      <tr>
183  *        <td>`.highlightClass(string)`</td>
184  *        <td>
185  *          If set, the given class will be applied to the highlighted action button.<br/>
186  *          This allows you to specify the highlight color easily. Highlight classes are `md-primary`, `md-warn`
187  *          and `md-accent`
188  *        </td>
189  *      </tr>
190  *      <tr>
191  *        <td>`.capsule(boolean)`</td>
192  *        <td>Whether or not to add the `md-capsule` class to the toast to provide rounded corners</td>
193  *      </tr>
194  *      <tr>
195  *        <td>`.theme(string)`</td>
196  *        <td>Sets the theme on the toast to the requested theme. Default is `$mdThemingProvider`'s default.</td>
197  *      </tr>
198  *      <tr>
199  *        <td>`.toastClass(string)`</td>
200  *        <td>Sets a class on the toast element</td>
201  *      </tr>
202  *    </tbody>
203  * </table>
204  *
205  */
206
207/**
208  * @ngdoc method
209  * @name $mdToast#updateTextContent
210  *
211  * @description
212  * Updates the content of an existing toast. Useful for updating things like counts, etc.
213  *
214  */
215
216 /**
217  * @ngdoc method
218  * @name $mdToast#build
219  *
220  * @description
221  * Creates a custom `$mdToastPreset` that you can configure.
222  *
223  * @returns {obj} a `$mdToastPreset` with the chainable configuration methods for shows' options (see below).
224  */
225
226 /**
227  * @ngdoc method
228  * @name $mdToast#show
229  *
230  * @description Shows the toast.
231  *
232  * @param {object} optionsOrPreset Either provide an `$mdToastPreset` returned from `simple()`
233  * and `build()`, or an options object with the following properties:
234  *
235  *   - `templateUrl` - `{string=}`: The url of an html template file that will
236  *     be used as the content of the toast. Restrictions: the template must
237  *     have an outer `md-toast` element.
238  *   - `template` - `{string=}`: Same as templateUrl, except this is an actual
239  *     template string.
240  *   - `autoWrap` - `{boolean=}`: Whether or not to automatically wrap the template content with a
241  *     `<div class="md-toast-content">` if one is not provided. Defaults to true. Can be disabled if you provide a
242  *     custom toast directive.
243  *   - `scope` - `{object=}`: the scope to link the template / controller to. If none is specified, it will create a new child scope.
244  *     This scope will be destroyed when the toast is removed unless `preserveScope` is set to true.
245  *   - `preserveScope` - `{boolean=}`: whether to preserve the scope when the element is removed. Default is false
246  *   - `hideDelay` - `{number=}`: How many milliseconds the toast should stay
247  *     active before automatically closing.  Set to 0 or false to have the toast stay open until
248  *     closed manually. Default: 3000.
249  *   - `position` - `{string=}`: Sets the position of the toast. <br/>
250  *     Available: any combination of `'bottom'`, `'left'`, `'top'`, `'right'`, `'end'` and `'start'`.
251  *     The properties `'end'` and `'start'` are dynamic and can be used for RTL support.<br/>
252  *     Default combination: `'bottom left'`.
253  *   - `toastClass` - `{string=}`: A class to set on the toast element.
254  *   - `controller` - `{string=}`: The controller to associate with this toast.
255  *     The controller will be injected the local `$mdToast.hide( )`, which is a function
256  *     used to hide the toast.
257  *   - `locals` - `{string=}`: An object containing key/value pairs. The keys will
258  *     be used as names of values to inject into the controller. For example,
259  *     `locals: {three: 3}` would inject `three` into the controller with the value
260  *     of 3.
261  *   - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.
262  *   - `resolve` - `{object=}`: Similar to locals, except it takes promises as values
263  *     and the toast will not open until the promises resolve.
264  *   - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
265  *   - `parent` - `{element=}`: The element to append the toast to. Defaults to appending
266  *     to the root element of the application.
267  *
268  * @returns {promise} A promise that can be resolved with `$mdToast.hide()` or
269  * rejected with `$mdToast.cancel()`. `$mdToast.hide()` will resolve either with a Boolean
270  * value == 'true' or the value passed as an argument to `$mdToast.hide()`.
271  * And `$mdToast.cancel()` will resolve the promise with a Boolean value == 'false'
272  */
273
274/**
275  * @ngdoc method
276  * @name $mdToast#hide
277  *
278  * @description
279  * Hide an existing toast and resolve the promise returned from `$mdToast.show()`.
280  *
281  * @param {*=} response An argument for the resolved promise.
282  *
283  * @returns {promise} a promise that is called when the existing element is removed from the DOM.
284  * The promise is resolved with either a Boolean value == 'true' or the value passed as the
285  * argument to `.hide()`.
286  *
287  */
288
289/**
290  * @ngdoc method
291  * @name $mdToast#cancel
292  *
293  * @description
294  * `DEPRECATED` - The promise returned from opening a toast is used only to notify about the closing of the toast.
295  * As such, there isn't any reason to also allow that promise to be rejected,
296  * since it's not clear what the difference between resolve and reject would be.
297  *
298  * Hide the existing toast and reject the promise returned from
299  * `$mdToast.show()`.
300  *
301  * @param {*=} response An argument for the rejected promise.
302  *
303  * @returns {promise} a promise that is called when the existing element is removed from the DOM
304  * The promise is resolved with a Boolean value == 'false'.
305  *
306  */
307
308function MdToastProvider($$interimElementProvider) {
309  // Differentiate promise resolves: hide timeout (value == true) and hide action clicks (value == ok).
310  toastDefaultOptions['$inject'] = ["$animate", "$mdToast", "$mdUtil", "$mdMedia"];
311  var ACTION_RESOLVE = 'ok';
312
313  var activeToastContent;
314  var $mdToast = $$interimElementProvider('$mdToast')
315    .setDefaults({
316      methods: ['position', 'hideDelay', 'capsule', 'parent', 'position', 'toastClass'],
317      options: toastDefaultOptions
318    })
319    .addPreset('simple', {
320      argOption: 'textContent',
321      methods: ['textContent', 'content', 'action', 'highlightAction', 'highlightClass', 'theme', 'parent' ],
322      options: /* ngInject */ ["$mdToast", "$mdTheming", function($mdToast, $mdTheming) {
323        return {
324          template:
325            '<md-toast md-theme="{{ toast.theme }}" ng-class="{\'md-capsule\': toast.capsule}">' +
326            '  <div class="md-toast-content">' +
327            '    <span class="md-toast-text" role="alert" aria-relevant="all" aria-atomic="true">' +
328            '      {{ toast.content }}' +
329            '    </span>' +
330            '    <md-button class="md-action" ng-if="toast.action" ng-click="toast.resolve()" ' +
331            '        ng-class="highlightClasses">' +
332            '      {{ toast.action }}' +
333            '    </md-button>' +
334            '  </div>' +
335            '</md-toast>',
336          controller: /* ngInject */ ["$scope", function mdToastCtrl($scope) {
337            var self = this;
338
339            if (self.highlightAction) {
340              $scope.highlightClasses = [
341                'md-highlight',
342                self.highlightClass
343              ]
344            }
345
346            $scope.$watch(function() { return activeToastContent; }, function() {
347              self.content = activeToastContent;
348            });
349
350            this.resolve = function() {
351              $mdToast.hide( ACTION_RESOLVE );
352            };
353          }],
354          theme: $mdTheming.defaultTheme(),
355          controllerAs: 'toast',
356          bindToController: true
357        };
358      }]
359    })
360    .addMethod('updateTextContent', updateTextContent)
361    .addMethod('updateContent', updateTextContent);
362
363    function updateTextContent(newContent) {
364      activeToastContent = newContent;
365    }
366
367    return $mdToast;
368
369  /* ngInject */
370  function toastDefaultOptions($animate, $mdToast, $mdUtil, $mdMedia) {
371    var SWIPE_EVENTS = '$md.swipeleft $md.swiperight $md.swipeup $md.swipedown';
372    return {
373      onShow: onShow,
374      onRemove: onRemove,
375      toastClass: '',
376      position: 'bottom left',
377      themable: true,
378      hideDelay: 3000,
379      autoWrap: true,
380      transformTemplate: function(template, options) {
381        var shouldAddWrapper = options.autoWrap && template && !/md-toast-content/g.test(template);
382
383        if (shouldAddWrapper) {
384          // Root element of template will be <md-toast>. We need to wrap all of its content inside of
385          // of <div class="md-toast-content">. All templates provided here should be static, developer-controlled
386          // content (meaning we're not attempting to guard against XSS).
387          var templateRoot = document.createElement('md-template');
388          templateRoot.innerHTML = template;
389
390          // Iterate through all root children, to detect possible md-toast directives.
391          for (var i = 0; i < templateRoot.children.length; i++) {
392            if (templateRoot.children[i].nodeName === 'MD-TOAST') {
393              var wrapper = angular.element('<div class="md-toast-content">');
394
395              // Wrap the children of the `md-toast` directive in jqLite, to be able to append multiple
396              // nodes with the same execution.
397              wrapper.append(angular.element(templateRoot.children[i].childNodes));
398
399              // Append the new wrapped element to the `md-toast` directive.
400              templateRoot.children[i].appendChild(wrapper[0]);
401            }
402          }
403
404          // We have to return the innerHTMl, because we do not want to have the `md-template` element to be
405          // the root element of our interimElement.
406          return templateRoot.innerHTML;
407        }
408
409        return template || '';
410      }
411    };
412
413    function onShow(scope, element, options) {
414      activeToastContent = options.textContent || options.content; // support deprecated #content method
415
416      var isSmScreen = !$mdMedia('gt-sm');
417
418      element = $mdUtil.extractElementByName(element, 'md-toast', true);
419      options.element = element;
420
421      options.onSwipe = function(ev, gesture) {
422        //Add the relevant swipe class to the element so it can animate correctly
423        var swipe = ev.type.replace('$md.','');
424        var direction = swipe.replace('swipe', '');
425
426        // If the swipe direction is down/up but the toast came from top/bottom don't fade away
427        // Unless the screen is small, then the toast always on bottom
428        if ((direction === 'down' && options.position.indexOf('top') != -1 && !isSmScreen) ||
429            (direction === 'up' && (options.position.indexOf('bottom') != -1 || isSmScreen))) {
430          return;
431        }
432
433        if ((direction === 'left' || direction === 'right') && isSmScreen) {
434          return;
435        }
436
437        element.addClass('md-' + swipe);
438        $mdUtil.nextTick($mdToast.cancel);
439      };
440      options.openClass = toastOpenClass(options.position);
441
442      element.addClass(options.toastClass);
443
444      // 'top left' -> 'md-top md-left'
445      options.parent.addClass(options.openClass);
446
447      // static is the default position
448      if ($mdUtil.hasComputedStyle(options.parent, 'position', 'static')) {
449        options.parent.css('position', 'relative');
450      }
451
452      element.on(SWIPE_EVENTS, options.onSwipe);
453      element.addClass(isSmScreen ? 'md-bottom' : options.position.split(' ').map(function(pos) {
454        return 'md-' + pos;
455      }).join(' '));
456
457      if (options.parent) options.parent.addClass('md-toast-animating');
458      return $animate.enter(element, options.parent).then(function() {
459        if (options.parent) options.parent.removeClass('md-toast-animating');
460      });
461    }
462
463    function onRemove(scope, element, options) {
464      element.off(SWIPE_EVENTS, options.onSwipe);
465      if (options.parent) options.parent.addClass('md-toast-animating');
466      if (options.openClass) options.parent.removeClass(options.openClass);
467
468      return ((options.$destroy == true) ? element.remove() : $animate.leave(element))
469        .then(function () {
470          if (options.parent) options.parent.removeClass('md-toast-animating');
471          if ($mdUtil.hasComputedStyle(options.parent, 'position', 'static')) {
472            options.parent.css('position', '');
473          }
474        });
475    }
476
477    function toastOpenClass(position) {
478      // For mobile, always open full-width on bottom
479      if (!$mdMedia('gt-xs')) {
480        return 'md-toast-open-bottom';
481      }
482
483      return 'md-toast-open-' +
484        (position.indexOf('top') > -1 ? 'top' : 'bottom');
485    }
486  }
487
488}
489
490})(window, window.angular);