Skip to content

Commit a148bad

Browse files
committed
fix(html_extractor): correct handling of camelCased attributes
fix dart-archive#1047 closes dart-archive#1301
1 parent cdde8c4 commit a148bad

File tree

3 files changed

+60
-19
lines changed

3 files changed

+60
-19
lines changed

lib/tools/common.dart

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
11
library angular.tools.common;
22

3+
import 'dart:collection';
4+
35
class DirectiveInfo {
46
String selector;
57
String template;
6-
List<String> expressionAttrs = <String>[];
7-
List<String> expressions = <String>[];
8-
DirectiveInfo([this.selector, this.expressionAttrs, this.expressions]) {
9-
if (expressionAttrs == null) {
10-
expressionAttrs = <String>[];
11-
}
12-
if (expressions == null) {
13-
expressions = <String>[];
8+
List<String> _expressionAttrs = <String>[];
9+
10+
List<String> get expressionAttrs => _expressionAttrs;
11+
void set expressionAttrs(value) {
12+
if (value is _AttributeList) {
13+
_expressionAttrs = value;
14+
} else if (value == null) {
15+
_expressionAttrs = new _AttributeList();
16+
} else {
17+
assert(value is Iterable);
18+
_expressionAttrs = new _AttributeList()..addAll(value);
1419
}
1520
}
21+
22+
List<String> expressions = <String>[];
23+
DirectiveInfo([this.selector, List<String> expAttrs, this.expressions]) {
24+
expressionAttrs = expAttrs;
25+
26+
if (expressions == null) expressions = <String>[];
27+
}
1628
}
1729

1830
const String DIRECTIVE = 'DIRECTIVE';
@@ -42,3 +54,29 @@ class DirectiveMetadata {
4254
}
4355
}
4456

57+
/**
58+
* Extends list to always returned lowercase attribute name:
59+
*
60+
* var l = new _AttributeList();
61+
* l.add('fooBar');
62+
* print(l[0]); // "foobar"
63+
*
64+
* It helps working with html5lib `Node` class which also lowercase attribute names.
65+
*
66+
* Note: attribute names are case-insensitive in HTML.
67+
*/
68+
class _AttributeList extends ListBase<String> {
69+
final List<String> _attributes = [];
70+
71+
void set length(int len) {
72+
_attributes.length = len;
73+
}
74+
75+
int get length => _attributes.length;
76+
77+
String operator [](int index) => _attributes[index].toLowerCase();
78+
79+
void operator []=(int index, String value) {
80+
_attributes[index] = value;
81+
}
82+
}

lib/tools/html_extractor.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,12 @@ class HtmlExpressionExtractor {
4949
});
5050
}
5151
if (matchesNode(node, r'[ng-repeat]')) {
52-
var expr = _NG_REPEAT_SYNTAX.
53-
firstMatch(node.attributes['ng-repeat']).group(2);
52+
var expr = _NG_REPEAT_SYNTAX.firstMatch(node.attributes['ng-repeat']).group(2);
5453
expressions.add(expr);
5554
}
5655

5756
for (DirectiveInfo directiveInfo in directiveInfos) {
58-
if (directiveInfo.selector != null &&
59-
matchesNode(node, directiveInfo.selector)) {
57+
if (directiveInfo.selector != null && matchesNode(node, directiveInfo.selector)) {
6058
directiveInfo.expressionAttrs.forEach((attr) {
6159
if (node.attributes[attr] != null && attr != 'ng-repeat') {
6260
expressions.add(node.attributes[attr]);

test/tools/html_extractor_spec.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,23 @@ void main() {
6161
});
6262

6363
it('should extract expressions from expression attributes', () {
64-
var ioService = new MockIoService({
65-
'foo.html': r'''
66-
<foo bar="ctrl.baz"></foo>
67-
'''
68-
});
64+
var ioService = new MockIoService({'foo.html': r'<foo bar="ctrl.baz"></foo>'});
6965

7066
var extractor = new HtmlExpressionExtractor([
7167
new DirectiveInfo('foo', ['bar'])
7268
]);
7369
extractor.crawl('/', ioService);
74-
expect(extractor.expressions.toList()..sort(),
75-
equals(['ctrl.baz']));
70+
expect(extractor.expressions.toList()).toEqual(['ctrl.baz']);
71+
});
72+
73+
it('should extract expressions from expression attributes for camelCased attributes', () {
74+
var ioService = new MockIoService({'foo.html': r'<foo fooBar="ctrl.baz"></foo>'});
75+
76+
var extractor = new HtmlExpressionExtractor([
77+
new DirectiveInfo('foo', ['fooBar'])
78+
]);
79+
extractor.crawl('/', ioService);
80+
expect(extractor.expressions.toList()).toEqual(['ctrl.baz']);
7681
});
7782

7883
it('should ignore ng-repeat while extracting attribute expressions', () {

0 commit comments

Comments
 (0)