progressLinear.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*!
  2. * Angular Material Design
  3. * https://github.com/angular/material
  4. * @license MIT
  5. * v0.11.4
  6. */
  7. (function( window, angular, undefined ){
  8. "use strict";
  9. /**
  10. * @ngdoc module
  11. * @name material.components.progressLinear
  12. * @description Linear Progress module!
  13. */
  14. angular.module('material.components.progressLinear', [
  15. 'material.core'
  16. ])
  17. .directive('mdProgressLinear', MdProgressLinearDirective);
  18. /**
  19. * @ngdoc directive
  20. * @name mdProgressLinear
  21. * @module material.components.progressLinear
  22. * @restrict E
  23. *
  24. * @description
  25. * The linear progress directive is used to make loading content
  26. * in your app as delightful and painless as possible by minimizing
  27. * the amount of visual change a user sees before they can view
  28. * and interact with content.
  29. *
  30. * Each operation should only be represented by one activity indicator
  31. * For example: one refresh operation should not display both a
  32. * refresh bar and an activity circle.
  33. *
  34. * For operations where the percentage of the operation completed
  35. * can be determined, use a determinate indicator. They give users
  36. * a quick sense of how long an operation will take.
  37. *
  38. * For operations where the user is asked to wait a moment while
  39. * something finishes up, and it’s not necessary to expose what's
  40. * happening behind the scenes and how long it will take, use an
  41. * indeterminate indicator.
  42. *
  43. * @param {string} md-mode Select from one of four modes: determinate, indeterminate, buffer or query.
  44. *
  45. * Note: if the `md-mode` value is set as undefined or specified as 1 of the four (4) valid modes, then `.ng-hide`
  46. * will be auto-applied as a style to the component.
  47. *
  48. * Note: if not configured, the `md-mode="indeterminate"` will be auto injected as an attribute. If `value=""` is also specified, however,
  49. * then `md-mode="determinate"` would be auto-injected instead.
  50. * @param {number=} value In determinate and buffer modes, this number represents the percentage of the primary progress bar. Default: 0
  51. * @param {number=} md-buffer-value In the buffer mode, this number represents the percentage of the secondary progress bar. Default: 0
  52. *
  53. * @usage
  54. * <hljs lang="html">
  55. * <md-progress-linear md-mode="determinate" value="..."></md-progress-linear>
  56. *
  57. * <md-progress-linear md-mode="determinate" ng-value="..."></md-progress-linear>
  58. *
  59. * <md-progress-linear md-mode="indeterminate"></md-progress-linear>
  60. *
  61. * <md-progress-linear md-mode="buffer" value="..." md-buffer-value="..."></md-progress-linear>
  62. *
  63. * <md-progress-linear md-mode="query"></md-progress-linear>
  64. * </hljs>
  65. */
  66. function MdProgressLinearDirective($mdTheming, $mdUtil, $log) {
  67. var MODE_DETERMINATE = "determinate",
  68. MODE_INDETERMINATE = "indeterminate",
  69. MODE_BUFFER = "buffer",
  70. MODE_QUERY = "query";
  71. return {
  72. restrict: 'E',
  73. template: '<div class="md-container">' +
  74. '<div class="md-dashed"></div>' +
  75. '<div class="md-bar md-bar1"></div>' +
  76. '<div class="md-bar md-bar2"></div>' +
  77. '</div>',
  78. compile: compile
  79. };
  80. function compile(tElement, tAttrs, transclude) {
  81. tElement.attr('aria-valuemin', 0);
  82. tElement.attr('aria-valuemax', 100);
  83. tElement.attr('role', 'progressbar');
  84. return postLink;
  85. }
  86. function postLink(scope, element, attr) {
  87. $mdTheming(element);
  88. var lastMode, toVendorCSS = $mdUtil.dom.animator.toCss;
  89. var bar1 = angular.element(element[0].querySelector('.md-bar1')),
  90. bar2 = angular.element(element[0].querySelector('.md-bar2')),
  91. container = angular.element(element[0].querySelector('.md-container'));
  92. element.attr('md-mode', mode());
  93. validateMode();
  94. watchAttributes();
  95. /**
  96. * Watch the value, md-buffer-value, and md-mode attributes
  97. */
  98. function watchAttributes() {
  99. attr.$observe('value', function(value) {
  100. var percentValue = clamp(value);
  101. element.attr('aria-valuenow', percentValue);
  102. if (mode() != MODE_QUERY) animateIndicator(bar2, percentValue);
  103. });
  104. attr.$observe('mdBufferValue', function(value) {
  105. animateIndicator(bar1, clamp(value));
  106. });
  107. attr.$observe('mdMode',function(mode){
  108. switch( mode ) {
  109. case MODE_QUERY:
  110. case MODE_BUFFER:
  111. case MODE_DETERMINATE:
  112. case MODE_INDETERMINATE:
  113. container.removeClass( 'ng-hide' + ' ' + lastMode );
  114. container.addClass( lastMode = "md-mode-" + mode );
  115. break;
  116. default:
  117. container.removeClass( lastMode );
  118. container.addClass('ng-hide');
  119. lastMode = undefined;
  120. break;
  121. }
  122. });
  123. }
  124. /**
  125. * Auto-defaults the mode to either `determinate` or `indeterminate` mode; if not specified
  126. */
  127. function validateMode() {
  128. if ( angular.isUndefined(attr.mdMode) ) {
  129. var hasValue = angular.isDefined(attr.value);
  130. var mode = hasValue ? MODE_DETERMINATE : MODE_INDETERMINATE;
  131. var info = "Auto-adding the missing md-mode='{0}' to the ProgressLinear element";
  132. $log.debug( $mdUtil.supplant(info, [mode]) );
  133. element.attr("md-mode",mode);
  134. attr['mdMode'] = mode;
  135. }
  136. }
  137. /**
  138. * Is the md-mode a valid option?
  139. */
  140. function mode() {
  141. var value = (attr.mdMode || "").trim();
  142. if ( value ) {
  143. switch(value) {
  144. case MODE_DETERMINATE:
  145. case MODE_INDETERMINATE:
  146. case MODE_BUFFER:
  147. case MODE_QUERY:
  148. break;
  149. default:
  150. value = undefined;
  151. break;
  152. }
  153. }
  154. return value;
  155. }
  156. /**
  157. * Manually set CSS to animate the Determinate indicator based on the specified
  158. * percentage value (0-100).
  159. */
  160. function animateIndicator(target, value) {
  161. if ( !mode() ) return;
  162. var to = $mdUtil.supplant("translateX({0}%) scale({1},1)", [ (value-100)/2, value/100 ]);
  163. var styles = toVendorCSS({ transform : to });
  164. angular.element(target).css( styles );
  165. }
  166. }
  167. /**
  168. * Clamps the value to be between 0 and 100.
  169. * @param {number} value The value to clamp.
  170. * @returns {number}
  171. */
  172. function clamp(value) {
  173. return Math.max(0, Math.min(value || 0, 100));
  174. }
  175. }
  176. MdProgressLinearDirective.$inject = ["$mdTheming", "$mdUtil", "$log"];
  177. })(window, window.angular);