5496005d1d
Review URL: http://codereview.chromium.org//8424012 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@947 260f80e4-7a28-3924-810f-c04153c831b5
219 lines
5.2 KiB
Dart
219 lines
5.2 KiB
Dart
// 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.
|
|
|
|
class _ChildrenNodeList implements NodeList {
|
|
// Raw node.
|
|
final _node;
|
|
final _childNodes;
|
|
|
|
_ChildrenNodeList._wrap(var node)
|
|
: _childNodes = node.childNodes,
|
|
_node = node;
|
|
|
|
List<Node> _toList() {
|
|
final output = new List(_childNodes.length);
|
|
for (int i = 0, len = _childNodes.length; i < len; i++) {
|
|
output[i] = LevelDom.wrapNode(_childNodes[i]);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
Node get first() {
|
|
return LevelDom.wrapNode(_node.firstChild);
|
|
}
|
|
|
|
void forEach(void f(Node element)) {
|
|
for (var node in _childNodes) {
|
|
f(LevelDom.wrapNode(node));
|
|
}
|
|
}
|
|
|
|
Collection<Node> filter(bool f(Node element)) {
|
|
List<Node> output = new List<Node>();
|
|
forEach((Node element) {
|
|
if (f(element)) {
|
|
output.add(element);
|
|
}
|
|
});
|
|
return output;
|
|
}
|
|
|
|
bool every(bool f(Node element)) {
|
|
for(Node element in this) {
|
|
if (!f(element)) {
|
|
return false;
|
|
}
|
|
};
|
|
return true;
|
|
}
|
|
|
|
bool some(bool f(Node element)) {
|
|
for(Node element in this) {
|
|
if (f(element)) {
|
|
return true;
|
|
}
|
|
};
|
|
return false;
|
|
}
|
|
|
|
bool isEmpty() {
|
|
return _node.hasChildNodes();
|
|
}
|
|
|
|
int get length() {
|
|
return _childNodes.length;
|
|
}
|
|
|
|
Node operator [](int index) {
|
|
return LevelDom.wrapNode(_childNodes[index]);
|
|
}
|
|
|
|
void operator []=(int index, Node value) {
|
|
_childNodes[index] = LevelDom.unwrap(value);
|
|
}
|
|
|
|
void set length(int newLength) {
|
|
throw new UnsupportedOperationException('');
|
|
}
|
|
|
|
Node add(Node value) {
|
|
_node.appendChild(LevelDom.unwrap(value));
|
|
return value;
|
|
}
|
|
|
|
Node addLast(Node value) {
|
|
_node.appendChild(LevelDom.unwrap(value));
|
|
return value;
|
|
}
|
|
|
|
Iterator<Node> iterator() {
|
|
return _toList().iterator();
|
|
}
|
|
|
|
void addAll(Collection<Node> collection) {
|
|
for (Node node in collection) {
|
|
_node.appendChild(LevelDom.unwrap(node));
|
|
}
|
|
}
|
|
|
|
void sort(int compare(Node a, Node b)) {
|
|
throw const UnsupportedOperationException('TODO(jacobr): should we impl?');
|
|
}
|
|
|
|
void copyFrom(List<Object> src, int srcStart, int dstStart, int count) {
|
|
throw 'Not impl yet. todo(jacobr)';
|
|
}
|
|
|
|
void setRange(int start, int length, List from, [int startFrom = 0]) {
|
|
throw const NotImplementedException();
|
|
}
|
|
|
|
void removeRange(int start, int length) {
|
|
throw const NotImplementedException();
|
|
}
|
|
|
|
void insertRange(int start, int length, [initialValue = null]) {
|
|
throw const NotImplementedException();
|
|
}
|
|
|
|
List getRange(int start, int length) {
|
|
throw const NotImplementedException();
|
|
}
|
|
|
|
int indexOf(Node element, [int start = 0]) {
|
|
return _Lists.indexOf(this, element, start, this.length);
|
|
}
|
|
|
|
int lastIndexOf(Node element, [int start = null]) {
|
|
if (start === null) start = length - 1;
|
|
return _Lists.lastIndexOf(this, element, start);
|
|
}
|
|
|
|
void clear() {
|
|
_node.textContent = '';
|
|
}
|
|
|
|
Node removeLast() {
|
|
final last = this.last();
|
|
if (last != null) {
|
|
_node.removeChild(LevelDom.unwrap(last));
|
|
}
|
|
return last;
|
|
}
|
|
|
|
Node last() {
|
|
return LevelDom.wrapNode(_node.lastChild);
|
|
}
|
|
}
|
|
|
|
class NodeWrappingImplementation extends EventTargetWrappingImplementation implements Node {
|
|
NodeList _nodes;
|
|
|
|
NodeWrappingImplementation._wrap(ptr) : super._wrap(ptr);
|
|
|
|
void set nodes(Collection<Node> value) {
|
|
// Copy list first since we don't want liveness during iteration.
|
|
List copy = new List.from(value);
|
|
nodes.clear();
|
|
nodes.addAll(copy);
|
|
}
|
|
|
|
NodeList get nodes() {
|
|
if (_nodes === null) {
|
|
_nodes = new _ChildrenNodeList._wrap(_ptr);
|
|
}
|
|
return _nodes;
|
|
}
|
|
|
|
Node get nextNode() => LevelDom.wrapNode(_ptr.nextSibling);
|
|
|
|
Document get document() => LevelDom.wrapDocument(_ptr.ownerDocument);
|
|
|
|
Node get parent() => LevelDom.wrapNode(_ptr.parentNode);
|
|
|
|
Node get previousNode() => LevelDom.wrapNode(_ptr.previousSibling);
|
|
|
|
String get text() => _ptr.textContent;
|
|
|
|
void set text(String value) { _ptr.textContent = value; }
|
|
|
|
// New methods implemented.
|
|
Node replaceWith(Node otherNode) {
|
|
try {
|
|
_ptr.parentNode.replaceChild(LevelDom.unwrap(otherNode), _ptr);
|
|
} catch(var e) {
|
|
// TODO(jacobr): what should we return on failure?
|
|
}
|
|
return this;
|
|
}
|
|
|
|
Node remove() {
|
|
// TODO(jacobr): should we throw an exception if parent is already null?
|
|
if (_ptr.parentNode !== null) {
|
|
_ptr.parentNode.removeChild(_ptr);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
bool contains(Node otherNode) {
|
|
// TODO: Feature detect and use built in.
|
|
while (otherNode != null && otherNode != this) {
|
|
otherNode = otherNode.parent;
|
|
}
|
|
return otherNode == this;
|
|
}
|
|
|
|
// TODO(jacobr): remove when/if List supports a method similar to
|
|
// insertBefore or we switch NodeList to implement LinkedList rather than
|
|
// array.
|
|
Node insertBefore(Node newChild, Node refChild) {
|
|
return LevelDom.wrapNode(_ptr.insertBefore(
|
|
LevelDom.unwrap(newChild), LevelDom.unwrap(refChild)));
|
|
}
|
|
|
|
Node clone(bool deep) {
|
|
return LevelDom.wrapNode(_ptr.cloneNode(deep));
|
|
}
|
|
}
|