* mcs/class/Makefile, mcs/class/Mono.Mozilla,
[mono.git] / mcs / class / Mono.WebBrowser / Mono.Mozilla / DOM / NodeList.cs
1 // Permission is hereby granted, free of charge, to any person obtaining\r
2 // a copy of this software and associated documentation files (the\r
3 // "Software"), to deal in the Software without restriction, including\r
4 // without limitation the rights to use, copy, modify, merge, publish,\r
5 // distribute, sublicense, and/or sell copies of the Software, and to\r
6 // permit persons to whom the Software is furnished to do so, subject to\r
7 // the following conditions:\r
8 // \r
9 // The above copyright notice and this permission notice shall be\r
10 // included in all copies or substantial portions of the Software.\r
11 // \r
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
19 //\r
20 // Copyright (c) 2008 Novell, Inc.\r
21 //\r
22 // Authors:\r
23 //      Andreia Gaita (avidigal@novell.com)\r
24 //
25
26 using System;
27 using System.Collections;
28 using Mono.WebBrowser;
29 using Mono.WebBrowser.DOM;
30
31 namespace Mono.Mozilla.DOM
32 {
33         internal class NodeList : DOMObject, INodeList
34         {
35                 protected nsIDOMNodeList unmanagedNodes;
36                 protected INode [] nodes;
37                 protected int nodeCount;
38                 
39                 public NodeList(WebBrowser control, nsIDOMNodeList nodeList) : base (control)
40                 {
41                         if (control.platform != control.enginePlatform)
42                                 unmanagedNodes = nsDOMNodeList.GetProxy (control, nodeList);
43                         else
44                                 unmanagedNodes = nodeList;
45                 }\r
46 \r
47                 public NodeList (WebBrowser control) : base (control)\r
48                 {\r
49                         nodes = new Node[0];\r
50                 }\r
51                 \r
52                 public NodeList (WebBrowser control, bool loaded) : base (control)\r
53                 {\r
54                 }\r
55                 
56                 #region IDisposable Members
57                 protected override  void Dispose (bool disposing)
58                 {
59                         if (!disposed) {
60                                 if (disposing) {
61                                         Clear ();
62                                 }
63                         }
64                         base.Dispose(disposing);
65                 }               
66                 #endregion
67
68                 #region Helpers
69                 protected void Clear () 
70                 {
71                         if (nodes != null) {
72                                 for (int i = 0; i < nodeCount; i++) {
73                                         nodes[i] = null;
74                                 }
75                                 nodeCount = 0;
76                                 unmanagedNodes = null;\r
77                                 nodes = null;
78                         }
79                 }
80                 
81                 internal virtual void Load ()
82                 {
83                         Clear ();
84                         uint count;
85                         unmanagedNodes.getLength (out count);
86                         nodeCount = (int) count; // hmm.... not good
87                         nodes = new Node[nodeCount];
88                         for (int i = 0; i < nodeCount; i++) {
89                                 nsIDOMNode node;
90                                 unmanagedNodes.item ((uint)i, out node);\r
91                                 ushort type;\r
92                                 node.getNodeType (out type);\r
93                                 switch (type) {\r
94                                         case (ushort)NodeType.Element:\r
95                                                 nodes[i] = new HTMLElement (control, node as nsIDOMHTMLElement);\r
96                                                 break;\r
97                                         default:\r
98                                                 nodes[i] = new Node (control, node);\r
99                                                 break;\r
100                                 }                               
101                         }
102                 }
103                 #endregion
104                 
105                 #region IEnumerable members
106                 public IEnumerator GetEnumerator () 
107                 {
108                         return new NodeListEnumerator (this);
109                 }
110                 #endregion
111                 
112                 #region ICollection members
113                 public void CopyTo (Array dest, int index) 
114                 {
115                         if (nodes != null) {
116                                 Array.Copy (nodes, 0, dest, index, Count);
117                         }
118                 }
119         
120                 public virtual int Count {
121                         get {
122                                 if (unmanagedNodes != null && nodes == null)
123                                         Load ();
124                                 return nodeCount; 
125                         }
126                 }
127                 
128                 object ICollection.SyncRoot {
129                         get { return this; }
130                 }
131                 
132                 bool ICollection.IsSynchronized {
133                         get { return false; }
134                 }
135
136                 #endregion
137                 
138                 #region IList members
139                 public bool IsReadOnly 
140                 {
141                         get { return false;}
142                 }
143
144                 bool IList.IsFixedSize 
145                 {
146                         get { return false;}
147                 }
148
149                 void IList.RemoveAt  (int index) 
150                 {
151                         RemoveAt (index);                       
152                 }
153                 
154                 public void RemoveAt (int index)
155                 {
156                         if (index > Count || index < 0)
157                                 return;                 
158                         Array.Copy (nodes, index + 1, nodes, index, (nodeCount - index) - 1);
159                         nodeCount--;
160                         nodes[nodeCount] = null;
161                 }
162                 
163                 public void Remove (INode node) 
164                 {
165                         this.RemoveAt (IndexOf (node));
166                 }
167
168                 void IList.Remove (object node) 
169                 {
170                         Remove (node as INode);
171                 }
172                 
173                 public void Insert (int index, INode value) 
174                 {
175                         if (index > Count)
176                                 index = nodeCount;
177                         INode[] tmp = new Node[nodeCount+1];
178                         if (index > 0)
179                                 Array.Copy (nodes, 0, tmp, 0, index);
180                         tmp[index] = value;
181                         if (index < nodeCount)
182                                 Array.Copy (nodes, index, tmp, index + 1, (nodeCount - index));
183                         nodes = tmp;
184                         nodeCount++;
185                 }
186
187                 void IList.Insert (int index, object value) 
188                 {
189                         this.Insert (index, value as INode);
190                 }
191                 
192                 public int IndexOf (INode node) 
193                 {
194                         return Array.IndexOf (nodes, node);
195                 }
196
197                 int IList.IndexOf (object node) 
198                 {
199                         return IndexOf (node as INode);
200                 }
201                 
202                 
203                 public bool Contains (INode node)
204                 {
205                         return this.IndexOf (node) != -1;
206                 }
207                 
208                 bool IList.Contains (object node)
209                 {
210                         return Contains (node as INode);                        
211                 }
212                 
213                 void IList.Clear () 
214                 {
215                         this.Clear ();
216                 }
217                 
218                 public int Add (INode node) 
219                 {
220                         this.Insert (Count + 1, node as INode);
221                         return nodeCount - 1;
222                 }
223                 
224                 int IList.Add (object node) 
225                 {
226                         return Add (node as INode);
227                 }
228                 
229                 object IList.this [int index] {
230                         get { 
231                                 return this [index]; 
232                         }
233                         set { 
234                                 this [index] = value as INode; 
235                         }
236                 }
237                 
238                 public INode this [int index] {
239                         get {
240                                 if (index < 0 || index >= Count)
241                                         throw new ArgumentOutOfRangeException ("index");
242                                 return nodes [index];                                                           
243                         }
244                         set {
245                                 if (index < 0 || index >= Count)
246                                         throw new ArgumentOutOfRangeException ("index");
247                                 nodes [index] = value as INode;
248                         }
249                 }
250                 
251                 #endregion
252                 
253                 public override int GetHashCode () {
254                         if (this.unmanagedNodes != null)
255                                 return this.unmanagedNodes.GetHashCode ();
256                         return base.GetHashCode ();
257                 }               
258
259                 internal class NodeListEnumerator : IEnumerator {
260
261                         private NodeList collection;
262                         private int index = -1;
263
264                         public NodeListEnumerator (NodeList collection)
265                         {
266                                 this.collection = collection;
267                         }
268
269                         public object Current {
270                                 get {
271                                         if (index == -1)
272                                                 return null;
273                                         return collection [index];
274                                 }
275                         }
276
277                         public bool MoveNext ()
278                         {
279                                 if (index + 1 >= collection.Count)
280                                         return false;
281                                 index++;
282                                 return true;
283                         }
284
285                         public void Reset ()
286                         {
287                                 index = -1;
288                         }
289                 }
290                 
291         }       
292 }