fix(TemplateParser): match element and attributes regardless the namespace
This commit is contained in:
parent
778677ba75
commit
7c13372721
|
@ -16,7 +16,7 @@ import {HtmlAst, HtmlAttrAst, HtmlTextAst, HtmlElementAst} from './html_ast';
|
|||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {HtmlToken, HtmlTokenType, tokenizeHtml} from './html_lexer';
|
||||
import {ParseError, ParseLocation, ParseSourceSpan} from './parse_util';
|
||||
import {HtmlTagDefinition, getHtmlTagDefinition, getHtmlTagNamespacePrefix} from './html_tags';
|
||||
import {HtmlTagDefinition, getHtmlTagDefinition, getNsPrefix} from './html_tags';
|
||||
|
||||
export class HtmlTreeError extends ParseError {
|
||||
static create(elementName: string, location: ParseLocation, msg: string): HtmlTreeError {
|
||||
|
@ -144,7 +144,7 @@ class TreeBuilder {
|
|||
if (this.peek.type === HtmlTokenType.TAG_OPEN_END_VOID) {
|
||||
this._advance();
|
||||
selfClosing = true;
|
||||
if (getHtmlTagNamespacePrefix(fullName) == null && !getHtmlTagDefinition(fullName).isVoid) {
|
||||
if (getNsPrefix(fullName) == null && !getHtmlTagDefinition(fullName).isVoid) {
|
||||
this.errors.push(HtmlTreeError.create(
|
||||
fullName, startTagToken.sourceSpan.start,
|
||||
`Only void and foreign elements can be self closed "${startTagToken.parts[1]}"`));
|
||||
|
@ -247,7 +247,7 @@ function getElementFullName(prefix: string, localName: string,
|
|||
if (isBlank(prefix)) {
|
||||
prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix;
|
||||
if (isBlank(prefix) && isPresent(parentElement)) {
|
||||
prefix = getHtmlTagNamespacePrefix(parentElement.name);
|
||||
prefix = getNsPrefix(parentElement.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -409,7 +409,7 @@ export function getHtmlTagDefinition(tagName: string): HtmlTagDefinition {
|
|||
|
||||
var NS_PREFIX_RE = /^@([^:]+):(.+)/g;
|
||||
|
||||
export function splitHtmlTagNamespace(elementName: string): string[] {
|
||||
export function splitNsName(elementName: string): string[] {
|
||||
if (elementName[0] != '@') {
|
||||
return [null, elementName];
|
||||
}
|
||||
|
@ -417,6 +417,6 @@ export function splitHtmlTagNamespace(elementName: string): string[] {
|
|||
return [match[1], match[2]];
|
||||
}
|
||||
|
||||
export function getHtmlTagNamespacePrefix(elementName: string): string {
|
||||
return splitHtmlTagNamespace(elementName)[0];
|
||||
export function getNsPrefix(elementName: string): string {
|
||||
return splitNsName(elementName)[0];
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import {Injectable} from 'angular2/src/core/di';
|
|||
import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {splitHtmlTagNamespace} from 'angular2/src/compiler/html_tags';
|
||||
import {splitNsName} from 'angular2/src/compiler/html_tags';
|
||||
|
||||
import {ElementSchemaRegistry} from './element_schema_registry';
|
||||
|
||||
|
@ -16,7 +16,7 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
|||
private _getProtoElement(tagName: string): Element {
|
||||
var element = this._protoElements.get(tagName);
|
||||
if (isBlank(element)) {
|
||||
var nsAndName = splitHtmlTagNamespace(tagName);
|
||||
var nsAndName = splitNsName(tagName);
|
||||
element = isPresent(nsAndName[0]) ?
|
||||
DOM.createElementNS(NAMESPACE_URIS[nsAndName[0]], nsAndName[1]) :
|
||||
DOM.createElement(nsAndName[1]);
|
||||
|
|
|
@ -7,7 +7,7 @@ import {Parser, AST, ASTWithSource} from 'angular2/src/core/change_detection/cha
|
|||
import {TemplateBinding} from 'angular2/src/core/change_detection/parser/ast';
|
||||
import {CompileDirectiveMetadata} from './directive_metadata';
|
||||
import {HtmlParser} from './html_parser';
|
||||
import {splitHtmlTagNamespace} from './html_tags';
|
||||
import {splitNsName} from './html_tags';
|
||||
import {ParseSourceSpan, ParseError, ParseLocation} from './parse_util';
|
||||
|
||||
|
||||
|
@ -216,7 +216,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||
}
|
||||
});
|
||||
|
||||
var lcElName = splitHtmlTagNamespace(nodeName.toLowerCase())[1];
|
||||
var lcElName = splitNsName(nodeName.toLowerCase())[1];
|
||||
var isTemplateElement = lcElName == TEMPLATE_ELEMENT;
|
||||
var elementCssSelector = createElementCssSelector(nodeName, matchableAttrs);
|
||||
var directives = this._createDirectiveAsts(
|
||||
|
@ -687,13 +687,17 @@ class Component {
|
|||
|
||||
function createElementCssSelector(elementName: string, matchableAttrs: string[][]): CssSelector {
|
||||
var cssSelector = new CssSelector();
|
||||
let elNameNoNs = splitNsName(elementName)[1];
|
||||
|
||||
cssSelector.setElement(elNameNoNs);
|
||||
|
||||
cssSelector.setElement(elementName);
|
||||
for (var i = 0; i < matchableAttrs.length; i++) {
|
||||
var attrName = matchableAttrs[i][0];
|
||||
var attrValue = matchableAttrs[i][1];
|
||||
cssSelector.addAttribute(attrName, attrValue);
|
||||
if (attrName == CLASS_ATTR) {
|
||||
let attrName = matchableAttrs[i][0];
|
||||
let attrNameNoNs = splitNsName(attrName)[1];
|
||||
let attrValue = matchableAttrs[i][1];
|
||||
|
||||
cssSelector.addAttribute(attrNameNoNs, attrValue);
|
||||
if (attrName.toLowerCase() == CLASS_ATTR) {
|
||||
var classes = splitClasses(attrValue);
|
||||
classes.forEach(className => cssSelector.addClassName(className));
|
||||
}
|
||||
|
|
|
@ -908,6 +908,24 @@ Property binding a not used by any directive on an embedded template ("[ERROR ->
|
|||
]);
|
||||
});
|
||||
|
||||
it('should support directive in namespace', () => {
|
||||
var tagSel = CompileDirectiveMetadata.create(
|
||||
{selector: 'circle', type: new CompileTypeMetadata({name: 'elDir'})});
|
||||
var attrSel = CompileDirectiveMetadata.create(
|
||||
{selector: '[href]', type: new CompileTypeMetadata({name: 'attrDir'})});
|
||||
|
||||
expect(humanizeTplAstSourceSpans(
|
||||
parse('<svg><circle /><use xlink:href="Port" /></svg>', [tagSel, attrSel])))
|
||||
.toEqual([
|
||||
[ElementAst, '@svg:svg', '<svg>'],
|
||||
[ElementAst, '@svg:circle', '<circle />'],
|
||||
[DirectiveAst, tagSel, '<circle />'],
|
||||
[ElementAst, '@svg:use', '<use xlink:href="Port" />'],
|
||||
[AttrAst, '@xlink:href', 'Port', 'xlink:href="Port"'],
|
||||
[DirectiveAst, attrSel, '<use xlink:href="Port" />'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should support directive property', () => {
|
||||
var dirA = CompileDirectiveMetadata.create(
|
||||
{selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['aProp']});
|
||||
|
|
Loading…
Reference in New Issue