Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(animations): ensure
position
and display
styles are handled o…
…utside of keyframes/web-animations When web-animations and/or CSS keyframes are used for animations certain CSS style values (such as `display` and `position`) may be ignored by a keyframe-based animation. Angular should special-case these styles to ensure that they get applied as inline styles throughout the duration of the animation. Closes #24923 Closes #25635 Jira Issue: FW-1091 Jira Issue: FW-1092
- Loading branch information
Showing
8 changed files
with
278 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
packages/animations/browser/src/render/special_cased_styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
import {eraseStyles, setStyles} from '../util'; | ||
|
||
export function packageSpecialStyles( | ||
element: any, styles: {[key: string]: any} | {[key: string]: any}[]): SpecialCasedStyles|null { | ||
const result: SpecialStyles = {start: null, end: null}; | ||
if (Array.isArray(styles) && styles.length) { | ||
result.start = filterSpecialStyles(styles[0]); | ||
if (styles.length > 1) { | ||
result.end = filterSpecialStyles(styles[styles.length - 1]); | ||
} | ||
} else if (styles) { | ||
result.start = filterSpecialStyles(styles); | ||
} | ||
|
||
return (result.start || result.end) ? new SpecialCasedStyles(element, result) : null; | ||
} | ||
|
||
const enum SpecialCasedStylesState { | ||
Pending = 0, | ||
Started = 1, | ||
Finished = 2, | ||
Destroyed = 3, | ||
} | ||
|
||
export class SpecialCasedStyles { | ||
static initialStylesByElement = new WeakMap<any, {[key: string]: any}>(); | ||
|
||
private _state = SpecialCasedStylesState.Pending; | ||
private _startStyles: {[key: string]: any}|null = null; | ||
private _endStyles: {[key: string]: any}|null = null; | ||
private _initialStyles !: {[key: string]: any}; | ||
|
||
constructor(private _element: any, styles: SpecialStyles) { | ||
this._startStyles = styles.start; | ||
this._endStyles = styles.end; | ||
|
||
let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element); | ||
if (!initialStyles) { | ||
SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = {}); | ||
} | ||
this._initialStyles = initialStyles; | ||
} | ||
|
||
start() { | ||
if (this._state < SpecialCasedStylesState.Started) { | ||
if (this._startStyles) { | ||
setStyles(this._element, this._startStyles, this._initialStyles); | ||
} | ||
this._state = SpecialCasedStylesState.Started; | ||
} | ||
} | ||
|
||
finish() { | ||
this.start(); | ||
if (this._state < SpecialCasedStylesState.Finished) { | ||
setStyles(this._element, this._initialStyles); | ||
if (this._endStyles) { | ||
setStyles(this._element, this._endStyles); | ||
this._endStyles = null; | ||
} | ||
this._state = SpecialCasedStylesState.Started; | ||
} | ||
} | ||
|
||
destroy() { | ||
this.finish(); | ||
if (this._state < SpecialCasedStylesState.Destroyed) { | ||
SpecialCasedStyles.initialStylesByElement.delete(this._element); | ||
if (this._startStyles) { | ||
eraseStyles(this._element, this._startStyles); | ||
this._endStyles = null; | ||
} | ||
if (this._endStyles) { | ||
eraseStyles(this._element, this._endStyles); | ||
this._endStyles = null; | ||
} | ||
setStyles(this._element, this._initialStyles); | ||
this._state = SpecialCasedStylesState.Destroyed; | ||
} | ||
} | ||
} | ||
|
||
export interface SpecialStyles { | ||
start: {[key: string]: any}|null; | ||
end: {[key: string]: any}|null; | ||
} | ||
|
||
function filterSpecialStyles(styles: {[key: string]: any}) { | ||
let result: {[key: string]: any}|null = null; | ||
const props = Object.keys(styles); | ||
for (let i = 0; i < props.length; i++) { | ||
const prop = props[i]; | ||
if (isSpecialStyle(prop)) { | ||
result = result || {}; | ||
result[prop] = styles[prop]; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
function isSpecialStyle(prop: string) { | ||
return prop === 'display' || prop === 'position'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.