| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  | import {NgForOfContext} from '@angular/common'; | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  | import {getSortedClassName} from '@angular/core/testing/src/styling'; | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  | import {ɵɵdefineComponent} from '../../src/render3/definition'; | 
					
						
							| 
									
										
										
										
											2020-01-22 12:33:06 -08:00
										 |  |  | import {RenderFlags, ɵɵattribute, ɵɵclassMap, ɵɵelement, ɵɵelementEnd, ɵɵelementStart, ɵɵproperty, ɵɵselect, ɵɵstyleMap, ɵɵstyleProp, ɵɵstyleSanitizer, ɵɵtemplate, ɵɵtext, ɵɵtextInterpolate1} from '../../src/render3/index'; | 
					
						
							| 
									
										
										
										
											2018-10-12 18:49:00 -07:00
										 |  |  | import {AttributeMarker} from '../../src/render3/interfaces/node'; | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  | import {SafeValue, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, getSanitizationBypassType, unwrapSafeValue} from '../../src/sanitization/bypass'; | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  | import {ɵɵdefaultStyleSanitizer, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl} from '../../src/sanitization/sanitization'; | 
					
						
							| 
									
										
										
										
											2019-07-31 13:15:50 -07:00
										 |  |  | import {Sanitizer} from '../../src/sanitization/sanitizer'; | 
					
						
							|  |  |  | import {SecurityContext} from '../../src/sanitization/security'; | 
					
						
							| 
									
										
										
										
											2019-04-04 11:41:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  | import {NgForOf} from './common_with_def'; | 
					
						
							| 
									
										
										
										
											2018-06-06 13:38:19 -07:00
										 |  |  | import {ComponentFixture, TemplateFixture} from './render_util'; | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('instructions', () => { | 
					
						
							| 
									
										
										
										
											2019-09-09 13:14:26 -07:00
										 |  |  |   function createAnchor() { ɵɵelement(0, 'a'); } | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |   function createDiv() { ɵɵelement(0, 'div', 0); } | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |   function createScript() { ɵɵelement(0, 'script'); } | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |   describe('ɵɵselect', () => { | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |     it('should error in DevMode if index is out of range', () => { | 
					
						
							|  |  |  |       // Only one constant added, meaning only index `0` is valid.
 | 
					
						
							|  |  |  |       const t = new TemplateFixture(createDiv, () => {}, 1, 0); | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |       expect(() => { t.update(() => { ɵɵselect(-1); }); }).toThrow(); | 
					
						
							|  |  |  |       expect(() => { t.update(() => { ɵɵselect(1); }); }).toThrow(); | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  |   describe('bind', () => { | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |     it('should update bindings when value changes with the correct perf counters', () => { | 
					
						
							| 
									
										
										
										
											2018-08-21 00:03:21 -07:00
										 |  |  |       const t = new TemplateFixture(createAnchor, () => {}, 1, 1); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('title', 'Hello'); }); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  |       expect(t.html).toEqual('<a title="Hello"></a>'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('title', 'World'); }); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  |       expect(t.html).toEqual('<a title="World"></a>'); | 
					
						
							|  |  |  |       expect(ngDevMode).toHaveProperties({ | 
					
						
							| 
									
										
										
										
											2019-11-01 13:06:17 -07:00
										 |  |  |         firstCreatePass: 1, | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  |         tNode: 2,  // 1 for hostElement + 1 for the template under test
 | 
					
						
							| 
									
										
										
										
											2018-09-13 16:07:23 -07:00
										 |  |  |         tView: 2,  // 1 for rootView + 1 for the template view
 | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  |         rendererCreateElement: 1, | 
					
						
							|  |  |  |         rendererSetProperty: 2 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |     it('should not update bindings when value does not change, with the correct perf counters', | 
					
						
							|  |  |  |        () => { | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |          const idempotentUpdate = () => { ɵɵproperty('title', 'Hello'); }; | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |          const t = new TemplateFixture(createAnchor, idempotentUpdate, 1, 1); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |          t.update(); | 
					
						
							|  |  |  |          expect(t.html).toEqual('<a title="Hello"></a>'); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |          t.update(); | 
					
						
							|  |  |  |          expect(t.html).toEqual('<a title="Hello"></a>'); | 
					
						
							|  |  |  |          expect(ngDevMode).toHaveProperties({ | 
					
						
							| 
									
										
										
										
											2019-11-01 13:06:17 -07:00
										 |  |  |            firstCreatePass: 1, | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |            tNode: 2,  // 1 for hostElement + 1 for the template under test
 | 
					
						
							|  |  |  |            tView: 2,  // 1 for rootView + 1 for the template view
 | 
					
						
							|  |  |  |            rendererCreateElement: 1, | 
					
						
							|  |  |  |            rendererSetProperty: 1 | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  |        }); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:01:37 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 10:48:27 -07:00
										 |  |  |   describe('element', () => { | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |     it('should create an element with the correct perf counters', () => { | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |       const t = new TemplateFixture(() => { | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |         ɵɵelement(0, 'div', 0); | 
					
						
							|  |  |  |       }, () => {}, 1, 0, null, null, null, undefined, [['id', 'test', 'title', 'Hello']]); | 
					
						
							| 
									
										
										
										
											2018-06-08 10:48:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-12 15:02:54 -07:00
										 |  |  |       const div = (t.hostElement as HTMLElement).querySelector('div') !; | 
					
						
							| 
									
										
										
										
											2018-06-08 10:48:27 -07:00
										 |  |  |       expect(div.id).toEqual('test'); | 
					
						
							|  |  |  |       expect(div.title).toEqual('Hello'); | 
					
						
							| 
									
										
										
										
											2018-06-08 15:25:39 -07:00
										 |  |  |       expect(ngDevMode).toHaveProperties({ | 
					
						
							| 
									
										
										
										
											2019-11-01 13:06:17 -07:00
										 |  |  |         firstCreatePass: 1, | 
					
						
							| 
									
										
										
										
											2018-06-08 15:25:39 -07:00
										 |  |  |         tNode: 2,  // 1 for div, 1 for host element
 | 
					
						
							| 
									
										
										
										
											2018-09-13 16:07:23 -07:00
										 |  |  |         tView: 2,  // 1 for rootView + 1 for the template view
 | 
					
						
							| 
									
										
										
										
											2018-06-08 15:25:39 -07:00
										 |  |  |         rendererCreateElement: 1, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-06-08 10:48:27 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |   describe('attribute', () => { | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  |     it('should use sanitizer function', () => { | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, () => {}, 1, 1); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('title', 'javascript:true', ɵɵsanitizeUrl); }); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  |       expect(t.html).toEqual('<div title="unsafe:javascript:true"></div>'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       t.update(() => { | 
					
						
							|  |  |  |         ɵɵattribute('title', bypassSanitizationTrustUrl('javascript:true'), ɵɵsanitizeUrl); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  |       expect(t.html).toEqual('<div title="javascript:true"></div>'); | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |       expect(ngDevMode).toHaveProperties({ | 
					
						
							| 
									
										
										
										
											2019-11-01 13:06:17 -07:00
										 |  |  |         firstCreatePass: 1, | 
					
						
							| 
									
										
										
										
											2018-05-16 05:56:01 -07:00
										 |  |  |         tNode: 2,  // 1 for div, 1 for host element
 | 
					
						
							| 
									
										
										
										
											2018-09-13 16:07:23 -07:00
										 |  |  |         tView: 2,  // 1 for rootView + 1 for the template view
 | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |         rendererCreateElement: 1, | 
					
						
							|  |  |  |         rendererSetAttribute: 2 | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 14:57:36 -07:00
										 |  |  |   describe('property', () => { | 
					
						
							| 
									
										
										
										
											2019-05-06 12:45:09 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * TODO: We need to replace this with an acceptance test, but for right now, | 
					
						
							|  |  |  |      * this is the only test that ensures chaining works, since code generation | 
					
						
							|  |  |  |      * is not producing chained instructions yet. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-03-26 14:57:36 -07:00
										 |  |  |     it('should chain', () => { | 
					
						
							|  |  |  |       // <div [title]="title" [accesskey]="key"></div>
 | 
					
						
							|  |  |  |       const t = new TemplateFixture(createDiv, () => {}, 1, 2); | 
					
						
							| 
									
										
										
										
											2019-06-03 10:29:14 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('title', 'one')('accessKey', 'A'); }); | 
					
						
							| 
									
										
										
										
											2019-03-26 14:57:36 -07:00
										 |  |  |       expect(t.html).toEqual('<div accesskey="A" title="one"></div>'); | 
					
						
							| 
									
										
										
										
											2019-06-03 10:29:14 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('title', 'two')('accessKey', 'B'); }); | 
					
						
							| 
									
										
										
										
											2019-03-26 14:57:36 -07:00
										 |  |  |       expect(t.html).toEqual('<div accesskey="B" title="two"></div>'); | 
					
						
							|  |  |  |       expect(ngDevMode).toHaveProperties({ | 
					
						
							| 
									
										
										
										
											2019-11-01 13:06:17 -07:00
										 |  |  |         firstCreatePass: 1, | 
					
						
							| 
									
										
										
										
											2019-03-26 14:57:36 -07:00
										 |  |  |         tNode: 2,  // 1 for div, 1 for host element
 | 
					
						
							|  |  |  |         tView: 2,  // 1 for rootView + 1 for the template view
 | 
					
						
							|  |  |  |         rendererCreateElement: 1, | 
					
						
							|  |  |  |         rendererSetProperty: 4, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-08 11:26:40 -07:00
										 |  |  |   describe('styleProp', () => { | 
					
						
							| 
									
										
										
										
											2018-07-11 10:58:18 -07:00
										 |  |  |     it('should automatically sanitize unless a bypass operation is applied', () => { | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  |       let backgroundImage: string|SafeValue = 'url("http://server")'; | 
					
						
							|  |  |  |       const t = new TemplateFixture( | 
					
						
							|  |  |  |           () => { return createDiv(); }, | 
					
						
							|  |  |  |           () => { | 
					
						
							|  |  |  |             ɵɵstyleSanitizer(ɵɵdefaultStyleSanitizer); | 
					
						
							|  |  |  |             ɵɵstyleProp('background-image', backgroundImage); | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           2, 2); | 
					
						
							| 
									
										
										
										
											2020-01-22 12:33:06 -08:00
										 |  |  |       // nothing is set because sanitizer suppresses it.
 | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  |       expect((t.hostElement.firstChild as HTMLElement).style.getPropertyValue('background-image')) | 
					
						
							|  |  |  |           .toEqual(''); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  |       backgroundImage = bypassSanitizationTrustStyle('url("http://server2")'); | 
					
						
							|  |  |  |       t.update(); | 
					
						
							| 
									
										
										
										
											2020-01-22 12:33:06 -08:00
										 |  |  |       expect((t.hostElement.firstChild as HTMLElement).style.getPropertyValue('background-image')) | 
					
						
							|  |  |  |           .toEqual('url("http://server2")'); | 
					
						
							| 
									
										
										
										
											2018-07-11 10:58:18 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-03-08 13:57:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-08 11:26:40 -07:00
										 |  |  |   describe('styleMap', () => { | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |     const attrs = [[AttributeMarker.Styles, 'height', '10px']]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function createDivWithStyle() { ɵɵelement(0, 'div', 0); } | 
					
						
							| 
									
										
										
										
											2018-03-08 13:57:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should add style', () => { | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  |       const fixture = new TemplateFixture(createDivWithStyle, () => { | 
					
						
							|  |  |  |         ɵɵstyleMap({'background-color': 'red'}); | 
					
						
							|  |  |  |       }, 1, 2, null, null, null, undefined, attrs); | 
					
						
							|  |  |  |       fixture.update(); | 
					
						
							| 
									
										
										
										
											2020-01-22 12:33:06 -08:00
										 |  |  |       expect(fixture.html).toEqual('<div style="background-color: red; height: 10px;"></div>'); | 
					
						
							| 
									
										
										
										
											2018-03-08 13:57:56 -08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-07-11 10:58:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should sanitize new styles that may contain `url` properties', () => { | 
					
						
							|  |  |  |       const detectedValues: string[] = []; | 
					
						
							|  |  |  |       const sanitizerInterceptor = | 
					
						
							|  |  |  |           new MockSanitizerInterceptor(value => { detectedValues.push(value); }); | 
					
						
							| 
									
										
										
										
											2019-10-29 15:35:00 -07:00
										 |  |  |       const fixture = new TemplateFixture( | 
					
						
							|  |  |  |           () => { return createDiv(); },  //
 | 
					
						
							|  |  |  |           () => { | 
					
						
							| 
									
										
										
										
											2020-01-22 12:33:06 -08:00
										 |  |  |             ɵɵstyleSanitizer(sanitizerInterceptor.getStyleSanitizer()); | 
					
						
							| 
									
										
										
										
											2019-10-29 15:35:00 -07:00
										 |  |  |             ɵɵstyleMap({ | 
					
						
							|  |  |  |               'background-image': 'background-image', | 
					
						
							|  |  |  |               'background': 'background', | 
					
						
							|  |  |  |               'border-image': 'border-image', | 
					
						
							|  |  |  |               'list-style': 'list-style', | 
					
						
							|  |  |  |               'list-style-image': 'list-style-image', | 
					
						
							|  |  |  |               'filter': 'filter', | 
					
						
							|  |  |  |               'width': 'width' | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  |           1, 2, null, null, sanitizerInterceptor); | 
					
						
							| 
									
										
										
										
											2018-07-11 10:58:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const props = detectedValues.sort(); | 
					
						
							|  |  |  |       expect(props).toEqual([ | 
					
						
							|  |  |  |         'background', 'background-image', 'border-image', 'filter', 'list-style', 'list-style-image' | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-03-08 13:57:56 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('elementClass', () => { | 
					
						
							| 
									
										
										
										
											2019-09-09 13:14:26 -07:00
										 |  |  |     function createDivWithStyling() { ɵɵelement(0, 'div'); } | 
					
						
							| 
									
										
										
										
											2018-03-08 13:57:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should add class', () => { | 
					
						
							| 
									
										
										
										
											2019-12-17 15:40:37 -08:00
										 |  |  |       const fixture = new TemplateFixture( | 
					
						
							|  |  |  |           createDivWithStyling, () => { ɵɵclassMap('multiple classes'); }, 1, 2); | 
					
						
							|  |  |  |       const div = fixture.containerElement.querySelector('div.multiple') !; | 
					
						
							|  |  |  |       expect(getSortedClassName(div)).toEqual('classes multiple'); | 
					
						
							| 
									
										
										
										
											2018-03-08 13:57:56 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe('performance counters', () => { | 
					
						
							|  |  |  |     it('should create tViews only once for each nested level', () => { | 
					
						
							| 
									
										
										
										
											2019-11-28 19:42:00 +01:00
										 |  |  |       function ToDoAppComponent_NgForOf_Template_0( | 
					
						
							|  |  |  |           rf: RenderFlags, ctx0: NgForOfContext<any, any>) { | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |           ɵɵelementStart(0, 'ul'); | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |           ɵɵtemplate(1, ToDoAppComponent_NgForOf_NgForOf_Template_1, 2, 1, 'li', 0); | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |           ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           const row_r2 = ctx0.$implicit; | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |           ɵɵselect(1); | 
					
						
							|  |  |  |           ɵɵproperty('ngForOf', row_r2); | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       function ToDoAppComponent_NgForOf_NgForOf_Template_1( | 
					
						
							| 
									
										
										
										
											2019-11-28 19:42:00 +01:00
										 |  |  |           rf: RenderFlags, ctx1: NgForOfContext<any, any>) { | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |           ɵɵelementStart(0, 'li'); | 
					
						
							|  |  |  |           ɵɵtext(1); | 
					
						
							|  |  |  |           ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           const col_r3 = ctx1.$implicit; | 
					
						
							| 
									
										
										
										
											2019-05-31 14:41:07 -07:00
										 |  |  |           ɵɵselect(1); | 
					
						
							|  |  |  |           ɵɵtextInterpolate1('', col_r3, ''); | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <ul *ngFor="let row of rows"> | 
					
						
							|  |  |  |        *   <li *ngFor="let col of row.cols">{{col}}</li> | 
					
						
							|  |  |  |        * </ul> | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       class NestedLoops { | 
					
						
							|  |  |  |         rows = [['a', 'b'], ['A', 'B'], ['a', 'b'], ['A', 'B']]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-11 14:18:45 -07:00
										 |  |  |         static ɵfac = function ToDoAppComponent_Factory() { return new NestedLoops(); }; | 
					
						
							| 
									
										
										
										
											2019-10-10 14:57:15 -07:00
										 |  |  |         static ɵcmp = ɵɵdefineComponent({ | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |           type: NestedLoops, | 
					
						
							| 
									
										
										
										
											2018-04-26 10:44:49 -07:00
										 |  |  |           selectors: [['nested-loops']], | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |           decls: 1, | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |           vars: 1, | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |           consts: [[AttributeMarker.Template, 'ngFor', 'ngForOf']], | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |           template: function ToDoAppComponent_Template(rf: RenderFlags, ctx: NestedLoops) { | 
					
						
							| 
									
										
										
										
											2018-04-26 10:44:49 -07:00
										 |  |  |             if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-09-23 20:08:51 +02:00
										 |  |  |               ɵɵtemplate(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, 'ul', 0); | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-04-26 10:44:49 -07:00
										 |  |  |             if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |               ɵɵproperty('ngForOf', ctx.rows); | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           directives: [NgForOf] | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       const fixture = new ComponentFixture(NestedLoops); | 
					
						
							|  |  |  |       expect(ngDevMode).toHaveProperties({ | 
					
						
							| 
									
										
										
										
											2018-04-26 10:44:49 -07:00
										 |  |  |         // Expect: fixture view/Host view + component + ngForRow + ngForCol
 | 
					
						
							|  |  |  |         tView: 4,  // should be: 4,
 | 
					
						
							| 
									
										
										
										
											2018-04-14 11:52:53 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe('sanitization injection compatibility', () => { | 
					
						
							|  |  |  |     it('should work for url sanitization', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => `${value}-sanitized`); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createAnchor, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = 'http://foo'; | 
					
						
							|  |  |  |       const outputValue = 'http://foo-sanitized'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('href', inputValue, ɵɵsanitizeUrl); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<a href="${outputValue}"></a>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toEqual(outputValue); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass url sanitization if marked by the service', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createAnchor, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = s.bypassSecurityTrustUrl('http://foo'); | 
					
						
							|  |  |  |       const outputValue = 'http://foo'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('href', inputValue, ɵɵsanitizeUrl); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<a href="${outputValue}"></a>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass ivy-level url sanitization if a custom sanitizer is used', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createAnchor, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = bypassSanitizationTrustUrl('http://foo'); | 
					
						
							|  |  |  |       const outputValue = 'http://foo-ivy'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('href', inputValue, ɵɵsanitizeUrl); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<a href="${outputValue}"></a>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work for style sanitization', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => `color:blue`); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = 'color:red'; | 
					
						
							|  |  |  |       const outputValue = 'color:blue'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('style', inputValue, ɵɵsanitizeStyle); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(stripStyleWsCharacters(t.html)).toEqual(`<div style="${outputValue}"></div>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toEqual(outputValue); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass style sanitization if marked by the service', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = s.bypassSecurityTrustStyle('color:maroon'); | 
					
						
							|  |  |  |       const outputValue = 'color:maroon'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('style', inputValue, ɵɵsanitizeStyle); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(stripStyleWsCharacters(t.html)).toEqual(`<div style="${outputValue}"></div>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass ivy-level style sanitization if a custom sanitizer is used', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = bypassSanitizationTrustStyle('font-family:foo'); | 
					
						
							|  |  |  |       const outputValue = 'font-family:foo-ivy'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('style', inputValue, ɵɵsanitizeStyle); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(stripStyleWsCharacters(t.html)).toEqual(`<div style="${outputValue}"></div>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work for resourceUrl sanitization', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => `${value}-sanitized`); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createScript, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = 'http://resource'; | 
					
						
							|  |  |  |       const outputValue = 'http://resource-sanitized'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('src', inputValue, ɵɵsanitizeResourceUrl); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<script src="${outputValue}"></script>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toEqual(outputValue); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass resourceUrl sanitization if marked by the service', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createScript, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = s.bypassSecurityTrustResourceUrl('file://all-my-secrets.pdf'); | 
					
						
							|  |  |  |       const outputValue = 'file://all-my-secrets.pdf'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('src', inputValue, ɵɵsanitizeResourceUrl); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<script src="${outputValue}"></script>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass ivy-level resourceUrl sanitization if a custom sanitizer is used', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-31 10:39:14 -07:00
										 |  |  |       const t = new TemplateFixture(createScript, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = bypassSanitizationTrustResourceUrl('file://all-my-secrets.pdf'); | 
					
						
							|  |  |  |       const outputValue = 'file://all-my-secrets.pdf-ivy'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵattribute('src', inputValue, ɵɵsanitizeResourceUrl); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<script src="${outputValue}"></script>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work for script sanitization', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => `${value} //sanitized`); | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |       const t = new TemplateFixture(createScript, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = 'fn();'; | 
					
						
							|  |  |  |       const outputValue = 'fn(); //sanitized'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('innerHTML', inputValue, ɵɵsanitizeScript); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<script>${outputValue}</script>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toEqual(outputValue); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass script sanitization if marked by the service', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |       const t = new TemplateFixture(createScript, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = s.bypassSecurityTrustScript('alert("bar")'); | 
					
						
							|  |  |  |       const outputValue = 'alert("bar")'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('innerHTML', inputValue, ɵɵsanitizeScript); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<script>${outputValue}</script>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass ivy-level script sanitization if a custom sanitizer is used', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |       const t = new TemplateFixture(createScript, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = bypassSanitizationTrustScript('alert("bar")'); | 
					
						
							|  |  |  |       const outputValue = 'alert("bar")-ivy'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('innerHTML', inputValue, ɵɵsanitizeScript); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<script>${outputValue}</script>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should work for html sanitization', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => `${value} <!--sanitized-->`); | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = '<header></header>'; | 
					
						
							|  |  |  |       const outputValue = '<header></header> <!--sanitized-->'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('innerHTML', inputValue, ɵɵsanitizeHtml); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<div>${outputValue}</div>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toEqual(outputValue); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass html sanitization if marked by the service', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = s.bypassSecurityTrustHtml('<div onclick="alert(123)"></div>'); | 
					
						
							|  |  |  |       const outputValue = '<div onclick="alert(123)"></div>'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('innerHTML', inputValue, ɵɵsanitizeHtml); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<div>${outputValue}</div>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should bypass ivy-level script sanitization if a custom sanitizer is used', () => { | 
					
						
							|  |  |  |       const s = new LocalMockSanitizer(value => ''); | 
					
						
							| 
									
										
										
										
											2019-05-24 14:20:41 -07:00
										 |  |  |       const t = new TemplateFixture(createDiv, undefined, 1, 1, null, null, s); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       const inputValue = bypassSanitizationTrustHtml('<div onclick="alert(123)"></div>'); | 
					
						
							|  |  |  |       const outputValue = '<div onclick="alert(123)"></div>-ivy'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 10:31:01 -07:00
										 |  |  |       t.update(() => { ɵɵproperty('innerHTML', inputValue, ɵɵsanitizeHtml); }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |       expect(t.html).toEqual(`<div>${outputValue}</div>`); | 
					
						
							|  |  |  |       expect(s.lastSanitizedValue).toBeFalsy(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:01 -08:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class LocalSanitizedValue { | 
					
						
							|  |  |  |   constructor(public value: any) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   toString() { return this.value; } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class LocalMockSanitizer implements Sanitizer { | 
					
						
							| 
									
										
										
										
											2018-06-18 16:38:33 -07:00
										 |  |  |   // TODO(issue/24571): remove '!'.
 | 
					
						
							|  |  |  |   public lastSanitizedValue !: string | null; | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constructor(private _interceptor: (value: string|null|any) => string) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sanitize(context: SecurityContext, value: LocalSanitizedValue|string|null|any): string|null { | 
					
						
							| 
									
										
										
										
											2019-07-31 13:15:50 -07:00
										 |  |  |     if (getSanitizationBypassType(value) != null) { | 
					
						
							|  |  |  |       return unwrapSafeValue(value) + '-ivy'; | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (value instanceof LocalSanitizedValue) { | 
					
						
							|  |  |  |       return value.toString(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return this.lastSanitizedValue = this._interceptor(value); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bypassSecurityTrustHtml(value: string) { return new LocalSanitizedValue(value); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bypassSecurityTrustStyle(value: string) { return new LocalSanitizedValue(value); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bypassSecurityTrustScript(value: string) { return new LocalSanitizedValue(value); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bypassSecurityTrustUrl(value: string) { return new LocalSanitizedValue(value); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bypassSecurityTrustResourceUrl(value: string) { return new LocalSanitizedValue(value); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 10:58:18 -07:00
										 |  |  | class MockSanitizerInterceptor { | 
					
						
							|  |  |  |   public lastValue: string|null = null; | 
					
						
							|  |  |  |   constructor(private _interceptorFn?: ((value: any) => any)|null) {} | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |   getStyleSanitizer() { return ɵɵdefaultStyleSanitizer; } | 
					
						
							| 
									
										
										
										
											2018-07-11 10:58:18 -07:00
										 |  |  |   sanitize(context: SecurityContext, value: LocalSanitizedValue|string|null|any): string|null { | 
					
						
							|  |  |  |     if (this._interceptorFn) { | 
					
						
							|  |  |  |       this._interceptorFn(value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return this.lastValue = value; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 15:30:16 -07:00
										 |  |  | function stripStyleWsCharacters(value: string): string { | 
					
						
							|  |  |  |   // color: blue; => color:blue
 | 
					
						
							|  |  |  |   return value.replace(/;/g, '').replace(/:\s+/g, ':'); | 
					
						
							|  |  |  | } |