Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: lib/dom.dart

Issue 2996603002: Update generic comment syntax (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/src/css_class_set.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /// A simple tree API that results from parsing html. Intended to be compatible 1 /// A simple tree API that results from parsing html. Intended to be compatible
2 /// with dart:html, but it is missing many types and APIs. 2 /// with dart:html, but it is missing many types and APIs.
3 library dom; 3 library dom;
4 4
5 // TODO(jmesserly): lots to do here. Originally I wanted to generate this using 5 // TODO(jmesserly): lots to do here. Originally I wanted to generate this using
6 // our Blink IDL generator, but another idea is to directly use the excellent 6 // our Blink IDL generator, but another idea is to directly use the excellent
7 // http://dom.spec.whatwg.org/ and http://html.spec.whatwg.org/ and just 7 // http://dom.spec.whatwg.org/ and http://html.spec.whatwg.org/ and just
8 // implement that. 8 // implement that.
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
11
11 import 'package:source_span/source_span.dart'; 12 import 'package:source_span/source_span.dart';
12 13
14 import 'dom_parsing.dart';
15 import 'parser.dart';
13 import 'src/constants.dart'; 16 import 'src/constants.dart';
14 import 'src/css_class_set.dart'; 17 import 'src/css_class_set.dart';
15 import 'src/list_proxy.dart'; 18 import 'src/list_proxy.dart';
16 import 'src/query_selector.dart' as query; 19 import 'src/query_selector.dart' as query;
17 import 'src/token.dart'; 20 import 'src/token.dart';
18 import 'src/tokenizer.dart'; 21 import 'src/tokenizer.dart';
19 import 'dom_parsing.dart';
20 import 'parser.dart';
21 22
22 export 'src/css_class_set.dart' show CssClassSet; 23 export 'src/css_class_set.dart' show CssClassSet;
23 24
24 // TODO(jmesserly): this needs to be replaced by an AttributeMap for attributes 25 // TODO(jmesserly): this needs to be replaced by an AttributeMap for attributes
25 // that exposes namespace info. 26 // that exposes namespace info.
26 class AttributeName implements Comparable { 27 class AttributeName implements Comparable {
27 /// The namespace prefix, e.g. `xlink`. 28 /// The namespace prefix, e.g. `xlink`.
28 final String prefix; 29 final String prefix;
29 30
30 /// The attribute name, e.g. `title`. 31 /// The attribute name, e.g. `title`.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // This doesn't exist as an interface in the spec, but it's useful to merge 104 // This doesn't exist as an interface in the spec, but it's useful to merge
104 // common methods from these: 105 // common methods from these:
105 // http://dom.spec.whatwg.org/#interface-document 106 // http://dom.spec.whatwg.org/#interface-document
106 // http://dom.spec.whatwg.org/#element 107 // http://dom.spec.whatwg.org/#element
107 abstract class _ElementAndDocument implements _ParentNode { 108 abstract class _ElementAndDocument implements _ParentNode {
108 // TODO(jmesserly): could be faster, should throw on invalid tag/class names. 109 // TODO(jmesserly): could be faster, should throw on invalid tag/class names.
109 110
110 List<Element> getElementsByTagName(String localName) => 111 List<Element> getElementsByTagName(String localName) =>
111 querySelectorAll(localName); 112 querySelectorAll(localName);
112 113
113 List<Element> getElementsByClassName(String classNames) => querySelectorAll( 114 List<Element> getElementsByClassName(String classNames) =>
114 classNames.splitMapJoin(' ', 115 querySelectorAll(classNames.splitMapJoin(' ',
115 onNonMatch: (m) => m.isNotEmpty ? '.$m' : m, onMatch: (m) => '')); 116 onNonMatch: (m) => m.isNotEmpty ? '.$m' : m, onMatch: (m) => ''));
116 } 117 }
117 118
118 /// Really basic implementation of a DOM-core like Node. 119 /// Really basic implementation of a DOM-core like Node.
119 abstract class Node { 120 abstract class Node {
120 static const int ATTRIBUTE_NODE = 2; 121 static const int ATTRIBUTE_NODE = 2;
121 static const int CDATA_SECTION_NODE = 4; 122 static const int CDATA_SECTION_NODE = 4;
122 static const int COMMENT_NODE = 8; 123 static const int COMMENT_NODE = 8;
123 static const int DOCUMENT_FRAGMENT_NODE = 11; 124 static const int DOCUMENT_FRAGMENT_NODE = 11;
124 static const int DOCUMENT_NODE = 9; 125 static const int DOCUMENT_NODE = 9;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 tokenizer.moveNext(); 286 tokenizer.moveNext();
286 var token = tokenizer.current as StartTagToken; 287 var token = tokenizer.current as StartTagToken;
287 288
288 if (token.attributeSpans == null) return; // no attributes 289 if (token.attributeSpans == null) return; // no attributes
289 290
290 for (var attr in token.attributeSpans) { 291 for (var attr in token.attributeSpans) {
291 var offset = sourceSpan.start.offset; 292 var offset = sourceSpan.start.offset;
292 _attributeSpans[attr.name] = 293 _attributeSpans[attr.name] =
293 sourceSpan.file.span(offset + attr.start, offset + attr.end); 294 sourceSpan.file.span(offset + attr.start, offset + attr.end);
294 if (attr.startValue != null) { 295 if (attr.startValue != null) {
295 _attributeValueSpans[attr.name] = sourceSpan.file.span( 296 _attributeValueSpans[attr.name] = sourceSpan.file
296 offset + attr.startValue, offset + attr.endValue); 297 .span(offset + attr.startValue, offset + attr.endValue);
297 } 298 }
298 } 299 }
299 } 300 }
300 301
301 _clone(Node shallowClone, bool deep) { 302 _clone(Node shallowClone, bool deep) {
302 if (deep) { 303 if (deep) {
303 for (var child in nodes) { 304 for (var child in nodes) {
304 shallowClone.append(child.clone(true)); 305 shallowClone.append(child.clone(true));
305 } 306 }
306 } 307 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 401
401 DocumentType clone(bool deep) => new DocumentType(name, publicId, systemId); 402 DocumentType clone(bool deep) => new DocumentType(name, publicId, systemId);
402 } 403 }
403 404
404 class Text extends Node { 405 class Text extends Node {
405 /// The text node's data, stored as either a String or StringBuffer. 406 /// The text node's data, stored as either a String or StringBuffer.
406 /// We support storing a StringBuffer here to support fast [appendData]. 407 /// We support storing a StringBuffer here to support fast [appendData].
407 /// It will flatten back to a String on read. 408 /// It will flatten back to a String on read.
408 var _data; 409 var _data;
409 410
410 Text(String data) : _data = data != null ? data : '', super._(); 411 Text(String data)
412 : _data = data != null ? data : '',
413 super._();
411 414
412 int get nodeType => Node.TEXT_NODE; 415 int get nodeType => Node.TEXT_NODE;
413 416
414 String get data => _data = _data.toString(); 417 String get data => _data = _data.toString();
415 set data(String value) { 418 set data(String value) {
416 _data = value != null ? value : ''; 419 _data = value != null ? value : '';
417 } 420 }
418 421
419 String toString() => '"$data"'; 422 String toString() => '"$data"';
420 423
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 'thead': 'table', 472 'thead': 'table',
470 'track': 'audio', 473 'track': 'audio',
471 }; 474 };
472 475
473 // TODO(jmesserly): this is from dart:html _ElementFactoryProvider... 476 // TODO(jmesserly): this is from dart:html _ElementFactoryProvider...
474 // TODO(jmesserly): have a look at fixing some things in dart:html, in 477 // TODO(jmesserly): have a look at fixing some things in dart:html, in
475 // particular: is the parent tag map complete? Is it faster without regexp? 478 // particular: is the parent tag map complete? Is it faster without regexp?
476 // TODO(jmesserly): for our version we can do something smarter in the parser. 479 // TODO(jmesserly): for our version we can do something smarter in the parser.
477 // All we really need is to set the correct parse state. 480 // All we really need is to set the correct parse state.
478 factory Element.html(String html) { 481 factory Element.html(String html) {
479
480 // TODO(jacobr): this method can be made more robust and performant. 482 // TODO(jacobr): this method can be made more robust and performant.
481 // 1) Cache the dummy parent elements required to use innerHTML rather than 483 // 1) Cache the dummy parent elements required to use innerHTML rather than
482 // creating them every call. 484 // creating them every call.
483 // 2) Verify that the html does not contain leading or trailing text nodes. 485 // 2) Verify that the html does not contain leading or trailing text nodes.
484 // 3) Verify that the html does not contain both <head> and <body> tags. 486 // 3) Verify that the html does not contain both <head> and <body> tags.
485 // 4) Detatch the created element from its dummy parent. 487 // 4) Detatch the created element from its dummy parent.
486 String parentTag = 'div'; 488 String parentTag = 'div';
487 String tag; 489 String tag;
488 final match = _START_TAG_REGEXP.firstMatch(html); 490 final match = _START_TAG_REGEXP.firstMatch(html);
489 if (match != null) { 491 if (match != null) {
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 } 802 }
801 } 803 }
802 return result; 804 return result;
803 } 805 }
804 } 806 }
805 807
806 /// An indexable collection of a node's descendants in the document tree, 808 /// An indexable collection of a node's descendants in the document tree,
807 /// filtered so that only elements are in the collection. 809 /// filtered so that only elements are in the collection.
808 // TODO(jmesserly): this was copied from dart:html 810 // TODO(jmesserly): this was copied from dart:html
809 // TODO(jmesserly): "implements List<Element>" is a workaround for analyzer bug. 811 // TODO(jmesserly): "implements List<Element>" is a workaround for analyzer bug.
810 class FilteredElementList extends IterableBase<Element> with ListMixin<Element> 812 class FilteredElementList extends IterableBase<Element>
813 with ListMixin<Element>
811 implements List<Element> { 814 implements List<Element> {
812 final List<Node> _childNodes; 815 final List<Node> _childNodes;
813 816
814 /// Creates a collection of the elements that descend from a node. 817 /// Creates a collection of the elements that descend from a node.
815 /// 818 ///
816 /// Example usage: 819 /// Example usage:
817 /// 820 ///
818 /// var filteredElements = new FilteredElementList(query("#container")); 821 /// var filteredElements = new FilteredElementList(query("#container"));
819 /// // filteredElements is [a, b, c]. 822 /// // filteredElements is [a, b, c].
820 FilteredElementList(Node node) 823 FilteredElementList(Node node) : _childNodes = node.nodes;
821 : _childNodes = node.nodes;
822
823 824
824 // We can't memoize this, since it's possible that children will be messed 825 // We can't memoize this, since it's possible that children will be messed
825 // with externally to this class. 826 // with externally to this class.
826 // 827 //
827 // TODO(nweiz): we don't always need to create a new list. For example 828 // TODO(nweiz): we don't always need to create a new list. For example
828 // forEach, every, any, ... could directly work on the _childNodes. 829 // forEach, every, any, ... could directly work on the _childNodes.
829 List<Element> get _filtered => 830 List<Element> get _filtered =>
830 new List<Element>.from(_childNodes.where((n) => n is Element)); 831 new List<Element>.from(_childNodes.where((n) => n is Element));
831 832
832 void forEach(void f(Element element)) { 833 void forEach(void f(Element element)) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 } 895 }
895 896
896 Element removeLast() { 897 Element removeLast() {
897 final result = this.last; 898 final result = this.last;
898 if (result != null) { 899 if (result != null) {
899 result.remove(); 900 result.remove();
900 } 901 }
901 return result; 902 return result;
902 } 903 }
903 904
904 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(Element element)) => _filtered.map(f); 905 Iterable<T> map<T>(T f(Element element)) => _filtered.map(f);
905 Iterable<Element> where(bool f(Element element)) => _filtered.where(f); 906 Iterable<Element> where(bool f(Element element)) => _filtered.where(f);
906 Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(Element element)) => 907 Iterable<T> expand<T>(Iterable<T> f(Element element)) => _filtered.expand(f);
907 _filtered.expand(f);
908 908
909 void insert(int index, Element value) { 909 void insert(int index, Element value) {
910 _childNodes.insert(index, value); 910 _childNodes.insert(index, value);
911 } 911 }
912 912
913 void insertAll(int index, Iterable<Element> iterable) { 913 void insertAll(int index, Iterable<Element> iterable) {
914 _childNodes.insertAll(index, iterable); 914 _childNodes.insertAll(index, iterable);
915 } 915 }
916 916
917 Element removeAt(int index) { 917 Element removeAt(int index) {
(...skipping 11 matching lines...) Expand all
929 return true; 929 return true;
930 } 930 }
931 } 931 }
932 return false; 932 return false;
933 } 933 }
934 934
935 Element reduce(Element combine(Element value, Element element)) { 935 Element reduce(Element combine(Element value, Element element)) {
936 return _filtered.reduce(combine); 936 return _filtered.reduce(combine);
937 } 937 }
938 938
939 dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue, 939 T fold<T>(T initialValue, T combine(T previousValue, Element element)) {
940 dynamic/*=T*/ combine(var/*=T*/ previousValue, Element element)) {
941 return _filtered.fold(initialValue, combine); 940 return _filtered.fold(initialValue, combine);
942 } 941 }
943 942
944 bool every(bool f(Element element)) => _filtered.every(f); 943 bool every(bool f(Element element)) => _filtered.every(f);
945 bool any(bool f(Element element)) => _filtered.any(f); 944 bool any(bool f(Element element)) => _filtered.any(f);
946 List<Element> toList({bool growable: true}) => 945 List<Element> toList({bool growable: true}) =>
947 new List<Element>.from(this, growable: growable); 946 new List<Element>.from(this, growable: growable);
948 Set<Element> toSet() => new Set<Element>.from(this); 947 Set<Element> toSet() => new Set<Element>.from(this);
949 Element firstWhere(bool test(Element value), {Element orElse()}) { 948 Element firstWhere(bool test(Element value), {Element orElse()}) {
950 return _filtered.firstWhere(test, orElse: orElse); 949 return _filtered.firstWhere(test, orElse: orElse);
(...skipping 13 matching lines...) Expand all
964 963
965 bool get isEmpty => _filtered.isEmpty; 964 bool get isEmpty => _filtered.isEmpty;
966 int get length => _filtered.length; 965 int get length => _filtered.length;
967 Element operator [](int index) => _filtered[index]; 966 Element operator [](int index) => _filtered[index];
968 Iterator<Element> get iterator => _filtered.iterator; 967 Iterator<Element> get iterator => _filtered.iterator;
969 List<Element> sublist(int start, [int end]) => _filtered.sublist(start, end); 968 List<Element> sublist(int start, [int end]) => _filtered.sublist(start, end);
970 Iterable<Element> getRange(int start, int end) => 969 Iterable<Element> getRange(int start, int end) =>
971 _filtered.getRange(start, end); 970 _filtered.getRange(start, end);
972 // TODO(sigmund): this should be typed Element, but we currently run into a 971 // TODO(sigmund): this should be typed Element, but we currently run into a
973 // bug where ListMixin<E>.indexOf() expects Object as the argument. 972 // bug where ListMixin<E>.indexOf() expects Object as the argument.
974 int indexOf(element, [int start = 0]) => 973 int indexOf(element, [int start = 0]) => _filtered.indexOf(element, start);
975 _filtered.indexOf(element, start);
976 974
977 // TODO(sigmund): this should be typed Element, but we currently run into a 975 // TODO(sigmund): this should be typed Element, but we currently run into a
978 // bug where ListMixin<E>.lastIndexOf() expects Object as the argument. 976 // bug where ListMixin<E>.lastIndexOf() expects Object as the argument.
979 int lastIndexOf(element, [int start = null]) { 977 int lastIndexOf(element, [int start = null]) {
980 if (start == null) start = length - 1; 978 if (start == null) start = length - 1;
981 return _filtered.lastIndexOf(element, start); 979 return _filtered.lastIndexOf(element, start);
982 } 980 }
983 981
984 Element get first => _filtered.first; 982 Element get first => _filtered.first;
985 983
(...skipping 14 matching lines...) Expand all
1000 998
1001 class _ConcatTextVisitor extends TreeVisitor { 999 class _ConcatTextVisitor extends TreeVisitor {
1002 final _str = new StringBuffer(); 1000 final _str = new StringBuffer();
1003 1001
1004 String toString() => _str.toString(); 1002 String toString() => _str.toString();
1005 1003
1006 visitText(Text node) { 1004 visitText(Text node) {
1007 _str.write(node.data); 1005 _str.write(node.data);
1008 } 1006 }
1009 } 1007 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/css_class_set.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698