Skip to content

Commit 45f3bf9

Browse files
authored
refactor(material/progress-spinner): clean up IE workarounds (#23283)
Cleans up the various workarounds for IE from the progress spinner.
1 parent b3a6a0a commit 45f3bf9

File tree

5 files changed

+27
-81
lines changed

5 files changed

+27
-81
lines changed

src/material/progress-spinner/progress-spinner.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<!--
22
preserveAspectRatio of xMidYMid meet as the center of the viewport is the circle's
33
center. The center of the circle will remain at the center of the mat-progress-spinner
4-
element containing the SVG. `focusable="false"` prevents IE from allowing the user to
5-
tab into the SVG element.
4+
element containing the SVG.
65
-->
76
<!--
87
All children need to be hidden for screen readers in order to support ChromeVox.

src/material/progress-spinner/progress-spinner.scss

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
@use '../../cdk/a11y';
44

55

6-
// Animation config
7-
$stroke-rotate-fallback-duration: 10 * 1000ms !default;
8-
$stroke-rotate-fallback-ease: cubic-bezier(0.87, 0.03, 0.33, 1) !default;
9-
106
$_default-radius: 45px;
117
$_default-circumference: variables.$pi * $_default-radius * 2;
128

@@ -35,10 +31,9 @@ $_default-circumference: variables.$pi * $_default-radius * 2;
3531

3632
@include a11y.high-contrast(active, off) {
3733
// SVG colors aren't inverted automatically in high contrast mode. Set the
38-
// stroke to currentColor in order to respect the user's color settings.
39-
stroke: currentColor;
40-
// currentColor blends in with the background in Chromium-based browsers
41-
// so we have to fall back to `CanvasText` which isn't supported on IE.
34+
// stroke to `CanvasText` in order to respect the user's color settings.
35+
// Note that we use `CanvasText` instead of `currentColor`, because
36+
// the latter blends in with the background on Chromium browsers.
4237
stroke: CanvasText;
4338
}
4439
}
@@ -59,21 +54,6 @@ $_default-circumference: variables.$pi * $_default-radius * 2;
5954
animation-iteration-count: infinite;
6055
}
6156
}
62-
63-
&.mat-progress-spinner-indeterminate-fallback-animation[mode='indeterminate'] {
64-
svg {
65-
@include private.private-animation-noop();
66-
animation: mat-progress-spinner-stroke-rotate-fallback
67-
$stroke-rotate-fallback-duration
68-
$stroke-rotate-fallback-ease
69-
infinite;
70-
}
71-
72-
circle {
73-
@include private.private-animation-noop();
74-
transition-property: stroke;
75-
}
76-
}
7757
}
7858

7959

@@ -86,7 +66,6 @@ $_default-circumference: variables.$pi * $_default-radius * 2;
8666
@at-root {
8767
$start: (1 - 0.05) * $_default-circumference; // start the animation at 5%
8868
$end: (1 - 0.8) * $_default-circumference; // end the animation at 80%
89-
$fallback-iterations: 4;
9069

9170
@keyframes mat-progress-spinner-stroke-rotate-100 {
9271
// stylelint-disable declaration-block-single-line-max-declarations
@@ -119,15 +98,4 @@ $_default-circumference: variables.$pi * $_default-radius * 2;
11998
100% { stroke-dashoffset: $start; transform: rotateX(180deg) rotate(341.5deg); }
12099
// stylelint-enable
121100
}
122-
123-
// For IE11 and Edge, we fall back to simply rotating the spinner because
124-
// animating stroke-dashoffset is not supported. The fallback uses multiple
125-
// iterations to vary where the spin "lands".
126-
@keyframes mat-progress-spinner-stroke-rotate-fallback {
127-
@for $i from 0 through $fallback-iterations {
128-
$percent: private.private-div(100, $fallback-iterations) * $i;
129-
$offset: private.private-div(360, $fallback-iterations);
130-
#{$percent}% { transform: rotate(#{$i * (360 * 3 + $offset)}deg); }
131-
}
132-
}
133101
}

src/material/progress-spinner/progress-spinner.spec.ts

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import {TestBed, waitForAsync, inject} from '@angular/core/testing';
1+
import {TestBed, waitForAsync} from '@angular/core/testing';
22
import {Component, ViewEncapsulation, ViewChild, ElementRef} from '@angular/core';
33
import {By} from '@angular/platform-browser';
4-
import {Platform, _getShadowRoot, _supportsShadowDom} from '@angular/cdk/platform';
4+
import {_getShadowRoot, _supportsShadowDom} from '@angular/cdk/platform';
55
import {CommonModule} from '@angular/common';
66
import {
77
MatProgressSpinnerModule,
@@ -158,13 +158,7 @@ describe('MatProgressSpinner', () => {
158158
});
159159

160160
it('should add a style tag with the indeterminate animation to the document head when using a ' +
161-
'non-default diameter', inject([Platform], (platform: Platform) => {
162-
// On Edge and IE we use a fallback animation because the
163-
// browser doesn't support animating SVG correctly.
164-
if (platform.EDGE || platform.TRIDENT) {
165-
return;
166-
}
167-
161+
'non-default diameter', () => {
168162
const fixture = TestBed.createComponent(ProgressSpinnerCustomDiameter);
169163
fixture.componentInstance.diameter = 32;
170164
fixture.detectChanges();
@@ -184,7 +178,7 @@ describe('MatProgressSpinner', () => {
184178

185179
expect(document.head.querySelectorAll('style[mat-spinner-animation="32"]').length).toBe(1);
186180
expect(document.head.querySelectorAll('style[mat-spinner-animation="64"]').length).toBe(1);
187-
}));
181+
});
188182

189183
it('should allow floating point values for custom diameter', () => {
190184
const fixture = TestBed.createComponent(ProgressSpinnerCustomDiameter);
@@ -207,26 +201,19 @@ describe('MatProgressSpinner', () => {
207201
.toBe('0 0 25.75 25.75', 'Expected the custom diameter to be applied to the svg viewBox.');
208202
});
209203

210-
it('should handle creating animation style tags based on a floating point diameter',
211-
inject([Platform], (platform: Platform) => {
212-
// On Edge and IE we use a fallback animation because the
213-
// browser doesn't support animating SVG correctly.
214-
if (platform.EDGE || platform.TRIDENT) {
215-
return;
216-
}
217-
218-
const fixture = TestBed.createComponent(IndeterminateSpinnerCustomDiameter);
204+
it('should handle creating animation style tags based on a floating point diameter', () => {
205+
const fixture = TestBed.createComponent(IndeterminateSpinnerCustomDiameter);
219206

220-
fixture.componentInstance.diameter = 32.5;
221-
fixture.detectChanges();
207+
fixture.componentInstance.diameter = 32.5;
208+
fixture.detectChanges();
222209

223-
const circleElement = fixture.nativeElement.querySelector('circle');
210+
const circleElement = fixture.nativeElement.querySelector('circle');
224211

225-
expect(circleElement.style.animationName).toBe('mat-progress-spinner-stroke-rotate-32_5',
226-
'Expected the spinner circle element to have an animation name based on the custom diameter');
227-
expect(document.head.querySelectorAll('style[mat-spinner-animation="32_5"]').length).toBe(1,
228-
'Expected a style tag with the indeterminate animation to be attached to the document head');
229-
}));
212+
expect(circleElement.style.animationName).toBe('mat-progress-spinner-stroke-rotate-32_5',
213+
'Expected the spinner circle element to have an animation name based on the custom diameter');
214+
expect(document.head.querySelectorAll('style[mat-spinner-animation="32_5"]').length).toBe(1,
215+
'Expected a style tag with the indeterminate animation to be attached to the document head');
216+
});
230217

231218
it('should allow a custom stroke width', () => {
232219
const fixture = TestBed.createComponent(ProgressSpinnerCustomStrokeWidth);

src/material/progress-spinner/progress-spinner.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
128128
private _diameter = BASE_SIZE;
129129
private _value = 0;
130130
private _strokeWidth: number;
131-
private _fallbackAnimation = false;
132131

133132
/**
134133
* Element to which we should add the generated style tags for the indeterminate animation.
@@ -159,7 +158,7 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
159158
this._spinnerAnimationLabel = this._getSpinnerAnimationLabel();
160159

161160
// If this is set before `ngOnInit`, the style root may not have been resolved yet.
162-
if (!this._fallbackAnimation && this._styleRoot) {
161+
if (this._styleRoot) {
163162
this._attachStyleNode();
164163
}
165164
}
@@ -186,7 +185,11 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
186185
}
187186

188187
constructor(elementRef: ElementRef<HTMLElement>,
189-
platform: Platform,
188+
/**
189+
* @deprecated `_platform` parameter no longer being used.
190+
* @breaking-change 14.0.0
191+
*/
192+
_platform: Platform,
190193
@Optional() @Inject(DOCUMENT) private _document: any,
191194
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode: string,
192195
@Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS)
@@ -203,7 +206,6 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
203206
trackedDiameters.set(_document.head, new Set<number>([BASE_SIZE]));
204207
}
205208

206-
this._fallbackAnimation = platform.EDGE || platform.TRIDENT;
207209
this._noopAnimations = animationMode === 'NoopAnimations' &&
208210
(!!defaults && !defaults._forceAnimations);
209211

@@ -226,13 +228,7 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
226228
// node is inside an `ngIf` and a ShadowDom-encapsulated component.
227229
this._styleRoot = _getShadowRoot(element) || this._document.head;
228230
this._attachStyleNode();
229-
230-
// On IE and Edge, we can't animate the `stroke-dashoffset`
231-
// reliably so we fall back to a non-spec animation.
232-
const animationClass =
233-
`mat-progress-spinner-indeterminate${this._fallbackAnimation ? '-fallback' : ''}-animation`;
234-
235-
element.classList.add(animationClass);
231+
element.classList.add('mat-progress-spinner-indeterminate-animation');
236232
}
237233

238234
/** The radius of the spinner, adjusted for stroke width. */
@@ -257,11 +253,6 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
257253
return this._getStrokeCircumference() * (100 - this._value) / 100;
258254
}
259255

260-
// In fallback mode set the circle to 80% and rotate it with CSS.
261-
if (this._fallbackAnimation && this.mode === 'indeterminate') {
262-
return this._getStrokeCircumference() * 0.2;
263-
}
264-
265256
return null;
266257
}
267258

tools/public_api_guard/material/progress-spinner.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export function MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY(): MatProgressSpinn
2424

2525
// @public
2626
export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnInit, CanColor {
27-
constructor(elementRef: ElementRef<HTMLElement>, platform: Platform, _document: any, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions);
27+
constructor(elementRef: ElementRef<HTMLElement>,
28+
_platform: Platform, _document: any, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions);
2829
get diameter(): number;
2930
set diameter(size: number);
3031
_getCircleRadius(): number;

0 commit comments

Comments
 (0)