Repository navigation
feat(compiler): allow self-closing tags on custom elements #48535
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Allows for self-closing tags to be used for non-native tag names, e.g. `<foo [input]="bar"></foo>` can now be written as `<foo [input]="bar"/>`. Native tag names still have to have closing tags. Fixes #39525.
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import {Component, NgModule} from '@angular/core'; | ||
|
|
||
| @Component({selector: 'my-comp', template: 'hello'}) | ||
| export class MyComp { | ||
| } | ||
|
|
||
| @Component({template: `<my-comp/>`}) | ||
| export class App { | ||
| } | ||
|
|
||
| @NgModule({declarations: [App, MyComp]}) | ||
| export class MyModule { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import {Component, NgModule} from '@angular/core'; | ||
|
|
||
| @Component({selector: 'my-comp', template: 'hello'}) | ||
| export class MyComp { | ||
| } | ||
|
|
||
| @Component({ | ||
| template: ` | ||
| <my-comp title="a">Before<my-comp title="b"></my-comp>After</my-comp> | ||
| ` | ||
| }) | ||
| export class App { | ||
| } | ||
|
|
||
| @NgModule({declarations: [App, MyComp]}) | ||
| export class MyModule { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| template: function App_Template(rf, ctx) { | ||
| if (rf & 1) { | ||
| … | ||
| i0.ɵɵelementStart(0, "my-comp", 0); | ||
| i0.ɵɵtext(1, "Before"); | ||
| i0.ɵɵelement(2, "my-comp", 1); | ||
| i0.ɵɵtext(3, "After"); | ||
| i0.ɵɵelementEnd(); | ||
| … | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| template: function App_Template(rf, ctx) { | ||
| if (rf & 1) { | ||
| … | ||
| i0.ɵɵelement(0, "my-comp"); | ||
| … | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,8 +6,6 @@ | |
| * found in the LICENSE file at https://angular.io/license | ||
| */ | ||
|
|
||
| import {getHtmlTagDefinition} from './ml_parser/html_tags'; | ||
|
|
||
| const _SELECTOR_REGEXP = new RegExp( | ||
| '(\\:not\\()|' + // 1: ":not(" | ||
| '(([\\.\\#]?)[-\\w]+)|' + // 2: "tag"; 3: "."/"#"; | ||
|
|
@@ -172,22 +170,6 @@ export class CssSelector { | |
| this.element = element; | ||
| } | ||
|
|
||
| /** Gets a template string for an element that matches the selector. */ | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The context here is that this would've caused a circular import with my latest changes. I removed the code, because it wasn't being referenced anywhere except the unit tests for the method.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| getMatchingElementTemplate(): string { | ||
| const tagName = this.element || 'div'; | ||
| const classAttr = this.classNames.length > 0 ? ` class="${this.classNames.join(' ')}"` : ''; | ||
|
|
||
| let attrs = ''; | ||
| for (let i = 0; i < this.attrs.length; i += 2) { | ||
| const attrName = this.attrs[i]; | ||
| const attrValue = this.attrs[i + 1] !== '' ? `="${this.attrs[i + 1]}"` : ''; | ||
| attrs += ` ${attrName}${attrValue}`; | ||
| } | ||
|
|
||
| return getHtmlTagDefinition(tagName).isVoid ? `<${tagName}${classAttr}${attrs}/>` : | ||
| `<${tagName}${classAttr}${attrs}></${tagName}>`; | ||
| } | ||
|
|
||
| getAttrs(): string[] { | ||
| const result: string[] = []; | ||
| if (this.classNames.length > 0) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change here and to the
DEFAULT_TAG_DEFINITIONare the key ones. Now we mark any element from the DOM schema, that hasn't been added to the tag definition already, as not being able to self-close, whereas all unknown elements are allowed to self-close.