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. | 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* | ### *disableExpressionLowering* | ||||||
| 
 | 
 | ||||||
| The Angular template compiler transforms code that is used, or could be used, in an annotation | 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"> |     <div style="display: flex"> | ||||||
|       <scroll-area id="testArea"></scroll-area> |       <scroll-area id="testArea"></scroll-area> | ||||||
|     </div> |     </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> |       <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> | ||||||
|   </div>` |   </div>` | ||||||
| }) | }) | ||||||
|  | |||||||
| @ -62,7 +62,7 @@ export class Stage { | |||||||
|   directives: [NgFor], |   directives: [NgFor], | ||||||
|   template: ` |   template: ` | ||||||
|       <div [style.width.px]="cellWidth"> |       <div [style.width.px]="cellWidth"> | ||||||
|           <button template="ngFor let stage of stages" |           <button *ngFor="let stage of stages" | ||||||
|                   [disabled]="stage.isDisabled" |                   [disabled]="stage.isDisabled" | ||||||
|                   [style.background-color]="stage.backgroundColor" |                   [style.background-color]="stage.backgroundColor" | ||||||
|                   on-click="setStage(stage)"> |                   on-click="setStage(stage)"> | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ import {ScrollItemComponent} from './scroll_item'; | |||||||
|             <div id="padding"></div> |             <div id="padding"></div> | ||||||
|             <div id="inner"> |             <div id="inner"> | ||||||
|                 <scroll-item |                 <scroll-item | ||||||
|                     template="ngFor let item of visibleItems" |                     *ngFor="let item of visibleItems" | ||||||
|                     [offering]="item"> |                     [offering]="item"> | ||||||
|                 </scroll-item> |                 </scroll-item> | ||||||
|             </div> |             </div> | ||||||
|  | |||||||
| @ -50,7 +50,6 @@ export interface CompilerOptions extends ts.CompilerOptions { | |||||||
|   annotateForClosureCompiler?: boolean; |   annotateForClosureCompiler?: boolean; | ||||||
|   annotationsAs?: 'decorators'|'static fields'; |   annotationsAs?: 'decorators'|'static fields'; | ||||||
|   trace?: boolean; |   trace?: boolean; | ||||||
|   enableLegacyTemplate?: boolean; |  | ||||||
|   disableExpressionLowering?: boolean; |   disableExpressionLowering?: boolean; | ||||||
|   i18nOutLocale?: string; |   i18nOutLocale?: string; | ||||||
|   i18nOutFormat?: string; |   i18nOutFormat?: string; | ||||||
|  | |||||||
| @ -125,9 +125,6 @@ export interface CompilerOptions extends ts.CompilerOptions { | |||||||
|   // Print extra information while running the compiler
 |   // Print extra information while running the compiler
 | ||||||
|   trace?: boolean; |   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
 |   // Whether to enable lowering expressions lambdas and expressions in a reference value
 | ||||||
|   // position.
 |   // position.
 | ||||||
|   disableExpressionLowering?: boolean; |   disableExpressionLowering?: boolean; | ||||||
|  | |||||||
| @ -828,7 +828,6 @@ function getAotCompilerOptions(options: CompilerOptions): AotCompilerOptions { | |||||||
|   return { |   return { | ||||||
|     locale: options.i18nInLocale, |     locale: options.i18nInLocale, | ||||||
|     i18nFormat: options.i18nInFormat || options.i18nOutFormat, translations, missingTranslation, |     i18nFormat: options.i18nInFormat || options.i18nOutFormat, translations, missingTranslation, | ||||||
|     enableLegacyTemplate: options.enableLegacyTemplate, |  | ||||||
|     enableSummariesForJit: options.enableSummariesForJit, |     enableSummariesForJit: options.enableSummariesForJit, | ||||||
|     preserveWhitespaces: options.preserveWhitespaces, |     preserveWhitespaces: options.preserveWhitespaces, | ||||||
|     fullTemplateTypeCheck: options.fullTemplateTypeCheck, |     fullTemplateTypeCheck: options.fullTemplateTypeCheck, | ||||||
|  | |||||||
| @ -536,7 +536,6 @@ The recommended options for producing a ivy application are | |||||||
| | `"renderer2BackPatching"`      | `true`   | implied     | | | `"renderer2BackPatching"`      | `true`   | implied     | | ||||||
| | `"generateCodeForLibraries"`   | `true`   | default     | | | `"generateCodeForLibraries"`   | `true`   | default     | | ||||||
| | `"annotationsAs"`              | `remove` | implied     | | | `"annotationsAs"`              | `remove` | implied     | | ||||||
| | `"enableLegacyTemplate"`       | `false`  | default     | |  | ||||||
| | `"preserveWhitespaces"`        | `false`  | default     | | | `"preserveWhitespaces"`        | `false`  | default     | | ||||||
| | `"skipMetadataEmit"`           | `true`   | default     | | | `"skipMetadataEmit"`           | `true`   | default     | | ||||||
| | `"strictMetadataEmit"`         | `false`  | implied     | | | `"strictMetadataEmit"`         | `false`  | implied     | | ||||||
| @ -574,7 +573,6 @@ The recommended options for producing a ivy library are: | |||||||
| | `"renderer2BackPatching"`      | `false`  | default     | | | `"renderer2BackPatching"`      | `false`  | default     | | ||||||
| | `"generateCodeForLibraries"`   | `false`  |             | | | `"generateCodeForLibraries"`   | `false`  |             | | ||||||
| | `"annotationsAs"`              | `remove` | implied     | | | `"annotationsAs"`              | `remove` | implied     | | ||||||
| | `"enableLegacyTemplate"`       | `false`  | default     | |  | ||||||
| | `"preserveWhitespaces"`        | `false`  | default     | | | `"preserveWhitespaces"`        | `false`  | default     | | ||||||
| | `"skipMetadataEmit"`           | `false`  |             | | | `"skipMetadataEmit"`           | `false`  |             | | ||||||
| | `"strictMetadataEmit"`         | `true `  |             | | | `"strictMetadataEmit"`         | `true `  |             | | ||||||
| @ -598,25 +596,21 @@ depending on the target: | |||||||
| |                   | `"renderer2BackPatching"`      | `true`       | enforced    | | |                   | `"renderer2BackPatching"`      | `true`       | enforced    | | ||||||
| |                   | `"generateCodeForLibraries"`   | `true`       |             | | |                   | `"generateCodeForLibraries"`   | `true`       |             | | ||||||
| |                   | `"annotationsAs"`              | `remove`     |             | | |                   | `"annotationsAs"`              | `remove`     |             | | ||||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | |  | ||||||
| |                   | `"preserveWhitespaces"`        | `false`      |             | | |                   | `"preserveWhitespaces"`        | `false`      |             | | ||||||
| |                   | `"skipMetadataEmit"`           | `false`      |             | | |                   | `"skipMetadataEmit"`           | `false`      |             | | ||||||
| |                   | `"strictMetadataEmit"`         | `true`       |             | | |                   | `"strictMetadataEmit"`         | `true`       |             | | ||||||
| |                   | `"skipTemplateCodegen"`        | `false`      |             | | |                   | `"skipTemplateCodegen"`        | `false`      |             | | ||||||
| |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | ||||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | |  | ||||||
| |                   |                                |              |             | | |                   |                                |              |             | | ||||||
| | `"library"`       | `"generateRenderer2Factories"` | `false`      | enforced    | | | `"library"`       | `"generateRenderer2Factories"` | `false`      | enforced    | | ||||||
| |                   | `"renderer2BackPatching"`      | `false`      | enforced    | | |                   | `"renderer2BackPatching"`      | `false`      | enforced    | | ||||||
| |                   | `"generateCodeForLibraries"`   | `false`      | enforced    | | |                   | `"generateCodeForLibraries"`   | `false`      | enforced    | | ||||||
| |                   | `"annotationsAs"`              | `decorators` |             | | |                   | `"annotationsAs"`              | `decorators` |             | | ||||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | |  | ||||||
| |                   | `"preserveWhitespaces"`        | `false`      |             | | |                   | `"preserveWhitespaces"`        | `false`      |             | | ||||||
| |                   | `"skipMetadataEmit"`           | `false`      | enforced    | | |                   | `"skipMetadataEmit"`           | `false`      | enforced    | | ||||||
| |                   | `"strictMetadataEmit"`         | `true`       |             | | |                   | `"strictMetadataEmit"`         | `true`       |             | | ||||||
| |                   | `"skipTemplateCodegen"`        | `false`      | enforced    | | |                   | `"skipTemplateCodegen"`        | `false`      | enforced    | | ||||||
| |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | ||||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | |  | ||||||
| |                   |                                |              |             | | |                   |                                |              |             | | ||||||
| | `"package"`       | `"flatModuleOutFile"`          |              | required    | | | `"package"`       | `"flatModuleOutFile"`          |              | required    | | ||||||
| |                   | `"flatModuleId"`               |              | required    | | |                   | `"flatModuleId"`               |              | required    | | ||||||
| @ -625,13 +619,11 @@ depending on the target: | |||||||
| |                   | `"renderer2BackPatching"`      | `false`      | enforced    | | |                   | `"renderer2BackPatching"`      | `false`      | enforced    | | ||||||
| |                   | `"generateCodeForLibraries"`   | `false`      | enforced    | | |                   | `"generateCodeForLibraries"`   | `false`      | enforced    | | ||||||
| |                   | `"annotationsAs"`              | `remove`     |             | | |                   | `"annotationsAs"`              | `remove`     |             | | ||||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | |  | ||||||
| |                   | `"preserveWhitespaces"`        | `false`      |             | | |                   | `"preserveWhitespaces"`        | `false`      |             | | ||||||
| |                   | `"skipMetadataEmit"`           | `false`      | enforced    | | |                   | `"skipMetadataEmit"`           | `false`      | enforced    | | ||||||
| |                   | `"strictMetadataEmit"`         | `true`       |             | | |                   | `"strictMetadataEmit"`         | `true`       |             | | ||||||
| |                   | `"skipTemplateCodegen"`        | `false`      | enforced    | | |                   | `"skipTemplateCodegen"`        | `false`      | enforced    | | ||||||
| |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | |                   | `"fullTemplateTypeCheck"`      | `true`       |             | | ||||||
| |                   | `"enableLegacyTemplate"`       | `false`      |             | |  | ||||||
| 
 | 
 | ||||||
| Options that are marked "enforced" are reported as an error if they are | 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 | explicitly set to a value different from what is specified here. The options | ||||||
|  | |||||||
| @ -70,7 +70,6 @@ export function createAotCompiler( | |||||||
|   const config = new CompilerConfig({ |   const config = new CompilerConfig({ | ||||||
|     defaultEncapsulation: ViewEncapsulation.Emulated, |     defaultEncapsulation: ViewEncapsulation.Emulated, | ||||||
|     useJit: false, |     useJit: false, | ||||||
|     enableLegacyTemplate: options.enableLegacyTemplate === true, |  | ||||||
|     missingTranslation: options.missingTranslation, |     missingTranslation: options.missingTranslation, | ||||||
|     preserveWhitespaces: options.preserveWhitespaces, |     preserveWhitespaces: options.preserveWhitespaces, | ||||||
|     strictInjectionParameters: options.strictInjectionParameters, |     strictInjectionParameters: options.strictInjectionParameters, | ||||||
|  | |||||||
| @ -13,7 +13,6 @@ export interface AotCompilerOptions { | |||||||
|   i18nFormat?: string; |   i18nFormat?: string; | ||||||
|   translations?: string; |   translations?: string; | ||||||
|   missingTranslation?: MissingTranslationStrategy; |   missingTranslation?: MissingTranslationStrategy; | ||||||
|   enableLegacyTemplate?: boolean; |  | ||||||
|   enableSummariesForJit?: boolean; |   enableSummariesForJit?: boolean; | ||||||
|   preserveWhitespaces?: boolean; |   preserveWhitespaces?: boolean; | ||||||
|   fullTemplateTypeCheck?: boolean; |   fullTemplateTypeCheck?: boolean; | ||||||
|  | |||||||
| @ -14,9 +14,6 @@ import {noUndefined} from './util'; | |||||||
| 
 | 
 | ||||||
| export class CompilerConfig { | export class CompilerConfig { | ||||||
|   public defaultEncapsulation: ViewEncapsulation|null; |   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 useJit: boolean; | ||||||
|   public jitDevMode: boolean; |   public jitDevMode: boolean; | ||||||
|   public missingTranslation: MissingTranslationStrategy|null; |   public missingTranslation: MissingTranslationStrategy|null; | ||||||
| @ -25,13 +22,11 @@ export class CompilerConfig { | |||||||
| 
 | 
 | ||||||
|   constructor( |   constructor( | ||||||
|       {defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, jitDevMode = false, |       {defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, jitDevMode = false, | ||||||
|        missingTranslation = null, enableLegacyTemplate, preserveWhitespaces, |        missingTranslation = null, preserveWhitespaces, strictInjectionParameters}: { | ||||||
|        strictInjectionParameters}: { |  | ||||||
|         defaultEncapsulation?: ViewEncapsulation, |         defaultEncapsulation?: ViewEncapsulation, | ||||||
|         useJit?: boolean, |         useJit?: boolean, | ||||||
|         jitDevMode?: boolean, |         jitDevMode?: boolean, | ||||||
|         missingTranslation?: MissingTranslationStrategy, |         missingTranslation?: MissingTranslationStrategy, | ||||||
|         enableLegacyTemplate?: boolean, |  | ||||||
|         preserveWhitespaces?: boolean, |         preserveWhitespaces?: boolean, | ||||||
|         strictInjectionParameters?: boolean, |         strictInjectionParameters?: boolean, | ||||||
|       } = {}) { |       } = {}) { | ||||||
| @ -39,7 +34,6 @@ export class CompilerConfig { | |||||||
|     this.useJit = !!useJit; |     this.useJit = !!useJit; | ||||||
|     this.jitDevMode = !!jitDevMode; |     this.jitDevMode = !!jitDevMode; | ||||||
|     this.missingTranslation = missingTranslation; |     this.missingTranslation = missingTranslation; | ||||||
|     this.enableLegacyTemplate = enableLegacyTemplate === true; |  | ||||||
|     this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces)); |     this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces)); | ||||||
|     this.strictInjectionParameters = strictInjectionParameters === true; |     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.
 | // This list is not exhaustive to keep the compiler footprint low.
 | ||||||
| // The `{` / `ƫ` syntax should be used when the named character reference does not
 | // The `{` / `ƫ` syntax should be used when the named character reference does not
 | ||||||
| // exist.
 | // exist.
 | ||||||
| 
 |  | ||||||
| export const NAMED_ENTITIES: {[k: string]: string} = { | export const NAMED_ENTITIES: {[k: string]: string} = { | ||||||
|   'Aacute': '\u00C1', |   'Aacute': '\u00C1', | ||||||
|   'aacute': '\u00E1', |   'aacute': '\u00E1', | ||||||
|  | |||||||
| @ -55,20 +55,11 @@ const IDENT_PROPERTY_IDX = 9; | |||||||
| // Group 10 = identifier inside ()
 | // Group 10 = identifier inside ()
 | ||||||
| const IDENT_EVENT_IDX = 10; | 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 TEMPLATE_ATTR_PREFIX = '*'; | ||||||
| const CLASS_ATTR = 'class'; | const CLASS_ATTR = 'class'; | ||||||
| 
 | 
 | ||||||
| const TEXT_CSS_SELECTOR = CssSelector.parse('*')[0]; | 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} = {}; | let warningCounts: {[warning: string]: number} = {}; | ||||||
| 
 | 
 | ||||||
| function warnOnlyOnce(warnings: string[]): (warning: ParseError) => boolean { | function warnOnlyOnce(warnings: string[]): (warning: ParseError) => boolean { | ||||||
| @ -109,10 +100,7 @@ export class TemplateParser { | |||||||
|       preserveWhitespaces: boolean): {template: TemplateAst[], pipes: CompilePipeSummary[]} { |       preserveWhitespaces: boolean): {template: TemplateAst[], pipes: CompilePipeSummary[]} { | ||||||
|     const result = this.tryParse( |     const result = this.tryParse( | ||||||
|         component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces); |         component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces); | ||||||
|     const warnings = |     const warnings = result.errors !.filter(error => error.level === ParseErrorLevel.WARNING); | ||||||
|         result.errors !.filter(error => error.level === ParseErrorLevel.WARNING) |  | ||||||
|             .filter(warnOnlyOnce( |  | ||||||
|                 [TEMPLATE_ATTR_DEPRECATION_WARNING, TEMPLATE_ELEMENT_DEPRECATION_WARNING])); |  | ||||||
| 
 | 
 | ||||||
|     const errors = result.errors !.filter(error => error.level === ParseErrorLevel.ERROR); |     const errors = result.errors !.filter(error => error.level === ParseErrorLevel.ERROR); | ||||||
| 
 | 
 | ||||||
| @ -295,9 +283,7 @@ class TemplateParseVisitor implements html.Visitor { | |||||||
| 
 | 
 | ||||||
|     let hasInlineTemplates = false; |     let hasInlineTemplates = false; | ||||||
|     const attrs: AttrAst[] = []; |     const attrs: AttrAst[] = []; | ||||||
|     const isTemplateElement = isTemplate( |     const isTemplateElement = isNgTemplate(element.name); | ||||||
|         element, this.config.enableLegacyTemplate, |  | ||||||
|         (m: string, span: ParseSourceSpan) => this._reportError(m, span, ParseErrorLevel.WARNING)); |  | ||||||
| 
 | 
 | ||||||
|     element.attrs.forEach(attr => { |     element.attrs.forEach(attr => { | ||||||
|       const hasBinding = this._parseAttr( |       const hasBinding = this._parseAttr( | ||||||
| @ -306,13 +292,9 @@ class TemplateParseVisitor implements html.Visitor { | |||||||
| 
 | 
 | ||||||
|       let templateBindingsSource: string|undefined; |       let templateBindingsSource: string|undefined; | ||||||
|       let prefixToken: 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) { |       if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) { | ||||||
|         this._reportError( |  | ||||||
|             TEMPLATE_ATTR_DEPRECATION_WARNING, attr.sourceSpan, ParseErrorLevel.WARNING); |  | ||||||
|         templateBindingsSource = attr.value; |  | ||||||
|       } else if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) { |  | ||||||
|         templateBindingsSource = attr.value; |         templateBindingsSource = attr.value; | ||||||
|         prefixToken = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length) + ':'; |         prefixToken = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length) + ':'; | ||||||
|       } |       } | ||||||
| @ -321,7 +303,7 @@ class TemplateParseVisitor implements html.Visitor { | |||||||
|       if (hasTemplateBinding) { |       if (hasTemplateBinding) { | ||||||
|         if (hasInlineTemplates) { |         if (hasInlineTemplates) { | ||||||
|           this._reportError( |           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); |               attr.sourceSpan); | ||||||
|         } |         } | ||||||
|         hasInlineTemplates = true; |         hasInlineTemplates = true; | ||||||
| @ -400,7 +382,7 @@ class TemplateParseVisitor implements html.Visitor { | |||||||
| 
 | 
 | ||||||
|     if (hasInlineTemplates) { |     if (hasInlineTemplates) { | ||||||
|       const templateQueryStartIndex = this.contentQueryStartId; |       const templateQueryStartIndex = this.contentQueryStartId; | ||||||
|       const templateSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs); |       const templateSelector = createElementCssSelector('ng-template', templateMatchableAttrs); | ||||||
|       const {directives: templateDirectiveMetas} = |       const {directives: templateDirectiveMetas} = | ||||||
|           this._parseDirectives(this.selectorMatcher, templateSelector); |           this._parseDirectives(this.selectorMatcher, templateSelector); | ||||||
|       const templateBoundDirectivePropNames = new Set<string>(); |       const templateBoundDirectivePropNames = new Set<string>(); | ||||||
| @ -909,19 +891,3 @@ function isEmptyExpression(ast: AST): boolean { | |||||||
|   } |   } | ||||||
|   return ast instanceof EmptyExpr; |   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', () => { |         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([ |           expect(humanizeDom(parser.parse('<ng-template>a</ng-template>', 'TestComp'))).toEqual([ | ||||||
|             [html.Element, 'ng-template', 0], [html.Text, 'a', 1] |             [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', () => { |         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'))) |           expect(humanizeDom(parser.parse('<ng-template><span></span></ng-template>', 'TestComp'))) | ||||||
|               .toEqual([[html.Element, 'ng-template', 0], [html.Element, 'span', 1]]); |               .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>', () => { |         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'))) |           expect(humanizeDom(parser.parse('<ng-template><tr></tr></ng-template>', 'TestComp'))) | ||||||
|               .toEqual([ |               .toEqual([ | ||||||
|                 [html.Element, 'ng-template', 0], |                 [html.Element, 'ng-template', 0], | ||||||
| @ -282,10 +272,6 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         it('should parse attributes on <ng-template> elements', () => { |         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'))) |           expect(humanizeDom(parser.parse('<ng-template k="v"></ng-template>', 'TestComp'))) | ||||||
|               .toEqual([ |               .toEqual([ | ||||||
|                 [html.Element, 'ng-template', 0], |                 [html.Element, 'ng-template', 0], | ||||||
|  | |||||||
| @ -158,7 +158,6 @@ function doCompile( | |||||||
|   const config = new CompilerConfig({ |   const config = new CompilerConfig({ | ||||||
|     defaultEncapsulation: ViewEncapsulation.Emulated, |     defaultEncapsulation: ViewEncapsulation.Emulated, | ||||||
|     useJit: false, |     useJit: false, | ||||||
|     enableLegacyTemplate: options.enableLegacyTemplate === true, |  | ||||||
|     missingTranslation: options.missingTranslation, |     missingTranslation: options.missingTranslation, | ||||||
|     preserveWhitespaces: options.preserveWhitespaces, |     preserveWhitespaces: options.preserveWhitespaces, | ||||||
|     strictInjectionParameters: options.strictInjectionParameters, |     strictInjectionParameters: options.strictInjectionParameters, | ||||||
|  | |||||||
| @ -336,7 +336,6 @@ class ArrayConsole implements Console { | |||||||
|       TestBed.configureCompiler({ |       TestBed.configureCompiler({ | ||||||
|         providers: [ |         providers: [ | ||||||
|           {provide: Console, useValue: console}, |           {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', () => { |       describe('events', () => { | ||||||
| @ -852,17 +880,11 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen | |||||||
|            () => { |            () => { | ||||||
|              const dirA = |              const dirA = | ||||||
|                  compileDirectiveMetadataCreate({ |                  compileDirectiveMetadataCreate({ | ||||||
|                    selector: 'template,ng-template', |                    selector: 'ng-template', | ||||||
|                    outputs: ['e'], |                    outputs: ['e'], | ||||||
|                    type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) |                    type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) | ||||||
|                  }).toSummary(); |                  }).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([ |              expect(humanizeTplAst(parse('<ng-template (e)="f"></ng-template>', [dirA]))).toEqual([ | ||||||
|                [EmbeddedTemplateAst], |                [EmbeddedTemplateAst], | ||||||
|                [BoundEventAst, 'e', null, 'f'], |                [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', () => { |         it('should locate directives in inline templates', () => { | ||||||
|           const dirTemplate = |           const dirTemplate = | ||||||
|               compileDirectiveMetadataCreate({ |               compileDirectiveMetadataCreate({ | ||||||
|                 selector: 'template', |                 selector: 'ng-template', | ||||||
|                 type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'onTemplate'}}) |                 type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'onTemplate'}}) | ||||||
|               }).toSummary(); |               }).toSummary(); | ||||||
|           expect(humanizeTplAst(parse('<div *ngIf="cond">', [ngIf, dirTemplate]))).toEqual([ |           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', |         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>', [])) |              expect(() => parse('<div #a><ng-template #a><span>OK</span></ng-template></div>', [])) | ||||||
|                  .not.toThrowError(); |                  .not.toThrowError(); | ||||||
|            }); |            }); | ||||||
| @ -1500,20 +1520,12 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | |||||||
|         beforeEach(() => { reflector = new JitReflector(); }); |         beforeEach(() => { reflector = new JitReflector(); }); | ||||||
| 
 | 
 | ||||||
|         it('should create embedded templates for <ng-template> elements', () => { |         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>', [ |           expect(humanizeTplAst(parse('<ng-template></ng-template>', [ | ||||||
|           ]))).toEqual([[EmbeddedTemplateAst]]); |           ]))).toEqual([[EmbeddedTemplateAst]]); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         it('should create embedded templates for <ng-template> elements regardless the namespace', |         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([ |              expect(humanizeTplAst(parse('<svg><ng-template></ng-template></svg>', []))).toEqual([ | ||||||
|                [ElementAst, ':svg:svg'], |                [ElementAst, ':svg:svg'], | ||||||
|                [EmbeddedTemplateAst], |                [EmbeddedTemplateAst], | ||||||
| @ -1521,12 +1533,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | |||||||
|            }); |            }); | ||||||
| 
 | 
 | ||||||
|         it('should support references via #...', () => { |         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([ |           expect(humanizeTplAst(parse('<ng-template #a>', []))).toEqual([ | ||||||
|             [EmbeddedTemplateAst], |             [EmbeddedTemplateAst], | ||||||
|             [ |             [ | ||||||
| @ -1536,12 +1542,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         it('should support references via ref-...', () => { |         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([ |           expect(humanizeTplAst(parse('<ng-template ref-a>', []))).toEqual([ | ||||||
|             [EmbeddedTemplateAst], |             [EmbeddedTemplateAst], | ||||||
|             [ |             [ | ||||||
| @ -1551,10 +1551,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         it('should parse variables via let-...', () => { |         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([ |           expect(humanizeTplAst(parse('<ng-template let-a="b">', []))).toEqual([ | ||||||
|             [EmbeddedTemplateAst], |             [EmbeddedTemplateAst], | ||||||
|             [VariableAst, 'a', 'b'], |             [VariableAst, 'a', 'b'], | ||||||
| @ -1567,10 +1563,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | |||||||
|                 selector: '[a]', |                 selector: '[a]', | ||||||
|                 type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) |                 type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) | ||||||
|               }).toSummary(); |               }).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([ |           expect(humanizeTplAst(parse('<ng-template let-a="b"></ng-template>', [dirA]))).toEqual([ | ||||||
|             [EmbeddedTemplateAst], |             [EmbeddedTemplateAst], | ||||||
|             [VariableAst, 'a', 'b'], |             [VariableAst, 'a', 'b'], | ||||||
| @ -1580,30 +1572,6 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div> | |||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       describe('inline templates', () => { |       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 #', () => { |         it('should report an error on variables declared with #', () => { | ||||||
|           expect(() => humanizeTplAst(parse('<div *ngIf="#a=b">', []))) |           expect(() => humanizeTplAst(parse('<div *ngIf="#a=b">', []))) | ||||||
|               .toThrowError(/Parser Error: Unexpected token # at column 1/); |               .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]', |                   selector: '[b]', | ||||||
|                   type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirB'}}) |                   type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirB'}}) | ||||||
|                 }).toSummary(); |                 }).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'], |               [EmbeddedTemplateAst], [DirectiveAst, dirA], [BoundDirectivePropertyAst, 'a', 'b'], | ||||||
|               [ElementAst, 'div'], [AttrAst, 'b', ''], [DirectiveAst, dirB] |               [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]', |                   selector: '[a]', | ||||||
|                   type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) |                   type: createTypeMeta({reference: {filePath: someModuleUrl, name: 'DirA'}}) | ||||||
|                 }).toSummary(); |                 }).toSummary(); | ||||||
|             expect(humanizeTplAst(parse('<div template="let a=b">', [dirA]))).toEqual([ |             expect( | ||||||
|               [EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div'] |                 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', () => { |           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', () => { |       describe('embedded templates', () => { | ||||||
|         it('should project embedded templates with wildcard selector', () => { |         it('should project embedded templates with wildcard selector', () => { | ||||||
|           expect(humanizeContentProjection(parse( |           expect(humanizeContentProjection( | ||||||
|                      '<div><template></template><ng-template></ng-template></div>', |                      parse('<div><ng-template></ng-template></div>', [createComp('div', ['*'])]))) | ||||||
|                      [createComp('div', ['*'])]))) |  | ||||||
|               .toEqual([ |               .toEqual([ | ||||||
|                 ['div', null], |                 ['div', null], | ||||||
|                 ['template', 0], |                 ['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>', () => { |         it('should override <ng-template>', () => { | ||||||
|           expect( |           expect(humanizeContentProjection(parse( | ||||||
|               humanizeContentProjection(parse( |                      '<div><ng-template ngProjectAs="b"></ng-template></div>', | ||||||
|                   '<div><template ngProjectAs="b"></template><ng-template ngProjectAs="b"></ng-template></div>', |                      [createComp('div', ['template', 'b'])]))) | ||||||
|                   [createComp('div', ['template', 'b'])]))) |  | ||||||
|               .toEqual([ |               .toEqual([ | ||||||
|                 ['div', null], |                 ['div', null], | ||||||
|                 ['template', 1], |                 ['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`); |                 `<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', () => { |       it('should treat *attr on a template element as valid', | ||||||
|         expect(() => parse('<template *ngIf>', [])).not.toThrowError(); |          () => { expect(() => parse('<ng-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 report when multiple *attrs are used on the same element', () => { |       it('should report when multiple *attrs are used on the same element', () => { | ||||||
|         expect(() => parse('<div *ngIf *ngFor>', [])).toThrowError(`Template parse errors:
 |         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', () => { |       it('should report invalid property names', () => { | ||||||
|         expect(() => parse('<div [invalidProp]></div>', [])).toThrowError(`Template parse errors:
 |         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: []}) |                  template: compileTemplateMetadata({ngContentSelectors: []}) | ||||||
|                }).toSummary(); |                }).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])) |            expect(() => parse('<ng-template [a]="b" (e)="f"></ng-template>', [dirA])) | ||||||
|                .toThrowError(`Template parse errors:
 |                .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 | 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', () => { |       it('should support embedded template', () => { | ||||||
|         expect(humanizeTplAstSourceSpans(parse('<template></template>', [ |  | ||||||
|         ]))).toEqual([[EmbeddedTemplateAst, '<template>']]); |  | ||||||
|         expect(humanizeTplAstSourceSpans(parse('<ng-template></ng-template>', [ |         expect(humanizeTplAstSourceSpans(parse('<ng-template></ng-template>', [ | ||||||
|         ]))).toEqual([[EmbeddedTemplateAst, '<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', () => { |       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>', []))) |         expect(humanizeTplAstSourceSpans(parse('<ng-template let-a="b"></ng-template>', []))) | ||||||
|             .toEqual([ |             .toEqual([ | ||||||
|               [EmbeddedTemplateAst, '<ng-template let-a="b">'], |               [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 |         ...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, |   defaultEncapsulation?: ViewEncapsulation, | ||||||
|   providers?: StaticProvider[], |   providers?: StaticProvider[], | ||||||
|   missingTranslation?: MissingTranslationStrategy, |   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, |   preserveWhitespaces?: boolean, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -38,14 +38,7 @@ const ANCHOR_ELEMENT = new InjectionToken('AnchorElement'); | |||||||
| function declareTests({useJit}: {useJit: boolean}) { | function declareTests({useJit}: {useJit: boolean}) { | ||||||
|   describe('integration tests', function() { |   describe('integration tests', function() { | ||||||
| 
 | 
 | ||||||
|     beforeEach(() => { |     beforeEach(() => { TestBed.configureCompiler({useJit}); }); | ||||||
|       TestBed.configureCompiler({ |  | ||||||
|         useJit, |  | ||||||
|         providers: [ |  | ||||||
|           {provide: CompilerConfig, useValue: new CompilerConfig({enableLegacyTemplate: true})} |  | ||||||
|         ] |  | ||||||
|       }); |  | ||||||
|     }); |  | ||||||
| 
 | 
 | ||||||
|     describe('react to record changes', function() { |     describe('react to record changes', function() { | ||||||
|       it('should consume text node changes', () => { |       it('should consume text node changes', () => { | ||||||
| @ -420,22 +413,6 @@ function declareTests({useJit}: {useJit: boolean}) { | |||||||
|         expect(getDOM().isCommentNode(childNodesOfWrapper[0])).toBe(true); |         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', () => { |       it('should allow to transplant TemplateRefs into other ViewContainers', () => { | ||||||
|         TestBed.configureTestingModule({ |         TestBed.configureTestingModule({ | ||||||
|           declarations: [ |           declarations: [ | ||||||
|  | |||||||
| @ -162,7 +162,6 @@ export class JitCompilerFactory implements CompilerFactory { | |||||||
|       useJit: true, |       useJit: true, | ||||||
|       defaultEncapsulation: ViewEncapsulation.Emulated, |       defaultEncapsulation: ViewEncapsulation.Emulated, | ||||||
|       missingTranslation: MissingTranslationStrategy.Warning, |       missingTranslation: MissingTranslationStrategy.Warning, | ||||||
|       enableLegacyTemplate: false, |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     this._defaultOptions = [compilerOptions, ...defaultOptions]; |     this._defaultOptions = [compilerOptions, ...defaultOptions]; | ||||||
| @ -182,7 +181,6 @@ export class JitCompilerFactory implements CompilerFactory { | |||||||
|             // from the app providers
 |             // from the app providers
 | ||||||
|             defaultEncapsulation: opts.defaultEncapsulation, |             defaultEncapsulation: opts.defaultEncapsulation, | ||||||
|             missingTranslation: opts.missingTranslation, |             missingTranslation: opts.missingTranslation, | ||||||
|             enableLegacyTemplate: opts.enableLegacyTemplate, |  | ||||||
|             preserveWhitespaces: opts.preserveWhitespaces, |             preserveWhitespaces: opts.preserveWhitespaces, | ||||||
|           }); |           }); | ||||||
|         }, |         }, | ||||||
| @ -200,7 +198,6 @@ function _mergeOptions(optionsArr: CompilerOptions[]): CompilerOptions { | |||||||
|     defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)), |     defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)), | ||||||
|     providers: _mergeArrays(optionsArr.map(options => options.providers !)), |     providers: _mergeArrays(optionsArr.map(options => options.providers !)), | ||||||
|     missingTranslation: _lastDefined(optionsArr.map(options => options.missingTranslation)), |     missingTranslation: _lastDefined(optionsArr.map(options => options.missingTranslation)), | ||||||
|     enableLegacyTemplate: _lastDefined(optionsArr.map(options => options.enableLegacyTemplate)), |  | ||||||
|     preserveWhitespaces: _lastDefined(optionsArr.map(options => options.preserveWhitespaces)), |     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; |     defaultEncapsulation?: ViewEncapsulation; | ||||||
|     providers?: StaticProvider[]; |     providers?: StaticProvider[]; | ||||||
|     missingTranslation?: MissingTranslationStrategy; |     missingTranslation?: MissingTranslationStrategy; | ||||||
|     enableLegacyTemplate?: boolean; |  | ||||||
|     preserveWhitespaces?: boolean; |     preserveWhitespaces?: boolean; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user