blob: 33d1ab33932f3af256a0c950cda215e4c83c5089 [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of html;
class FilteredElementList implements List {
final Node _node;
final List<Node> _childNodes;
FilteredElementList(Node node): _childNodes = node.nodes, _node = node;
// We can't memoize this, since it's possible that children will be messed
// with externally to this class.
//
// TODO(nweiz): Do we really need to copy the list to make the types work out?
List<Element> get _filtered =>
new List.from(_childNodes.filter((n) => n is Element));
void forEach(void f(Element element)) {
_filtered.forEach(f);
}
void operator []=(int index, Element value) {
this[index].replaceWith(value);
}
void set length(int newLength) {
final len = this.length;
if (newLength >= len) {
return;
} else if (newLength < 0) {
throw new ArgumentError("Invalid list length");
}
removeRange(newLength - 1, len - newLength);
}
void add(Element value) {
_childNodes.add(value);
}
void addAll(Collection<Element> collection) {
collection.forEach(add);
}
void addLast(Element value) {
add(value);
}
bool contains(Element element) {
return element is Element && _childNodes.contains(element);
}
void sort([Comparator<Element> compare = Comparable.compare]) {
throw new UnsupportedError('TODO(jacobr): should we impl?');
}
void setRange(int start, int rangeLength, List from, [int startFrom = 0]) {
throw new UnimplementedError();
}
void removeRange(int start, int rangeLength) {
_filtered.getRange(start, rangeLength).forEach((el) => el.remove());
}
void insertRange(int start, int rangeLength, [initialValue = null]) {
throw new UnimplementedError();
}
void clear() {
// Currently, ElementList#clear clears even non-element nodes, so we follow
// that behavior.
_childNodes.clear();
}
Element removeLast() {
final result = this.last;
if (result != null) {
result.remove();
}
return result;
}
Collection map(f(Element element)) => _filtered.map(f);
Collection<Element> filter(bool f(Element element)) => _filtered.filter(f);
bool every(bool f(Element element)) => _filtered.every(f);
bool some(bool f(Element element)) => _filtered.some(f);
bool get isEmpty => _filtered.isEmpty;
int get length => _filtered.length;
Element operator [](int index) => _filtered[index];
Iterator<Element> iterator() => _filtered.iterator();
List<Element> getRange(int start, int rangeLength) =>
_filtered.getRange(start, rangeLength);
int indexOf(Element element, [int start = 0]) =>
_filtered.indexOf(element, start);
int lastIndexOf(Element element, [int start = null]) {
if (start == null) start = length - 1;
return _filtered.lastIndexOf(element, start);
}
Element get first => _filtered.first;
Element get last => _filtered.last;
}