Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit eb4422a

Browse files
committed
feat(selector): DirectiveSelector is real now: matchElement, matchText
1 parent 8016340 commit eb4422a

File tree

4 files changed

+117
-98
lines changed

4 files changed

+117
-98
lines changed

lib/core_dom/selector.dart

Lines changed: 114 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ part of angular.core.dom;
2727
*
2828
*
2929
*/
30-
typedef ElementBinder DirectiveSelector(dom.Node node);
31-
3230
class _Directive {
3331
final Type type;
3432
final NgAnnotation annotation;
@@ -239,21 +237,19 @@ List<_SelectorPart> _splitCss(String selector, Type type) {
239237
return parts;
240238
}
241239

242-
/**
243-
* Factory for creating a [DirectiveSelector].
244-
*/
245-
@NgInjectableService()
246-
class DirectiveSelectorFactory {
247-
ElementBinderFactory _binderFactory;
248-
249-
DirectiveSelectorFactory(this._binderFactory);
250-
251-
DirectiveSelector selector(DirectiveMap directives) {
252240

253-
var elementSelector = new _ElementSelector('');
254-
var attrSelector = <_ContainsSelector>[];
255-
var textSelector = <_ContainsSelector>[];
256-
directives.forEach((NgAnnotation annotation, Type type) {
241+
class DirectiveSelector {
242+
ElementBinderFactory _binderFactory;
243+
DirectiveMap _directives;
244+
var elementSelector;
245+
var attrSelector;
246+
var textSelector;
247+
248+
DirectiveSelector(this._directives, this._binderFactory) {
249+
elementSelector = new _ElementSelector('');
250+
attrSelector = <_ContainsSelector>[];
251+
textSelector = <_ContainsSelector>[];
252+
_directives.forEach((NgAnnotation annotation, Type type) {
257253
var match;
258254
var selector = annotation.selector;
259255
List<_SelectorPart> selectorParts;
@@ -267,93 +263,116 @@ class DirectiveSelectorFactory {
267263
attrSelector.add(new _ContainsSelector(annotation, match[1]));
268264
} else if ((selectorParts = _splitCss(selector, type)) != null){
269265
elementSelector.addDirective(selectorParts,
270-
new _Directive(type, annotation));
266+
new _Directive(type, annotation));
271267
} else {
272268
throw new ArgumentError('Unsupported Selector: $selector');
273269
}
274270
});
271+
}
272+
273+
ElementBinder matchElement(dom.Node node) {
274+
assert(node is dom.Element);
275+
276+
ElementBinder binder = _binderFactory.binder();
277+
List<_ElementSelector> partialSelection;
278+
var classes = <String, bool>{};
279+
Map<String, String> attrs = {};
280+
281+
dom.Element element = node;
282+
String nodeName = element.tagName.toLowerCase();
283+
284+
// Set default attribute
285+
if (nodeName == 'input' && !element.attributes.containsKey('type')) {
286+
element.attributes['type'] = 'text';
287+
}
288+
289+
// Select node
290+
partialSelection = elementSelector.selectNode(binder,
291+
partialSelection, element, nodeName);
292+
293+
// Select .name
294+
if ((element.classes) != null) {
295+
for (var name in element.classes) {
296+
classes[name] = true;
297+
partialSelection = elementSelector.selectClass(binder,
298+
partialSelection, element, name);
299+
}
300+
}
275301

276-
return (dom.Node node) {
277-
//var directiveRefs = <DirectiveRef>[];
278-
ElementBinder binder = _binderFactory.binder();
279-
List<_ElementSelector> partialSelection;
280-
var classes = <String, bool>{};
281-
var attrs = <String, String>{};
282-
283-
switch(node.nodeType) {
284-
case 1: // Element
285-
dom.Element element = node;
286-
String nodeName = element.tagName.toLowerCase();
287-
Map<String, String> attrs = {};
288-
289-
// Set default attribute
290-
if (nodeName == 'input' && !element.attributes.containsKey('type')) {
291-
element.attributes['type'] = 'text';
292-
}
293-
294-
// Select node
295-
partialSelection = elementSelector.selectNode(binder,
296-
partialSelection, element, nodeName);
297-
298-
// Select .name
299-
if ((element.classes) != null) {
300-
for (var name in element.classes) {
301-
classes[name] = true;
302-
partialSelection = elementSelector.selectClass(binder,
303-
partialSelection, element, name);
304-
}
305-
}
306-
307-
// Select [attributes]
308-
element.attributes.forEach((attrName, value) {
309-
attrs[attrName] = value;
310-
for (var k = 0; k < attrSelector.length; k++) {
311-
_ContainsSelector selectorRegExp = attrSelector[k];
312-
if (selectorRegExp.regexp.hasMatch(value)) {
313-
// this directive is matched on any attribute name, and so
314-
// we need to pass the name to the directive by prefixing it to
315-
// the value. Yes it is a bit of a hack.
316-
directives[selectorRegExp.annotation].forEach((type) {
317-
binder.addDirective(new DirectiveRef(
318-
node, type, selectorRegExp.annotation, '$attrName=$value'));
319-
});
320-
}
321-
}
322-
323-
partialSelection = elementSelector.selectAttr(binder,
324-
partialSelection, node, attrName, value);
302+
// Select [attributes]
303+
element.attributes.forEach((attrName, value) {
304+
attrs[attrName] = value;
305+
for (var k = 0; k < attrSelector.length; k++) {
306+
_ContainsSelector selectorRegExp = attrSelector[k];
307+
if (selectorRegExp.regexp.hasMatch(value)) {
308+
// this directive is matched on any attribute name, and so
309+
// we need to pass the name to the directive by prefixing it to
310+
// the value. Yes it is a bit of a hack.
311+
_directives[selectorRegExp.annotation].forEach((type) {
312+
binder.addDirective(new DirectiveRef(
313+
node, type, selectorRegExp.annotation, '$attrName=$value'));
325314
});
315+
}
316+
}
317+
318+
partialSelection = elementSelector.selectAttr(binder,
319+
partialSelection, node, attrName, value);
320+
});
326321

327-
while(partialSelection != null) {
328-
List<_ElementSelector> elementSelectors = partialSelection;
329-
partialSelection = null;
330-
elementSelectors.forEach((_ElementSelector elementSelector) {
331-
classes.forEach((className, _) {
332-
partialSelection = elementSelector.selectClass(binder,
333-
partialSelection, node, className);
334-
});
335-
attrs.forEach((attrName, value) {
336-
partialSelection = elementSelector.selectAttr(binder,
337-
partialSelection, node, attrName, value);
338-
});
339-
});
340-
}
341-
break;
342-
case 3: // Text Node
343-
var value = node.nodeValue;
344-
for (var k = 0; k < textSelector.length; k++) {
345-
var selectorRegExp = textSelector[k];
346-
if (selectorRegExp.regexp.hasMatch(value)) {
347-
directives[selectorRegExp.annotation].forEach((type) {
348-
binder.addDirective(new DirectiveRef(node, type,
349-
selectorRegExp.annotation, value));
350-
});
351-
}
352-
}
353-
break;
322+
while(partialSelection != null) {
323+
List<_ElementSelector> elementSelectors = partialSelection;
324+
partialSelection = null;
325+
elementSelectors.forEach((_ElementSelector elementSelector) {
326+
classes.forEach((className, _) {
327+
partialSelection = elementSelector.selectClass(binder,
328+
partialSelection, node, className);
329+
});
330+
attrs.forEach((attrName, value) {
331+
partialSelection = elementSelector.selectAttr(binder,
332+
partialSelection, node, attrName, value);
333+
});
334+
});
335+
}
336+
return binder;
337+
}
338+
339+
ElementBinder matchText(dom.Node node) {
340+
ElementBinder binder = _binderFactory.binder();
341+
342+
var value = node.nodeValue;
343+
for (var k = 0; k < textSelector.length; k++) {
344+
var selectorRegExp = textSelector[k];
345+
if (selectorRegExp.regexp.hasMatch(value)) {
346+
_directives[selectorRegExp.annotation].forEach((type) {
347+
binder.addDirective(new DirectiveRef(node, type,
348+
selectorRegExp.annotation, value));
349+
});
354350
}
351+
}
352+
return binder;
353+
}
354+
ElementBinder match(dom.Node node) {
355+
switch(node.nodeType) {
356+
case 1: // Element
357+
return matchElement(node);
358+
359+
case 3: // Text Node
360+
return matchText(node);
361+
}
362+
// TODO: This is wrong.
363+
return _binderFactory.binder();
364+
}
365+
}
366+
/**
367+
* Factory for creating a [DirectiveSelector].
368+
*/
369+
@NgInjectableService()
370+
class DirectiveSelectorFactory {
371+
ElementBinderFactory _binderFactory;
355372

356-
return binder;
357-
};
373+
DirectiveSelectorFactory(this._binderFactory);
374+
375+
DirectiveSelector selector(DirectiveMap directives) {
376+
return new DirectiveSelector(directives, _binderFactory);
358377
}
359378
}

lib/core_dom/tagging_compiler.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class TaggingCompiler implements Compiler {
2525

2626
// TODO: selector will return null for non-useful bindings.
2727
ElementBinder elementBinder = useExistingElementBinder == null
28-
? directives.selector(node)
28+
? directives.selector.match(node)
2929
: useExistingElementBinder;
3030

3131
if (elementBinder.hasTemplate) {

lib/core_dom/walking_compiler.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class WalkingCompiler implements Compiler {
1818
var subtrees, binder;
1919

2020
ElementBinder elementBinder = existingElementBinder == null
21-
? directives.selector(domCursor.current)
21+
? directives.selector.match(domCursor.current)
2222
: existingElementBinder;
2323

2424
if (elementBinder.hasTemplate) {

test/core_dom/selector_spec.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ main() {
6363
..type(_TwoOfTwoDirectives);
6464
}));
6565
beforeEach(inject((DirectiveMap directives) {
66-
selector = directives.selector;
66+
selector = (node) => directives.selector.match(node);
6767
}));
6868

6969
it('should match directive on element', () {

0 commit comments

Comments
 (0)