1 use webcore::value::{Value, Reference}; 2 use webcore::try_from::TryInto; 3 use webcore::reference_type::ReferenceType; 4 use webapi::node::Node; 5 6 /// `NodeList` objects are collections of nodes such as those returned by properties 7 /// such as [INode::child_nodes](trait.INode.html#method.child_nodes) and the 8 /// [Document::query_selector_all](struct.Document.html#method.query_selector_all) method. 9 /// 10 /// In some cases, the `NodeList` is a live collection, which means that changes in the DOM 11 /// are reflected in the collection - for example [INode::child_nodes](trait.INode.html#method.child_nodes) is live. 12 /// 13 /// In other cases, the `NodeList` is a static collection, meaning any subsequent change 14 /// in the DOM does not affect the content of the collection - for example 15 /// [Document::query_selector_all](struct.Document.html#method.query_selector_all) returns 16 /// a static `NodeList`. 17 /// 18 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/NodeList) 19 // https://dom.spec.whatwg.org/#nodelist 20 #[derive(Clone, Debug, PartialEq, Eq, ReferenceType)] 21 #[reference(instance_of = "NodeList")] 22 pub struct NodeList( Reference ); 23 24 impl NodeList { 25 /// Returns the number of [Node](struct.Node.html)s contained in this list. 26 /// 27 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/length) 28 // https://dom.spec.whatwg.org/#ref-for-dom-nodelist-length len( &self ) -> u3229 pub fn len( &self ) -> u32 { 30 js!( return @{self}.length; ).try_into().unwrap() 31 } 32 33 /// Returns a node from a NodeList by index. 34 /// 35 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/item) 36 // https://dom.spec.whatwg.org/#ref-for-dom-nodelist-item item( &self, index: u32 ) -> Option< Node >37 pub fn item( &self, index: u32 ) -> Option< Node > { 38 js!( 39 return @{self}[ @{index} ]; 40 ).try_into().unwrap() 41 } 42 43 /// Returns an iterator over the list. iter( &self ) -> NodeIter44 pub fn iter( &self ) -> NodeIter { 45 NodeIter { 46 list: self.clone(), 47 index: 0 48 } 49 } 50 } 51 52 impl IntoIterator for NodeList { 53 type Item = Node; 54 type IntoIter = NodeIter; 55 56 #[inline] into_iter( self ) -> Self::IntoIter57 fn into_iter( self ) -> Self::IntoIter { 58 NodeIter { 59 list: self, 60 index: 0 61 } 62 } 63 } 64 65 impl< 'a > IntoIterator for &'a NodeList { 66 type Item = Node; 67 type IntoIter = NodeIter; 68 69 #[inline] into_iter( self ) -> Self::IntoIter70 fn into_iter( self ) -> Self::IntoIter { 71 NodeIter { 72 list: self.clone(), 73 index: 0 74 } 75 } 76 } 77 78 #[derive(Debug)] 79 pub struct NodeIter { 80 list: NodeList, 81 index: i32 82 } 83 84 impl Iterator for NodeIter { 85 type Item = Node; next( &mut self ) -> Option< Self::Item >86 fn next( &mut self ) -> Option< Self::Item > { 87 let value = js!( 88 return @{&self.list}[ @{self.index} ]; 89 ); 90 91 let node = match value { 92 Value::Undefined => return None, 93 Value::Reference( reference ) => unsafe { Node::from_reference_unchecked( reference ) }, 94 _ => unreachable!() 95 }; 96 97 self.index += 1; 98 Some( node ) 99 } 100 } 101