fix(compiler): fix for element needing implicit parent placed in top-level ng-container
fixes #18314
This commit is contained in:
parent
ebef5e697a
commit
381471d338
|
@ -230,14 +230,11 @@ class _TreeBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _closeVoidElement(): void {
|
private _closeVoidElement(): void {
|
||||||
if (this._elementStack.length > 0) {
|
const el = this._getParentElement();
|
||||||
const el = this._elementStack[this._elementStack.length - 1];
|
if (el && this.getTagDefinition(el.name).isVoid) {
|
||||||
|
|
||||||
if (this.getTagDefinition(el.name).isVoid) {
|
|
||||||
this._elementStack.pop();
|
this._elementStack.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private _consumeStartTag(startTagToken: lex.Token) {
|
private _consumeStartTag(startTagToken: lex.Token) {
|
||||||
const prefix = startTagToken.parts[0];
|
const prefix = startTagToken.parts[0];
|
||||||
|
@ -274,12 +271,11 @@ class _TreeBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _pushElement(el: html.Element) {
|
private _pushElement(el: html.Element) {
|
||||||
if (this._elementStack.length > 0) {
|
const parentEl = this._getParentElement();
|
||||||
const parentEl = this._elementStack[this._elementStack.length - 1];
|
|
||||||
if (this.getTagDefinition(parentEl.name).isClosedByChild(el.name)) {
|
if (parentEl && this.getTagDefinition(parentEl.name).isClosedByChild(el.name)) {
|
||||||
this._elementStack.pop();
|
this._elementStack.pop();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const tagDef = this.getTagDefinition(el.name);
|
const tagDef = this.getTagDefinition(el.name);
|
||||||
const {parent, container} = this._getParentElementSkippingContainers();
|
const {parent, container} = this._getParentElementSkippingContainers();
|
||||||
|
@ -353,7 +349,7 @@ class _TreeBuilder {
|
||||||
* `<ng-container>` elements are skipped as they are not rendered as DOM element.
|
* `<ng-container>` elements are skipped as they are not rendered as DOM element.
|
||||||
*/
|
*/
|
||||||
private _getParentElementSkippingContainers():
|
private _getParentElementSkippingContainers():
|
||||||
{parent: html.Element, container: html.Element|null} {
|
{parent: html.Element | null, container: html.Element|null} {
|
||||||
let container: html.Element|null = null;
|
let container: html.Element|null = null;
|
||||||
|
|
||||||
for (let i = this._elementStack.length - 1; i >= 0; i--) {
|
for (let i = this._elementStack.length - 1; i >= 0; i--) {
|
||||||
|
@ -363,7 +359,7 @@ class _TreeBuilder {
|
||||||
container = this._elementStack[i];
|
container = this._elementStack[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return {parent: this._elementStack[this._elementStack.length - 1], container};
|
return {parent: null, container};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addToParent(node: html.Node) {
|
private _addToParent(node: html.Node) {
|
||||||
|
|
|
@ -56,24 +56,22 @@ export function isNgTemplate(tagName: string): boolean {
|
||||||
return splitNsName(tagName)[1] === 'ng-template';
|
return splitNsName(tagName)[1] === 'ng-template';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNsPrefix(fullName: string): string
|
export function getNsPrefix(fullName: string): string;
|
||||||
export function getNsPrefix(fullName: null): null;
|
export function getNsPrefix(fullName: null): null;
|
||||||
export function getNsPrefix(fullName: string | null): string |
|
export function getNsPrefix(fullName: string | null): string|null {
|
||||||
null {
|
|
||||||
return fullName === null ? null : splitNsName(fullName)[0];
|
return fullName === null ? null : splitNsName(fullName)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mergeNsAndName(prefix: string, localName: string):
|
export function mergeNsAndName(prefix: string, localName: string): string {
|
||||||
string {
|
|
||||||
return prefix ? `:${prefix}:${localName}` : localName;
|
return prefix ? `:${prefix}:${localName}` : localName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
|
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
|
||||||
// see https://html.spec.whatwg.org/multipage/entities.json
|
// see https://html.spec.whatwg.org/multipage/entities.json
|
||||||
// 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',
|
||||||
'Acirc': '\u00C2',
|
'Acirc': '\u00C2',
|
||||||
|
@ -326,4 +324,4 @@ export function getNsPrefix(fullName: null): null;
|
||||||
'zeta': '\u03B6',
|
'zeta': '\u03B6',
|
||||||
'zwj': '\u200D',
|
'zwj': '\u200D',
|
||||||
'zwnj': '\u200C',
|
'zwnj': '\u200C',
|
||||||
};
|
};
|
||||||
|
|
|
@ -152,6 +152,16 @@ export function main() {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should append the required parent considering top level ng-container', () => {
|
||||||
|
expect(humanizeDom(
|
||||||
|
parser.parse('<ng-container><tr></tr></ng-container><p></p>', 'TestComp')))
|
||||||
|
.toEqual([
|
||||||
|
[html.Element, 'ng-container', 0],
|
||||||
|
[html.Element, 'tr', 1],
|
||||||
|
[html.Element, 'p', 0],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should special case ng-container when adding a required parent', () => {
|
it('should special case ng-container when adding a required parent', () => {
|
||||||
expect(humanizeDom(parser.parse(
|
expect(humanizeDom(parser.parse(
|
||||||
'<table><thead><ng-container><tr></tr></ng-container></thead></table>',
|
'<table><thead><ng-container><tr></tr></ng-container></thead></table>',
|
||||||
|
|
Loading…
Reference in New Issue