refactor(compiler): Drop support for the deprecated <template>. Use <ng-template> instead (#22783)
				
					
				
			BREAKING CHANGE:
The `<template>` tag was deprecated in Angular v4 to avoid collisions (i.e. when
using Web Components).
This commit removes support for `<template>`. `<ng-template>` should be used
instead.
BEFORE:
    <!-- html template -->
    <template>some template content</template>
    # tsconfig.json
    {
      # ...
      "angularCompilerOptions": {
        # ...
        # This option is no more supported and will have no effect
        "enableLegacyTemplate": [true|false]
      }
    }
AFTER:
    <!-- html template -->
    <ng-template>some template content</ng-template>
PR Close #22783
			
			
This commit is contained in:
		
							parent
							
								
									4e6ac185e5
								
							
						
					
					
						commit
						0ebd577db4
					
				| @ -215,13 +215,6 @@ value           | description | ||||
| 
 | ||||
| This tells the compiler to print extra information while compiling templates. | ||||
| 
 | ||||
| ### *enableLegacyTemplate* | ||||
| 
 | ||||
| The use of `<template>` element was deprecated starting in Angular 4.0 in favor of using | ||||
| `<ng-template>` to avoid colliding with the DOM's element of the same name. Setting this option to | ||||
| `true` enables the use of the deprecated `<template>` element . This option | ||||
| is `false` by default. This option might be required by some third-party Angular libraries. | ||||
| 
 | ||||
| ### *disableExpressionLowering* | ||||
| 
 | ||||
| The Angular template compiler transforms code that is used, or could be used, in an annotation | ||||
|  | ||||
| @ -25,9 +25,9 @@ import {ScrollAreaComponent} from './scroll_area'; | ||||
|     <div style="display: flex"> | ||||
|       <scroll-area id="testArea"></scroll-area> | ||||
|     </div> | ||||
|     <div template="ngIf scrollAreas.length > 0"> | ||||
|     <div *ngIf="scrollAreas.length > 0"> | ||||
|       <p>Following tables are only here to add weight to the UI:</p> | ||||
|       <scroll-area template="ngFor let scrollArea of scrollAreas"></scroll-area> | ||||
|       <scroll-area *ngFor="let scrollArea of scrollAreas"></scroll-area> | ||||
|     </div> | ||||
|   </div>` | ||||
| }) | ||||
|  | ||||
| @ -62,7 +62,7 @@ export class Stage { | ||||
|   directives: [NgFor], | ||||
|   template: ` | ||||
|       <div [style.width.px]="cellWidth"> | ||||
|           <button template="ngFor let stage of stages" | ||||
|           <button *ngFor="let stage of stages" | ||||
|                   [disabled]="stage.isDisabled" | ||||
|                   [style.background-color]="stage.backgroundColor" | ||||
|                   on-click="setStage(stage)"> | ||||
|  | ||||
| @ -25,7 +25,7 @@ import {ScrollItemComponent} from './scroll_item'; | ||||
|             <div id="padding"></div> | ||||
|             <div id="inner"> | ||||
|                 <scroll-item | ||||
|                     template="ngFor let item of visibleItems" | ||||
|                     *ngFor="let item of visibleItems" | ||||
|                     [offering]="item"> | ||||
|                 </scroll-item> | ||||
|             </div> | ||||
|  | ||||
| @ -50,7 +50,6 @@ export interface CompilerOptions extends ts.CompilerOptions { | ||||
|   annotateForClosureCompiler?: boolean; | ||||
|   annotationsAs?: 'decorators'|'static fields'; | ||||
|   trace?: boolean; | ||||
|   enableLegacyTemplate?: boolean; | ||||
|   disableExpressionLowering?: boolean; | ||||
|   i18nOutLocale?: string; | ||||
|   i18nOutFormat?: string; | ||||
|  | ||||
| @ -125,9 +125,6 @@ export interface CompilerOptions extends ts.CompilerOptions { | ||||
|   // Print extra information while running the compiler
 | ||||
|   trace?: boolean; | ||||
| 
 | ||||
|   // Whether to enable support for <template> and the template attribute (false by default)
 | ||||
|   enableLegacyTemplate?: boolean; | ||||
| 
 | ||||
|   // Whether to enable lowering expressions lambdas and expressions in a reference value
 | ||||
|   // position.
 | ||||
|   disableExpressionLowering?: boolean; | ||||
|  | ||||
| @ -828,7 +828,6 @@ function getAotCompilerOptions(options: CompilerOptions): AotCompilerOptions { | ||||
|   return { | ||||
|     locale: options.i18nInLocale, | ||||
|     i18nFormat: options.i18nInFormat || options.i18nOutFormat, translations, missingTranslation, | ||||
|     enableLegacyTemplate: options.enableLegacyTemplate, | ||||
|     enableSummariesForJit: options.enableSummariesForJit, | ||||
|     preserveWhitespaces: options.preserveWhitespaces, | ||||
|     fullTemplateTypeCheck: options.fullTemplateTypeCheck, | ||||
|  | ||||
| @ -536,7 +536,6 @@ The recommended options for producing a ivy application are | ||||
| | `"renderer2BackPatching"`      | `true`   | implied     | | ||||
| | `"generateCodeForLibraries"`   | `true`   | default     | | ||||
| | `"annotationsAs"`              | `remove` | implied     | | ||||
| | `"enableLegacyTemplate"`       | `false`  | default     | | ||||
| | `"preserveWhitespaces"`        | `false`  | default     | | ||||
| | `"skipMetadataEmit"`           | `true`   | default     | | ||||
| | `"strictMetadataEmit"`         | `false`  | implied     | | ||||
| @ -574,7 +573,6 @@ The recommended options for producing a ivy library are: | ||||
| | `"renderer2BackPatching"`      | `false`  | default     | | ||||
| | `"generateCodeForLibraries"`   | `false`  |             | | ||||
| | `"annotationsAs"`              | `remove` | implied     | | ||||
| | `"enableLegacyTemplate"`       | `false`  | default     | | ||||
| | `"preserveWhitespaces"`        | `false`  | default     | | ||||
| | `"skipMetadataEmit"`           | `false`  |             | | ||||
| | `"strictMetadataEmit"`         | `true `  |             | | ||||
| @ -598,25 +596,21 @@ depending on the target: | ||||
| |                   | `"renderer2BackPatching"`      | `true`       | enforced    | | ||||
| |                   | `"generateCodeForLibraries"`   | `true`       |             | | ||||
| |                   | `"annotationsAs"`              | `remove`     |             | | ||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | | ||||
| |                   | `"preserveWhitespaces"`        | `false`      |             | | ||||
| |                   | `"skipMetadataEmit"`           | `false`      |             | | ||||
| |                   | `"strictMetadataEmit"`         | `true`       |             | | ||||
| |                   | `"skipTemplateCodegen"`        | `false`      |             | | ||||
| |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | ||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | | ||||
| |                   |                                |              |             | | ||||
| | `"library"`       | `"generateRenderer2Factories"` | `false`      | enforced    | | ||||
| |                   | `"renderer2BackPatching"`      | `false`      | enforced    | | ||||
| |                   | `"generateCodeForLibraries"`   | `false`      | enforced    | | ||||
| |                   | `"annotationsAs"`              | `decorators` |             | | ||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | | ||||
| |                   | `"preserveWhitespaces"`        | `false`      |             | | ||||
| |                   | `"skipMetadataEmit"`           | `false`      | enforced    | | ||||
| |                   | `"strictMetadataEmit"`         | `true`       |             | | ||||
| |                   | `"skipTemplateCodegen"`        | `false`      | enforced    | | ||||
| |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | ||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | | ||||
| |                   |                                |              |             | | ||||
| | `"package"`       | `"flatModuleOutFile"`          |              | required    | | ||||
| |                   | `"flatModuleId"`               |              | required    | | ||||
| @ -625,13 +619,11 @@ depending on the target: | ||||
| |                   | `"renderer2BackPatching"`      | `false`      | enforced    | | ||||
| |                   | `"generateCodeForLibraries"`   | `false`      | enforced    | | ||||
| |                   | `"annotationsAs"`              | `remove`     |             | | ||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | | ||||
| |                   | `"preserveWhitespaces"`        | `false`      |             | | ||||
| |                   | `"skipMetadataEmit"`           | `false`      | enforced    | | ||||
| |                   | `"strictMetadataEmit"`         | `true`       |             | | ||||
| |                   | `"skipTemplateCodegen"`        | `false`      | enforced    | | ||||
| |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | ||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | | ||||
| 
 | ||||
| Options that are marked "enforced" are reported as an error if they are | ||||
| explicitly set to a value different from what is specified here. The options | ||||
|  | ||||
| @ -70,7 +70,6 @@ export function createAotCompiler( | ||||
|   const config = new CompilerConfig({ | ||||
|     defaultEncapsulation: ViewEncapsulation.Emulated, | ||||
|     useJit: false, | ||||
|     enableLegacyTemplate: options.enableLegacyTemplate === true, | ||||
|     missingTranslation: options.missingTranslation, | ||||
|     preserveWhitespaces: options.preserveWhitespaces, | ||||
|     strictInjectionParameters: options.strictInjectionParameters, | ||||
|  | ||||
| @ -13,7 +13,6 @@ export interface AotCompilerOptions { | ||||
|   i18nFormat?: string; | ||||
|   translations?: string; | ||||
|   missingTranslation?: MissingTranslationStrategy; | ||||
|   enableLegacyTemplate?: boolean; | ||||
|   enableSummariesForJit?: boolean; | ||||
|   preserveWhitespaces?: boolean; | ||||
|   fullTemplateTypeCheck?: boolean; | ||||
|  | ||||
| @ -14,9 +14,6 @@ import {noUndefined} from './util'; | ||||
| 
 | ||||
| export class CompilerConfig { | ||||
|   public defaultEncapsulation: ViewEncapsulation|null; | ||||
|   // Whether to support the `<template>` tag and the `template` attribute to define angular
 | ||||
|   // templates. They have been deprecated in 4.x, `<ng-template>` should be used instead.
 | ||||
|   public enableLegacyTemplate: boolean; | ||||
|   public useJit: boolean; | ||||
|   public jitDevMode: boolean; | ||||
|   public missingTranslation: MissingTranslationStrategy|null; | ||||
| @ -25,13 +22,11 @@ export class CompilerConfig { | ||||
| 
 | ||||
|   constructor( | ||||
|       {defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, jitDevMode = false, | ||||
|        missingTranslation = null, enableLegacyTemplate, preserveWhitespaces, | ||||
|        strictInjectionParameters}: { | ||||
|        missingTranslation = null, preserveWhitespaces, strictInjectionParameters}: { | ||||
|         defaultEncapsulation?: ViewEncapsulation, | ||||
|         useJit?: boolean, | ||||
|         jitDevMode?: boolean, | ||||
|         missingTranslation?: MissingTranslationStrategy, | ||||
|         enableLegacyTemplate?: boolean, | ||||
|         preserveWhitespaces?: boolean, | ||||
|         strictInjectionParameters?: boolean, | ||||
|       } = {}) { | ||||
| @ -39,7 +34,6 @@ export class CompilerConfig { | ||||
|     this.useJit = !!useJit; | ||||
|     this.jitDevMode = !!jitDevMode; | ||||
|     this.missingTranslation = missingTranslation; | ||||
|     this.enableLegacyTemplate = enableLegacyTemplate === true; | ||||
|     this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces)); | ||||
|     this.strictInjectionParameters = strictInjectionParameters === true; | ||||
|   } | ||||
|  | ||||
| @ -71,7 +71,6 @@ export function mergeNsAndName(prefix: string, localName: string): string { | ||||
| // This list is not exhaustive to keep the compiler footprint low.
 | ||||
| // The `{` / `ƫ` syntax should be used when the named character reference does not
 | ||||
| // exist.
 | ||||
| 
 | ||||
| export const NAMED_ENTITIES: {[k: string]: string} = { | ||||
|   'Aacute': '\u00C1', | ||||
|   'aacute': '\u00E1', | ||||
|  | ||||
| @ -55,20 +55,11 @@ const IDENT_PROPERTY_IDX = 9; | ||||
| // Group 10 = identifier inside ()
 | ||||
| const IDENT_EVENT_IDX = 10; | ||||
| 
 | ||||
| // deprecated in 4.x
 | ||||
| const TEMPLATE_ELEMENT = 'template'; | ||||
| // deprecated in 4.x
 | ||||
| const TEMPLATE_ATTR = 'template'; | ||||
| const TEMPLATE_ATTR_PREFIX = '*'; | ||||
| const CLASS_ATTR = 'class'; | ||||
| 
 | ||||
| const TEXT_CSS_SELECTOR = CssSelector.parse('*')[0]; | ||||
| 
 | ||||
| const TEMPLATE_ELEMENT_DEPRECATION_WARNING = | ||||
|     'The <template> element is deprecated. Use <ng-template> instead'; | ||||
| const TEMPLATE_ATTR_DEPRECATION_WARNING = | ||||
|     'The template attribute is deprecated. Use an ng-template element instead.'; | ||||
| 
 | ||||
| let warningCounts: {[warning: string]: number} = {}; | ||||
| 
 | ||||
| function warnOnlyOnce(warnings: string[]): (warning: ParseError) => boolean { | ||||
| @ -109,10 +100,7 @@ export class TemplateParser { | ||||
|       preserveWhitespaces: boolean): {template: TemplateAst[], pipes: CompilePipeSummary[]} { | ||||
|     const result = this.tryParse( | ||||
|         component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces); | ||||
|     const warnings = | ||||
|         result.errors !.filter(error => error.level === ParseErrorLevel.WARNING) | ||||
|             .filter(warnOnlyOnce( | ||||
|                 [TEMPLATE_ATTR_DEPRECATION_WARNING, TEMPLATE_ELEMENT_DEPRECATION_WARNING])); | ||||
|     const warnings = result.errors !.filter(error => error.level === ParseErrorLevel.WARNING); | ||||
| 
 | ||||
|     const errors = result.errors !.filter(error => error.level === ParseErrorLevel.ERROR); | ||||
| 
 | ||||
| @ -295,9 +283,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
| 
 | ||||
|     let hasInlineTemplates = false; | ||||
|     const attrs: AttrAst[] = []; | ||||
|     const isTemplateElement = isTemplate( | ||||
|         element, this.config.enableLegacyTemplate, | ||||
|         (m: string, span: ParseSourceSpan) => this._reportError(m, span, ParseErrorLevel.WARNING)); | ||||
|     const isTemplateElement = isNgTemplate(element.name); | ||||
| 
 | ||||
|     element.attrs.forEach(attr => { | ||||
|       const hasBinding = this._parseAttr( | ||||
| @ -306,13 +292,9 @@ class TemplateParseVisitor implements html.Visitor { | ||||
| 
 | ||||
|       let templateBindingsSource: string|undefined; | ||||
|       let prefixToken: string|undefined; | ||||
|       let normalizedName = this._normalizeAttributeName(attr.name); | ||||
|       const normalizedName = this._normalizeAttributeName(attr.name); | ||||
| 
 | ||||
|       if (this.config.enableLegacyTemplate && normalizedName == TEMPLATE_ATTR) { | ||||
|         this._reportError( | ||||
|             TEMPLATE_ATTR_DEPRECATION_WARNING, attr.sourceSpan, ParseErrorLevel.WARNING); | ||||
|         templateBindingsSource = attr.value; | ||||
|       } else if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) { | ||||
|       if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) { | ||||
|         templateBindingsSource = attr.value; | ||||
|         prefixToken = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length) + ':'; | ||||
|       } | ||||
| @ -321,7 +303,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|       if (hasTemplateBinding) { | ||||
|         if (hasInlineTemplates) { | ||||
|           this._reportError( | ||||
|               `Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *`, | ||||
|               `Can't have multiple template bindings on one element. Use only one attribute prefixed with *`, | ||||
|               attr.sourceSpan); | ||||
|         } | ||||
|         hasInlineTemplates = true; | ||||
| @ -400,7 +382,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
| 
 | ||||
|     if (hasInlineTemplates) { | ||||
|       const templateQueryStartIndex = this.contentQueryStartId; | ||||
|       const templateSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs); | ||||
|       const templateSelector = createElementCssSelector('ng-template', templateMatchableAttrs); | ||||
|       const {directives: templateDirectiveMetas} = | ||||
|           this._parseDirectives(this.selectorMatcher, templateSelector); | ||||
|       const templateBoundDirectivePropNames = new Set<string>(); | ||||
| @ -908,20 +890,4 @@ function isEmptyExpression(ast: AST): boolean { | ||||
|     ast = ast.ast; | ||||
|   } | ||||
|   return ast instanceof EmptyExpr; | ||||
| } | ||||
| 
 | ||||
| // `template` is deprecated in 4.x
 | ||||
| function isTemplate( | ||||
|     el: html.Element, enableLegacyTemplate: boolean, | ||||
|     reportDeprecation: (m: string, span: ParseSourceSpan) => void): boolean { | ||||
|   if (isNgTemplate(el.name)) return true; | ||||
|   const tagNoNs = splitNsName(el.name)[1]; | ||||
|   // `<template>` is HTML and case insensitive
 | ||||
|   if (tagNoNs.toLowerCase() === TEMPLATE_ELEMENT) { | ||||
|     if (enableLegacyTemplate && tagNoNs.toLowerCase() === TEMPLATE_ELEMENT) { | ||||
|       reportDeprecation(TEMPLATE_ELEMENT_DEPRECATION_WARNING, el.sourceSpan !); | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| } | ||||
| @ -32,10 +32,6 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe | ||||
|         }); | ||||
| 
 | ||||
|         it('should parse text nodes inside <ng-template> elements', () => { | ||||
|           // deprecated in 4.0
 | ||||
|           expect(humanizeDom(parser.parse('<template>a</template>', 'TestComp'))).toEqual([ | ||||
|             [html.Element, 'template', 0], [html.Text, 'a', 1] | ||||
|           ]); | ||||
|           expect(humanizeDom(parser.parse('<ng-template>a</ng-template>', 'TestComp'))).toEqual([ | ||||
|             [html.Element, 'ng-template', 0], [html.Text, 'a', 1] | ||||
|           ]); | ||||
| @ -62,8 +58,6 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe | ||||
|         }); | ||||
| 
 | ||||
|         it('should parse elements inside  <ng-template> elements', () => { | ||||
|           expect(humanizeDom(parser.parse('<template><span></span></template>', 'TestComp'))) | ||||
|               .toEqual([[html.Element, 'template', 0], [html.Element, 'span', 1]]); | ||||
|           expect(humanizeDom(parser.parse('<ng-template><span></span></ng-template>', 'TestComp'))) | ||||
|               .toEqual([[html.Element, 'ng-template', 0], [html.Element, 'span', 1]]); | ||||
|         }); | ||||
| @ -175,10 +169,6 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe | ||||
|         }); | ||||
| 
 | ||||
|         it('should not add the requiredParent when the parent is a <ng-template>', () => { | ||||
|           expect(humanizeDom(parser.parse('<template><tr></tr></template>', 'TestComp'))).toEqual([ | ||||
|             [html.Element, 'template', 0], | ||||
|             [html.Element, 'tr', 1], | ||||
|           ]); | ||||
|           expect(humanizeDom(parser.parse('<ng-template><tr></tr></ng-template>', 'TestComp'))) | ||||
|               .toEqual([ | ||||
|                 [html.Element, 'ng-template', 0], | ||||
| @ -282,10 +272,6 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe | ||||
|         }); | ||||
| 
 | ||||
|         it('should parse attributes on <ng-template> elements', () => { | ||||
|           expect(humanizeDom(parser.parse('<template k="v"></template>', 'TestComp'))).toEqual([ | ||||
|             [html.Element, 'template', 0], | ||||
|             [html.Attribute, 'k', 'v'], | ||||
|           ]); | ||||
|           expect(humanizeDom(parser.parse('<ng-template k="v"></ng-template>', 'TestComp'))) | ||||
|               .toEqual([ | ||||
|                 [html.Element, 'ng-template', 0], | ||||
|  | ||||
| @ -158,7 +158,6 @@ function doCompile( | ||||
|   const config = new CompilerConfig({ | ||||
|     defaultEncapsulation: ViewEncapsulation.Emulated, | ||||
|     useJit: false, | ||||
|     enableLegacyTemplate: options.enableLegacyTemplate === true, | ||||
|     missingTranslation: options.missingTranslation, | ||||
|     preserveWhitespaces: options.preserveWhitespaces, | ||||
|     strictInjectionParameters: options.strictInjectionParameters, | ||||
|  | ||||
| @ -336,7 +336,6 @@ class ArrayConsole implements Console { | ||||
|       TestBed.configureCompiler({ | ||||
|         providers: [ | ||||
|           {provide: Console, useValue: console}, | ||||
|           {provide: CompilerConfig, useValue: new CompilerConfig({enableLegacyTemplate: true})} | ||||
|         ], | ||||
|       }); | ||||
|     }); | ||||
| @ -812,6 +811,35 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen | ||||
|             ] | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should support * directives', () => { | ||||
|           expect(humanizeTplAst(parse('<div *ngIf>', [ngIf]))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [DirectiveAst, ngIf], | ||||
|             [BoundDirectivePropertyAst, 'ngIf', 'null'], | ||||
|             [ElementAst, 'div'], | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should support <ng-template>', () => { | ||||
|           expect(humanizeTplAst(parse('<ng-template>', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should treat <template> as a regular tag', () => { | ||||
|           expect(humanizeTplAst(parse('<template>', []))).toEqual([ | ||||
|             [ElementAst, 'template'], | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should not special case the template attribute', () => { | ||||
|           expect(humanizeTplAst(parse('<p template="ngFor">', []))).toEqual([ | ||||
|             [ElementAst, 'p'], | ||||
|             [AttrAst, 'template', 'ngFor'], | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|       }); | ||||
| 
 | ||||
|       describe('events', () => { | ||||
| @ -852,17 +880,11 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen | ||||
|            () => { | ||||
|              const dirA = | ||||
|                  compileDirectiveMetadataCreate({ | ||||
|                    selector: 'template,ng-template', | ||||
|                    selector: 'ng-template', | ||||
|                    outputs: ['e'], | ||||
|                    type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) | ||||
|                  }).toSummary(); | ||||
| 
 | ||||
|              expect(humanizeTplAst(parse('<template (e)="f"></template>', [dirA]))).toEqual([ | ||||
|                [EmbeddedTemplateAst], | ||||
|                [BoundEventAst, 'e', null, 'f'], | ||||
|                [DirectiveAst, dirA], | ||||
|              ]); | ||||
| 
 | ||||
|              expect(humanizeTplAst(parse('<ng-template (e)="f"></ng-template>', [dirA]))).toEqual([ | ||||
|                [EmbeddedTemplateAst], | ||||
|                [BoundEventAst, 'e', null, 'f'], | ||||
| @ -952,7 +974,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen | ||||
|         it('should locate directives in inline templates', () => { | ||||
|           const dirTemplate = | ||||
|               compileDirectiveMetadataCreate({ | ||||
|                 selector: 'template', | ||||
|                 selector: 'ng-template', | ||||
|                 type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'onTemplate'}}) | ||||
|               }).toSummary(); | ||||
|           expect(humanizeTplAst(parse('<div *ngIf="cond">', [ngIf, dirTemplate]))).toEqual([ | ||||
| @ -1460,8 +1482,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
| 
 | ||||
|         it('should not throw error when there is same reference name in different templates', | ||||
|            () => { | ||||
|              expect(() => parse('<div #a><template #a><span>OK</span></template></div>', [])) | ||||
|                  .not.toThrowError(); | ||||
|              expect(() => parse('<div #a><ng-template #a><span>OK</span></ng-template></div>', [])) | ||||
|                  .not.toThrowError(); | ||||
|            }); | ||||
| @ -1500,20 +1520,12 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|         beforeEach(() => { reflector = new JitReflector(); }); | ||||
| 
 | ||||
|         it('should create embedded templates for <ng-template> elements', () => { | ||||
|           expect(humanizeTplAst(parse('<template></template>', [ | ||||
|           ]))).toEqual([[EmbeddedTemplateAst]]); | ||||
|           expect(humanizeTplAst(parse('<TEMPLATE></TEMPLATE>', [ | ||||
|           ]))).toEqual([[EmbeddedTemplateAst]]); | ||||
|           expect(humanizeTplAst(parse('<ng-template></ng-template>', [ | ||||
|           ]))).toEqual([[EmbeddedTemplateAst]]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should create embedded templates for <ng-template> elements regardless the namespace', | ||||
|            () => { | ||||
|              expect(humanizeTplAst(parse('<svg><template></template></svg>', []))).toEqual([ | ||||
|                [ElementAst, ':svg:svg'], | ||||
|                [EmbeddedTemplateAst], | ||||
|              ]); | ||||
|              expect(humanizeTplAst(parse('<svg><ng-template></ng-template></svg>', []))).toEqual([ | ||||
|                [ElementAst, ':svg:svg'], | ||||
|                [EmbeddedTemplateAst], | ||||
| @ -1521,12 +1533,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|            }); | ||||
| 
 | ||||
|         it('should support references via #...', () => { | ||||
|           expect(humanizeTplAst(parse('<template #a>', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [ | ||||
|               ReferenceAst, 'a', createTokenForExternalReference(reflector, Identifiers.TemplateRef) | ||||
|             ], | ||||
|           ]); | ||||
|           expect(humanizeTplAst(parse('<ng-template #a>', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [ | ||||
| @ -1536,12 +1542,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|         }); | ||||
| 
 | ||||
|         it('should support references via ref-...', () => { | ||||
|           expect(humanizeTplAst(parse('<template ref-a>', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [ | ||||
|               ReferenceAst, 'a', createTokenForExternalReference(reflector, Identifiers.TemplateRef) | ||||
|             ] | ||||
|           ]); | ||||
|           expect(humanizeTplAst(parse('<ng-template ref-a>', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [ | ||||
| @ -1551,10 +1551,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|         }); | ||||
| 
 | ||||
|         it('should parse variables via let-...', () => { | ||||
|           expect(humanizeTplAst(parse('<template let-a="b">', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [VariableAst, 'a', 'b'], | ||||
|           ]); | ||||
|           expect(humanizeTplAst(parse('<ng-template let-a="b">', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [VariableAst, 'a', 'b'], | ||||
| @ -1567,10 +1563,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|                 selector: '[a]', | ||||
|                 type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) | ||||
|               }).toSummary(); | ||||
|           expect(humanizeTplAst(parse('<template let-a="b"></template>', [dirA]))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [VariableAst, 'a', 'b'], | ||||
|           ]); | ||||
|           expect(humanizeTplAst(parse('<ng-template let-a="b"></ng-template>', [dirA]))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [VariableAst, 'a', 'b'], | ||||
| @ -1580,30 +1572,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|       }); | ||||
| 
 | ||||
|       describe('inline templates', () => { | ||||
|         it('should wrap the element into an EmbeddedTemplateAST', () => { | ||||
|           expect(humanizeTplAst(parse('<div template>', []))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [ElementAst, 'div'], | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should wrap the element with data-template attribute into an EmbeddedTemplateAST ', | ||||
|            () => { | ||||
|              expect(humanizeTplAst(parse('<div data-template>', []))).toEqual([ | ||||
|                [EmbeddedTemplateAst], | ||||
|                [ElementAst, 'div'], | ||||
|              ]); | ||||
|            }); | ||||
| 
 | ||||
|         it('should parse bound properties', () => { | ||||
|           expect(humanizeTplAst(parse('<div template="ngIf test">', [ngIf]))).toEqual([ | ||||
|             [EmbeddedTemplateAst], | ||||
|             [DirectiveAst, ngIf], | ||||
|             [BoundDirectivePropertyAst, 'ngIf', 'test'], | ||||
|             [ElementAst, 'div'], | ||||
|           ]); | ||||
|         }); | ||||
| 
 | ||||
|         it('should report an error on variables declared with #', () => { | ||||
|           expect(() => humanizeTplAst(parse('<div *ngIf="#a=b">', []))) | ||||
|               .toThrowError(/Parser Error: Unexpected token # at column 1/); | ||||
| @ -1646,7 +1614,7 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|                   selector: '[b]', | ||||
|                   type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirB'}}) | ||||
|                 }).toSummary(); | ||||
|             expect(humanizeTplAst(parse('<div template="a b" b>', [dirA, dirB]))).toEqual([ | ||||
|             expect(humanizeTplAst(parse('<div *a="b" b>', [dirA, dirB]))).toEqual([ | ||||
|               [EmbeddedTemplateAst], [DirectiveAst, dirA], [BoundDirectivePropertyAst, 'a', 'b'], | ||||
|               [ElementAst, 'div'], [AttrAst, 'b', ''], [DirectiveAst, dirB] | ||||
|             ]); | ||||
| @ -1658,9 +1626,13 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|                   selector: '[a]', | ||||
|                   type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) | ||||
|                 }).toSummary(); | ||||
|             expect(humanizeTplAst(parse('<div template="let a=b">', [dirA]))).toEqual([ | ||||
|               [EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div'] | ||||
|             ]); | ||||
|             expect( | ||||
|                 humanizeTplAst(parse('<ng-template let-a="b"><div></div></ng-template>', [dirA]))) | ||||
|                 .toEqual([ | ||||
|                   [EmbeddedTemplateAst], | ||||
|                   [VariableAst, 'a', 'b'], | ||||
|                   [ElementAst, 'div'], | ||||
|                 ]); | ||||
|           }); | ||||
| 
 | ||||
|           it('should not locate directives in references', () => { | ||||
| @ -1760,13 +1732,11 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
| 
 | ||||
|       describe('embedded templates', () => { | ||||
|         it('should project embedded templates with wildcard selector', () => { | ||||
|           expect(humanizeContentProjection(parse( | ||||
|                      '<div><template></template><ng-template></ng-template></div>', | ||||
|                      [createComp('div', ['*'])]))) | ||||
|           expect(humanizeContentProjection( | ||||
|                      parse('<div><ng-template></ng-template></div>', [createComp('div', ['*'])]))) | ||||
|               .toEqual([ | ||||
|                 ['div', null], | ||||
|                 ['template', 0], | ||||
|                 ['template', 0], | ||||
|               ]); | ||||
|         }); | ||||
| 
 | ||||
| @ -1848,14 +1818,12 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|         }); | ||||
| 
 | ||||
|         it('should override <ng-template>', () => { | ||||
|           expect( | ||||
|               humanizeContentProjection(parse( | ||||
|                   '<div><template ngProjectAs="b"></template><ng-template ngProjectAs="b"></ng-template></div>', | ||||
|                   [createComp('div', ['template', 'b'])]))) | ||||
|           expect(humanizeContentProjection(parse( | ||||
|                      '<div><ng-template ngProjectAs="b"></ng-template></div>', | ||||
|                      [createComp('div', ['template', 'b'])]))) | ||||
|               .toEqual([ | ||||
|                 ['div', null], | ||||
|                 ['template', 1], | ||||
|                 ['template', 1], | ||||
|               ]); | ||||
|         }); | ||||
| 
 | ||||
| @ -1894,26 +1862,14 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | ||||
|                 `<ng-content> element cannot have content. ("[ERROR ->]<ng-content>content</ng-content>"): TestComp@0:0`); | ||||
|       }); | ||||
| 
 | ||||
|       it('should treat *attr on a template element as valid', () => { | ||||
|         expect(() => parse('<template *ngIf>', [])).not.toThrowError(); | ||||
|         expect(() => parse('<ng-template *ngIf>', [])).not.toThrowError(); | ||||
|       }); | ||||
| 
 | ||||
|       it('should treat template attribute on a template element as valid', () => { | ||||
|         expect(() => parse('<template template="ngIf">', [])).not.toThrowError(); | ||||
|         expect(() => parse('<ng-template template="ngIf">', [])).not.toThrowError(); | ||||
|       }); | ||||
|       it('should treat *attr on a template element as valid', | ||||
|          () => { expect(() => parse('<ng-template *ngIf>', [])).not.toThrowError(); }); | ||||
| 
 | ||||
|       it('should report when multiple *attrs are used on the same element', () => { | ||||
|         expect(() => parse('<div *ngIf *ngFor>', [])).toThrowError(`Template parse errors:
 | ||||
| Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with * ("<div *ngIf [ERROR ->]*ngFor>"): TestComp@0:11`);
 | ||||
| Can't have multiple template bindings on one element. Use only one attribute prefixed with * ("<div *ngIf [ERROR ->]*ngFor>"): TestComp@0:11`);
 | ||||
|       }); | ||||
| 
 | ||||
|       it('should report when mix of template and *attrs are used on the same element', () => { | ||||
|         expect(() => parse('<span template="ngIf" *ngFor>', [])) | ||||
|             .toThrowError(`Template parse errors:
 | ||||
| Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with * ("<span template="ngIf" [ERROR ->]*ngFor>"): TestComp@0:22`);
 | ||||
|       }); | ||||
| 
 | ||||
|       it('should report invalid property names', () => { | ||||
|         expect(() => parse('<div [invalidProp]></div>', [])).toThrowError(`Template parse errors:
 | ||||
| @ -1977,12 +1933,6 @@ Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [ | ||||
|                  template: compileTemplateMetadata({ngContentSelectors: []}) | ||||
|                }).toSummary(); | ||||
| 
 | ||||
|            expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA])) | ||||
|                .toThrowError(`Template parse errors:
 | ||||
| Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("<template [a]="b" [ERROR ->](e)="f"></template>"): TestComp@0:18 | ||||
| Components on an embedded template: DirA ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0 | ||||
| Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0`);
 | ||||
| 
 | ||||
|            expect(() => parse('<ng-template [a]="b" (e)="f"></ng-template>', [dirA])) | ||||
|                .toThrowError(`Template parse errors:
 | ||||
| Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("<ng-template [a]="b" [ERROR ->](e)="f"></ng-template>"): TestComp@0:21 | ||||
| @ -2093,8 +2043,6 @@ Property binding a not used by any directive on an embedded template. Make sure | ||||
|       }); | ||||
| 
 | ||||
|       it('should support embedded template', () => { | ||||
|         expect(humanizeTplAstSourceSpans(parse('<template></template>', [ | ||||
|         ]))).toEqual([[EmbeddedTemplateAst, '<template>']]); | ||||
|         expect(humanizeTplAstSourceSpans(parse('<ng-template></ng-template>', [ | ||||
|         ]))).toEqual([[EmbeddedTemplateAst, '<ng-template>']]); | ||||
|       }); | ||||
| @ -2112,10 +2060,6 @@ Property binding a not used by any directive on an embedded template. Make sure | ||||
|       }); | ||||
| 
 | ||||
|       it('should support variables', () => { | ||||
|         expect(humanizeTplAstSourceSpans(parse('<template let-a="b"></template>', []))).toEqual([ | ||||
|           [EmbeddedTemplateAst, '<template let-a="b">'], | ||||
|           [VariableAst, 'a', 'b', 'let-a="b"'], | ||||
|         ]); | ||||
|         expect(humanizeTplAstSourceSpans(parse('<ng-template let-a="b"></ng-template>', []))) | ||||
|             .toEqual([ | ||||
|               [EmbeddedTemplateAst, '<ng-template let-a="b">'], | ||||
| @ -2342,47 +2286,6 @@ The pipe 'test' could not be found ("{{[ERROR ->]a | test}}"): TestComp@0:2`); | ||||
|         ...humanizedExpandedForm, ...humanizedExpandedForm | ||||
|       ]); | ||||
|     }); | ||||
| 
 | ||||
|   }); | ||||
| 
 | ||||
|   describe('Template Parser - `<template>` support disabled by default', () => { | ||||
|     beforeEach(() => { | ||||
|       TestBed.configureCompiler({ | ||||
|         providers: [ | ||||
|           {provide: Console, useValue: console}, | ||||
|           {provide: CompilerConfig, useValue: new CompilerConfig()} | ||||
|         ], | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     commonBeforeEach(); | ||||
| 
 | ||||
|     it('should support * directives', () => { | ||||
|       expect(humanizeTplAst(parse('<div *ngIf>', [ngIf]))).toEqual([ | ||||
|         [EmbeddedTemplateAst], | ||||
|         [DirectiveAst, ngIf], | ||||
|         [BoundDirectivePropertyAst, 'ngIf', 'null'], | ||||
|         [ElementAst, 'div'], | ||||
|       ]); | ||||
|     }); | ||||
| 
 | ||||
|     it('should support <ng-template>', () => { | ||||
|       expect(humanizeTplAst(parse('<ng-template>', []))).toEqual([ | ||||
|         [EmbeddedTemplateAst], | ||||
|       ]); | ||||
|     }); | ||||
| 
 | ||||
|     it('should treat <template> as a regular tag', () => { | ||||
|       expect(humanizeTplAst(parse('<template>', []))).toEqual([ | ||||
|         [ElementAst, 'template'], | ||||
|       ]); | ||||
|     }); | ||||
| 
 | ||||
|     it('should not special case the template attribute', () => { | ||||
|       expect(humanizeTplAst(parse('<p template="ngFor">', []))).toEqual([ | ||||
|         [ElementAst, 'p'], | ||||
|         [AttrAst, 'template', 'ngFor'], | ||||
|       ]); | ||||
|     }); | ||||
|   }); | ||||
| })(); | ||||
|  | ||||
| @ -90,9 +90,6 @@ export type CompilerOptions = { | ||||
|   defaultEncapsulation?: ViewEncapsulation, | ||||
|   providers?: StaticProvider[], | ||||
|   missingTranslation?: MissingTranslationStrategy, | ||||
|   // Whether to support the `<template>` tag and the `template` attribute to define angular
 | ||||
|   // templates. They have been deprecated in 4.x, `<ng-template>` should be used instead.
 | ||||
|   enableLegacyTemplate?: boolean, | ||||
|   preserveWhitespaces?: boolean, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -38,14 +38,7 @@ const ANCHOR_ELEMENT = new InjectionToken('AnchorElement'); | ||||
| function declareTests({useJit}: {useJit: boolean}) { | ||||
|   describe('integration tests', function() { | ||||
| 
 | ||||
|     beforeEach(() => { | ||||
|       TestBed.configureCompiler({ | ||||
|         useJit, | ||||
|         providers: [ | ||||
|           {provide: CompilerConfig, useValue: new CompilerConfig({enableLegacyTemplate: true})} | ||||
|         ] | ||||
|       }); | ||||
|     }); | ||||
|     beforeEach(() => { TestBed.configureCompiler({useJit}); }); | ||||
| 
 | ||||
|     describe('react to record changes', function() { | ||||
|       it('should consume text node changes', () => { | ||||
| @ -420,22 +413,6 @@ function declareTests({useJit}: {useJit: boolean}) { | ||||
|         expect(getDOM().isCommentNode(childNodesOfWrapper[0])).toBe(true); | ||||
|       }); | ||||
| 
 | ||||
|       it('should support template directives via `template` attribute.', () => { | ||||
|         TestBed.configureTestingModule({declarations: [MyComp, SomeViewport]}); | ||||
|         const template = | ||||
|             '<span template="some-viewport: let greeting=someTmpl">{{greeting}}</span>'; | ||||
|         TestBed.overrideComponent(MyComp, {set: {template}}); | ||||
|         const fixture = TestBed.createComponent(MyComp); | ||||
| 
 | ||||
|         fixture.detectChanges(); | ||||
| 
 | ||||
|         const childNodesOfWrapper = getDOM().childNodes(fixture.nativeElement); | ||||
|         // 1 template + 2 copies.
 | ||||
|         expect(childNodesOfWrapper.length).toBe(3); | ||||
|         expect(childNodesOfWrapper[1]).toHaveText('hello'); | ||||
|         expect(childNodesOfWrapper[2]).toHaveText('again'); | ||||
|       }); | ||||
| 
 | ||||
|       it('should allow to transplant TemplateRefs into other ViewContainers', () => { | ||||
|         TestBed.configureTestingModule({ | ||||
|           declarations: [ | ||||
|  | ||||
| @ -162,7 +162,6 @@ export class JitCompilerFactory implements CompilerFactory { | ||||
|       useJit: true, | ||||
|       defaultEncapsulation: ViewEncapsulation.Emulated, | ||||
|       missingTranslation: MissingTranslationStrategy.Warning, | ||||
|       enableLegacyTemplate: false, | ||||
|     }; | ||||
| 
 | ||||
|     this._defaultOptions = [compilerOptions, ...defaultOptions]; | ||||
| @ -182,7 +181,6 @@ export class JitCompilerFactory implements CompilerFactory { | ||||
|             // from the app providers
 | ||||
|             defaultEncapsulation: opts.defaultEncapsulation, | ||||
|             missingTranslation: opts.missingTranslation, | ||||
|             enableLegacyTemplate: opts.enableLegacyTemplate, | ||||
|             preserveWhitespaces: opts.preserveWhitespaces, | ||||
|           }); | ||||
|         }, | ||||
| @ -200,7 +198,6 @@ function _mergeOptions(optionsArr: CompilerOptions[]): CompilerOptions { | ||||
|     defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)), | ||||
|     providers: _mergeArrays(optionsArr.map(options => options.providers !)), | ||||
|     missingTranslation: _lastDefined(optionsArr.map(options => options.missingTranslation)), | ||||
|     enableLegacyTemplate: _lastDefined(optionsArr.map(options => options.enableLegacyTemplate)), | ||||
|     preserveWhitespaces: _lastDefined(optionsArr.map(options => options.preserveWhitespaces)), | ||||
|   }; | ||||
| } | ||||
|  | ||||
							
								
								
									
										1
									
								
								tools/public_api_guard/core/core.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								tools/public_api_guard/core/core.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -112,7 +112,6 @@ export declare type CompilerOptions = { | ||||
|     defaultEncapsulation?: ViewEncapsulation; | ||||
|     providers?: StaticProvider[]; | ||||
|     missingTranslation?: MissingTranslationStrategy; | ||||
|     enableLegacyTemplate?: boolean; | ||||
|     preserveWhitespaces?: boolean; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user