2009-05-13 Andreia Gaita <avidigal@novell.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / HtmlDocument.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2007, 2008 Novell, Inc.
21 //
22 // Authors:
23 //      Andreia Gaita   <avidigal@novell.com>
24
25 #if NET_2_0
26
27 using System;
28 using System.Drawing;
29 using System.ComponentModel;
30 using System.Globalization;
31 using Mono.WebBrowser.DOM;
32
33 namespace System.Windows.Forms
34 {
35         public sealed class HtmlDocument
36         {
37                 private EventHandlerList events;
38                 private Mono.WebBrowser.IWebBrowser webHost;
39                 private IDocument document;
40                 private WebBrowser owner;
41
42                 internal HtmlDocument (WebBrowser owner, Mono.WebBrowser.IWebBrowser webHost) : 
43                         this (owner, webHost, webHost.Document)
44                 {
45                 }
46
47                 internal HtmlDocument (WebBrowser owner, Mono.WebBrowser.IWebBrowser webHost, IDocument doc)
48                 {
49                         this.webHost = webHost;
50                         this.document = doc;
51                         this.owner = owner;
52                 }
53
54
55                 internal EventHandlerList Events {
56                         get {
57                                 if (events == null)
58                                         events = new EventHandlerList ();
59
60                                 return events;
61                         }
62                 }
63
64                 #region Methods
65
66
67                 public void AttachEventHandler (string eventName, EventHandler eventHandler)
68                 { 
69                         document.AttachEventHandler (eventName, eventHandler);
70                 }
71
72                 public HtmlElement CreateElement (string elementTag) 
73                 { 
74                         Mono.WebBrowser.DOM.IElement element = document.CreateElement (elementTag);
75                         return new HtmlElement (owner, webHost, element);
76                 }
77
78                 public void DetachEventHandler (string eventName, EventHandler eventHandler) 
79                 {
80                         document.DetachEventHandler (eventName, eventHandler);
81                 }
82
83                 public override bool Equals (object obj) {
84                         return this == (HtmlDocument) obj;
85                 }
86
87                 public void ExecCommand (string command, bool showUI, Object value) 
88                 {
89                         throw new NotImplementedException ("Not Supported");
90                 }
91
92                 [EditorBrowsable(EditorBrowsableState.Advanced)]
93                 public void Focus () 
94                 {
95                         webHost.FocusIn (Mono.WebBrowser.FocusOption.None);
96                 }
97
98                 public HtmlElement GetElementById (string id)
99                 {
100                         IElement elem = document.GetElementById (id);
101                         if (elem != null)
102                                 return new HtmlElement (owner, webHost, elem);
103                         return null;
104                 }
105
106                 public HtmlElement GetElementFromPoint (Point point) 
107                 {
108                         Mono.WebBrowser.DOM.IElement elem = document.GetElement (point.X, point.Y);
109                         if (elem != null)
110                                 return new HtmlElement(owner, webHost, elem);
111                         return null;
112                 }
113
114                 public HtmlElementCollection GetElementsByTagName (string tagName) 
115                 {
116                         Mono.WebBrowser.DOM.IElementCollection col = document.GetElementsByTagName (tagName);
117                         if (col != null)
118                                 return new HtmlElementCollection (owner, webHost, col);
119                         return null;
120                 }
121
122                 public override int GetHashCode () 
123                 {
124                         if (document == null)
125                                 return 0;                       
126                         return document.GetHashCode (); 
127                 }
128
129                 public Object InvokeScript (string scriptName)
130                 { 
131                         return document.InvokeScript ("eval ('" + scriptName + "()');");
132                 }
133
134                 public Object InvokeScript (string scriptName, object[] args) 
135                 {
136                         string[] strArgs = new string[args.Length];
137                         for (int i = 0; i < args.Length; i++) {
138                                 if (args[i] is string)
139                                         strArgs[i] = "\"" + args[i].ToString() + "\"";
140                                 else
141                                         strArgs[i] = args[i].ToString();
142                         }
143                         return document.InvokeScript ("eval ('" + scriptName + "(" + String.Join (",", strArgs) + ")');");
144                 }
145
146                 public static bool operator ==(HtmlDocument left, HtmlDocument right) {
147                         if ((object)left == (object)right) {
148                                 return true;
149                         }
150
151                         if ((object)left == null || (object)right == null) {
152                                 return false;
153                         }
154
155                         return left.document.Equals (right.document); 
156                 }
157
158                 public static bool operator !=(HtmlDocument left, HtmlDocument right) {
159                         return !(left == right);
160                 }
161
162
163                 public HtmlDocument OpenNew (bool replaceInHistory) 
164                 {
165                         Mono.WebBrowser.DOM.LoadFlags flags = Mono.WebBrowser.DOM.LoadFlags.None;
166                         if (replaceInHistory)
167                                 flags |= Mono.WebBrowser.DOM.LoadFlags.ReplaceHistory;
168                         webHost.Navigation.Go ("about:blank", flags);
169                         return this;
170                 }
171
172                 public void Write (string text) 
173                 {
174                         document.Write (text);
175                 }
176
177                 #endregion
178
179                 #region Properties
180                 public HtmlElement ActiveElement {
181                         get { 
182                                 Mono.WebBrowser.DOM.IElement element = document.Active;
183                                 if (element == null)
184                                         return null;
185                                 return new HtmlElement (owner, webHost, element);
186                         
187                         }
188                 }
189                 
190                 public Color ActiveLinkColor {
191                         get { return ParseColor(document.ActiveLinkColor); }
192                         set { document.ActiveLinkColor = value.ToArgb().ToString(); }
193                 }
194
195                 public HtmlElementCollection All {
196                         get {
197                                 return new HtmlElementCollection (owner, webHost, document.DocumentElement.All);
198                         }
199                 }
200
201                 public Color BackColor {
202                         get { return ParseColor(document.BackColor); }
203                         set { document.BackColor = value.ToArgb().ToString(); }
204                 }
205                 
206                 public HtmlElement Body {
207                         get { return new HtmlElement (owner, webHost, document.Body); }
208                 }
209                 
210                 public string Cookie {
211                         get { return document.Cookie; }
212                         set { document.Cookie = value; }
213                 }
214                 
215                 public string DefaultEncoding { 
216                         get { return document.Charset; }
217                 }
218                 
219                 public string Domain {
220                         get { return document.Domain; }
221                         set { throw new NotSupportedException ("Setting the domain is not supported per the DOM Level 2 HTML specification. Sorry."); }
222                 }
223                 
224                 public Object DomDocument { 
225                         get { throw new NotSupportedException ("Retrieving a reference to an mshtml interface is not supported. Sorry."); } 
226                 }
227                 
228                 public string Encoding {
229                         get { return document.Charset; }
230                         set { document.Charset = value; }
231                 }
232
233                 public bool Focused { 
234                         get { return webHost.Window.Document == document; }
235                 }
236                 
237                 public Color ForeColor {
238                         get { return ParseColor(document.ForeColor); }
239                         set { document.ForeColor = value.ToArgb().ToString(); }
240                 }
241                 
242                 public HtmlElementCollection Forms { 
243                         get { return new HtmlElementCollection (owner, webHost, document.Forms); } 
244                 }
245                 
246                 public HtmlElementCollection Images { 
247                         get { return new HtmlElementCollection (owner, webHost, document.Images); }     
248                 }
249                 
250                 public Color LinkColor {
251                         get { return ParseColor(document.LinkColor); }
252                         set { document.LinkColor = value.ToArgb().ToString(); }
253                 }
254                 
255                 public HtmlElementCollection Links {
256                         get { return new HtmlElementCollection (owner, webHost, document.Links); } 
257                 }
258                 
259                 public bool RightToLeft {
260                         get { 
261                                 IAttribute dir = document.Attributes["dir"];
262                                 return (dir != null && dir.Value == "rtl");                                     
263                         }
264                         set {
265                                 
266                                 IAttribute dir = document.Attributes["dir"];
267                                 if (dir == null && value) {
268                                         IAttribute attr = document.CreateAttribute ("dir");
269                                         attr.Value = "rtl";
270                                         document.AppendChild (attr);
271                                 } else if (dir != null && !value) {
272                                         document.RemoveChild (dir);
273                                 }
274                         }
275                 }
276                 
277                 public string Title {
278                         get {
279                                 if (document == null)
280                                         return String.Empty;
281                                 return document.Title; 
282                         }
283                         set { document.Title = value; }
284                 }
285                 
286                 public Uri Url { 
287                         get { return new Uri (document.Url); } 
288                 }
289                 
290                 public Color VisitedLinkColor {
291                         get { return ParseColor(document.VisitedLinkColor); }
292                         set { document.VisitedLinkColor =  value.ToArgb().ToString(); }
293                 }
294                 
295                 public HtmlWindow Window { 
296                         get { return new HtmlWindow (owner, webHost, webHost.Window); } 
297                 
298                 }
299
300
301                 #endregion
302
303                 #region Events
304                 private static object ClickEvent = new object ();
305                 public event HtmlElementEventHandler Click {
306                         add { 
307                                 Events.AddHandler (ClickEvent, value);
308                                 document.Click += new NodeEventHandler (OnClick);
309                         }
310                         remove { 
311                                 Events.RemoveHandler (ClickEvent, value);
312                                 document.Click -= new NodeEventHandler (OnClick);
313                         }
314                 }
315                 
316                 private void OnClick (object sender, EventArgs e)
317                 {
318                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[ClickEvent];
319                         if (eh != null) {
320                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
321                                 eh (this, ev);
322                         }
323                 }
324
325                 private static object ContextMenuShowingEvent = new object ();
326                 public event HtmlElementEventHandler ContextMenuShowing {
327                         add { 
328                                 Events.AddHandler (ContextMenuShowingEvent, value);
329                                 owner.WebHost.ContextMenuShown += new Mono.WebBrowser.ContextMenuEventHandler (OnContextMenuShowing);
330                         }
331                         remove { 
332                                 Events.RemoveHandler (ContextMenuShowingEvent, value);
333                                 owner.WebHost.ContextMenuShown -= new Mono.WebBrowser.ContextMenuEventHandler (OnContextMenuShowing);
334                         }
335                 }
336                 private void OnContextMenuShowing (object sender, Mono.WebBrowser.ContextMenuEventArgs e)
337                 {
338                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[ContextMenuShowingEvent];
339                         if (eh != null) {
340                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
341                                 eh (this, ev);
342                                 if (ev.ReturnValue) {
343                                         owner.OnWebHostContextMenuShown (sender, e);
344                                 }
345                         }
346                 }
347
348                 private static object FocusingEvent = new object ();
349                 public event HtmlElementEventHandler Focusing {
350                         add { 
351                                 Events.AddHandler (FocusingEvent, value); 
352                                 document.OnFocus += new NodeEventHandler (OnFocusing);
353                         }
354                         remove { 
355                                 Events.RemoveHandler (FocusingEvent, value); 
356                                 document.OnFocus -= new NodeEventHandler (OnFocusing);
357                         }
358                 }
359                 
360                 private void OnFocusing (object sender, EventArgs e)
361                 {
362                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[FocusingEvent];
363                         if (eh != null) {
364                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
365                                 eh (this, ev);
366                         }
367                 }
368
369                 private static object LosingFocusEvent = new object ();
370                 public event HtmlElementEventHandler LosingFocus {
371                         add { 
372                                 Events.AddHandler (LosingFocusEvent, value); 
373                                 document.OnBlur += new NodeEventHandler (OnLosingFocus);
374                         }
375                         remove { 
376                                 Events.RemoveHandler (LosingFocusEvent, value); 
377                                 document.OnBlur -= new NodeEventHandler (OnLosingFocus);
378                         }
379                 }
380                 
381                 private void OnLosingFocus (object sender, EventArgs e)
382                 {
383                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[LosingFocusEvent];
384                         if (eh != null) {
385                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
386                                 eh (this, ev);
387                         }
388                 }
389
390                 private static object MouseDownEvent = new object ();
391                 public event HtmlElementEventHandler MouseDown {
392                         add { 
393                                 Events.AddHandler (MouseDownEvent, value); 
394                                 document.MouseDown += new NodeEventHandler (OnMouseDown);
395                         }
396                         remove { 
397                                 Events.RemoveHandler (MouseDownEvent, value); 
398                                 document.MouseDown -= new NodeEventHandler (OnMouseDown);
399                         }
400                 }
401                 
402                 private void OnMouseDown (object sender, EventArgs e)
403                 {
404                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[MouseDownEvent];
405                         if (eh != null) {
406                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
407                                 eh (this, ev);
408                         }
409                 }
410
411                 private static object MouseLeaveEvent = new object ();
412                 public event HtmlElementEventHandler MouseLeave {
413                         add { 
414                                 Events.AddHandler (MouseLeaveEvent, value); 
415                                 document.MouseLeave += new NodeEventHandler (OnMouseLeave);
416                         }
417                         remove { 
418                                 Events.RemoveHandler (MouseLeaveEvent, value); 
419                                 document.MouseLeave -= new NodeEventHandler (OnMouseLeave);
420                         }
421                 }
422                 
423                 private void OnMouseLeave (object sender, EventArgs e)
424                 {
425                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[MouseLeaveEvent];
426                         if (eh != null) {
427                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
428                                 eh (this, ev);
429                         }
430                 }
431
432                 private static object MouseMoveEvent = new object ();
433                 public event HtmlElementEventHandler MouseMove {
434                         add { 
435                                 Events.AddHandler (MouseMoveEvent, value); 
436                                 document.MouseMove += new NodeEventHandler (OnMouseMove);
437                         }
438                         remove { 
439                                 Events.RemoveHandler (MouseMoveEvent, value); 
440                                 document.MouseMove -= new NodeEventHandler (OnMouseMove);
441                         }
442                 }
443                 
444                 private void OnMouseMove (object sender, EventArgs e)
445                 {
446                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[MouseMoveEvent];
447                         if (eh != null) {
448                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
449                                 eh (this, ev);
450                         }
451                 }
452
453                 private static object MouseOverEvent = new object ();
454                 public event HtmlElementEventHandler MouseOver {
455                         add { 
456                                 Events.AddHandler (MouseOverEvent, value); 
457                                 document.MouseOver += new NodeEventHandler (OnMouseOver);
458                         }
459                         remove { 
460                                 Events.RemoveHandler (MouseOverEvent, value); 
461                                 document.MouseOver -= new NodeEventHandler (OnMouseOver);
462                         }
463                 }
464                 
465                 private void OnMouseOver (object sender, EventArgs e)
466                 {
467                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[MouseOverEvent];
468                         if (eh != null) {
469                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
470                                 eh (this, ev);
471                         }
472                 }
473
474                 private static object MouseUpEvent = new object ();
475                 public event HtmlElementEventHandler MouseUp {
476                         add { 
477                                 Events.AddHandler (MouseUpEvent, value); 
478                                 document.MouseUp += new NodeEventHandler (OnMouseUp);
479                         }
480                         remove { 
481                                 Events.RemoveHandler (MouseUpEvent, value); 
482                                 document.MouseUp -= new NodeEventHandler (OnMouseUp);
483                         }
484                 }
485                 
486                 private void OnMouseUp (object sender, EventArgs e)
487                 {
488                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[MouseUpEvent];
489                         if (eh != null) {
490                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
491                                 eh (this, ev);
492                         }
493                 }
494
495                 private static object StopEvent = new object ();
496                 public event HtmlElementEventHandler Stop {
497                         add { 
498                                 Events.AddHandler (StopEvent, value); 
499                                 document.LoadStopped += new EventHandler (OnStop);
500                         }                       
501                         remove { 
502                                 Events.RemoveHandler (StopEvent, value); 
503                                 document.LoadStopped -= new EventHandler (OnStop);
504                         }
505                 }
506                 
507                 private void OnStop (object sender, EventArgs e)
508                 {
509                         HtmlElementEventHandler eh = (HtmlElementEventHandler) Events[StopEvent];
510                         if (eh != null) {
511                                 HtmlElementEventArgs ev = new HtmlElementEventArgs ();
512                                 eh (this, ev);
513                         }
514                 }
515
516                 #endregion
517
518
519                 #region Internal and Private
520                 private Color ParseColor (string color) {
521                         if (color.IndexOf ("#") >= 0) {
522                                 return Color.FromArgb (int.Parse (color.Substring (color.IndexOf ("#") + 1), NumberStyles.HexNumber));
523                         }
524                         return Color.FromName (color);
525                 }
526                 
527                 internal string DocType {
528                         get { 
529                                 if (this.document == null)
530                                         return String.Empty;
531                                 if (this.document.DocType != null)
532                                         return this.document.DocType.Name;
533                                 return String.Empty;
534                         }
535                 }
536                 #endregion
537         }
538                 
539 }
540
541 #endif