From f3d0f0cd609a6deb24021ad1760f9d3faed1ba47 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Sat, 2 Aug 2014 14:21:48 +0200 Subject: [PATCH] fix(html_extractor): correct handling of camelCased attributes fix #1047 closes #1301 --- lib/tools/common.dart | 55 ++++++++++++++++++++++++----- lib/tools/html_extractor.dart | 6 ++-- test/tools/html_extractor_spec.dart | 19 ++++++---- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/lib/tools/common.dart b/lib/tools/common.dart index a6eb482b5..8dbcee882 100644 --- a/lib/tools/common.dart +++ b/lib/tools/common.dart @@ -1,16 +1,29 @@ library angular.tools.common; +import 'dart:collection'; + class DirectiveInfo { String selector; String template; - List expressionAttrs = []; - List expressions = []; - DirectiveInfo([this.selector, this.expressionAttrs, this.expressions]) { - if (expressionAttrs == null) { - expressionAttrs = []; - } - if (expressions == null) { - expressions = []; + List expressions; + _AttributeList _expressionAttrs; + + DirectiveInfo([this.selector, List expAttrs, this.expressions]) { + expressionAttrs = expAttrs; + + if (expressions == null) expressions = []; + } + + List get expressionAttrs => _expressionAttrs; + + void set expressionAttrs(value) { + if (value is _AttributeList) { + _expressionAttrs = value; + } else if (value == null) { + _expressionAttrs = new _AttributeList(); + } else { + assert(value is Iterable); + _expressionAttrs = new _AttributeList()..addAll(value); } } } @@ -42,3 +55,29 @@ class DirectiveMetadata { } } +/** + * Extends list to always returned lowercase attribute name: + * + * var l = new _AttributeList(); + * l.add('fooBar'); + * print(l[0]); // "foobar" + * + * It helps working with html5lib `Node` class which also lowercase attribute names. + * + * Note: attribute names are case-insensitive in HTML. + */ +class _AttributeList extends ListBase { + final List _attributes = []; + + void set length(int len) { + _attributes.length = len; + } + + int get length => _attributes.length; + + String operator [](int index) => _attributes[index].toLowerCase(); + + void operator []=(int index, String value) { + _attributes[index] = value; + } +} diff --git a/lib/tools/html_extractor.dart b/lib/tools/html_extractor.dart index ddeef0e07..8a140b911 100644 --- a/lib/tools/html_extractor.dart +++ b/lib/tools/html_extractor.dart @@ -49,14 +49,12 @@ class HtmlExpressionExtractor { }); } if (matchesNode(node, r'[ng-repeat]')) { - var expr = _NG_REPEAT_SYNTAX. - firstMatch(node.attributes['ng-repeat']).group(2); + var expr = _NG_REPEAT_SYNTAX.firstMatch(node.attributes['ng-repeat']).group(2); expressions.add(expr); } for (DirectiveInfo directiveInfo in directiveInfos) { - if (directiveInfo.selector != null && - matchesNode(node, directiveInfo.selector)) { + if (directiveInfo.selector != null && matchesNode(node, directiveInfo.selector)) { directiveInfo.expressionAttrs.forEach((attr) { if (node.attributes[attr] != null && attr != 'ng-repeat') { expressions.add(node.attributes[attr]); diff --git a/test/tools/html_extractor_spec.dart b/test/tools/html_extractor_spec.dart index da610dd20..253059d11 100644 --- a/test/tools/html_extractor_spec.dart +++ b/test/tools/html_extractor_spec.dart @@ -61,18 +61,23 @@ void main() { }); it('should extract expressions from expression attributes', () { - var ioService = new MockIoService({ - 'foo.html': r''' - - ''' - }); + var ioService = new MockIoService({'foo.html': r''}); var extractor = new HtmlExpressionExtractor([ new DirectiveInfo('foo', ['bar']) ]); extractor.crawl('/', ioService); - expect(extractor.expressions.toList()..sort(), - equals(['ctrl.baz'])); + expect(extractor.expressions.toList()).toEqual(['ctrl.baz']); + }); + + it('should extract expressions from expression attributes for camelCased attributes', () { + var ioService = new MockIoService({'foo.html': r''}); + + var extractor = new HtmlExpressionExtractor([ + new DirectiveInfo('foo', ['fooBar']) + ]); + extractor.crawl('/', ioService); + expect(extractor.expressions.toList()).toEqual(['ctrl.baz']); }); it('should ignore ng-repeat while extracting attribute expressions', () {