fix(compiler): fix for element needing implicit parent placed in top-level ng-container

fixes #18314
This commit is contained in:
Victor Berchet 2017-07-26 14:53:59 -07:00 committed by Alex Rickabaugh
parent ebef5e697a
commit 381471d338
3 changed files with 285 additions and 281 deletions

View File

@ -230,12 +230,9 @@ 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) {
this._elementStack.pop();
if (this.getTagDefinition(el.name).isVoid) {
this._elementStack.pop();
}
} }
} }
@ -274,11 +271,10 @@ 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);
@ -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) {

View File

@ -56,274 +56,272 @@ 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 `&#123;` / `&#x1ab;` syntax should be used when the named character reference does not // The `&#123;` / `&#x1ab;` 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',
'acirc': '\u00E2', 'acirc': '\u00E2',
'acute': '\u00B4', 'acute': '\u00B4',
'AElig': '\u00C6', 'AElig': '\u00C6',
'aelig': '\u00E6', 'aelig': '\u00E6',
'Agrave': '\u00C0', 'Agrave': '\u00C0',
'agrave': '\u00E0', 'agrave': '\u00E0',
'alefsym': '\u2135', 'alefsym': '\u2135',
'Alpha': '\u0391', 'Alpha': '\u0391',
'alpha': '\u03B1', 'alpha': '\u03B1',
'amp': '&', 'amp': '&',
'and': '\u2227', 'and': '\u2227',
'ang': '\u2220', 'ang': '\u2220',
'apos': '\u0027', 'apos': '\u0027',
'Aring': '\u00C5', 'Aring': '\u00C5',
'aring': '\u00E5', 'aring': '\u00E5',
'asymp': '\u2248', 'asymp': '\u2248',
'Atilde': '\u00C3', 'Atilde': '\u00C3',
'atilde': '\u00E3', 'atilde': '\u00E3',
'Auml': '\u00C4', 'Auml': '\u00C4',
'auml': '\u00E4', 'auml': '\u00E4',
'bdquo': '\u201E', 'bdquo': '\u201E',
'Beta': '\u0392', 'Beta': '\u0392',
'beta': '\u03B2', 'beta': '\u03B2',
'brvbar': '\u00A6', 'brvbar': '\u00A6',
'bull': '\u2022', 'bull': '\u2022',
'cap': '\u2229', 'cap': '\u2229',
'Ccedil': '\u00C7', 'Ccedil': '\u00C7',
'ccedil': '\u00E7', 'ccedil': '\u00E7',
'cedil': '\u00B8', 'cedil': '\u00B8',
'cent': '\u00A2', 'cent': '\u00A2',
'Chi': '\u03A7', 'Chi': '\u03A7',
'chi': '\u03C7', 'chi': '\u03C7',
'circ': '\u02C6', 'circ': '\u02C6',
'clubs': '\u2663', 'clubs': '\u2663',
'cong': '\u2245', 'cong': '\u2245',
'copy': '\u00A9', 'copy': '\u00A9',
'crarr': '\u21B5', 'crarr': '\u21B5',
'cup': '\u222A', 'cup': '\u222A',
'curren': '\u00A4', 'curren': '\u00A4',
'dagger': '\u2020', 'dagger': '\u2020',
'Dagger': '\u2021', 'Dagger': '\u2021',
'darr': '\u2193', 'darr': '\u2193',
'dArr': '\u21D3', 'dArr': '\u21D3',
'deg': '\u00B0', 'deg': '\u00B0',
'Delta': '\u0394', 'Delta': '\u0394',
'delta': '\u03B4', 'delta': '\u03B4',
'diams': '\u2666', 'diams': '\u2666',
'divide': '\u00F7', 'divide': '\u00F7',
'Eacute': '\u00C9', 'Eacute': '\u00C9',
'eacute': '\u00E9', 'eacute': '\u00E9',
'Ecirc': '\u00CA', 'Ecirc': '\u00CA',
'ecirc': '\u00EA', 'ecirc': '\u00EA',
'Egrave': '\u00C8', 'Egrave': '\u00C8',
'egrave': '\u00E8', 'egrave': '\u00E8',
'empty': '\u2205', 'empty': '\u2205',
'emsp': '\u2003', 'emsp': '\u2003',
'ensp': '\u2002', 'ensp': '\u2002',
'Epsilon': '\u0395', 'Epsilon': '\u0395',
'epsilon': '\u03B5', 'epsilon': '\u03B5',
'equiv': '\u2261', 'equiv': '\u2261',
'Eta': '\u0397', 'Eta': '\u0397',
'eta': '\u03B7', 'eta': '\u03B7',
'ETH': '\u00D0', 'ETH': '\u00D0',
'eth': '\u00F0', 'eth': '\u00F0',
'Euml': '\u00CB', 'Euml': '\u00CB',
'euml': '\u00EB', 'euml': '\u00EB',
'euro': '\u20AC', 'euro': '\u20AC',
'exist': '\u2203', 'exist': '\u2203',
'fnof': '\u0192', 'fnof': '\u0192',
'forall': '\u2200', 'forall': '\u2200',
'frac12': '\u00BD', 'frac12': '\u00BD',
'frac14': '\u00BC', 'frac14': '\u00BC',
'frac34': '\u00BE', 'frac34': '\u00BE',
'frasl': '\u2044', 'frasl': '\u2044',
'Gamma': '\u0393', 'Gamma': '\u0393',
'gamma': '\u03B3', 'gamma': '\u03B3',
'ge': '\u2265', 'ge': '\u2265',
'gt': '>', 'gt': '>',
'harr': '\u2194', 'harr': '\u2194',
'hArr': '\u21D4', 'hArr': '\u21D4',
'hearts': '\u2665', 'hearts': '\u2665',
'hellip': '\u2026', 'hellip': '\u2026',
'Iacute': '\u00CD', 'Iacute': '\u00CD',
'iacute': '\u00ED', 'iacute': '\u00ED',
'Icirc': '\u00CE', 'Icirc': '\u00CE',
'icirc': '\u00EE', 'icirc': '\u00EE',
'iexcl': '\u00A1', 'iexcl': '\u00A1',
'Igrave': '\u00CC', 'Igrave': '\u00CC',
'igrave': '\u00EC', 'igrave': '\u00EC',
'image': '\u2111', 'image': '\u2111',
'infin': '\u221E', 'infin': '\u221E',
'int': '\u222B', 'int': '\u222B',
'Iota': '\u0399', 'Iota': '\u0399',
'iota': '\u03B9', 'iota': '\u03B9',
'iquest': '\u00BF', 'iquest': '\u00BF',
'isin': '\u2208', 'isin': '\u2208',
'Iuml': '\u00CF', 'Iuml': '\u00CF',
'iuml': '\u00EF', 'iuml': '\u00EF',
'Kappa': '\u039A', 'Kappa': '\u039A',
'kappa': '\u03BA', 'kappa': '\u03BA',
'Lambda': '\u039B', 'Lambda': '\u039B',
'lambda': '\u03BB', 'lambda': '\u03BB',
'lang': '\u27E8', 'lang': '\u27E8',
'laquo': '\u00AB', 'laquo': '\u00AB',
'larr': '\u2190', 'larr': '\u2190',
'lArr': '\u21D0', 'lArr': '\u21D0',
'lceil': '\u2308', 'lceil': '\u2308',
'ldquo': '\u201C', 'ldquo': '\u201C',
'le': '\u2264', 'le': '\u2264',
'lfloor': '\u230A', 'lfloor': '\u230A',
'lowast': '\u2217', 'lowast': '\u2217',
'loz': '\u25CA', 'loz': '\u25CA',
'lrm': '\u200E', 'lrm': '\u200E',
'lsaquo': '\u2039', 'lsaquo': '\u2039',
'lsquo': '\u2018', 'lsquo': '\u2018',
'lt': '<', 'lt': '<',
'macr': '\u00AF', 'macr': '\u00AF',
'mdash': '\u2014', 'mdash': '\u2014',
'micro': '\u00B5', 'micro': '\u00B5',
'middot': '\u00B7', 'middot': '\u00B7',
'minus': '\u2212', 'minus': '\u2212',
'Mu': '\u039C', 'Mu': '\u039C',
'mu': '\u03BC', 'mu': '\u03BC',
'nabla': '\u2207', 'nabla': '\u2207',
'nbsp': '\u00A0', 'nbsp': '\u00A0',
'ndash': '\u2013', 'ndash': '\u2013',
'ne': '\u2260', 'ne': '\u2260',
'ni': '\u220B', 'ni': '\u220B',
'not': '\u00AC', 'not': '\u00AC',
'notin': '\u2209', 'notin': '\u2209',
'nsub': '\u2284', 'nsub': '\u2284',
'Ntilde': '\u00D1', 'Ntilde': '\u00D1',
'ntilde': '\u00F1', 'ntilde': '\u00F1',
'Nu': '\u039D', 'Nu': '\u039D',
'nu': '\u03BD', 'nu': '\u03BD',
'Oacute': '\u00D3', 'Oacute': '\u00D3',
'oacute': '\u00F3', 'oacute': '\u00F3',
'Ocirc': '\u00D4', 'Ocirc': '\u00D4',
'ocirc': '\u00F4', 'ocirc': '\u00F4',
'OElig': '\u0152', 'OElig': '\u0152',
'oelig': '\u0153', 'oelig': '\u0153',
'Ograve': '\u00D2', 'Ograve': '\u00D2',
'ograve': '\u00F2', 'ograve': '\u00F2',
'oline': '\u203E', 'oline': '\u203E',
'Omega': '\u03A9', 'Omega': '\u03A9',
'omega': '\u03C9', 'omega': '\u03C9',
'Omicron': '\u039F', 'Omicron': '\u039F',
'omicron': '\u03BF', 'omicron': '\u03BF',
'oplus': '\u2295', 'oplus': '\u2295',
'or': '\u2228', 'or': '\u2228',
'ordf': '\u00AA', 'ordf': '\u00AA',
'ordm': '\u00BA', 'ordm': '\u00BA',
'Oslash': '\u00D8', 'Oslash': '\u00D8',
'oslash': '\u00F8', 'oslash': '\u00F8',
'Otilde': '\u00D5', 'Otilde': '\u00D5',
'otilde': '\u00F5', 'otilde': '\u00F5',
'otimes': '\u2297', 'otimes': '\u2297',
'Ouml': '\u00D6', 'Ouml': '\u00D6',
'ouml': '\u00F6', 'ouml': '\u00F6',
'para': '\u00B6', 'para': '\u00B6',
'permil': '\u2030', 'permil': '\u2030',
'perp': '\u22A5', 'perp': '\u22A5',
'Phi': '\u03A6', 'Phi': '\u03A6',
'phi': '\u03C6', 'phi': '\u03C6',
'Pi': '\u03A0', 'Pi': '\u03A0',
'pi': '\u03C0', 'pi': '\u03C0',
'piv': '\u03D6', 'piv': '\u03D6',
'plusmn': '\u00B1', 'plusmn': '\u00B1',
'pound': '\u00A3', 'pound': '\u00A3',
'prime': '\u2032', 'prime': '\u2032',
'Prime': '\u2033', 'Prime': '\u2033',
'prod': '\u220F', 'prod': '\u220F',
'prop': '\u221D', 'prop': '\u221D',
'Psi': '\u03A8', 'Psi': '\u03A8',
'psi': '\u03C8', 'psi': '\u03C8',
'quot': '\u0022', 'quot': '\u0022',
'radic': '\u221A', 'radic': '\u221A',
'rang': '\u27E9', 'rang': '\u27E9',
'raquo': '\u00BB', 'raquo': '\u00BB',
'rarr': '\u2192', 'rarr': '\u2192',
'rArr': '\u21D2', 'rArr': '\u21D2',
'rceil': '\u2309', 'rceil': '\u2309',
'rdquo': '\u201D', 'rdquo': '\u201D',
'real': '\u211C', 'real': '\u211C',
'reg': '\u00AE', 'reg': '\u00AE',
'rfloor': '\u230B', 'rfloor': '\u230B',
'Rho': '\u03A1', 'Rho': '\u03A1',
'rho': '\u03C1', 'rho': '\u03C1',
'rlm': '\u200F', 'rlm': '\u200F',
'rsaquo': '\u203A', 'rsaquo': '\u203A',
'rsquo': '\u2019', 'rsquo': '\u2019',
'sbquo': '\u201A', 'sbquo': '\u201A',
'Scaron': '\u0160', 'Scaron': '\u0160',
'scaron': '\u0161', 'scaron': '\u0161',
'sdot': '\u22C5', 'sdot': '\u22C5',
'sect': '\u00A7', 'sect': '\u00A7',
'shy': '\u00AD', 'shy': '\u00AD',
'Sigma': '\u03A3', 'Sigma': '\u03A3',
'sigma': '\u03C3', 'sigma': '\u03C3',
'sigmaf': '\u03C2', 'sigmaf': '\u03C2',
'sim': '\u223C', 'sim': '\u223C',
'spades': '\u2660', 'spades': '\u2660',
'sub': '\u2282', 'sub': '\u2282',
'sube': '\u2286', 'sube': '\u2286',
'sum': '\u2211', 'sum': '\u2211',
'sup': '\u2283', 'sup': '\u2283',
'sup1': '\u00B9', 'sup1': '\u00B9',
'sup2': '\u00B2', 'sup2': '\u00B2',
'sup3': '\u00B3', 'sup3': '\u00B3',
'supe': '\u2287', 'supe': '\u2287',
'szlig': '\u00DF', 'szlig': '\u00DF',
'Tau': '\u03A4', 'Tau': '\u03A4',
'tau': '\u03C4', 'tau': '\u03C4',
'there4': '\u2234', 'there4': '\u2234',
'Theta': '\u0398', 'Theta': '\u0398',
'theta': '\u03B8', 'theta': '\u03B8',
'thetasym': '\u03D1', 'thetasym': '\u03D1',
'thinsp': '\u2009', 'thinsp': '\u2009',
'THORN': '\u00DE', 'THORN': '\u00DE',
'thorn': '\u00FE', 'thorn': '\u00FE',
'tilde': '\u02DC', 'tilde': '\u02DC',
'times': '\u00D7', 'times': '\u00D7',
'trade': '\u2122', 'trade': '\u2122',
'Uacute': '\u00DA', 'Uacute': '\u00DA',
'uacute': '\u00FA', 'uacute': '\u00FA',
'uarr': '\u2191', 'uarr': '\u2191',
'uArr': '\u21D1', 'uArr': '\u21D1',
'Ucirc': '\u00DB', 'Ucirc': '\u00DB',
'ucirc': '\u00FB', 'ucirc': '\u00FB',
'Ugrave': '\u00D9', 'Ugrave': '\u00D9',
'ugrave': '\u00F9', 'ugrave': '\u00F9',
'uml': '\u00A8', 'uml': '\u00A8',
'upsih': '\u03D2', 'upsih': '\u03D2',
'Upsilon': '\u03A5', 'Upsilon': '\u03A5',
'upsilon': '\u03C5', 'upsilon': '\u03C5',
'Uuml': '\u00DC', 'Uuml': '\u00DC',
'uuml': '\u00FC', 'uuml': '\u00FC',
'weierp': '\u2118', 'weierp': '\u2118',
'Xi': '\u039E', 'Xi': '\u039E',
'xi': '\u03BE', 'xi': '\u03BE',
'Yacute': '\u00DD', 'Yacute': '\u00DD',
'yacute': '\u00FD', 'yacute': '\u00FD',
'yen': '\u00A5', 'yen': '\u00A5',
'yuml': '\u00FF', 'yuml': '\u00FF',
'Yuml': '\u0178', 'Yuml': '\u0178',
'Zeta': '\u0396', 'Zeta': '\u0396',
'zeta': '\u03B6', 'zeta': '\u03B6',
'zwj': '\u200D', 'zwj': '\u200D',
'zwnj': '\u200C', 'zwnj': '\u200C',
}; };

View File

@ -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>',