angular.core.dom library
Functions
DirectiveSelector directiveSelectorFactory(DirectiveMap directives) #
Factory method for creating a DirectiveSelector.
DirectiveSelector directiveSelectorFactory(DirectiveMap directives) {
_ElementSelector elementSelector = new _ElementSelector('');
List<_ContainsSelector> attrSelector = [];
List<_ContainsSelector> textSelector = [];
directives.forEach((NgAnnotation annotation, Type type) {
var match;
var selector = annotation.selector;
List<_SelectorPart> selectorParts;
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)) != null){
elementSelector.addDirective(selectorParts, new _Directive(type, annotation));
} else {
throw new ArgumentError('Unsupported Selector: $selector');
}
});
return (dom.Node node) {
List<DirectiveRef> directiveRefs = [];
List<_ElementSelector> partialSelection = null;
Map<String, bool> classes = new Map<String, bool>();
Map<String, String> attrs = new Map<String, String>();
switch(node.nodeType) {
case 1: // Element
dom.Element element = node;
String nodeName = element.tagName.toLowerCase();
Map<String, String> attrs = {};
// Select node
partialSelection = elementSelector.selectNode(directiveRefs, partialSelection, element, nodeName);
// Select .name
if ((element.classes) != null) {
for(var name in element.classes) {
classes[name] = true;
partialSelection = elementSelector.selectClass(directiveRefs, partialSelection, element, name);
}
}
// Select [attributes]
element.attributes.forEach((attrName, value){
attrs[attrName] = value;
for(var k = 0, kk = attrSelector.length; k < kk; 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.
Type type = directives[selectorRegExp.annotation];
directiveRefs.add(new DirectiveRef(
node, type, selectorRegExp.annotation, '$attrName=$value'));
}
}
partialSelection = elementSelector.selectAttr(directiveRefs, partialSelection, node, attrName, value);
});
while(partialSelection != null) {
List<_ElementSelector> elementSelectors = partialSelection;
partialSelection = null;
elementSelectors.forEach((_ElementSelector elementSelector) {
classes.forEach((className, _) {
partialSelection = elementSelector.selectClass(directiveRefs, partialSelection, node, className);
});
attrs.forEach((attrName, value) {
partialSelection = elementSelector.selectAttr(directiveRefs, partialSelection, node, attrName, value);
});
});
}
break;
case 3: // Text Node
for(var value = node.nodeValue, k = 0, kk = textSelector.length; k < kk; k++) {
var selectorRegExp = textSelector[k];
if (selectorRegExp.regexp.hasMatch(value)) {
Type type = directives[selectorRegExp.annotation];
directiveRefs.add(new DirectiveRef(node, type, selectorRegExp.annotation, value));
}
}
break;
}
directiveRefs.sort(_priorityComparator);
return directiveRefs;
};
}
List<Node> cloneElements(elements) #
List<dom.Node> cloneElements(elements) {
var clones = [];
for(var i = 0, ii = elements.length; i < ii; i++) {
clones.add(elements[i].clone(true));
}
return clones;
}