angular: getAnimationStyle causes exceptions in older browsers

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

Errors are thrown during collection of animation styles (in older browsers). The problem is on this line: https://github.com/angular/angular/blob/13cb75da8b02ed7aa60508dbb5ecd9065809fd12/packages/animations/browser/src/render/css_keyframes/element_animation_style_handler.ts#L137 Most of browsers will return empty string if the style property is not set. But some browsers (like Chrome on Android 4.4) returns null instead of empty string. Several string functions are applied on the output of the method “getAnimationStyle” - like trim, split, indexOf, etc… But if the output of the"getAnimationStyle" is null, exception is thrown.

Simple fix of this bug:

  return element.style[ANIMATION_PROP + name] || '';

Expected behavior

Animation should work without errors.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: 6.0.3


Browser:
- [ ] Chrome (desktop) version XX
- [X] Chrome (Android) version 34
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 16
  • Comments: 15 (2 by maintainers)

Most upvoted comments

@janousek I’ve solved issue on my side with a polyfill, added this code to src/polyfills.ts

if (document.body.style.animation === undefined && CSSStyleDeclaration) {
  CSSStyleDeclaration.prototype.animation = '';
}
if (document.body.style['animation-name'] === undefined && CSSStyleDeclaration) {
  CSSStyleDeclaration.prototype['animation-name'] = '';
  CSSStyleDeclaration.prototype['animationName'] = '';
}
if (document.body.style['animation-duration'] === undefined && CSSStyleDeclaration) {
  CSSStyleDeclaration.prototype['animation-duration'] = '';
  CSSStyleDeclaration.prototype['animationDuration'] = '';
}
if (document.body.style['animation-play-state'] === undefined && CSSStyleDeclaration) {
  CSSStyleDeclaration.prototype['animation-play-state'] = '';
  CSSStyleDeclaration.prototype['animationPlayState'] = '';
}

Only the last one (with animationPlayState) is fixing my issue, but I’ve added few more to be more future-proof

Any progress on this issue? It now causes issues with PhantomJS tests

have the same problem:

  • TypeError: Cannot call method ‘split’ of undefined
  • TypeError: Cannot call method ‘trim’ of undefined

Errors on the following User-Agents:

  1. Mozilla/5.0 (Linux; Android 4.4.2; Doro Liberto 820 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
  2. Mozilla/5.0 (Linux; Android 4.4.2; de-de; SAMSUNG GT-I9301I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36
  3. Mozilla/5.0 (Linux; U; Android 4.4.4; de-at; GT-I9060I Build/KTU84P) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
  4. MT6582_TD/V1 Linux/3.4.67 Android/4.4.2 Release/ Browser/AppleWebKit537.36 Chrome/30.0.0.0 Mobile Safari/537.36 System/Android 4.4.2

FYI duplicate issue #25563

@janousek i fixed my issue with using NoopAnimationsModule in my unit-test

Is there still no fix for this?

I think you can get pretty far by adding some vendor prefix checks at these 2 points https://github.com/angular/angular/blob/6482f6f0fe16a488ec1509faca76015315ed8d29/packages/animations/browser/src/render/css_keyframes/css_keyframes_driver.ts#L43

https://github.com/angular/angular/blob/cf0968f98e844043a0f6c2548201f3c0dfd329a7/packages/animations/browser/src/render/css_keyframes/element_animation_style_handler.ts#L9

maybe simply something like this?

function vendorPrefix() {
  return ['', '-webkit-', '-moz-', '-o-'].find((prefix) =>
    document.body.style[prefix+'animation'] !== undefined || ''
  )
}

// [...]
let keyframeStr = `@${vendorPrefix()}keyframes ${name} {\n`; 
// [...]
const ANIMATION_PROP = vendorPrefix()+'animation'; 

This approach requires calls to setAnimationStyle to use the lowercase-dashes version of the css properties https://github.com/angular/angular/blob/cf0968f98e844043a0f6c2548201f3c0dfd329a7/packages/animations/browser/src/render/css_keyframes/element_animation_style_handler.ts#L43 https://github.com/angular/angular/blob/cf0968f98e844043a0f6c2548201f3c0dfd329a7/packages/animations/browser/src/render/css_keyframes/element_animation_style_handler.ts#L75

Thoughts?

It seems that no one cares about this issue. My temporary solution/workaround to prevent errors, looks like this:

@Component({
  ....
})
class AppComponent {

	@HostBinding('@.disabled')
	public disableAnimations = document.createElement('div').style['animation'] == null;
  
  .....
}

This will disable animations in problematic browsers.

So, this has been blowing up our Sentry logging, and it’s an absolutely tiny fix with a PR that has no chance of causing issues, and has been sitting in the queue forever. Seems unfortunate that it’s taken over 2 years and several conversations to fail to change a single reference.

Is there any hope for this being solved soon?

There is a pull request opened (https://github.com/angular/angular/pull/29709), but nothing has been done about it.

@matsko any chance this will be merged?

@omieliekh your solution will break angular material dropdowns in Safari.