diff --git a/lib/core_dom/selector.dart b/lib/core_dom/selector.dart
index 7f7cbed7a..2e3a46b09 100644
--- a/lib/core_dom/selector.dart
+++ b/lib/core_dom/selector.dart
@@ -7,8 +7,7 @@ part of angular.core.dom_internal;
* DirectiveSelector is used by the [Compiler] during the template walking
* to extract the [DirectiveRef]s.
*
- * DirectiveSelector can be created using the [directiveSelectorFactory]
- * method.
+ * DirectiveSelector can be created using the [DirectiveSelectorFactory].
*
* The DirectiveSelector supports CSS selectors which do not cross
* element boundaries only. The selectors can have any mix of element-name,
@@ -16,27 +15,161 @@ part of angular.core.dom_internal;
*
* Examples:
*
- *
- * element
- * .class
- * [attribute]
- * [attribute=value]
- * element[attribute1][attribute2=value]
- * :contains(/abc/)
- *
- *
- *
+ * * element
+ * * .class
+ * * [attribute]
+ * * [attribute=value]
+ * * element[attribute1][attribute2=value]
+ * * :contains(/abc/)
+ */
+class DirectiveSelector {
+ ElementBinderFactory _binderFactory;
+ DirectiveMap _directives;
+ var elementSelector;
+ var attrSelector;
+ var textSelector;
+
+ DirectiveSelector(this._directives, this._binderFactory) {
+ elementSelector = new _ElementSelector('');
+ attrSelector = <_ContainsSelector>[];
+ textSelector = <_ContainsSelector>[];
+ _directives.forEach((AbstractNgAnnotation annotation, Type type) {
+ var match;
+ var selector = annotation.selector;
+ List<_SelectorPart> selectorParts;
+ if (selector == null) {
+ throw new ArgumentError('Missing selector annotation for $type');
+ }
+
+ if ((match = _CONTAINS_REGEXP.firstMatch(selector)) != null) {
+ textSelector.add(new _ContainsSelector(annotation, match.group(1)));
+ } else if ((match = _ATTR_CONTAINS_REGEXP.firstMatch(selector)) != null) {
+ attrSelector.add(new _ContainsSelector(annotation, match[1]));
+ } else if ((selectorParts = _splitCss(selector, type)) != null){
+ elementSelector.addDirective(selectorParts,
+ new _Directive(type, annotation));
+ } else {
+ throw new ArgumentError('Unsupported Selector: $selector');
+ }
+ });
+ }
+
+ ElementBinder matchElement(dom.Node node) {
+ assert(node is dom.Element);
+
+ ElementBinderBuilder builder = _binderFactory.builder();
+ List<_ElementSelector> partialSelection;
+ var classes = {};
+ Map attrs = {};
+
+ dom.Element element = node;
+ String nodeName = element.tagName.toLowerCase();
+
+ // Set default attribute
+ if (nodeName == 'input' && !element.attributes.containsKey('type')) {
+ element.attributes['type'] = 'text';
+ }
+
+ // Select node
+ partialSelection = elementSelector.selectNode(builder,
+ partialSelection, element, nodeName);
+
+ // Select .name
+ if ((element.classes) != null) {
+ for (var name in element.classes) {
+ classes[name] = true;
+ partialSelection = elementSelector.selectClass(builder,
+ partialSelection, element, name);
+ }
+ }
+
+ // Select [attributes]
+ element.attributes.forEach((attrName, value) {
+
+ if (attrName.startsWith("on-")) {
+ builder.onEvents[attrName] = value;
+ }
+
+ if (attrName.startsWith("bind-")) {
+ builder.bindAttrs[attrName] = value;
+ }
+
+ attrs[attrName] = value;
+ for (var k = 0; k < attrSelector.length; k++) {
+ _ContainsSelector selectorRegExp = attrSelector[k];
+ if (selectorRegExp.regexp.hasMatch(value)) {
+ // this directive is matched on any attribute name, and so
+ // we need to pass the name to the directive by prefixing it to
+ // the value. Yes it is a bit of a hack.
+ _directives[selectorRegExp.annotation].forEach((type) {
+ builder.addDirective(new DirectiveRef(
+ node, type, selectorRegExp.annotation, '$attrName=$value'));
+ });
+ }
+ }
+
+ partialSelection = elementSelector.selectAttr(builder,
+ partialSelection, node, attrName, value);
+ });
+
+ while (partialSelection != null) {
+ List<_ElementSelector> elementSelectors = partialSelection;
+ partialSelection = null;
+ elementSelectors.forEach((_ElementSelector elementSelector) {
+ classes.forEach((className, _) {
+ partialSelection = elementSelector.selectClass(builder,
+ partialSelection, node, className);
+ });
+ attrs.forEach((attrName, value) {
+ partialSelection = elementSelector.selectAttr(builder,
+ partialSelection, node, attrName, value);
+ });
+ });
+ }
+ return builder.binder;
+ }
+
+ ElementBinder matchText(dom.Node node) {
+ ElementBinderBuilder builder = _binderFactory.builder();
+
+ var value = node.nodeValue;
+ for (var k = 0; k < textSelector.length; k++) {
+ var selectorRegExp = textSelector[k];
+ if (selectorRegExp.regexp.hasMatch(value)) {
+ _directives[selectorRegExp.annotation].forEach((type) {
+ builder.addDirective(new DirectiveRef(node, type,
+ selectorRegExp.annotation, value));
+ });
+ }
+ }
+ return builder.binder;
+ }
+
+ ElementBinder matchComment(dom.Node node) =>_binderFactory.builder().binder;
+}
+
+/**
+ * Factory for creating a [DirectiveSelector].
*/
+@NgInjectableService()
+class DirectiveSelectorFactory {
+ ElementBinderFactory _binderFactory;
+
+ DirectiveSelectorFactory(this._binderFactory);
+
+ DirectiveSelector selector(DirectiveMap directives) =>
+ new DirectiveSelector(directives, _binderFactory);
+}
+
class _Directive {
final Type type;
final AbstractNgAnnotation annotation;
_Directive(this.type, this.annotation);
- toString() => annotation.selector;
+ String toString() => annotation.selector;
}
-
class _ContainsSelector {
final AbstractNgAnnotation annotation;
final RegExp regexp;
@@ -135,8 +268,6 @@ class _ElementSelector {
}
}
-
-
List<_ElementSelector> selectNode(ElementBinderBuilder builder,
List<_ElementSelector> partialSelection,
dom.Node node, String nodeName) {
@@ -239,145 +370,3 @@ List<_SelectorPart> _splitCss(String selector, Type type) {
}
return parts;
}
-
-
-class DirectiveSelector {
- ElementBinderFactory _binderFactory;
- DirectiveMap _directives;
- var elementSelector;
- var attrSelector;
- var textSelector;
-
- DirectiveSelector(this._directives, this._binderFactory) {
- elementSelector = new _ElementSelector('');
- attrSelector = <_ContainsSelector>[];
- textSelector = <_ContainsSelector>[];
- _directives.forEach((AbstractNgAnnotation annotation, Type type) {
- var match;
- var selector = annotation.selector;
- List<_SelectorPart> selectorParts;
- if (selector == null) {
- throw new ArgumentError('Missing selector annotation for $type');
- }
-
- if ((match = _CONTAINS_REGEXP.firstMatch(selector)) != null) {
- textSelector.add(new _ContainsSelector(annotation, match.group(1)));
- } else if ((match = _ATTR_CONTAINS_REGEXP.firstMatch(selector)) != null) {
- attrSelector.add(new _ContainsSelector(annotation, match[1]));
- } else if ((selectorParts = _splitCss(selector, type)) != null){
- elementSelector.addDirective(selectorParts,
- new _Directive(type, annotation));
- } else {
- throw new ArgumentError('Unsupported Selector: $selector');
- }
- });
- }
-
- ElementBinder matchElement(dom.Node node) {
- assert(node is dom.Element);
-
- ElementBinderBuilder builder = _binderFactory.builder();
- List<_ElementSelector> partialSelection;
- var classes = {};
- Map attrs = {};
-
- dom.Element element = node;
- String nodeName = element.tagName.toLowerCase();
-
- // Set default attribute
- if (nodeName == 'input' && !element.attributes.containsKey('type')) {
- element.attributes['type'] = 'text';
- }
-
- // Select node
- partialSelection = elementSelector.selectNode(builder,
- partialSelection, element, nodeName);
-
- // Select .name
- if ((element.classes) != null) {
- for (var name in element.classes) {
- classes[name] = true;
- partialSelection = elementSelector.selectClass(builder,
- partialSelection, element, name);
- }
- }
-
- // Select [attributes]
- element.attributes.forEach((attrName, value) {
-
- if (attrName.startsWith("on-")) {
- builder.onEvents[attrName] = value;
- }
-
- if (attrName.startsWith("bind-")) {
- builder.bindAttrs[attrName] = value;
- }
-
- attrs[attrName] = value;
- for (var k = 0; k < attrSelector.length; k++) {
- _ContainsSelector selectorRegExp = attrSelector[k];
- if (selectorRegExp.regexp.hasMatch(value)) {
- // this directive is matched on any attribute name, and so
- // we need to pass the name to the directive by prefixing it to
- // the value. Yes it is a bit of a hack.
- _directives[selectorRegExp.annotation].forEach((type) {
- builder.addDirective(new DirectiveRef(
- node, type, selectorRegExp.annotation, '$attrName=$value'));
- });
- }
- }
-
- partialSelection = elementSelector.selectAttr(builder,
- partialSelection, node, attrName, value);
- });
-
- while (partialSelection != null) {
- List<_ElementSelector> elementSelectors = partialSelection;
- partialSelection = null;
- elementSelectors.forEach((_ElementSelector elementSelector) {
- classes.forEach((className, _) {
- partialSelection = elementSelector.selectClass(builder,
- partialSelection, node, className);
- });
- attrs.forEach((attrName, value) {
- partialSelection = elementSelector.selectAttr(builder,
- partialSelection, node, attrName, value);
- });
- });
- }
- return builder.binder;
- }
-
- ElementBinder matchText(dom.Node node) {
- ElementBinderBuilder builder = _binderFactory.builder();
-
- var value = node.nodeValue;
- for (var k = 0; k < textSelector.length; k++) {
- var selectorRegExp = textSelector[k];
- if (selectorRegExp.regexp.hasMatch(value)) {
- _directives[selectorRegExp.annotation].forEach((type) {
- builder.addDirective(new DirectiveRef(node, type,
- selectorRegExp.annotation, value));
- });
- }
- }
- return builder.binder;
- }
-
- ElementBinder matchComment(dom.Node node) {
- return _binderFactory.builder().binder;
- }
-}
-/**
- * Factory for creating a [DirectiveSelector].
- */
-@NgInjectableService()
-class DirectiveSelectorFactory {
- ElementBinderFactory _binderFactory;
-
- DirectiveSelectorFactory(this._binderFactory);
-
- DirectiveSelector selector(DirectiveMap directives) {
- return new DirectiveSelector(directives, _binderFactory);
- }
-}