@@ -7548,6 +7548,158 @@ export const Foo = Foo__PRE_R3__;
75487548 } ) ;
75497549 } ) ;
75507550
7551+ describe ( 'iframe processing' , ( ) => {
7552+ it ( 'should generate attribute and property bindings with a validator fn when on <iframe>' ,
7553+ ( ) => {
7554+ env . write ( 'test.ts' , `
7555+ import {Component, Directive, NgModule} from '@angular/core';
7556+
7557+ @Directive({
7558+ selector: 'iframe',
7559+ inputs: ['sandbox']
7560+ })
7561+ class SomeDirective {}
7562+
7563+ @Component({
7564+ template: \`
7565+ <iframe src="http://angular.io"
7566+ [sandbox]="''" [attr.allow]="''"
7567+ [title]="'Hi!'"
7568+ ></iframe>
7569+ \`
7570+ })
7571+ class SomeComponent {}
7572+
7573+ @NgModule({
7574+ declarations: [SomeDirective, SomeComponent]
7575+ })
7576+ class SomeNgModule {}
7577+ ` ) ;
7578+
7579+ env . driveMain ( ) ;
7580+ const jsContents = env . getContents ( 'test.js' ) ;
7581+
7582+ // Only `sandbox` has an extra validation fn (since it's security-sensitive),
7583+ // the `title` property doesn't have an extra validation fn.
7584+ expect ( jsContents )
7585+ . toContain (
7586+ 'ɵɵproperty("sandbox", "", i0.ɵɵvalidateIframeAttribute)("title", "Hi!")' ) ;
7587+
7588+ // The `allow` property is also security-sensitive, thus an extra validation fn.
7589+ expect ( jsContents ) . toContain ( 'ɵɵattribute("allow", "", i0.ɵɵvalidateIframeAttribute)' ) ;
7590+ } ) ;
7591+
7592+ it ( 'should generate an attribute binding instruction with a validator function ' +
7593+ '(making sure it\'s case-insensitive, since this is allowed in Angular templates)' ,
7594+ ( ) => {
7595+ env . write ( 'test.ts' , `
7596+ import {Component} from '@angular/core';
7597+
7598+ @Component({
7599+ template: \`
7600+ <IFRAME
7601+ src="http://angular.io"
7602+ [attr.SANDBOX]="''"
7603+ ></IFRAME>
7604+ \`
7605+ })
7606+ export class SomeComponent {}
7607+ ` ) ;
7608+
7609+ env . driveMain ( ) ;
7610+ const jsContents = env . getContents ( 'test.js' ) ;
7611+
7612+ // Make sure that the `sandbox` has an extra validation fn,
7613+ // and the check is case-insensitive (since the `setAttribute` DOM API
7614+ // is case-insensitive as well).
7615+ expect ( jsContents ) . toContain ( 'ɵɵattribute("SANDBOX", "", i0.ɵɵvalidateIframeAttribute)' ) ;
7616+ } ) ;
7617+
7618+ it ( 'should *not* generate a validator fn for attribute and property bindings when *not* on <iframe>' ,
7619+ ( ) => {
7620+ env . write ( 'test.ts' , `
7621+ import {Component, Directive, NgModule} from '@angular/core';
7622+
7623+ @Directive({
7624+ selector: '[sandbox]',
7625+ inputs: ['sandbox']
7626+ })
7627+ class Dir {}
7628+
7629+ @Component({
7630+ imports: [Dir],
7631+ template: \`
7632+ <div [sandbox]="''" [title]="'Hi!'"></div>
7633+ \`
7634+ })
7635+ export class SomeComponent {}
7636+
7637+ @NgModule({
7638+ declarations: [Dir, SomeComponent]
7639+ })
7640+ class SomeNgModule {}
7641+ ` ) ;
7642+
7643+ env . driveMain ( ) ;
7644+ const jsContents = env . getContents ( 'test.js' ) ;
7645+
7646+ // Note: no extra validation fn, since a security-sensitive attribute is *not* on an
7647+ // <iframe>.
7648+ expect ( jsContents ) . toContain ( 'ɵɵproperty("sandbox", "")("title", "Hi!")' ) ;
7649+ } ) ;
7650+
7651+ it ( 'should generate a validator fn for attribute and property host bindings on a directive' ,
7652+ ( ) => {
7653+ env . write ( 'test.ts' , `
7654+ import {Directive} from '@angular/core';
7655+
7656+ @Directive({
7657+ host: {
7658+ '[sandbox]': "''",
7659+ '[attr.allow]': "''",
7660+ 'src': 'http://angular.io'
7661+ }
7662+ })
7663+ export class SomeDir {}
7664+ ` ) ;
7665+
7666+ env . driveMain ( ) ;
7667+ const jsContents = env . getContents ( 'test.js' ) ;
7668+
7669+ // The `sandbox` is potentially a security-sensitive attribute of an <iframe>.
7670+ // Generate an extra validation function to invoke at runtime, which would
7671+ // check if an underlying host element is an <iframe>.
7672+ expect ( jsContents )
7673+ . toContain ( 'ɵɵhostProperty("sandbox", "", i0.ɵɵvalidateIframeAttribute)' ) ;
7674+
7675+ // Similar to the above, but for an attribute binding (host attributes are
7676+ // represented via `ɵɵattribute`).
7677+ expect ( jsContents ) . toContain ( 'ɵɵattribute("allow", "", i0.ɵɵvalidateIframeAttribute)' ) ;
7678+ } ) ;
7679+
7680+ it ( 'should generate a validator fn for attribute host bindings on a directive ' +
7681+ '(making sure the check is case-insensitive)' ,
7682+ ( ) => {
7683+ env . write ( 'test.ts' , `
7684+ import {Directive} from '@angular/core';
7685+
7686+ @Directive({
7687+ host: {
7688+ '[attr.SANDBOX]': "''"
7689+ }
7690+ })
7691+ export class SomeDir {}
7692+ ` ) ;
7693+
7694+ env . driveMain ( ) ;
7695+ const jsContents = env . getContents ( 'test.js' ) ;
7696+
7697+ // Make sure that we generate a validation fn for the `sandbox` attribute,
7698+ // even when it was declared as `SANDBOX`.
7699+ expect ( jsContents ) . toContain ( 'ɵɵattribute("SANDBOX", "", i0.ɵɵvalidateIframeAttribute)' ) ;
7700+ } ) ;
7701+ } ) ;
7702+
75517703 describe ( 'undecorated providers' , ( ) => {
75527704 it ( 'should error when an undecorated class, with a non-trivial constructor, is provided directly in a module' ,
75537705 ( ) => {
0 commit comments