progress-spinner.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /**
  2. * @license
  3. * Copyright Google LLC All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. import { coerceNumberProperty } from '@angular/cdk/coercion';
  9. import { Platform } from '@angular/cdk/platform';
  10. import { DOCUMENT, CommonModule } from '@angular/common';
  11. import { ChangeDetectionStrategy, Component, ElementRef, Inject, InjectionToken, Input, Optional, ViewEncapsulation, NgModule } from '@angular/core';
  12. import { mixinColor, MatCommonModule } from '@angular/material/core';
  13. import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations';
  14. /**
  15. * @fileoverview added by tsickle
  16. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  17. */
  18. /**
  19. * Base reference size of the spinner.
  20. * \@docs-private
  21. * @type {?}
  22. */
  23. const BASE_SIZE = 100;
  24. /**
  25. * Base reference stroke width of the spinner.
  26. * \@docs-private
  27. * @type {?}
  28. */
  29. const BASE_STROKE_WIDTH = 10;
  30. // Boilerplate for applying mixins to MatProgressSpinner.
  31. /**
  32. * \@docs-private
  33. */
  34. class MatProgressSpinnerBase {
  35. /**
  36. * @param {?} _elementRef
  37. */
  38. constructor(_elementRef) {
  39. this._elementRef = _elementRef;
  40. }
  41. }
  42. /** @type {?} */
  43. const _MatProgressSpinnerMixinBase = mixinColor(MatProgressSpinnerBase, 'primary');
  44. /**
  45. * Injection token to be used to override the default options for `mat-progress-spinner`.
  46. * @type {?}
  47. */
  48. const MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS = new InjectionToken('mat-progress-spinner-default-options', {
  49. providedIn: 'root',
  50. factory: MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY,
  51. });
  52. /**
  53. * \@docs-private
  54. * @return {?}
  55. */
  56. function MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY() {
  57. return { diameter: BASE_SIZE };
  58. }
  59. // .0001 percentage difference is necessary in order to avoid unwanted animation frames
  60. // for example because the animation duration is 4 seconds, .1% accounts to 4ms
  61. // which are enough to see the flicker described in
  62. // https://github.com/angular/components/issues/8984
  63. /** @type {?} */
  64. const INDETERMINATE_ANIMATION_TEMPLATE = `
  65. @keyframes mat-progress-spinner-stroke-rotate-DIAMETER {
  66. 0% { stroke-dashoffset: START_VALUE; transform: rotate(0); }
  67. 12.5% { stroke-dashoffset: END_VALUE; transform: rotate(0); }
  68. 12.5001% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(72.5deg); }
  69. 25% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(72.5deg); }
  70. 25.0001% { stroke-dashoffset: START_VALUE; transform: rotate(270deg); }
  71. 37.5% { stroke-dashoffset: END_VALUE; transform: rotate(270deg); }
  72. 37.5001% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(161.5deg); }
  73. 50% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(161.5deg); }
  74. 50.0001% { stroke-dashoffset: START_VALUE; transform: rotate(180deg); }
  75. 62.5% { stroke-dashoffset: END_VALUE; transform: rotate(180deg); }
  76. 62.5001% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(251.5deg); }
  77. 75% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(251.5deg); }
  78. 75.0001% { stroke-dashoffset: START_VALUE; transform: rotate(90deg); }
  79. 87.5% { stroke-dashoffset: END_VALUE; transform: rotate(90deg); }
  80. 87.5001% { stroke-dashoffset: END_VALUE; transform: rotateX(180deg) rotate(341.5deg); }
  81. 100% { stroke-dashoffset: START_VALUE; transform: rotateX(180deg) rotate(341.5deg); }
  82. }
  83. `;
  84. /**
  85. * `<mat-progress-spinner>` component.
  86. */
  87. class MatProgressSpinner extends _MatProgressSpinnerMixinBase {
  88. /**
  89. * @param {?} _elementRef
  90. * @param {?} platform
  91. * @param {?} _document
  92. * @param {?} animationMode
  93. * @param {?=} defaults
  94. */
  95. constructor(_elementRef, platform, _document, animationMode, defaults) {
  96. super(_elementRef);
  97. this._elementRef = _elementRef;
  98. this._document = _document;
  99. this._diameter = BASE_SIZE;
  100. this._value = 0;
  101. this._fallbackAnimation = false;
  102. /**
  103. * Mode of the progress circle
  104. */
  105. this.mode = 'determinate';
  106. /** @type {?} */
  107. const trackedDiameters = MatProgressSpinner._diameters;
  108. // The base size is already inserted via the component's structural styles. We still
  109. // need to track it so we don't end up adding the same styles again.
  110. if (!trackedDiameters.has(_document.head)) {
  111. trackedDiameters.set(_document.head, new Set([BASE_SIZE]));
  112. }
  113. this._styleRoot = _getShadowRoot(_elementRef.nativeElement, _document) || _document.head;
  114. this._fallbackAnimation = platform.EDGE || platform.TRIDENT;
  115. this._noopAnimations = animationMode === 'NoopAnimations' &&
  116. (!!defaults && !defaults._forceAnimations);
  117. if (defaults) {
  118. if (defaults.diameter) {
  119. this.diameter = defaults.diameter;
  120. }
  121. if (defaults.strokeWidth) {
  122. this.strokeWidth = defaults.strokeWidth;
  123. }
  124. }
  125. // On IE and Edge, we can't animate the `stroke-dashoffset`
  126. // reliably so we fall back to a non-spec animation.
  127. /** @type {?} */
  128. const animationClass = `mat-progress-spinner-indeterminate${this._fallbackAnimation ? '-fallback' : ''}-animation`;
  129. _elementRef.nativeElement.classList.add(animationClass);
  130. }
  131. /**
  132. * The diameter of the progress spinner (will set width and height of svg).
  133. * @return {?}
  134. */
  135. get diameter() { return this._diameter; }
  136. /**
  137. * @param {?} size
  138. * @return {?}
  139. */
  140. set diameter(size) {
  141. this._diameter = coerceNumberProperty(size);
  142. if (!this._fallbackAnimation) {
  143. /** @type {?} */
  144. const trackedDiameters = MatProgressSpinner._diameters;
  145. /** @type {?} */
  146. const diametersForElement = trackedDiameters.get(this._styleRoot);
  147. if (!diametersForElement || !diametersForElement.has(this._diameter)) {
  148. this._attachStyleNode();
  149. }
  150. }
  151. }
  152. /**
  153. * Stroke width of the progress spinner.
  154. * @return {?}
  155. */
  156. get strokeWidth() {
  157. return this._strokeWidth || this.diameter / 10;
  158. }
  159. /**
  160. * @param {?} value
  161. * @return {?}
  162. */
  163. set strokeWidth(value) {
  164. this._strokeWidth = coerceNumberProperty(value);
  165. }
  166. /**
  167. * Value of the progress circle.
  168. * @return {?}
  169. */
  170. get value() {
  171. return this.mode === 'determinate' ? this._value : 0;
  172. }
  173. /**
  174. * @param {?} newValue
  175. * @return {?}
  176. */
  177. set value(newValue) {
  178. this._value = Math.max(0, Math.min(100, coerceNumberProperty(newValue)));
  179. }
  180. /**
  181. * The radius of the spinner, adjusted for stroke width.
  182. * @return {?}
  183. */
  184. get _circleRadius() {
  185. return (this.diameter - BASE_STROKE_WIDTH) / 2;
  186. }
  187. /**
  188. * The view box of the spinner's svg element.
  189. * @return {?}
  190. */
  191. get _viewBox() {
  192. /** @type {?} */
  193. const viewBox = this._circleRadius * 2 + this.strokeWidth;
  194. return `0 0 ${viewBox} ${viewBox}`;
  195. }
  196. /**
  197. * The stroke circumference of the svg circle.
  198. * @return {?}
  199. */
  200. get _strokeCircumference() {
  201. return 2 * Math.PI * this._circleRadius;
  202. }
  203. /**
  204. * The dash offset of the svg circle.
  205. * @return {?}
  206. */
  207. get _strokeDashOffset() {
  208. if (this.mode === 'determinate') {
  209. return this._strokeCircumference * (100 - this._value) / 100;
  210. }
  211. // In fallback mode set the circle to 80% and rotate it with CSS.
  212. if (this._fallbackAnimation && this.mode === 'indeterminate') {
  213. return this._strokeCircumference * 0.2;
  214. }
  215. return null;
  216. }
  217. /**
  218. * Stroke width of the circle in percent.
  219. * @return {?}
  220. */
  221. get _circleStrokeWidth() {
  222. return this.strokeWidth / this.diameter * 100;
  223. }
  224. /**
  225. * Dynamically generates a style tag containing the correct animation for this diameter.
  226. * @private
  227. * @return {?}
  228. */
  229. _attachStyleNode() {
  230. /** @type {?} */
  231. const styleTag = this._document.createElement('style');
  232. /** @type {?} */
  233. const styleRoot = this._styleRoot;
  234. /** @type {?} */
  235. const currentDiameter = this._diameter;
  236. /** @type {?} */
  237. const diameters = MatProgressSpinner._diameters;
  238. /** @type {?} */
  239. let diametersForElement = diameters.get(styleRoot);
  240. styleTag.setAttribute('mat-spinner-animation', currentDiameter + '');
  241. styleTag.textContent = this._getAnimationText();
  242. styleRoot.appendChild(styleTag);
  243. if (!diametersForElement) {
  244. diametersForElement = new Set();
  245. diameters.set(styleRoot, diametersForElement);
  246. }
  247. diametersForElement.add(currentDiameter);
  248. }
  249. /**
  250. * Generates animation styles adjusted for the spinner's diameter.
  251. * @private
  252. * @return {?}
  253. */
  254. _getAnimationText() {
  255. return INDETERMINATE_ANIMATION_TEMPLATE
  256. // Animation should begin at 5% and end at 80%
  257. .replace(/START_VALUE/g, `${0.95 * this._strokeCircumference}`)
  258. .replace(/END_VALUE/g, `${0.2 * this._strokeCircumference}`)
  259. .replace(/DIAMETER/g, `${this.diameter}`);
  260. }
  261. }
  262. /**
  263. * Tracks diameters of existing instances to de-dupe generated styles (default d = 100).
  264. * We need to keep track of which elements the diameters were attached to, because for
  265. * elements in the Shadow DOM the style tags are attached to the shadow root, rather
  266. * than the document head.
  267. */
  268. MatProgressSpinner._diameters = new WeakMap();
  269. MatProgressSpinner.decorators = [
  270. { type: Component, args: [{selector: 'mat-progress-spinner',
  271. exportAs: 'matProgressSpinner',
  272. host: {
  273. 'role': 'progressbar',
  274. 'class': 'mat-progress-spinner',
  275. '[class._mat-animation-noopable]': `_noopAnimations`,
  276. '[style.width.px]': 'diameter',
  277. '[style.height.px]': 'diameter',
  278. '[attr.aria-valuemin]': 'mode === "determinate" ? 0 : null',
  279. '[attr.aria-valuemax]': 'mode === "determinate" ? 100 : null',
  280. '[attr.aria-valuenow]': 'mode === "determinate" ? value : null',
  281. '[attr.mode]': 'mode',
  282. },
  283. inputs: ['color'],
  284. template: "<svg [style.width.px]=\"diameter\" [style.height.px]=\"diameter\" [attr.viewBox]=\"_viewBox\" preserveAspectRatio=\"xMidYMid meet\" focusable=\"false\" [ngSwitch]=\"mode === 'indeterminate'\"><circle *ngSwitchCase=\"true\" cx=\"50%\" cy=\"50%\" [attr.r]=\"_circleRadius\" [style.animation-name]=\"'mat-progress-spinner-stroke-rotate-' + diameter\" [style.stroke-dashoffset.px]=\"_strokeDashOffset\" [style.stroke-dasharray.px]=\"_strokeCircumference\" [style.stroke-width.%]=\"_circleStrokeWidth\"></circle><circle *ngSwitchCase=\"false\" cx=\"50%\" cy=\"50%\" [attr.r]=\"_circleRadius\" [style.stroke-dashoffset.px]=\"_strokeDashOffset\" [style.stroke-dasharray.px]=\"_strokeCircumference\" [style.stroke-width.%]=\"_circleStrokeWidth\"></circle></svg>",
  285. styles: [".mat-progress-spinner{display:block;position:relative}.mat-progress-spinner svg{position:absolute;transform:rotate(-90deg);top:0;left:0;transform-origin:center;overflow:visible}.mat-progress-spinner circle{fill:transparent;transform-origin:center;transition:stroke-dashoffset 225ms linear}._mat-animation-noopable.mat-progress-spinner circle{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate]{animation:mat-progress-spinner-linear-rotate 2s linear infinite}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate]{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate] circle{transition-property:stroke;animation-duration:4s;animation-timing-function:cubic-bezier(.35,0,.25,1);animation-iteration-count:infinite}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate] circle{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate]{animation:mat-progress-spinner-stroke-rotate-fallback 10s cubic-bezier(.87,.03,.33,1) infinite}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate]{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate] circle{transition-property:stroke}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate] circle{transition:none;animation:none}@keyframes mat-progress-spinner-linear-rotate{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes mat-progress-spinner-stroke-rotate-100{0%{stroke-dashoffset:268.60617px;transform:rotate(0)}12.5%{stroke-dashoffset:56.54867px;transform:rotate(0)}12.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(72.5deg)}25%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(72.5deg)}25.0001%{stroke-dashoffset:268.60617px;transform:rotate(270deg)}37.5%{stroke-dashoffset:56.54867px;transform:rotate(270deg)}37.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(161.5deg)}50%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(161.5deg)}50.0001%{stroke-dashoffset:268.60617px;transform:rotate(180deg)}62.5%{stroke-dashoffset:56.54867px;transform:rotate(180deg)}62.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(251.5deg)}75%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(251.5deg)}75.0001%{stroke-dashoffset:268.60617px;transform:rotate(90deg)}87.5%{stroke-dashoffset:56.54867px;transform:rotate(90deg)}87.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(341.5deg)}100%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(341.5deg)}}@keyframes mat-progress-spinner-stroke-rotate-fallback{0%{transform:rotate(0)}25%{transform:rotate(1170deg)}50%{transform:rotate(2340deg)}75%{transform:rotate(3510deg)}100%{transform:rotate(4680deg)}}"],
  286. changeDetection: ChangeDetectionStrategy.OnPush,
  287. encapsulation: ViewEncapsulation.None,
  288. },] },
  289. ];
  290. /** @nocollapse */
  291. MatProgressSpinner.ctorParameters = () => [
  292. { type: ElementRef },
  293. { type: Platform },
  294. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] },
  295. { type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] },
  296. { type: undefined, decorators: [{ type: Inject, args: [MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS,] }] }
  297. ];
  298. MatProgressSpinner.propDecorators = {
  299. diameter: [{ type: Input }],
  300. strokeWidth: [{ type: Input }],
  301. mode: [{ type: Input }],
  302. value: [{ type: Input }]
  303. };
  304. /**
  305. * `<mat-spinner>` component.
  306. *
  307. * This is a component definition to be used as a convenience reference to create an
  308. * indeterminate `<mat-progress-spinner>` instance.
  309. */
  310. class MatSpinner extends MatProgressSpinner {
  311. /**
  312. * @param {?} elementRef
  313. * @param {?} platform
  314. * @param {?} document
  315. * @param {?} animationMode
  316. * @param {?=} defaults
  317. */
  318. constructor(elementRef, platform, document, animationMode, defaults) {
  319. super(elementRef, platform, document, animationMode, defaults);
  320. this.mode = 'indeterminate';
  321. }
  322. }
  323. MatSpinner.decorators = [
  324. { type: Component, args: [{selector: 'mat-spinner',
  325. host: {
  326. 'role': 'progressbar',
  327. 'mode': 'indeterminate',
  328. 'class': 'mat-spinner mat-progress-spinner',
  329. '[class._mat-animation-noopable]': `_noopAnimations`,
  330. '[style.width.px]': 'diameter',
  331. '[style.height.px]': 'diameter',
  332. },
  333. inputs: ['color'],
  334. template: "<svg [style.width.px]=\"diameter\" [style.height.px]=\"diameter\" [attr.viewBox]=\"_viewBox\" preserveAspectRatio=\"xMidYMid meet\" focusable=\"false\" [ngSwitch]=\"mode === 'indeterminate'\"><circle *ngSwitchCase=\"true\" cx=\"50%\" cy=\"50%\" [attr.r]=\"_circleRadius\" [style.animation-name]=\"'mat-progress-spinner-stroke-rotate-' + diameter\" [style.stroke-dashoffset.px]=\"_strokeDashOffset\" [style.stroke-dasharray.px]=\"_strokeCircumference\" [style.stroke-width.%]=\"_circleStrokeWidth\"></circle><circle *ngSwitchCase=\"false\" cx=\"50%\" cy=\"50%\" [attr.r]=\"_circleRadius\" [style.stroke-dashoffset.px]=\"_strokeDashOffset\" [style.stroke-dasharray.px]=\"_strokeCircumference\" [style.stroke-width.%]=\"_circleStrokeWidth\"></circle></svg>",
  335. styles: [".mat-progress-spinner{display:block;position:relative}.mat-progress-spinner svg{position:absolute;transform:rotate(-90deg);top:0;left:0;transform-origin:center;overflow:visible}.mat-progress-spinner circle{fill:transparent;transform-origin:center;transition:stroke-dashoffset 225ms linear}._mat-animation-noopable.mat-progress-spinner circle{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate]{animation:mat-progress-spinner-linear-rotate 2s linear infinite}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate]{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate] circle{transition-property:stroke;animation-duration:4s;animation-timing-function:cubic-bezier(.35,0,.25,1);animation-iteration-count:infinite}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-animation[mode=indeterminate] circle{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate]{animation:mat-progress-spinner-stroke-rotate-fallback 10s cubic-bezier(.87,.03,.33,1) infinite}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate]{transition:none;animation:none}.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate] circle{transition-property:stroke}._mat-animation-noopable.mat-progress-spinner.mat-progress-spinner-indeterminate-fallback-animation[mode=indeterminate] circle{transition:none;animation:none}@keyframes mat-progress-spinner-linear-rotate{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes mat-progress-spinner-stroke-rotate-100{0%{stroke-dashoffset:268.60617px;transform:rotate(0)}12.5%{stroke-dashoffset:56.54867px;transform:rotate(0)}12.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(72.5deg)}25%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(72.5deg)}25.0001%{stroke-dashoffset:268.60617px;transform:rotate(270deg)}37.5%{stroke-dashoffset:56.54867px;transform:rotate(270deg)}37.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(161.5deg)}50%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(161.5deg)}50.0001%{stroke-dashoffset:268.60617px;transform:rotate(180deg)}62.5%{stroke-dashoffset:56.54867px;transform:rotate(180deg)}62.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(251.5deg)}75%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(251.5deg)}75.0001%{stroke-dashoffset:268.60617px;transform:rotate(90deg)}87.5%{stroke-dashoffset:56.54867px;transform:rotate(90deg)}87.5001%{stroke-dashoffset:56.54867px;transform:rotateX(180deg) rotate(341.5deg)}100%{stroke-dashoffset:268.60617px;transform:rotateX(180deg) rotate(341.5deg)}}@keyframes mat-progress-spinner-stroke-rotate-fallback{0%{transform:rotate(0)}25%{transform:rotate(1170deg)}50%{transform:rotate(2340deg)}75%{transform:rotate(3510deg)}100%{transform:rotate(4680deg)}}"],
  336. changeDetection: ChangeDetectionStrategy.OnPush,
  337. encapsulation: ViewEncapsulation.None,
  338. },] },
  339. ];
  340. /** @nocollapse */
  341. MatSpinner.ctorParameters = () => [
  342. { type: ElementRef },
  343. { type: Platform },
  344. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] },
  345. { type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] },
  346. { type: undefined, decorators: [{ type: Inject, args: [MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS,] }] }
  347. ];
  348. /**
  349. * Gets the shadow root of an element, if supported and the element is inside the Shadow DOM.
  350. * @param {?} element
  351. * @param {?} _document
  352. * @return {?}
  353. */
  354. function _getShadowRoot(element, _document) {
  355. // TODO(crisbeto): see whether we should move this into the CDK
  356. // feature detection utilities once #15616 gets merged in.
  357. if (typeof window !== 'undefined') {
  358. /** @type {?} */
  359. const head = _document.head;
  360. // Check whether the browser supports Shadow DOM.
  361. if (head && (((/** @type {?} */ (head))).createShadowRoot || head.attachShadow)) {
  362. /** @type {?} */
  363. const rootNode = element.getRootNode ? element.getRootNode() : null;
  364. // We need to take the `ShadowRoot` off of `window`, because the built-in types are
  365. // incorrect. See https://github.com/Microsoft/TypeScript/issues/27929.
  366. if (rootNode instanceof ((/** @type {?} */ (window))).ShadowRoot) {
  367. return rootNode;
  368. }
  369. }
  370. }
  371. return null;
  372. }
  373. /**
  374. * @fileoverview added by tsickle
  375. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  376. */
  377. class MatProgressSpinnerModule {
  378. }
  379. MatProgressSpinnerModule.decorators = [
  380. { type: NgModule, args: [{
  381. imports: [MatCommonModule, CommonModule],
  382. exports: [
  383. MatProgressSpinner,
  384. MatSpinner,
  385. MatCommonModule
  386. ],
  387. declarations: [
  388. MatProgressSpinner,
  389. MatSpinner
  390. ],
  391. },] },
  392. ];
  393. /**
  394. * @fileoverview added by tsickle
  395. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  396. */
  397. /**
  398. * @fileoverview added by tsickle
  399. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  400. */
  401. export { MatProgressSpinner, MatSpinner, MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS, MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY, MatProgressSpinnerModule };
  402. //# sourceMappingURL=progress-spinner.js.map