Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(compiler): Drop support for the deprecated <template>. Use… #22783

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 0 additions & 7 deletions aio/content/guide/aot-compiler.md
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions modules/benchmarks/src/old/naive_infinite_scroll/app.ts
Expand Up @@ -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>`
})
Expand Down
2 changes: 1 addition & 1 deletion modules/benchmarks/src/old/naive_infinite_scroll/cells.ts
Expand Up @@ -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)">
Expand Down
Expand Up @@ -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>
Expand Down
1 change: 0 additions & 1 deletion packages/compiler-cli/src/ngtools_api2.ts
Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions packages/compiler-cli/src/transformers/api.ts
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion packages/compiler-cli/src/transformers/program.ts
Expand Up @@ -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,
Expand Down
8 changes: 0 additions & 8 deletions packages/compiler/design/separate_compilation.md
Expand Up @@ -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 |
Expand Down Expand Up @@ -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 ` | |
Expand All @@ -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 |
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion packages/compiler/src/aot/compiler_factory.ts
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion packages/compiler/src/aot/compiler_options.ts
Expand Up @@ -13,7 +13,6 @@ export interface AotCompilerOptions {
i18nFormat?: string;
translations?: string;
missingTranslation?: MissingTranslationStrategy;
enableLegacyTemplate?: boolean;
enableSummariesForJit?: boolean;
preserveWhitespaces?: boolean;
fullTemplateTypeCheck?: boolean;
Expand Down
8 changes: 1 addition & 7 deletions packages/compiler/src/config.ts
Expand Up @@ -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;
Expand All @@ -25,21 +22,18 @@ 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,
} = {}) {
this.defaultEncapsulation = defaultEncapsulation;
this.useJit = !!useJit;
this.jitDevMode = !!jitDevMode;
this.missingTranslation = missingTranslation;
this.enableLegacyTemplate = enableLegacyTemplate === true;
this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces));
this.strictInjectionParameters = strictInjectionParameters === true;
}
Expand Down
1 change: 0 additions & 1 deletion packages/compiler/src/ml_parser/tags.ts
Expand Up @@ -71,7 +71,6 @@ export function mergeNsAndName(prefix: string, localName: string): string {
// This list is not exhaustive to keep the compiler footprint low.
// The `&#123;` / `&#x1ab;` syntax should be used when the named character reference does not
// exist.

export const NAMED_ENTITIES: {[k: string]: string} = {
'Aacute': '\u00C1',
'aacute': '\u00E1',
Expand Down
48 changes: 7 additions & 41 deletions packages/compiler/src/template_parser/template_parser.ts
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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(
Expand All @@ -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) + ':';
}
Expand All @@ -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;
Expand Down Expand Up @@ -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>();
Expand Down Expand Up @@ -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;
}
}
14 changes: 0 additions & 14 deletions packages/compiler/test/ml_parser/html_parser_spec.ts
Expand Up @@ -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]
]);
Expand All @@ -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]]);
});
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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],
Expand Down
1 change: 0 additions & 1 deletion packages/compiler/test/render3/mock_compile.ts
Expand Up @@ -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,
Expand Down