diff --git a/modules/angular2/src/compiler/html_parser.ts b/modules/angular2/src/compiler/html_parser.ts
index 2f32a6e57e..af1fe27c08 100644
--- a/modules/angular2/src/compiler/html_parser.ts
+++ b/modules/angular2/src/compiler/html_parser.ts
@@ -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);
}
}
diff --git a/modules/angular2/src/compiler/html_tags.ts b/modules/angular2/src/compiler/html_tags.ts
index 6fc4f23fe5..d749cf3844 100644
--- a/modules/angular2/src/compiler/html_tags.ts
+++ b/modules/angular2/src/compiler/html_tags.ts
@@ -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];
}
diff --git a/modules/angular2/src/compiler/schema/dom_element_schema_registry.ts b/modules/angular2/src/compiler/schema/dom_element_schema_registry.ts
index 751e420a43..84a9230fe3 100644
--- a/modules/angular2/src/compiler/schema/dom_element_schema_registry.ts
+++ b/modules/angular2/src/compiler/schema/dom_element_schema_registry.ts
@@ -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]);
diff --git a/modules/angular2/src/compiler/template_parser.ts b/modules/angular2/src/compiler/template_parser.ts
index dbb26076c7..32a69f58b1 100644
--- a/modules/angular2/src/compiler/template_parser.ts
+++ b/modules/angular2/src/compiler/template_parser.ts
@@ -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));
}
diff --git a/modules/angular2/test/compiler/template_parser_spec.ts b/modules/angular2/test/compiler/template_parser_spec.ts
index 2d6b54b434..21916aacc1 100644
--- a/modules/angular2/test/compiler/template_parser_spec.ts
+++ b/modules/angular2/test/compiler/template_parser_spec.ts
@@ -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('', [tagSel, attrSel])))
+ .toEqual([
+ [ElementAst, '@svg:svg', '