fix(ivy): unable to bind to properties that start with class or style (#32421)
Fixes Ivy picking up property bindings that start with `class` or `style` as if they're style bindings. Fixes #32310 PR Close #32421
This commit is contained in:
		
							parent
							
								
									098feec4a0
								
							
						
					
					
						commit
						62d92f8091
					
				| @ -149,9 +149,10 @@ export class StylingBuilder { | ||||
| 
 | ||||
|   registerInputBasedOnName(name: string, expression: AST, sourceSpan: ParseSourceSpan) { | ||||
|     let binding: BoundStylingEntry|null = null; | ||||
|     const nameToMatch = name.substring(0, 5);  // class | style
 | ||||
|     const isStyle = nameToMatch === 'style'; | ||||
|     const isClass = isStyle ? false : (nameToMatch === 'class'); | ||||
|     const prefix = name.substring(0, 6); | ||||
|     const isStyle = name === 'style' || prefix === 'style.' || prefix === 'style!'; | ||||
|     const isClass = !isStyle && | ||||
|         (name === 'class' || name === 'className' || prefix === 'class.' || prefix === 'class!'); | ||||
|     if (isStyle || isClass) { | ||||
|       const isMapBased = name.charAt(5) !== '.';         // style.prop or class.prop makes this a no
 | ||||
|       const property = name.substr(isMapBased ? 5 : 6);  // the dot explains why there's a +1
 | ||||
|  | ||||
| @ -5,7 +5,7 @@ | ||||
|  * 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 {Component, Directive, ElementRef, Input} from '@angular/core'; | ||||
| import {Component, Directive, ElementRef, HostBinding, Input, ViewChild} from '@angular/core'; | ||||
| import {ngDevModeResetPerfCounters} from '@angular/core/src/util/ng_dev_mode'; | ||||
| import {TestBed} from '@angular/core/testing'; | ||||
| import {By, DomSanitizer, SafeStyle} from '@angular/platform-browser'; | ||||
| @ -631,4 +631,46 @@ describe('styling', () => { | ||||
| 
 | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   it('should be able to name inputs starting with `class` or `style`', () => { | ||||
|     @Directive({selector: '[dir]'}) | ||||
|     class Dir { | ||||
|       @Input('classesInSchool') classes = ''; | ||||
|       @Input('styleOfClothing') style = ''; | ||||
|     } | ||||
| 
 | ||||
|     @Component({ | ||||
|       template: '<span dir [classesInSchool]="classes" [styleOfClothing]="style"></span>', | ||||
|     }) | ||||
|     class App { | ||||
|       @ViewChild(Dir, {static: false}) dir !: Dir; | ||||
| 
 | ||||
|       classes = 'math'; | ||||
|       style = '80s'; | ||||
|     } | ||||
| 
 | ||||
|     TestBed.configureTestingModule({declarations: [App, Dir]}); | ||||
|     const fixture = TestBed.createComponent(App); | ||||
|     fixture.detectChanges(); | ||||
|     const directive = fixture.componentInstance.dir; | ||||
| 
 | ||||
|     expect(directive.classes).toBe('math'); | ||||
|     expect(directive.style).toBe('80s'); | ||||
|   }); | ||||
| 
 | ||||
|   it('should be able to bind to `className`', () => { | ||||
|     @Component({template: ''}) | ||||
|     class App { | ||||
|       @HostBinding('className') | ||||
|       klass = 'one two'; | ||||
|     } | ||||
| 
 | ||||
|     TestBed.configureTestingModule({declarations: [App]}); | ||||
|     const fixture = TestBed.createComponent(App); | ||||
|     fixture.detectChanges(); | ||||
|     const classList = fixture.nativeElement.classList; | ||||
| 
 | ||||
|     expect(classList.contains('one')).toBe(true); | ||||
|     expect(classList.contains('two')).toBe(true); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user