| Index: sdk/lib/html/html_common/filtered_element_list.dart
|
| diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
|
| index e4b2004964ce7c5e68fe246c20af5ca166058c8c..10beaf747fe19369b6f5cfb3b7ef2dd448ef115e 100644
|
| --- a/sdk/lib/html/html_common/filtered_element_list.dart
|
| +++ b/sdk/lib/html/html_common/filtered_element_list.dart
|
| @@ -5,11 +5,10 @@
|
| part of html_common;
|
|
|
| /**
|
| - * An indexable collection of a node's descendants in the document tree,
|
| + * An indexable collection of a node's direct descendants in the document tree,
|
| * filtered so that only elements are in the collection.
|
| */
|
| -class FilteredElementList<T extends Element> extends ListBase<T>
|
| - implements NodeListWrapper {
|
| +class FilteredElementList extends ListBase<Element> implements NodeListWrapper {
|
| final Node _node;
|
| final List<Node> _childNodes;
|
|
|
| @@ -28,16 +27,20 @@ class FilteredElementList<T extends Element> extends ListBase<T>
|
| // We can't memoize this, since it's possible that children will be messed
|
| // with externally to this class.
|
| //
|
| - // TODO(nweiz): we don't always need to create a new list. For example
|
| - // forEach, every, any, ... could directly work on the _childNodes.
|
| - Iterable<T> get _iterable => _childNodes.where((n) => n is Element);
|
| - List<T> get _filtered => new List<T>.from(_iterable, growable: false);
|
| -
|
| - void forEach(void f(T element)) {
|
| + // We can't use where directly because the types don't agree and there's
|
| + // no way to cast it, so take advantage of being in the SDK.
|
| + Iterable<Element> get _iterable =>
|
| + new WhereIterable<Element>(_childNodes, (n) => n is Element);
|
| + List<Element> get _filtered =>
|
| + new List<Element>.from(_iterable, growable: false);
|
| +
|
| + void forEach(void f(Element element)) {
|
| + // This cannot use the iterator, because operations during iteration might
|
| + // modify the collection, e.g. addAll might append a node to another parent.
|
| _filtered.forEach(f);
|
| }
|
|
|
| - void operator []=(int index, T value) {
|
| + void operator []=(int index, Element value) {
|
| this[index].replaceWith(value);
|
| }
|
|
|
| @@ -52,42 +55,44 @@ class FilteredElementList<T extends Element> extends ListBase<T>
|
| removeRange(newLength, len);
|
| }
|
|
|
| - void add(T value) {
|
| + void add(Element value) {
|
| _childNodes.add(value);
|
| }
|
|
|
| - void addAll(Iterable<T> iterable) {
|
| - for (T element in iterable) {
|
| + void addAll(Iterable<Element> iterable) {
|
| + for (Element element in iterable) {
|
| add(element);
|
| }
|
| }
|
|
|
| bool contains(Object needle) {
|
| if (needle is! Element) return false;
|
| - T element = needle;
|
| + Element element = needle;
|
| return element.parentNode == _node;
|
| }
|
|
|
| - Iterable<T> get reversed => _filtered.reversed;
|
| + Iterable<Element> get reversed => _filtered.reversed;
|
|
|
| - void sort([int compare(T a, T b)]) {
|
| + void sort([int compare(Element a, Element b)]) {
|
| throw new UnsupportedError('Cannot sort filtered list');
|
| }
|
|
|
| - void setRange(int start, int end, Iterable<T> iterable, [int skipCount = 0]) {
|
| + void setRange(int start, int end, Iterable<Element> iterable,
|
| + [int skipCount = 0]) {
|
| throw new UnsupportedError('Cannot setRange on filtered list');
|
| }
|
|
|
| - void fillRange(int start, int end, [T fillValue]) {
|
| + void fillRange(int start, int end, [Element fillValue]) {
|
| throw new UnsupportedError('Cannot fillRange on filtered list');
|
| }
|
|
|
| - void replaceRange(int start, int end, Iterable<T> iterable) {
|
| + void replaceRange(int start, int end, Iterable<Element> iterable) {
|
| throw new UnsupportedError('Cannot replaceRange on filtered list');
|
| }
|
|
|
| void removeRange(int start, int end) {
|
| - _filtered.sublist(start, end).forEach((el) => el.remove());
|
| + new List.from(_iterable.skip(start).take(end - start))
|
| + .forEach((el) => el.remove());
|
| }
|
|
|
| void clear() {
|
| @@ -96,25 +101,33 @@ class FilteredElementList<T extends Element> extends ListBase<T>
|
| _childNodes.clear();
|
| }
|
|
|
| - T removeLast() {
|
| - final result = this.last;
|
| + Element removeLast() {
|
| + final result = _iterable.last;
|
| if (result != null) {
|
| result.remove();
|
| }
|
| return result;
|
| }
|
|
|
| - void insert(int index, T value) {
|
| - var element = _iterable.elementAt(index);
|
| - element.parentNode.insertBefore(value, element);
|
| + void insert(int index, Element value) {
|
| + if (index == length) {
|
| + add(value);
|
| + } else {
|
| + var element = _iterable.elementAt(index);
|
| + element.parentNode.insertBefore(value, element);
|
| + }
|
| }
|
|
|
| - void insertAll(int index, Iterable<T> iterable) {
|
| - var element = _iterable.elementAt(index);
|
| - element.parentNode.insertAllBefore(iterable, element);
|
| + void insertAll(int index, Iterable<Element> iterable) {
|
| + if (index == length) {
|
| + addAll(iterable);
|
| + } else {
|
| + var element = _iterable.elementAt(index);
|
| + element.parentNode.insertAllBefore(iterable, element);
|
| + }
|
| }
|
|
|
| - T removeAt(int index) {
|
| + Element removeAt(int index) {
|
| final result = this[index];
|
| result.remove();
|
| return result;
|
| @@ -122,19 +135,19 @@ class FilteredElementList<T extends Element> extends ListBase<T>
|
|
|
| bool remove(Object element) {
|
| if (element is! Element) return false;
|
| - for (int i = 0; i < length; i++) {
|
| - T indexElement = this[i];
|
| - if (identical(indexElement, element)) {
|
| - indexElement.remove();
|
| - return true;
|
| - }
|
| + if (contains(element)) {
|
| + element.remove();
|
| + return true;
|
| + } else {
|
| + return false;
|
| }
|
| - return false;
|
| }
|
|
|
| - int get length => _filtered.length;
|
| - T operator [](int index) => _filtered[index];
|
| - Iterator<T> get iterator => _filtered.iterator;
|
| + int get length => _iterable.length;
|
| + Element operator [](int index) => _iterable.elementAt(index);
|
| + // This cannot use the iterator, because operations during iteration might
|
| + // modify the collection, e.g. addAll might append a node to another parent.
|
| + Iterator<Element> get iterator => _filtered.iterator;
|
|
|
| List<Node> get rawList => _node.childNodes;
|
| }
|
|
|